Align v10.38 (#698)

* chore(deps-dev): upgrade carbon-components to v10.38.0

* feat(text-input): support read-only variant

* docs: use consistent lingo for inline variant examples

* docs(popover): add Popover alignment example

* fix(file-uploader): adjust markup to avoid accessibility errors

Ref: 0dfde60e3

* fix(inline-loading): use error filled icon

* fix(inline-loading): render iconDescription as title in error/warning icons

Ref: 51c53c923

* fix(structured-list): update accessibility attributes

* fix(tooltip-definition): use span instead of div

Ref: cb6de3025

* fix(multi-select): close menu when blurring the last filterable option

* fix(multi-select): open/focus field for filterable multiselect #635

* fix(multi-select): unblock focus when blurring input #635

* fix(combo-box): select correct item with keys, allow input after clearing #195

* fix(combo-box): update input text if item is selected

* feat(combo-box): render checkmark icon for selected item

* fix(ui-shell): toggle SideNav rail when clicking the hamburger menu #699

* fix(context-menu): update context menu classes #684

* docs(context-menu): improve demo instructions #684

* fix(context-menu): close menu when clicking anywhere
This commit is contained in:
Eric Liu 2021-06-27 08:46:57 -07:00 committed by GitHub
commit e51f50da0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 285 additions and 88 deletions

View file

@ -79,6 +79,7 @@
on:change="{() => {
checked = !checked;
}}"
on:blur
/>
<label for="{id}" title="{title}" class:bx--checkbox-label="{true}">
<span

View file

@ -95,6 +95,7 @@
export let listRef = null;
import { createEventDispatcher, afterUpdate, tick } from "svelte";
import Checkmark16 from "carbon-icons-svelte/lib/Checkmark16/Checkmark16.svelte";
import WarningFilled16 from "carbon-icons-svelte/lib/WarningFilled16/WarningFilled16.svelte";
import WarningAltFilled16 from "carbon-icons-svelte/lib/WarningAltFilled16/WarningAltFilled16.svelte";
import ListBox from "../ListBox/ListBox.svelte";
@ -128,7 +129,6 @@
filteredItems = items.filter((item) => shouldFilterItem(item, value));
} else {
highlightedIndex = -1;
inputValue = selectedItem ? selectedItem.text : "";
if (!selectedItem) {
selectedId = undefined;
@ -149,7 +149,6 @@
: undefined;
$: filteredItems = items.filter((item) => shouldFilterItem(item, value));
$: selectedItem = items[selectedIndex];
$: inputValue = selectedItem ? selectedItem.text : undefined;
$: value = inputValue;
</script>
@ -217,16 +216,31 @@
class:bx--text-input="{true}"
class:bx--text-input--light="{light}"
class:bx--text-input--empty="{inputValue === ''}"
on:input="{({ target }) => {
on:input="{async ({ target }) => {
if (!open && target.value.length > 0) {
open = true;
}
inputValue = target.value;
}}"
on:keydown
on:keydown|stopPropagation="{({ key }) => {
if (key === 'Enter') {
open = !open;
if (highlightedIndex > -1 && highlightedIndex !== selectedIndex) {
selectedIndex = highlightedIndex;
open = false;
if (filteredItems[selectedIndex]) {
inputValue = filteredItems[selectedIndex].text;
}
}
if (highlightedIndex < 0 && selectedIndex > -1) {
if (filteredItems[selectedIndex]) {
inputValue = filteredItems[selectedIndex].text;
}
}
} else if (key === 'Tab') {
open = false;
@ -242,6 +256,12 @@
on:focus
on:blur
on:blur="{({ relatedTarget }) => {
if (inputValue.length === 0 && selectedIndex > -1) {
if (filteredItems[selectedIndex]) {
inputValue = filteredItems[selectedIndex].text;
}
}
if (!open || !relatedTarget) return;
if (
relatedTarget &&
@ -266,7 +286,9 @@
on:clear
on:clear="{() => {
selectedIndex = -1;
highlightedIndex = -1;
open = false;
inputValue = '';
ref.focus();
}}"
translateWithId="{translateWithId}"
@ -300,12 +322,19 @@
.map(({ id }) => id)
.indexOf(filteredItems[i].id);
open = false;
if (filteredItems[i]) {
inputValue = filteredItems[i].text;
}
}}"
on:mouseenter="{() => {
highlightedIndex = i;
}}"
>
{itemToString(item)}
{#if selectedItem && selectedItem.id === item.id}
<Checkmark16 class="bx--list-box__menu-item__selected-icon" />
{/if}
</ListBoxMenuItem>
{/each}
</ListBoxMenu>

View file

@ -79,6 +79,7 @@
<svelte:window
on:contextmenu|preventDefault="{(e) => {
if (level > 1) return;
if (!ref) return;
const { height, width } = ref.getBoundingClientRect();
@ -104,7 +105,7 @@
}}"
on:click="{(e) => {
if (!open) return;
if (e.target.contains(ref)) close();
close();
}}"
on:keydown="{(e) => {
if (open && e.key === 'Escape') close();
@ -117,10 +118,10 @@
tabindex="-1"
data-direction="{direction}"
data-level="{level}"
class:bx--context-menu="{true}"
class:bx--context-menu--open="{open}"
class:bx--context-menu--invisible="{open && x === 0 && y === 0}"
class:bx--context-menu--root="{level === 1}"
class:bx--menu="{true}"
class:bx--menu--open="{open}"
class:bx--menu--invisible="{open && x === 0 && y === 0}"
class:bx--menu--root="{level === 1}"
{...$$restProps}
style="left: {x}px; top: {y}px; {$$restProps.style}"
on:click

