diff --git a/packages/picker/README.md b/packages/picker/README.md index b3f139951eb..e1158bea53b 100644 --- a/packages/picker/README.md +++ b/packages/picker/README.md @@ -376,7 +376,7 @@ When the `value` of an `` matches the `value` attribute or the trimme

-Quiet: +Quiet: ` matches the `value` attribute or the trimme ``` +### Loading + +When given a `loading` attribute, an `` will be delivered with an `` to visually outline that it is `loading` and it will not toggle open or display its `` descendants until the attribute is removed. + +```html +Standard: + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + +
+
+Quiet: + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + +``` + ## Accessibility To render accessibly, an `` element should be paired with an `` element that has a `for` attribute referencing the `id` of the `` element. diff --git a/packages/picker/package.json b/packages/picker/package.json index ce69d8bfb70..5726c3b061d 100644 --- a/packages/picker/package.json +++ b/packages/picker/package.json @@ -73,6 +73,7 @@ "@spectrum-web-components/menu": "^0.16.15", "@spectrum-web-components/overlay": "^0.19.3", "@spectrum-web-components/popover": "^0.12.15", + "@spectrum-web-components/progress-circle": "^0.7.7", "@spectrum-web-components/reactive-controllers": "^0.3.5", "@spectrum-web-components/shared": "^0.15.5", "@spectrum-web-components/tray": "^0.5.1" diff --git a/packages/picker/src/Picker.ts b/packages/picker/src/Picker.ts index 1f5603ab2f2..1fdc0f08375 100644 --- a/packages/picker/src/Picker.ts +++ b/packages/picker/src/Picker.ts @@ -43,6 +43,8 @@ import type { } from '@spectrum-web-components/menu'; import '@spectrum-web-components/tray/sp-tray.js'; import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/progress-circle/sp-progress-circle.js'; + import type { Popover } from '@spectrum-web-components/popover'; import { openOverlay, @@ -105,6 +107,9 @@ export class PickerBase extends SizedMixin(Focusable) { @property({ type: Boolean, reflect: true }) public invalid = false; + @property({ type: Boolean, reflect: true }) + public loading = false; + @property() public label?: string; @@ -391,6 +396,7 @@ export class PickerBase extends SizedMixin(Focusable) { 'visually-hidden': this.icons === 'only' && !!this.value, placeholder: !this.value, }; + return [ html` @@ -406,6 +412,15 @@ export class PickerBase extends SizedMixin(Focusable) { > ` : nothing} + ${this.loading + ? html` + + ` + : nothing} ${this.buttonContent} diff --git a/packages/picker/src/picker.css b/packages/picker/src/picker.css index 0dd395f7843..22ea9c23aa7 100644 --- a/packages/picker/src/picker.css +++ b/packages/picker/src/picker.css @@ -35,6 +35,41 @@ governing permissions and limitations under the License. --spectrum-picker-width: var(--spectrum-global-dimension-size-2400); } +:host([loading]) sp-progress-circle { + margin-inline-start: var( + --mod-picker-spacing-text-to-alert-icon-inline-start, + var(--spectrum-picker-spacing-text-to-alert-icon-inline-start) + ); +} + +:host([size='s']) sp-progress-circle { + --spectrum-progress-circle-size: var(--spectrum-workflow-icon-size-75); + --spectrum-progress-circle-thickness: var( + --spectrum-progress-circle-thickness-small + ); +} + +:host([size='m']) sp-progress-circle { + --spectrum-progress-circle-size: var(--spectrum-workflow-icon-size-100); + --spectrum-progress-circle-thickness: var( + --spectrum-progress-circle-thickness-small + ); +} + +:host([size='l']) sp-progress-circle { + --spectrum-progress-circle-size: var(--spectrum-workflow-icon-size-200); + --spectrum-progress-circle-thickness: var( + --spectrum-progress-circle-thickness-medium + ); +} + +:host([size='xl']) sp-progress-circle { + --spectrum-progress-circle-size: var(--spectrum-workflow-icon-size-300); + --spectrum-progress-circle-thickness: var( + --spectrum-progress-circle-thickness-large + ); +} + #button { width: 100%; min-width: 100%; diff --git a/packages/picker/stories/picker-sizes.stories.ts b/packages/picker/stories/picker-sizes.stories.ts index a3f08d5589b..ce7701e76e4 100644 --- a/packages/picker/stories/picker-sizes.stories.ts +++ b/packages/picker/stories/picker-sizes.stories.ts @@ -22,19 +22,47 @@ export default { component: 'sp-picker', argTypes: { onChange: { action: 'change' }, + invalid: { + name: 'invalid', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + loading: { + name: 'loading', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, }, }; type StoryArgs = { onChange: (val: string) => void; + invalid: boolean; + loading: boolean; }; const picker = ({ onChange, size, + loading, + invalid, }: { onChange: (val: string) => void; size: 's' | 'm' | 'l' | 'xl'; + loading: boolean; + invalid: boolean; }): TemplateResult => { return html` @@ -48,6 +76,8 @@ const picker = ({ onChange(picker.value); }}" label="Select a Country with a very long label, too long, in fact" + ?loading="${loading}" + ?invalid="${invalid}" > Deselect Select Inverse diff --git a/packages/picker/stories/picker.stories.ts b/packages/picker/stories/picker.stories.ts index 34ecc4f87aa..40674fb1886 100644 --- a/packages/picker/stories/picker.stories.ts +++ b/packages/picker/stories/picker.stories.ts @@ -58,6 +58,17 @@ export default { type: 'boolean', }, }, + loading: { + name: 'loading', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, open: { name: 'open', type: { name: 'boolean', required: false }, @@ -405,6 +416,29 @@ export const custom = (args: StoryArgs): TemplateResult => { `; }; +export const Loading = (args: StoryArgs): TemplateResult => { + return html` + + Picker in loading state + + + Loading... + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + `; +}; + custom.args = { open: true, }; diff --git a/packages/picker/test/index.ts b/packages/picker/test/index.ts index aa6cd023681..afe464a7c3d 100644 --- a/packages/picker/test/index.ts +++ b/packages/picker/test/index.ts @@ -286,6 +286,13 @@ export function runPickerTests(): void { expect(el.invalid).to.be.true; await expect(el).to.be.accessible(); }); + it('renders loading accessibly', async () => { + el.loading = true; + await elementUpdated(el); + + expect(el.loading).to.be.true; + await expect(el).to.be.accessible(); + }); it('renders selection accessibly', async () => { el.value = 'option-2'; await elementUpdated(el);