View file

@ -1 +1 @@
<li role="separator" class:bx--context-menu-divider="{true}"></li>
<li role="separator" class:bx--menu-divider="{true}"></li>

View file

@ -173,14 +173,14 @@
aria-disabled="{!subOptions && disabled}"
aria-haspopup="{subOptions ? true : undefined}"
aria-expanded="{subOptions ? submenuOpen : undefined}"
class:bx--context-menu-option="{true}"
class:bx--context-menu-option--disabled="{true}"
class:bx--context-menu-option--active="{subOptions && submenuOpen}"
class:bx--context-menu-option--danger="{!subOptions && kind === 'danger'}"
class:bx--menu-option="{true}"
class:bx--menu-option--disabled="{true}"
class:bx--menu-option--active="{subOptions && submenuOpen}"
class:bx--menu-option--danger="{!subOptions && kind === 'danger'}"
indented="{indented}"
aria-checked="{isSelectable || isRadio ? selected : undefined}"
data-nested="{ref &&
ref.closest('.bx--context-menu').getAttribute('data-level') === '2'}"
ref.closest('.bx--menu').getAttribute('data-level') === '2'}"
data-sub="{subOptions}"
data-id="{id}"
{...$$restProps}
@ -240,18 +240,18 @@
>
{#if subOptions}
<div
class:bx--context-menu-option__content="{true}"
class:bx--context-menu-option__content--disabled="{disabled}"
class:bx--menu-option__content="{true}"
class:bx--menu-option__content--disabled="{disabled}"
>
{#if indented}
<div class:bx--context-menu-option__icon="{true}">
<div class:bx--menu-option__icon="{true}">
<svelte:component this="{icon}" />
</div>
{/if}
<span class:bx--context-menu-option__label="{true}" title="{labelText}">
<span class:bx--menu-option__label="{true}" title="{labelText}">
<slot name="labelText">{labelText}</slot>
</span>
<div class:bx--context-menu-option__info="{true}"><CaretRight16 /></div>
<div class:bx--menu-option__info="{true}"><CaretRight16 /></div>
</div>
<ContextMenu
@ -263,18 +263,18 @@
</ContextMenu>
{:else}
<div
class:bx--context-menu-option__content="{true}"
class:bx--context-menu-option__content--disabled="{disabled}"
class:bx--menu-option__content="{true}"
class:bx--menu-option__content--disabled="{disabled}"
>
{#if indented}
<div class:bx--context-menu-option__icon="{true}">
<div class:bx--menu-option__icon="{true}">
<svelte:component this="{icon}" />
</div>
{/if}
<span class:bx--context-menu-option__label="{true}" title="{labelText}">
<span class:bx--menu-option__label="{true}" title="{labelText}">
<slot name="labelText">{labelText}</slot>
</span>
<div class:bx--context-menu-option__info="{true}">
<div class:bx--menu-option__info="{true}">
<slot name="shortcutText">{shortcutText}</slot>
</div>
</div>

View file

@ -92,25 +92,25 @@
<slot name="labelText">
{labelText}
</slot>
<input
bind:this="{ref}"
type="file"
tabindex="-1"
id="{id}"
disabled="{disabled}"
accept="{accept}"
name="{name}"
multiple="{multiple}"
class:bx--file-input="{true}"
on:change
on:change="{({ target }) => {
dispatch('add', validateFiles(target.files));
}}"
on:click
on:click="{({ target }) => {
target.value = null;
}}"
/>
</div>
<input
bind:this="{ref}"
type="file"
tabindex="-1"
id="{id}"
disabled="{disabled}"
accept="{accept}"
name="{name}"
multiple="{multiple}"
class:bx--file-input="{true}"
on:change
on:change="{({ target }) => {
dispatch('add', validateFiles(target.files));
}}"
on:click
on:click="{({ target }) => {
target.value = null;
}}"
/>
</label>
</div>

View file

@ -22,7 +22,7 @@
import { createEventDispatcher, afterUpdate, onMount } from "svelte";
import CheckmarkFilled16 from "carbon-icons-svelte/lib/CheckmarkFilled16/CheckmarkFilled16.svelte";
import Error20 from "carbon-icons-svelte/lib/Error20/Error20.svelte";
import ErrorFilled16 from "carbon-icons-svelte/lib/ErrorFilled16/ErrorFilled16.svelte";
import Loading from "../Loading/Loading.svelte";
const dispatch = createEventDispatcher();
@ -55,9 +55,15 @@
>
<div class:bx--inline-loading__animation="{true}">
{#if status === "error"}
<Error20 class="bx--inline-loading--error" />
<ErrorFilled16
class="bx--inline-loading--error"
title="{iconDescription}"
/>
{:else if status === "finished"}
<CheckmarkFilled16 class="bx--inline-loading__checkmark-container" />
<CheckmarkFilled16
class="bx--inline-loading__checkmark-container"
title="{iconDescription}"
/>
{:else if status === "inactive" || status === "active"}
<Loading
small

View file

@ -61,6 +61,7 @@
on:mouseenter
on:mouseleave
on:keydown|preventDefault|stopPropagation
on:focus
on:blur
>
<slot />

View file

@ -319,6 +319,12 @@
}
}
}}"
on:focus="{() => {
if (filterable) {
open = true;
if (inputRef) inputRef.focus();
}
}}"
on:blur="{({ relatedTarget }) => {
if (
relatedTarget &&
@ -342,7 +348,7 @@
...item,
checked: false,
}));
fieldRef.blur();
if (fieldRef) fieldRef.blur();
}}"
translateWithId="{translateWithId}"
disabled="{disabled}"
@ -388,7 +394,11 @@
on:blur="{({ relatedTarget }) => {
if (
relatedTarget &&
relatedTarget.getAttribute('role') !== 'button'
!['INPUT', 'SELECT', 'TEXTAREA'].includes(
relatedTarget.tagName
) &&
relatedTarget.getAttribute('role') !== 'button' &&
relatedTarget.getAttribute('role') !== 'searchbox'
) {
inputRef.focus();
}
@ -453,6 +463,9 @@
labelText="{itemToString(item)}"
checked="{item.checked}"
disabled="{disabled}"
on:blur="{() => {
if (i === filteredItems.length - 1) open = false;
}}"
/>
</ListBoxMenuItem>
{/each}

View file

@ -38,7 +38,7 @@
</script>
<div
aria-label="Structured list section"
role="table"
class:bx--structured-list="{true}"
class:bx--structured-list--border="{border}"
class:bx--structured-list--selection="{selection}"

View file

@ -1,6 +1,6 @@
<div
class:bx--structured-list-tbody="{true}"
role="rowgroup"
class:bx--structured-list-tbody="{true}"
{...$$restProps}
on:click
on:mouseover

View file

@ -7,6 +7,7 @@
</script>
<div
role="{head ? 'columnheader' : 'cell'}"
class:bx--structured-list-th="{head}"
class:bx--structured-list-td="{!head}"
class:bx--structured-list-content--nowrap="{noWrap}"

View file

@ -1,4 +1,5 @@
<div
role="rowgroup"
class:bx--structured-list-thead="{true}"
{...$$restProps}
on:click

View file

@ -12,7 +12,6 @@
{#if label}
<!-- svelte-ignore a11y-label-has-associated-control -->
<label
role="presentation"
tabindex="{tabindex}"
class:bx--structured-list-row="{true}"
class:bx--structured-list-row--header-row="{head}"
@ -27,6 +26,7 @@
</label>
{:else}
<div
role="row"
class:bx--structured-list-row="{true}"
class:bx--structured-list-row--header-row="{head}"
{...$$restProps}

View file

@ -59,12 +59,16 @@
/** Set to `true` to mark the field as required */
export let required = false;
/** Set to `true` to use inline version */
/** Set to `true` to use the inline variant */
export let inline = false;
/** Set to `true` to use the read-only variant */
export let readonly = false;
import { getContext } from "svelte";
import WarningFilled16 from "carbon-icons-svelte/lib/WarningFilled16/WarningFilled16.svelte";
import WarningAltFilled16 from "carbon-icons-svelte/lib/WarningAltFilled16/WarningAltFilled16.svelte";
import EditOff16 from "carbon-icons-svelte/lib/EditOff16/EditOff16.svelte";
const ctx = getContext("Form");
@ -77,6 +81,8 @@
class:bx--form-item="{true}"
class:bx--text-input-wrapper="{true}"
class:bx--text-input-wrapper--inline="{inline}"
class:bx--text-input-wrapper--light="{light}"
class:bx--text-input-wrapper--readonly="{readonly}"
on:click
on:mouseover
on:mouseenter
@ -142,6 +148,9 @@
bx--text-input__invalid-icon--warning"
/>
{/if}
{#if readonly}
<EditOff16 class="bx--text-input__readonly-icon" />
{/if}
<input
bind:this="{ref}"
data-invalid="{invalid || undefined}"
@ -155,6 +164,7 @@
type="{type}"
value="{value}"
required="{required}"
readonly="{readonly}"
class:bx--text-input="{true}"
class:bx--text-input--light="{light}"
class:bx--text-input--invalid="{invalid}"

View file

@ -36,7 +36,7 @@
if (key === 'Escape') hide();
}}" />
<div
<span
class:bx--tooltip--definition="{true}"
class:bx--tooltip--a11y="{true}"
{...$$restProps}
@ -69,4 +69,4 @@
<div role="tooltip" id="{id}" class:bx--assistive-text="{true}">
<slot name="tooltip">{tooltipText}</slot>
</div>
</div>
</span>

View file

@ -25,6 +25,8 @@
const dispatch = createEventDispatcher();
let winWidth = undefined;
$: dispatch(isOpen ? "open" : "close");
onMount(() => {
@ -33,6 +35,8 @@
});
</script>
<svelte:window bind:innerWidth="{winWidth}" />
{#if !fixed}
<div
on:click="{() => {
@ -49,7 +53,7 @@
class:bx--side-nav__navigation="{true}"
class:bx--side-nav="{true}"
class:bx--side-nav--ux="{true}"
class:bx--side-nav--expanded="{isOpen && !rail}"
class:bx--side-nav--expanded="{rail && winWidth >= 1056 ? false : isOpen}"
class:bx--side-nav--collapsed="{!isOpen && !rail}"
class:bx--side-nav--rail="{rail}"
{...$$restProps}