From b6de7f4f02bfd0a8f04eb60b7b61aa4a19e31926 Mon Sep 17 00:00:00 2001 From: Ruben Carvalho Date: Sun, 2 Nov 2025 22:03:29 +0100 Subject: [PATCH 01/10] chore: move repository contents under 1st-gen/ --- 1st-gen/.eslintignore | 6 + 1st-gen/.eslintrc.json | 162 + 1st-gen/.prettierignore | 3 + 1st-gen/.prettierrc.yaml | 13 + CHANGELOG.md => 1st-gen/CHANGELOG.md | 0 INVENTORY.md => 1st-gen/INVENTORY.md | 0 1st-gen/README.md | 223 + .../cem-react-wrapper.config.js | 0 .../custom-elements-manifest.config.js | 1 + 1st-gen/linters/eslint/.npmrc | 3 + 1st-gen/linters/eslint/CHANGELOG.md | 178 + 1st-gen/linters/eslint/index.js | 62 + 1st-gen/linters/eslint/package.json | 27 + .../ts-rules/fileShouldContainHeaderRule.js | 114 + .../ts-rules/fileShouldContainHeaderRule.ts | 85 + 1st-gen/linters/ts-rules/tsconfig.json | 23 + 1st-gen/linters/ts-rules/tslint.json | 8 + 1st-gen/package.json | 434 ++ 1st-gen/packages/.eslintrc.json | 210 + 1st-gen/packages/accordion/.npmrc | 3 + 1st-gen/packages/accordion/CHANGELOG.md | 606 +++ 1st-gen/packages/accordion/README.md | 359 ++ 1st-gen/packages/accordion/accordion-item.md | 89 + 1st-gen/packages/accordion/package.json | 89 + .../packages/accordion/sp-accordion-item.ts | 22 + 1st-gen/packages/accordion/sp-accordion.ts | 22 + 1st-gen/packages/accordion/src/Accordion.ts | 123 + .../packages/accordion/src/AccordionItem.ts | 144 + .../src/accordion-item-overrides.css | 11 + .../packages/accordion/src/accordion-item.css | 27 + .../accordion/src/accordion-overrides.css | 17 + 1st-gen/packages/accordion/src/accordion.css | 18 + 1st-gen/packages/accordion/src/index.ts | 14 + .../accordion/src/spectrum-accordion-item.css | 168 + .../accordion/src/spectrum-accordion.css | 149 + .../accordion-densities-compact.stories.ts | 28 + .../accordion-densities-spacious.stories.ts | 28 + .../stories/accordion-sizes.stories.ts | 24 + .../accordion/stories/accordion.stories.ts | 61 + 1st-gen/packages/accordion/stories/args.ts | 72 + 1st-gen/packages/accordion/stories/index.ts | 54 + .../packages/accordion/stories/template.ts | 15 + .../packages/accordion/test/a11y-tree.test.ts | 43 + .../accordion/test/accordion-memory.test.ts | 18 + .../accordion/test/benchmark/basic-test.ts | 39 + .../accordion/test/controlled.test.ts | 47 + .../accordion/test/declarative.test.ts | 94 + .../packages/accordion/test/dev-mode.test.ts | 22 + .../accordion/test/imperative.test.ts | 149 + .../packages/accordion/test/keyboard.test.ts | 226 ++ .../packages/accordion/test/memory.test.ts | 18 + 1st-gen/packages/accordion/tsconfig.json | 14 + 1st-gen/packages/action-bar/.npmrc | 3 + 1st-gen/packages/action-bar/CHANGELOG.md | 552 +++ 1st-gen/packages/action-bar/README.md | 104 + 1st-gen/packages/action-bar/package.json | 79 + 1st-gen/packages/action-bar/sp-action-bar.ts | 22 + 1st-gen/packages/action-bar/src/ActionBar.ts | 126 + .../action-bar/src/action-bar-overrides.css | 16 + .../packages/action-bar/src/action-bar.css | 22 + 1st-gen/packages/action-bar/src/index.ts | 13 + .../action-bar/src/spectrum-action-bar.css | 128 + .../action-bar/stories/action-bar.stories.ts | 104 + 1st-gen/packages/action-bar/stories/args.ts | 50 + .../packages/action-bar/stories/template.ts | 46 + .../action-bar/test/action-bar-memory.test.ts | 16 + .../action-bar/test/action-bar.test.ts | 113 + .../action-bar/test/benchmark/basic-test.ts | 19 + 1st-gen/packages/action-bar/tsconfig.json | 14 + 1st-gen/packages/action-button/.npmrc | 3 + 1st-gen/packages/action-button/CHANGELOG.md | 649 +++ 1st-gen/packages/action-button/README.md | 740 ++++ 1st-gen/packages/action-button/package.json | 79 + .../action-button/sp-action-button.ts | 22 + .../action-button/src/ActionButton.ts | 280 ++ .../src/action-button-overrides.css | 103 + .../action-button/src/action-button.css | 56 + 1st-gen/packages/action-button/src/index.ts | 13 + .../src/spectrum-action-button.css | 328 ++ .../action-button-black-quiet.stories.ts | 60 + .../stories/action-button-black.stories.ts | 54 + .../action-button-emphasized-quiet.stories.ts | 58 + .../action-button-emphasized.stories.ts | 52 + .../stories/action-button-quiet.stories.ts | 52 + .../stories/action-button-standard.stories.ts | 45 + .../action-button-white-quiet.stories.ts | 60 + .../stories/action-button-white.stories.ts | 54 + .../stories/action-button.stories.ts | 59 + .../packages/action-button/stories/index.ts | 117 + .../test/action-button-memory.test.ts | 16 + .../action-button/test/action-button.test.ts | 316 ++ .../test/benchmark/basic-test.ts | 30 + 1st-gen/packages/action-button/tsconfig.json | 16 + 1st-gen/packages/action-group/.npmrc | 3 + 1st-gen/packages/action-group/CHANGELOG.md | 681 ++++ 1st-gen/packages/action-group/README.md | 478 +++ 1st-gen/packages/action-group/package.json | 79 + .../packages/action-group/sp-action-group.ts | 22 + .../packages/action-group/src/ActionGroup.ts | 447 ++ .../src/action-group-overrides.css | 17 + .../action-group/src/action-group.css | 110 + 1st-gen/packages/action-group/src/index.ts | 13 + .../src/spectrum-action-group.css | 139 + .../stories/action-group-sizes.stories.ts | 179 + .../stories/action-group-tooltip.stories.ts | 414 ++ .../stories/action-group.stories.ts | 393 ++ .../test/action-group-memory.test.ts | 16 + .../action-group/test/action-group.test.ts | 1543 +++++++ .../action-group/test/benchmark/basic-test.ts | 24 + 1st-gen/packages/action-group/tsconfig.json | 10 + 1st-gen/packages/action-menu/.npmrc | 3 + 1st-gen/packages/action-menu/CHANGELOG.md | 921 +++++ 1st-gen/packages/action-menu/README.md | 319 ++ 1st-gen/packages/action-menu/package.json | 84 + .../packages/action-menu/sp-action-menu.ts | 22 + .../packages/action-menu/src/ActionMenu.ts | 166 + .../packages/action-menu/src/action-menu.css | 61 + 1st-gen/packages/action-menu/src/index.ts | 12 + .../stories/action-menu-sizes.stories.ts | 43 + .../stories/action-menu.stories.ts | 565 +++ 1st-gen/packages/action-menu/stories/index.ts | 94 + .../action-menu/sync/sp-action-menu.ts | 14 + .../test/action-menu-directive.test.ts | 48 + .../test/action-menu-groups.test.ts | 98 + .../test/action-menu-memory.test.ts | 16 + .../test/action-menu-responsive.test.ts | 163 + .../action-menu/test/action-menu-sync.test.ts | 21 + .../action-menu/test/action-menu.test.ts | 21 + .../action-menu/test/benchmark/test-basic.ts | 31 + .../test/benchmark/test-directive.ts | 37 + .../action-menu/test/benchmark/test-lazy.ts | 50 + .../benchmark/test-open-close-directive.ts | 89 + .../test/benchmark/test-open-close.ts | 83 + 1st-gen/packages/action-menu/test/index.ts | 943 +++++ 1st-gen/packages/action-menu/tsconfig.json | 15 + 1st-gen/packages/alert-banner/.npmignore | 2 + 1st-gen/packages/alert-banner/.npmrc | 3 + 1st-gen/packages/alert-banner/CHANGELOG.md | 140 + 1st-gen/packages/alert-banner/README.md | 137 + 1st-gen/packages/alert-banner/package.json | 78 + .../packages/alert-banner/sp-alert-banner.ts | 21 + .../packages/alert-banner/src/AlertBanner.ts | 81 + .../src/alert-banner-overrides.css | 15 + .../alert-banner/src/alert-banner.css | 14 + 1st-gen/packages/alert-banner/src/index.ts | 12 + .../src/spectrum-alert-banner.css | 100 + .../stories/alert-banner.stories.ts | 76 + 1st-gen/packages/alert-banner/stories/args.ts | 62 + .../packages/alert-banner/stories/index.ts | 36 + .../packages/alert-banner/stories/template.ts | 15 + .../test/alert-banner-memory.test.ts | 16 + .../alert-banner/test/alert-banner.test.ts | 212 + .../alert-banner/test/benchmark/basic-test.ts | 18 + 1st-gen/packages/alert-banner/tsconfig.json | 10 + 1st-gen/packages/alert-dialog/.npmignore | 2 + 1st-gen/packages/alert-dialog/.npmrc | 3 + 1st-gen/packages/alert-dialog/CHANGELOG.md | 248 ++ 1st-gen/packages/alert-dialog/README.md | 399 ++ 1st-gen/packages/alert-dialog/package.json | 82 + .../packages/alert-dialog/sp-alert-dialog.ts | 21 + .../packages/alert-dialog/src/AlertDialog.ts | 227 ++ .../src/alert-dialog-overrides.css | 29 + .../alert-dialog/src/alert-dialog.css | 14 + 1st-gen/packages/alert-dialog/src/index.ts | 12 + .../src/spectrum-alert-dialog.css | 99 + .../stories/alert-dialog.stories.ts | 186 + .../test/alert-dialog-memory.test.ts | 16 + .../alert-dialog/test/alert-dialog.test.ts | 89 + .../alert-dialog/test/benchmark/basic-test.ts | 40 + 1st-gen/packages/alert-dialog/tsconfig.json | 13 + 1st-gen/packages/asset/.npmrc | 3 + 1st-gen/packages/asset/CHANGELOG.md | 473 +++ 1st-gen/packages/asset/README.md | 51 + 1st-gen/packages/asset/package.json | 80 + 1st-gen/packages/asset/sp-asset.ts | 22 + 1st-gen/packages/asset/src/Asset.ts | 77 + .../packages/asset/src/asset-overrides.css | 17 + 1st-gen/packages/asset/src/asset.css | 14 + 1st-gen/packages/asset/src/index.ts | 13 + 1st-gen/packages/asset/src/spectrum-asset.css | 61 + .../packages/asset/stories/asset.stories.ts | 41 + .../packages/asset/test/asset-memory.test.ts | 16 + 1st-gen/packages/asset/test/asset.test.ts | 42 + .../asset/test/benchmark/basic-test.ts | 19 + 1st-gen/packages/asset/tsconfig.json | 9 + 1st-gen/packages/avatar/.npmrc | 3 + 1st-gen/packages/avatar/CHANGELOG.md | 551 +++ 1st-gen/packages/avatar/README.md | 158 + 1st-gen/packages/avatar/package.json | 76 + 1st-gen/packages/avatar/sp-avatar.ts | 21 + 1st-gen/packages/avatar/src/Avatar.ts | 98 + .../packages/avatar/src/avatar-overrides.css | 11 + 1st-gen/packages/avatar/src/avatar.css | 18 + 1st-gen/packages/avatar/src/index.ts | 12 + .../packages/avatar/src/spectrum-avatar.css | 117 + .../packages/avatar/stories/avatar.stories.ts | 87 + 1st-gen/packages/avatar/stories/images.ts | 14 + .../avatar/test/avatar-memory.test.ts | 16 + 1st-gen/packages/avatar/test/avatar.test.ts | 122 + .../avatar/test/benchmark/test-basic.ts | 22 + 1st-gen/packages/avatar/tsconfig.json | 9 + 1st-gen/packages/badge/.npmignore | 2 + 1st-gen/packages/badge/.npmrc | 3 + 1st-gen/packages/badge/CHANGELOG.md | 350 ++ 1st-gen/packages/badge/README.md | 304 ++ 1st-gen/packages/badge/package.json | 77 + 1st-gen/packages/badge/sp-badge.ts | 22 + 1st-gen/packages/badge/src/Badge.ts | 111 + .../packages/badge/src/badge-overrides.css | 11 + 1st-gen/packages/badge/src/badge.css | 63 + 1st-gen/packages/badge/src/index.ts | 13 + 1st-gen/packages/badge/src/spectrum-badge.css | 265 ++ .../packages/badge/stories/badge.stories.ts | 156 + .../packages/badge/test/badge-memory.test.ts | 16 + 1st-gen/packages/badge/test/badge.test.ts | 116 + .../badge/test/benchmark/basic-test.ts | 23 + 1st-gen/packages/badge/tsconfig.json | 10 + 1st-gen/packages/breadcrumbs/.npmignore | 2 + 1st-gen/packages/breadcrumbs/.npmrc | 3 + 1st-gen/packages/breadcrumbs/CHANGELOG.md | 145 + 1st-gen/packages/breadcrumbs/README.md | 236 ++ .../packages/breadcrumbs/breadcrumb-item.md | 114 + 1st-gen/packages/breadcrumbs/package.json | 88 + .../breadcrumbs/sp-breadcrumb-item.ts | 21 + .../packages/breadcrumbs/sp-breadcrumbs.ts | 20 + .../breadcrumbs/src/BreadcrumbItem.ts | 135 + .../packages/breadcrumbs/src/Breadcrumbs.ts | 340 ++ .../breadcrumbs/src/breadcrumb-item.css | 21 + .../src/breadcrumbs-item-overrides.css | 11 + .../breadcrumbs/src/breadcrumbs-overrides.css | 11 + .../packages/breadcrumbs/src/breadcrumbs.css | 30 + 1st-gen/packages/breadcrumbs/src/index.ts | 13 + .../src/spectrum-breadcrumbs-item.css | 123 + .../breadcrumbs/src/spectrum-breadcrumbs.css | 115 + 1st-gen/packages/breadcrumbs/stories/args.ts | 48 + .../stories/breadcrumbs.stories.ts | 146 + .../packages/breadcrumbs/stories/template.ts | 91 + .../breadcrumbs/test/benchmark/basic-test.ts | 38 + .../breadcrumbs/test/breadcrumb-item.test.ts | 109 + .../breadcrumbs/test/breadcrumbs.test.ts | 227 ++ 1st-gen/packages/breadcrumbs/tsconfig.json | 10 + 1st-gen/packages/button-group/.npmrc | 3 + 1st-gen/packages/button-group/CHANGELOG.md | 537 +++ 1st-gen/packages/button-group/README.md | 52 + 1st-gen/packages/button-group/package.json | 76 + .../packages/button-group/sp-button-group.ts | 21 + .../packages/button-group/src/ButtonGroup.ts | 72 + .../src/button-group-overrides.css | 11 + .../button-group/src/button-group.css | 26 + 1st-gen/packages/button-group/src/index.ts | 13 + .../src/spectrum-button-group.css | 40 + .../stories/button-group-sizes.stories.ts | 52 + .../stories/button-group.stories.ts | 62 + .../button-group/test/benchmark/basic-test.ts | 24 + .../test/button-group-memory.test.ts | 16 + .../button-group/test/button-group.test.ts | 57 + 1st-gen/packages/button-group/tsconfig.json | 9 + 1st-gen/packages/button/.npmrc | 3 + 1st-gen/packages/button/CHANGELOG.md | 1007 +++++ 1st-gen/packages/button/README.md | 418 ++ 1st-gen/packages/button/clear-button.md | 160 + 1st-gen/packages/button/close-button.md | 144 + 1st-gen/packages/button/package.json | 107 + 1st-gen/packages/button/sp-button.ts | 21 + 1st-gen/packages/button/sp-clear-button.ts | 21 + 1st-gen/packages/button/sp-close-button.ts | 22 + 1st-gen/packages/button/src/Button.ts | 205 + 1st-gen/packages/button/src/ButtonBase.ts | 261 ++ 1st-gen/packages/button/src/ClearButton.ts | 124 + 1st-gen/packages/button/src/CloseButton.ts | 80 + 1st-gen/packages/button/src/StyledButton.ts | 15 + 1st-gen/packages/button/src/button-base.css | 89 + .../packages/button/src/button-overrides.css | 155 + 1st-gen/packages/button/src/button.css | 104 + 1st-gen/packages/button/src/index.ts | 16 + .../button/src/spectrum-button-base.css | 11 + .../packages/button/src/spectrum-button.css | 578 +++ .../button-accent-fill-pending.stories.ts | 50 + .../button-accent-fill-sizes.stories.ts | 48 + .../stories/button-accent-fill.stories.ts | 60 + .../button-accent-outline-pending.stories.ts | 50 + .../button-accent-outline-sizes.stories.ts | 48 + .../stories/button-accent-outline.stories.ts | 60 + .../button-black-fill-pending.stories.ts | 50 + .../button-black-fill-sizes.stories.ts | 49 + .../stories/button-black-fill.stories.ts | 76 + .../button-black-outline-pending.stories.ts | 50 + .../button-black-outline-sizes.stories.ts | 49 + .../stories/button-black-outline.stories.ts | 76 + .../button-negative-fill-pending.stories.ts | 50 + .../button-negative-fill-sizes.stories.ts | 48 + .../stories/button-negative-fill.stories.ts | 60 + ...button-negative-outline-pending.stories.ts | 50 + .../button-negative-outline-sizes.stories.ts | 48 + .../button-negative-outline.stories.ts | 60 + .../button-primary-fill-pending.stories.ts | 50 + .../button-primary-fill-sizes.stories.ts | 48 + .../stories/button-primary-fill.stories.ts | 75 + .../button-primary-outline-pending.stories.ts | 50 + .../button-primary-outline-sizes.stories.ts | 48 + .../stories/button-primary-outline.stories.ts | 60 + .../button-secondary-fill-pending.stories.ts | 50 + .../button-secondary-fill-sizes.stories.ts | 48 + .../stories/button-secondary-fill.stories.ts | 60 + ...utton-secondary-outline-pending.stories.ts | 50 + .../button-secondary-outline-sizes.stories.ts | 48 + .../button-secondary-outline.stories.ts | 60 + .../button-white-fill-pending.stories.ts | 50 + .../button-white-fill-sizes.stories.ts | 49 + .../stories/button-white-fill.stories.ts | 76 + .../button-white-outline-pending.stories.ts | 50 + .../button-white-outline-sizes.stories.ts | 49 + .../stories/button-white-outline.stories.ts | 76 + 1st-gen/packages/button/stories/index.ts | 243 ++ 1st-gen/packages/button/stories/template.ts | 51 + .../button/test/benchmark/test-basic.ts | 25 + .../button/test/button-memory.test.ts | 16 + 1st-gen/packages/button/test/button.test.ts | 930 +++++ .../packages/button/test/clear-button.test.ts | 82 + .../packages/button/test/close-button.test.ts | 44 + 1st-gen/packages/button/tsconfig.json | 15 + 1st-gen/packages/card/.npmrc | 3 + 1st-gen/packages/card/CHANGELOG.md | 788 ++++ 1st-gen/packages/card/README.md | 259 ++ 1st-gen/packages/card/package.json | 82 + 1st-gen/packages/card/sp-card.ts | 22 + 1st-gen/packages/card/src/Card.ts | 401 ++ 1st-gen/packages/card/src/card-overrides.css | 19 + 1st-gen/packages/card/src/card.css | 158 + 1st-gen/packages/card/src/index.ts | 12 + 1st-gen/packages/card/src/spectrum-card.css | 443 ++ 1st-gen/packages/card/stories/card.stories.ts | 459 +++ 1st-gen/packages/card/stories/images.ts | 16 + .../card/test/benchmark/test-basic.ts | 27 + .../packages/card/test/card-memory.test.ts | 16 + 1st-gen/packages/card/test/card.test.ts | 725 ++++ 1st-gen/packages/card/tsconfig.json | 15 + 1st-gen/packages/checkbox/.npmrc | 3 + 1st-gen/packages/checkbox/CHANGELOG.md | 784 ++++ 1st-gen/packages/checkbox/README.md | 252 ++ 1st-gen/packages/checkbox/package.json | 86 + 1st-gen/packages/checkbox/sp-checkbox.ts | 21 + 1st-gen/packages/checkbox/src/Checkbox.ts | 204 + 1st-gen/packages/checkbox/src/CheckboxBase.ts | 19 + .../packages/checkbox/src/CheckboxMixin.ts | 88 + .../checkbox/src/checkbox-overrides.css | 20 + 1st-gen/packages/checkbox/src/checkbox.css | 31 + 1st-gen/packages/checkbox/src/index.ts | 12 + .../checkbox/src/spectrum-checkbox.css | 399 ++ .../stories/checkbox-sizes.stories.ts | 90 + .../checkbox/stories/checkbox.stories.ts | 169 + .../checkbox/test/benchmark/test-basic.ts | 21 + .../checkbox/test/checkbox-memory.test.ts | 16 + .../packages/checkbox/test/checkbox.test.ts | 399 ++ 1st-gen/packages/checkbox/tsconfig.json | 14 + 1st-gen/packages/clear-button/.npmignore | 2 + 1st-gen/packages/clear-button/.npmrc | 3 + 1st-gen/packages/clear-button/CHANGELOG.md | 351 ++ 1st-gen/packages/clear-button/package.json | 60 + .../src/clear-button-overrides.css | 12 + .../clear-button/src/clear-button.css | 155 + 1st-gen/packages/clear-button/tsconfig.json | 10 + 1st-gen/packages/close-button/.npmignore | 2 + 1st-gen/packages/close-button/.npmrc | 3 + 1st-gen/packages/close-button/CHANGELOG.md | 351 ++ 1st-gen/packages/close-button/package.json | 60 + .../src/close-button-overrides.css | 30 + .../close-button/src/close-button.css | 14 + .../src/spectrum-close-button.css | 270 ++ 1st-gen/packages/close-button/tsconfig.json | 10 + 1st-gen/packages/coachmark/.npmrc | 3 + 1st-gen/packages/coachmark/CHANGELOG.md | 554 +++ 1st-gen/packages/coachmark/README.md | 277 ++ 1st-gen/packages/coachmark/coach-indicator.md | 69 + 1st-gen/packages/coachmark/package.json | 96 + .../packages/coachmark/sp-coach-indicator.ts | 21 + 1st-gen/packages/coachmark/sp-coachmark.ts | 21 + .../packages/coachmark/src/CoachIndicator.ts | 42 + 1st-gen/packages/coachmark/src/Coachmark.ts | 316 ++ .../packages/coachmark/src/CoachmarkItem.ts | 31 + .../src/coach-indicator-overrides.css | 44 + .../coachmark/src/coach-indicator.css | 18 + .../coachmark/src/coachmark-overrides.css | 45 + 1st-gen/packages/coachmark/src/coachmark.css | 65 + 1st-gen/packages/coachmark/src/index.ts | 14 + .../src/spectrum-coach-indicator.css | 106 + .../coachmark/src/spectrum-coachmark.css | 124 + .../stories/coach-indicator-static.stories.ts | 35 + .../stories/coach-indicator.stories.ts | 31 + .../coachmark/stories/coachmark.stories.ts | 336 ++ 1st-gen/packages/coachmark/stories/images.ts | 20 + .../coachmark/test/benchmark/basic-test.ts | 35 + .../test/coach-indicator-memory.test.ts | 19 + .../coachmark/test/coach-indicator.test.ts | 32 + .../coachmark/test/coach-mark-memory.test.ts | 16 + .../packages/coachmark/test/coachmark.test.ts | 234 ++ 1st-gen/packages/coachmark/tsconfig.json | 13 + 1st-gen/packages/color-area/.npmrc | 3 + 1st-gen/packages/color-area/CHANGELOG.md | 522 +++ 1st-gen/packages/color-area/README.md | 300 ++ 1st-gen/packages/color-area/package.json | 83 + 1st-gen/packages/color-area/sp-color-area.ts | 22 + 1st-gen/packages/color-area/src/ColorArea.ts | 617 +++ .../color-area/src/color-area-overrides.css | 11 + .../packages/color-area/src/color-area.css | 54 + 1st-gen/packages/color-area/src/index.ts | 13 + .../color-area/src/spectrum-color-area.css | 82 + 1st-gen/packages/color-area/src/types.ts | 33 + .../color-area/stories/color-area.stories.ts | 198 + .../color-area/test/benchmark/basic-test.ts | 19 + .../color-area/test/color-area-memory.test.ts | 19 + .../color-area/test/color-area.test.ts | 909 +++++ 1st-gen/packages/color-area/tsconfig.json | 10 + 1st-gen/packages/color-field/.npmignore | 2 + 1st-gen/packages/color-field/.npmrc | 3 + 1st-gen/packages/color-field/CHANGELOG.md | 177 + 1st-gen/packages/color-field/README.md | 252 ++ 1st-gen/packages/color-field/package.json | 76 + .../packages/color-field/sp-color-field.ts | 21 + .../packages/color-field/src/ColorField.ts | 101 + .../packages/color-field/src/color-field.css | 15 + 1st-gen/packages/color-field/src/index.ts | 12 + 1st-gen/packages/color-field/stories/args.ts | 67 + .../stories/color-field-sizes.stories.ts | 26 + .../stories/color-field.stories.ts | 97 + .../packages/color-field/stories/colors.ts | 77 + .../packages/color-field/stories/template.ts | 49 + .../color-field/test/benchmark/basic-test.ts | 18 + .../test/color-field-memory.test.ts | 16 + .../color-field/test/color-field.test.ts | 162 + 1st-gen/packages/color-field/tsconfig.json | 10 + 1st-gen/packages/color-handle/.npmrc | 3 + 1st-gen/packages/color-handle/CHANGELOG.md | 449 ++ 1st-gen/packages/color-handle/README.md | 164 + 1st-gen/packages/color-handle/package.json | 77 + .../packages/color-handle/sp-color-handle.ts | 22 + .../packages/color-handle/src/ColorHandle.ts | 74 + .../src/color-handle-overrides.css | 11 + .../color-handle/src/color-handle.css | 27 + 1st-gen/packages/color-handle/src/index.ts | 13 + .../src/spectrum-color-handle.css | 85 + .../stories/color-handle.stories.ts | 46 + .../color-handle/test/benchmark/basic-test.ts | 19 + .../test/color-handle-memory.test.ts | 19 + .../color-handle/test/color-handle.test.ts | 101 + 1st-gen/packages/color-handle/tsconfig.json | 10 + 1st-gen/packages/color-loupe/.npmrc | 3 + 1st-gen/packages/color-loupe/CHANGELOG.md | 407 ++ 1st-gen/packages/color-loupe/README.md | 229 ++ 1st-gen/packages/color-loupe/package.json | 76 + .../packages/color-loupe/sp-color-loupe.ts | 22 + .../packages/color-loupe/src/ColorLoupe.ts | 86 + .../color-loupe/src/color-loupe-overrides.css | 11 + .../packages/color-loupe/src/color-loupe.css | 32 + 1st-gen/packages/color-loupe/src/index.ts | 13 + .../color-loupe/src/spectrum-color-loupe.css | 72 + .../stories/color-loupe.stories.ts | 26 + .../color-loupe/test/benchmark/basic-test.ts | 19 + .../test/color-loupe-memory.test.ts | 19 + .../color-loupe/test/color-loupe.test.ts | 41 + 1st-gen/packages/color-loupe/tsconfig.json | 10 + 1st-gen/packages/color-slider/.npmrc | 3 + 1st-gen/packages/color-slider/CHANGELOG.md | 538 +++ 1st-gen/packages/color-slider/README.md | 157 + 1st-gen/packages/color-slider/package.json | 83 + .../packages/color-slider/sp-color-slider.ts | 22 + .../packages/color-slider/src/ColorSlider.ts | 367 ++ .../src/color-slider-overrides.css | 11 + .../color-slider/src/color-slider.css | 42 + 1st-gen/packages/color-slider/src/index.ts | 13 + .../src/spectrum-color-slider.css | 105 + 1st-gen/packages/color-slider/src/types.ts | 33 + .../stories/color-slider.stories.ts | 128 + .../packages/color-slider/stories/images.ts | 3 + .../color-slider/test/benchmark/basic-test.ts | 19 + .../test/color-slider-memory.test.ts | 19 + .../color-slider/test/color-slider.test.ts | 747 ++++ 1st-gen/packages/color-slider/tsconfig.json | 10 + 1st-gen/packages/color-wheel/.npmrc | 3 + 1st-gen/packages/color-wheel/CHANGELOG.md | 515 +++ 1st-gen/packages/color-wheel/README.md | 332 ++ 1st-gen/packages/color-wheel/package.json | 82 + .../packages/color-wheel/sp-color-wheel.ts | 22 + .../packages/color-wheel/src/ColorWheel.ts | 426 ++ .../color-wheel/src/color-wheel-overrides.css | 15 + .../packages/color-wheel/src/color-wheel.css | 39 + 1st-gen/packages/color-wheel/src/index.ts | 13 + .../color-wheel/src/spectrum-color-wheel.css | 111 + 1st-gen/packages/color-wheel/src/types.ts | 33 + .../stories/color-wheel.stories.ts | 145 + .../color-wheel/test/benchmark/basic-test.ts | 19 + .../test/color-wheel-memory.test.ts | 19 + .../color-wheel/test/color-wheel.test.ts | 773 ++++ 1st-gen/packages/color-wheel/tsconfig.json | 10 + 1st-gen/packages/combobox/.npmrc | 3 + 1st-gen/packages/combobox/CHANGELOG.md | 281 ++ 1st-gen/packages/combobox/README.md | 305 ++ 1st-gen/packages/combobox/package.json | 85 + 1st-gen/packages/combobox/sp-combobox.ts | 21 + 1st-gen/packages/combobox/src/Combobox.ts | 680 ++++ .../combobox/src/combobox-overrides.css | 22 + 1st-gen/packages/combobox/src/combobox.css | 87 + 1st-gen/packages/combobox/src/index.ts | 13 + .../combobox/src/spectrum-combobox.css | 411 ++ 1st-gen/packages/combobox/stories/args.ts | 88 + .../stories/combobox-sizes.stories.ts | 50 + .../combobox/stories/combobox.stories.ts | 286 ++ 1st-gen/packages/combobox/stories/index.ts | 324 ++ 1st-gen/packages/combobox/stories/template.ts | 15 + .../combobox/test/benchmark/basic-test.ts | 26 + .../combobox/test/benchmark/light-dom-test.ts | 34 + .../combobox/test/combobox-a11y.test.ts | 314 ++ .../combobox/test/combobox-memory.test.ts | 19 + .../combobox/test/combobox.data.test.ts | 417 ++ .../packages/combobox/test/combobox.test.ts | 1022 +++++ 1st-gen/packages/combobox/test/helpers.ts | 98 + 1st-gen/packages/combobox/test/index.ts | 268 ++ 1st-gen/packages/combobox/tsconfig.json | 10 + 1st-gen/packages/contextual-help/.npmignore | 2 + 1st-gen/packages/contextual-help/.npmrc | 3 + 1st-gen/packages/contextual-help/CHANGELOG.md | 170 + 1st-gen/packages/contextual-help/README.md | 128 + 1st-gen/packages/contextual-help/package.json | 82 + .../contextual-help/sp-contextual-help.ts | 20 + .../contextual-help/src/ContextualHelp.ts | 181 + .../src/contextual-help-overrides.css | 11 + .../contextual-help/src/contextual-help.css | 22 + 1st-gen/packages/contextual-help/src/index.ts | 12 + .../src/spectrum-contextual-help.css | 43 + .../packages/contextual-help/stories/args.ts | 108 + .../stories/contextual-help.stories.ts | 69 + .../packages/contextual-help/stories/index.ts | 36 + .../contextual-help/stories/template.ts | 15 + .../test/benchmark/basic-test.ts | 18 + .../test/contextual-help-memory.test.ts | 16 + .../test/contextual-help.test.ts | 140 + .../packages/contextual-help/tsconfig.json | 10 + 1st-gen/packages/dialog/.npmrc | 3 + 1st-gen/packages/dialog/CHANGELOG.md | 768 ++++ 1st-gen/packages/dialog/README.md | 230 ++ 1st-gen/packages/dialog/dialog-base.md | 303 ++ 1st-gen/packages/dialog/dialog-wrapper.md | 301 ++ 1st-gen/packages/dialog/package.json | 99 + 1st-gen/packages/dialog/sp-dialog-base.ts | 21 + 1st-gen/packages/dialog/sp-dialog-wrapper.ts | 21 + 1st-gen/packages/dialog/sp-dialog.ts | 21 + 1st-gen/packages/dialog/src/Dialog.ts | 177 + 1st-gen/packages/dialog/src/DialogBase.ts | 256 ++ 1st-gen/packages/dialog/src/DialogWrapper.ts | 204 + .../packages/dialog/src/dialog-overrides.css | 34 + 1st-gen/packages/dialog/src/dialog.css | 68 + 1st-gen/packages/dialog/src/index.ts | 14 + .../packages/dialog/src/spectrum-dialog.css | 296 ++ .../dialog/stories/dialog-base.stories.ts | 262 ++ .../dialog/stories/dialog-wrapper.stories.ts | 681 ++++ .../packages/dialog/stories/dialog.stories.ts | 536 +++ 1st-gen/packages/dialog/stories/images.ts | 16 + 1st-gen/packages/dialog/stories/index.ts | 62 + .../dialog/test/benchmark/basic-test.ts | 31 + .../packages/dialog/test/dialog-base.test.ts | 149 + .../dialog/test/dialog-memory.test.ts | 16 + .../dialog/test/dialog-wrapper.test.ts | 376 ++ 1st-gen/packages/dialog/test/dialog.test.ts | 262 ++ 1st-gen/packages/dialog/tsconfig.json | 16 + 1st-gen/packages/divider/.npmrc | 3 + 1st-gen/packages/divider/CHANGELOG.md | 427 ++ 1st-gen/packages/divider/README.md | 198 + 1st-gen/packages/divider/package.json | 77 + 1st-gen/packages/divider/sp-divider.ts | 22 + 1st-gen/packages/divider/src/Divider.ts | 31 + .../divider/src/divider-overrides.css | 17 + 1st-gen/packages/divider/src/divider.css | 23 + 1st-gen/packages/divider/src/index.ts | 13 + .../packages/divider/src/spectrum-divider.css | 72 + .../divider/stories/divider.stories.ts | 150 + .../divider/stories/typography-decorator.ts | 42 + .../divider/test/benchmark/basic-test.ts | 19 + .../divider/test/divider-memory.test.ts | 19 + 1st-gen/packages/divider/test/divider.test.ts | 57 + 1st-gen/packages/divider/tsconfig.json | 10 + 1st-gen/packages/dropzone/.npmrc | 3 + 1st-gen/packages/dropzone/CHANGELOG.md | 564 +++ 1st-gen/packages/dropzone/README.md | 294 ++ 1st-gen/packages/dropzone/package.json | 75 + 1st-gen/packages/dropzone/sp-dropzone.ts | 21 + 1st-gen/packages/dropzone/src/Dropzone.ts | 172 + .../dropzone/src/dropzone-overrides.css | 15 + 1st-gen/packages/dropzone/src/dropzone.css | 31 + 1st-gen/packages/dropzone/src/index.ts | 12 + .../dropzone/src/spectrum-dropzone.css | 122 + .../dropzone/stories/dropzone.stories.ts | 210 + .../dropzone/test/benchmark/test-basic.ts | 41 + .../dropzone/test/dropzone-memory.test.ts | 19 + .../packages/dropzone/test/dropzone.test.ts | 186 + 1st-gen/packages/dropzone/test/test-svg.ts | 74 + 1st-gen/packages/dropzone/tsconfig.json | 9 + 1st-gen/packages/field-group/.npmrc | 3 + 1st-gen/packages/field-group/CHANGELOG.md | 489 +++ 1st-gen/packages/field-group/README.md | 150 + 1st-gen/packages/field-group/package.json | 76 + .../packages/field-group/sp-field-group.ts | 22 + .../packages/field-group/src/FieldGroup.ts | 81 + .../field-group/src/field-group-overrides.css | 16 + .../packages/field-group/src/field-group.css | 26 + 1st-gen/packages/field-group/src/index.ts | 13 + .../field-group/src/spectrum-field-group.css | 45 + .../stories/field-group.stories.ts | 46 + .../field-group/test/benchmark/basic-test.ts | 26 + .../test/field-group-memory.test.ts | 19 + .../field-group/test/field-group.test.ts | 130 + 1st-gen/packages/field-group/tsconfig.json | 10 + 1st-gen/packages/field-label/.npmrc | 3 + 1st-gen/packages/field-label/CHANGELOG.md | 571 +++ 1st-gen/packages/field-label/README.md | 290 ++ 1st-gen/packages/field-label/package.json | 79 + .../packages/field-label/sp-field-label.ts | 22 + .../packages/field-label/src/FieldLabel.ts | 184 + .../field-label/src/field-label-overrides.css | 11 + .../packages/field-label/src/field-label.css | 18 + 1st-gen/packages/field-label/src/index.ts | 13 + .../field-label/src/spectrum-field-label.css | 111 + .../stories/field-label.stories.ts | 133 + .../field-label/test/benchmark/basic-test.ts | 19 + .../test/field-label-memory.test.ts | 19 + .../field-label/test/field-label.test.ts | 248 ++ 1st-gen/packages/field-label/tsconfig.json | 14 + 1st-gen/packages/help-text/.npmignore | 2 + 1st-gen/packages/help-text/.npmrc | 3 + 1st-gen/packages/help-text/CHANGELOG.md | 387 ++ 1st-gen/packages/help-text/README.md | 160 + 1st-gen/packages/help-text/help-text-mixin.md | 275 ++ 1st-gen/packages/help-text/package.json | 97 + 1st-gen/packages/help-text/sp-help-text.ts | 22 + 1st-gen/packages/help-text/src/HelpText.ts | 57 + .../help-text/src/HelpTextManagedElement.ts | 20 + .../packages/help-text/src/HelpTextManager.ts | 120 + .../help-text/src/help-text-overrides.css | 11 + 1st-gen/packages/help-text/src/help-text.css | 25 + 1st-gen/packages/help-text/src/index.ts | 13 + .../help-text/src/manage-help-text.ts | 41 + .../help-text/src/spectrum-help-text.css | 142 + .../stories/help-text-sizes.stories.ts | 52 + .../help-text/stories/help-text.stories.ts | 132 + .../help-text/test/benchmark/basic-test.ts | 19 + .../help-text/test/help-test-memory.test.ts | 19 + .../packages/help-text/test/help-text.test.ts | 46 + 1st-gen/packages/help-text/tsconfig.json | 10 + 1st-gen/packages/icon/.npmrc | 3 + 1st-gen/packages/icon/CHANGELOG.md | 652 +++ 1st-gen/packages/icon/README.md | 98 + 1st-gen/packages/icon/package.json | 100 + 1st-gen/packages/icon/sp-icon.ts | 21 + 1st-gen/packages/icon/src/Icon.ts | 143 + 1st-gen/packages/icon/src/IconBase.ts | 84 + .../icon/src/icon-arrow-overrides.css | 11 + .../icon/src/icon-asterisk-overrides.css | 11 + .../icon/src/icon-checkmark-overrides.css | 11 + .../icon/src/icon-chevron-overrides.css | 11 + .../src/icon-corner-triangle-overrides.css | 11 + .../icon/src/icon-cross-overrides.css | 11 + .../packages/icon/src/icon-dash-overrides.css | 11 + .../src/icon-double-gripper-overrides.css | 11 + 1st-gen/packages/icon/src/icon-overrides.css | 11 + .../src/icon-single-gripper-overrides.css | 11 + .../src/icon-triple-gripper-overrides.css | 11 + 1st-gen/packages/icon/src/icon.css | 38 + 1st-gen/packages/icon/src/index.ts | 13 + .../packages/icon/src/spectrum-icon-arrow.css | 144 + .../icon/src/spectrum-icon-asterisk.css | 27 + .../icon/src/spectrum-icon-checkmark.css | 43 + .../icon/src/spectrum-icon-chevron.css | 144 + .../src/spectrum-icon-corner-triangle.css | 27 + .../packages/icon/src/spectrum-icon-cross.css | 39 + .../packages/icon/src/spectrum-icon-dash.css | 43 + .../icon/src/spectrum-icon-double-gripper.css | 11 + .../icon/src/spectrum-icon-single-gripper.css | 11 + .../icon/src/spectrum-icon-triple-gripper.css | 11 + 1st-gen/packages/icon/src/spectrum-icon.css | 57 + 1st-gen/packages/icon/stories/icon.stories.ts | 114 + 1st-gen/packages/icon/stories/images.ts | 14 + .../icon/test/benchmark/test-basic.ts | 28 + .../packages/icon/test/icon-memory.test.ts | 19 + 1st-gen/packages/icon/test/icon.test.ts | 161 + 1st-gen/packages/icon/tsconfig.json | 10 + 1st-gen/packages/icons-ui/.gitignore | 11 + 1st-gen/packages/icons-ui/.npmrc | 3 + 1st-gen/packages/icons-ui/CHANGELOG.md | 541 +++ 1st-gen/packages/icons-ui/README.md | 168 + 1st-gen/packages/icons-ui/bin/build.js | 415 ++ 1st-gen/packages/icons-ui/package.json | 72 + 1st-gen/packages/icons-ui/src/custom-tag.ts | 41 + 1st-gen/packages/icons-ui/src/index.ts | 19 + .../icons-ui/stories/icons-ui.stories.ts | 127 + .../test/benchmark/test-attribute-many.ts | 70 + .../icons-ui/test/benchmark/test-attribute.ts | 70 + .../test/benchmark/test-injected-many.ts | 117 + .../icons-ui/test/benchmark/test-injected.ts | 58 + .../test/benchmark/test-registered-many.ts | 113 + .../test/benchmark/test-registered.ts | 65 + 1st-gen/packages/icons-ui/tsconfig.json | 15 + 1st-gen/packages/icons-workflow/.gitignore | 15 + 1st-gen/packages/icons-workflow/.npmrc | 3 + 1st-gen/packages/icons-workflow/CHANGELOG.md | 557 +++ 1st-gen/packages/icons-workflow/README.md | 171 + .../icons-workflow/bin/build-icons-mapping.js | 100 + 1st-gen/packages/icons-workflow/bin/build.js | 458 +++ .../icons-workflow/bin/icons-mapping.json | 164 + 1st-gen/packages/icons-workflow/package.json | 71 + .../icons-workflow/src/DefaultIcon.ts | 40 + .../packages/icons-workflow/src/custom-tag.ts | 41 + 1st-gen/packages/icons-workflow/src/index.ts | 19 + .../stories/icons-workflow.stories.ts | 126 + .../test/benchmark/test-attribute-many.ts | 58 + .../test/benchmark/test-attribute.ts | 58 + .../test/benchmark/test-injected-many.ts | 93 + .../test/benchmark/test-injected.ts | 58 + .../test/benchmark/test-registered-many.ts | 89 + .../test/benchmark/test-registered.ts | 54 + 1st-gen/packages/icons-workflow/tsconfig.json | 10 + 1st-gen/packages/icons/.npmrc | 3 + 1st-gen/packages/icons/CHANGELOG.md | 520 +++ 1st-gen/packages/icons/README.md | 38 + 1st-gen/packages/icons/package.json | 91 + 1st-gen/packages/icons/sp-icons-large.ts | 21 + 1st-gen/packages/icons/sp-icons-medium.ts | 21 + 1st-gen/packages/icons/src/IconsLarge.ts | 54 + 1st-gen/packages/icons/src/IconsMedium.ts | 54 + 1st-gen/packages/icons/src/icons-large.svg.ts | 1 + .../packages/icons/src/icons-medium.svg.ts | 1 + 1st-gen/packages/icons/src/index.ts | 13 + .../packages/icons/stories/icons.stories.ts | 45 + .../icons/test/benchmark/test-basic.ts | 19 + .../packages/icons/test/icons-memory.test.ts | 19 + 1st-gen/packages/icons/test/icons.test.ts | 108 + 1st-gen/packages/icons/tsconfig.json | 10 + 1st-gen/packages/iconset/.gitignore | 1 + 1st-gen/packages/iconset/.npmrc | 3 + 1st-gen/packages/iconset/CHANGELOG.md | 502 +++ 1st-gen/packages/iconset/README.md | 38 + 1st-gen/packages/iconset/package.json | 80 + .../packages/iconset/src/iconset-registry.ts | 72 + 1st-gen/packages/iconset/src/iconset-svg.ts | 147 + 1st-gen/packages/iconset/src/iconset.ts | 118 + 1st-gen/packages/iconset/src/index.ts | 14 + .../packages/iconset/stories/icons-demo.ts | 314 ++ .../packages/iconset/stories/iconsList.json | 1304 ++++++ 1st-gen/packages/iconset/test/iconset.test.ts | 149 + 1st-gen/packages/iconset/tsconfig.json | 11 + 1st-gen/packages/illustrated-message/.npmrc | 3 + .../packages/illustrated-message/CHANGELOG.md | 592 +++ .../packages/illustrated-message/README.md | 171 + .../packages/illustrated-message/package.json | 76 + .../sp-illustrated-message.ts | 21 + .../src/IllustratedMessage.ts | 59 + .../src/illustrated-message.css | 19 + .../src/illustratedmessage-overrides.css | 11 + .../packages/illustrated-message/src/index.ts | 12 + .../src/spectrum-illustratedmessage.css | 96 + .../stories/illustrated-message.stories.ts | 31 + .../test/benchmark/test-basic.ts | 34 + .../test/illustrated-message-memory.test.ts | 19 + .../test/illustrated-message.test.ts | 42 + .../illustrated-message/tsconfig.json | 10 + 1st-gen/packages/infield-button/.npmignore | 2 + 1st-gen/packages/infield-button/.npmrc | 3 + 1st-gen/packages/infield-button/CHANGELOG.md | 302 ++ 1st-gen/packages/infield-button/README.md | 122 + 1st-gen/packages/infield-button/package.json | 77 + .../infield-button/sp-infield-button.ts | 20 + .../infield-button/src/InfieldButton.ts | 59 + 1st-gen/packages/infield-button/src/index.ts | 12 + .../src/infield-button-overrides.css | 28 + .../infield-button/src/infield-button.css | 23 + .../src/spectrum-infield-button.css | 230 ++ .../packages/infield-button/stories/index.ts | 138 + .../stories/infield-button-sizes.stories.ts | 102 + .../stories/infield-button.stories.ts | 62 + .../test/benchmark/basic-test.ts | 18 + .../test/infield-button-memory.test.ts | 19 + .../test/infield-button.test.ts | 38 + 1st-gen/packages/infield-button/tsconfig.json | 10 + 1st-gen/packages/link/.npmrc | 3 + 1st-gen/packages/link/CHANGELOG.md | 685 ++++ 1st-gen/packages/link/README.md | 155 + 1st-gen/packages/link/package.json | 76 + 1st-gen/packages/link/sp-link.ts | 21 + 1st-gen/packages/link/src/Link.ts | 53 + 1st-gen/packages/link/src/index.ts | 12 + 1st-gen/packages/link/src/link-overrides.css | 11 + 1st-gen/packages/link/src/link.css | 32 + 1st-gen/packages/link/src/spectrum-link.css | 85 + 1st-gen/packages/link/stories/link.stories.ts | 123 + .../link/test/benchmark/test-basic.ts | 19 + .../packages/link/test/link-memory.test.ts | 19 + 1st-gen/packages/link/test/link.test.ts | 79 + 1st-gen/packages/link/tsconfig.json | 9 + 1st-gen/packages/menu/.npmrc | 3 + 1st-gen/packages/menu/CHANGELOG.md | 976 +++++ 1st-gen/packages/menu/README.md | 339 ++ 1st-gen/packages/menu/menu-group.md | 235 ++ 1st-gen/packages/menu/menu-item.md | 368 ++ 1st-gen/packages/menu/package.json | 115 + 1st-gen/packages/menu/sp-menu-divider.ts | 21 + 1st-gen/packages/menu/sp-menu-group.ts | 21 + 1st-gen/packages/menu/sp-menu-item.ts | 21 + 1st-gen/packages/menu/sp-menu.ts | 21 + 1st-gen/packages/menu/src/Menu.ts | 1108 +++++ 1st-gen/packages/menu/src/MenuDivider.ts | 37 + 1st-gen/packages/menu/src/MenuGroup.ts | 98 + 1st-gen/packages/menu/src/MenuItem.ts | 877 ++++ .../packages/menu/src/checkmark-overrides.css | 11 + .../packages/menu/src/chevron-overrides.css | 11 + 1st-gen/packages/menu/src/index.ts | 15 + .../menu/src/menu-divider-overrides.css | 11 + 1st-gen/packages/menu/src/menu-divider.css | 19 + 1st-gen/packages/menu/src/menu-group.css | 24 + .../packages/menu/src/menu-item-overrides.css | 11 + 1st-gen/packages/menu/src/menu-item.css | 75 + 1st-gen/packages/menu/src/menu-overrides.css | 22 + .../src/menu-sectionHeading-overrides.css | 11 + 1st-gen/packages/menu/src/menu.css | 34 + .../packages/menu/src/spectrum-checkmark.css | 61 + .../packages/menu/src/spectrum-chevron.css | 56 + .../menu/src/spectrum-menu-divider.css | 56 + .../packages/menu/src/spectrum-menu-item.css | 384 ++ .../menu/src/spectrum-menu-sectionHeading.css | 65 + 1st-gen/packages/menu/src/spectrum-menu.css | 254 ++ 1st-gen/packages/menu/stories/index.ts | 113 + .../menu/stories/menu-divider.stories.ts | 46 + .../menu/stories/menu-group.stories.ts | 166 + .../stories/menu-item.disconnected.stories.ts | 191 + .../menu/stories/menu-item.stories.ts | 160 + .../menu/stories/menu-sizes.stories.ts | 24 + 1st-gen/packages/menu/stories/menu.stories.ts | 593 +++ .../packages/menu/stories/submenu.stories.ts | 485 +++ .../menu/test/benchmark/test-basic.ts | 35 + 1st-gen/packages/menu/test/menu-group.test.ts | 454 +++ 1st-gen/packages/menu/test/menu-item.test.ts | 259 ++ .../packages/menu/test/menu-memory.test.ts | 16 + .../packages/menu/test/menu-selects.test.ts | 602 +++ 1st-gen/packages/menu/test/menu.test.ts | 981 +++++ 1st-gen/packages/menu/test/submenu.test.ts | 890 ++++ 1st-gen/packages/menu/tsconfig.json | 14 + 1st-gen/packages/meter/.npmrc | 3 + 1st-gen/packages/meter/CHANGELOG.md | 565 +++ 1st-gen/packages/meter/README.md | 161 + 1st-gen/packages/meter/package.json | 79 + 1st-gen/packages/meter/sp-meter.ts | 22 + 1st-gen/packages/meter/src/Meter.ts | 141 + 1st-gen/packages/meter/src/index.ts | 13 + .../packages/meter/src/meter-overrides.css | 37 + 1st-gen/packages/meter/src/meter.css | 24 + .../meter/src/progress-bar-overrides.css | 65 + 1st-gen/packages/meter/src/spectrum-meter.css | 32 + .../meter/src/spectrum-progress-bar.css | 147 + .../meter/stories/meter-sizes.stories.ts | 32 + .../packages/meter/stories/meter.stories.ts | 77 + .../meter/test/benchmark/basic-test.ts | 19 + .../packages/meter/test/meter-memory.test.ts | 19 + 1st-gen/packages/meter/test/meter.test.ts | 157 + 1st-gen/packages/meter/tsconfig.json | 10 + 1st-gen/packages/modal/.npmrc | 3 + 1st-gen/packages/modal/CHANGELOG.md | 455 +++ 1st-gen/packages/modal/package.json | 61 + .../packages/modal/src/modal-overrides.css | 15 + .../modal/src/modal-wrapper-overrides.css | 11 + 1st-gen/packages/modal/src/modal-wrapper.css | 13 + 1st-gen/packages/modal/src/modal.css | 26 + .../modal/src/spectrum-modal-wrapper.css | 47 + 1st-gen/packages/modal/src/spectrum-modal.css | 84 + 1st-gen/packages/modal/tsconfig.json | 10 + 1st-gen/packages/number-field/.npmrc | 3 + 1st-gen/packages/number-field/CHANGELOG.md | 740 ++++ 1st-gen/packages/number-field/README.md | 402 ++ 1st-gen/packages/number-field/package.json | 85 + .../packages/number-field/sp-number-field.ts | 22 + .../packages/number-field/src/NumberField.ts | 855 ++++ 1st-gen/packages/number-field/src/index.ts | 13 + .../src/number-field-overrides.css | 40 + .../number-field/src/number-field.css | 93 + .../src/spectrum-number-field.css | 321 ++ .../stories/number-field-sizes.stories.ts | 44 + .../stories/number-field.stories.ts | 524 +++ .../number-field/test/benchmark/basic-test.ts | 19 + 1st-gen/packages/number-field/test/helpers.ts | 52 + .../packages/number-field/test/inputs.test.ts | 435 ++ .../test/number-field-memory.test.ts | 16 + .../number-field/test/number-field.test.ts | 1838 +++++++++ 1st-gen/packages/number-field/tsconfig.json | 10 + 1st-gen/packages/overlay/.npmrc | 3 + 1st-gen/packages/overlay/CHANGELOG.md | 1073 +++++ 1st-gen/packages/overlay/README.md | 909 +++++ 1st-gen/packages/overlay/imperative-api.md | 198 + 1st-gen/packages/overlay/local.d.ts | 56 + 1st-gen/packages/overlay/overlay-trigger.md | 245 ++ 1st-gen/packages/overlay/overlay-trigger.ts | 21 + 1st-gen/packages/overlay/package.json | 186 + 1st-gen/packages/overlay/slottable-request.md | 148 + 1st-gen/packages/overlay/sp-overlay.ts | 21 + .../packages/overlay/src/AbstractOverlay.ts | 343 ++ .../packages/overlay/src/ClickController.ts | 54 + .../packages/overlay/src/HoverController.ts | 262 ++ .../overlay/src/InteractionController.ts | 145 + .../overlay/src/LongpressController.ts | 212 + 1st-gen/packages/overlay/src/Overlay.ts | 1214 ++++++ .../packages/overlay/src/OverlayNoPopover.ts | 153 + .../packages/overlay/src/OverlayPopover.ts | 250 ++ 1st-gen/packages/overlay/src/OverlayStack.ts | 283 ++ .../packages/overlay/src/OverlayTrigger.ts | 359 ++ .../overlay/src/PlacementController.ts | 471 +++ .../packages/overlay/src/VirtualTrigger.ts | 46 + 1st-gen/packages/overlay/src/events.ts | 65 + .../packages/overlay/src/fullSizePlugin.ts | 62 + 1st-gen/packages/overlay/src/index.ts | 17 + 1st-gen/packages/overlay/src/loader.ts | 45 + .../packages/overlay/src/overlay-events.ts | 25 + 1st-gen/packages/overlay/src/overlay-timer.ts | 105 + .../overlay/src/overlay-trigger-directive.ts | 140 + .../packages/overlay/src/overlay-trigger.css | 15 + 1st-gen/packages/overlay/src/overlay-types.ts | 96 + 1st-gen/packages/overlay/src/overlay.css | 202 + .../src/slottable-request-directive.ts | 100 + .../overlay/src/slottable-request-event.ts | 48 + 1st-gen/packages/overlay/src/strategies.ts | 21 + 1st-gen/packages/overlay/stories/index.ts | 275 ++ .../stories/overlay-directive.stories.ts | 376 ++ .../stories/overlay-element.stories.ts | 982 +++++ .../stories/overlay-story-components.ts | 386 ++ .../overlay/stories/overlay.stories.ts | 1909 +++++++++ .../packages/overlay/sync/overlay-trigger.ts | 19 + .../overlay/test/benchmark/basic-test.ts | 46 + .../overlay/test/benchmark/directive-test.ts | 53 + .../overlay/test/benchmark/element-test.ts | 46 + .../overlay/test/benchmark/lazy-test.ts | 61 + 1st-gen/packages/overlay/test/index.ts | 750 ++++ .../overlay/test/overlay-directive.test.ts | 159 + .../overlay/test/overlay-element.test.ts | 1017 +++++ .../overlay/test/overlay-lifecycle.test.ts | 181 + .../overlay/test/overlay-memory.test.ts | 22 + .../overlay/test/overlay-testing-helpers.ts | 53 + .../overlay/test/overlay-timer.test.ts | 140 + .../test/overlay-trigger-click.test.ts | 203 + .../test/overlay-trigger-directive.test.ts | 91 + .../test/overlay-trigger-extended.test.ts | 391 ++ .../test/overlay-trigger-hover-click.test.ts | 250 ++ .../test/overlay-trigger-hover.test.ts | 964 +++++ .../test/overlay-trigger-longpress.test.ts | 560 +++ .../test/overlay-trigger-optimization.test.ts | 170 + .../overlay/test/overlay-trigger-sync.test.ts | 16 + .../overlay/test/overlay-trigger.test.ts | 16 + .../overlay/test/overlay-update.test.ts | 44 + .../packages/overlay/test/overlay-v1.test.ts | 656 +++ 1st-gen/packages/overlay/test/overlay.test.ts | 1175 ++++++ 1st-gen/packages/overlay/trigger-directive.md | 129 + 1st-gen/packages/overlay/tsconfig.json | 14 + 1st-gen/packages/picker-button/.npmignore | 2 + 1st-gen/packages/picker-button/.npmrc | 3 + 1st-gen/packages/picker-button/CHANGELOG.md | 346 ++ 1st-gen/packages/picker-button/README.md | 209 + 1st-gen/packages/picker-button/package.json | 79 + .../picker-button/sp-picker-button.ts | 21 + .../picker-button/src/PickerButton.ts | 81 + 1st-gen/packages/picker-button/src/index.ts | 12 + .../src/picker-button-overrides.css | 24 + .../picker-button/src/picker-button.css | 22 + .../src/spectrum-picker-button-modifier.css | 11 + .../src/spectrum-picker-button.css | 194 + .../packages/picker-button/stories/index.ts | 89 + .../stories/picker-button-sizes.stories.ts | 45 + .../stories/picker-button.stories.ts | 63 + .../test/benchmark/basic-test.ts | 18 + .../test/picker-button-memory.test.ts | 19 + .../picker-button/test/picker-button.test.ts | 45 + 1st-gen/packages/picker-button/tsconfig.json | 10 + 1st-gen/packages/picker/.npmrc | 3 + 1st-gen/packages/picker/CHANGELOG.md | 905 +++++ 1st-gen/packages/picker/README.md | 694 ++++ 1st-gen/packages/picker/package.json | 114 + 1st-gen/packages/picker/sp-picker.ts | 22 + .../packages/picker/src/DesktopController.ts | 87 + .../picker/src/InteractionController.ts | 216 + .../packages/picker/src/MobileController.ts | 70 + 1st-gen/packages/picker/src/Picker.ts | 1006 +++++ 1st-gen/packages/picker/src/index.ts | 13 + .../packages/picker/src/picker-overrides.css | 28 + 1st-gen/packages/picker/src/picker.css | 130 + .../packages/picker/src/spectrum-picker.css | 454 +++ 1st-gen/packages/picker/src/strategies.ts | 19 + 1st-gen/packages/picker/stories/args.ts | 67 + .../picker/stories/picker-pending.stories.ts | 36 + .../picker/stories/picker-sizes.stories.ts | 128 + .../packages/picker/stories/picker.stories.ts | 883 ++++ 1st-gen/packages/picker/stories/states.ts | 240 ++ 1st-gen/packages/picker/stories/template.ts | 62 + 1st-gen/packages/picker/sync/index.ts | 15 + 1st-gen/packages/picker/sync/sp-picker.ts | 14 + .../picker/test/benchmark/basic-test.ts | 281 ++ 1st-gen/packages/picker/test/index.ts | 2534 ++++++++++++ .../picker/test/picker-memory.test.ts | 16 + .../picker/test/picker-reparenting.test.ts | 133 + .../picker/test/picker-responsive.test.ts | 175 + .../packages/picker/test/picker-sync.test.ts | 18 + 1st-gen/packages/picker/test/picker.test.ts | 18 + 1st-gen/packages/picker/tsconfig.json | 20 + 1st-gen/packages/popover/.npmrc | 3 + 1st-gen/packages/popover/CHANGELOG.md | 738 ++++ 1st-gen/packages/popover/README.md | 191 + 1st-gen/packages/popover/package.json | 76 + 1st-gen/packages/popover/sp-popover.ts | 21 + 1st-gen/packages/popover/src/Popover.ts | 75 + 1st-gen/packages/popover/src/index.ts | 12 + .../popover/src/popover-overrides.css | 15 + 1st-gen/packages/popover/src/popover.css | 81 + .../packages/popover/src/spectrum-popover.css | 323 ++ .../popover/stories/popover.stories.ts | 211 + .../popover/test/benchmark/test-basic.ts | 27 + .../popover/test/popover-memory.test.ts | 19 + 1st-gen/packages/popover/test/popover.test.ts | 71 + 1st-gen/packages/popover/tsconfig.json | 10 + 1st-gen/packages/progress-bar/.npmrc | 3 + 1st-gen/packages/progress-bar/CHANGELOG.md | 525 +++ 1st-gen/packages/progress-bar/README.md | 181 + 1st-gen/packages/progress-bar/package.json | 79 + .../packages/progress-bar/sp-progress-bar.ts | 22 + .../packages/progress-bar/src/ProgressBar.ts | 192 + 1st-gen/packages/progress-bar/src/index.ts | 13 + .../src/progress-bar-overrides.css | 65 + .../progress-bar/src/progress-bar.css | 43 + .../src/spectrum-progress-bar.css | 147 + .../stories/progress-bar-sizes.stories.ts | 60 + .../stories/progress-bar.stories.ts | 136 + .../progress-bar/test/benchmark/basic-test.ts | 19 + .../test/progress-bar-memory.test.ts | 19 + .../progress-bar/test/progress-bar.test.ts | 301 ++ 1st-gen/packages/progress-bar/tsconfig.json | 10 + 1st-gen/packages/progress-circle/.npmrc | 3 + 1st-gen/packages/progress-circle/CHANGELOG.md | 444 ++ 1st-gen/packages/progress-circle/README.md | 141 + 1st-gen/packages/progress-circle/package.json | 77 + .../progress-circle/sp-progress-circle.ts | 22 + .../progress-circle/src/ProgressCircle.ts | 84 + 1st-gen/packages/progress-circle/src/index.ts | 13 + .../src/progress-circle-overrides.css | 17 + .../progress-circle/src/progress-circle.css | 55 + .../src/spectrum-progress-circle.css | 628 +++ .../stories/progress-circle.stories.ts | 123 + .../test/benchmark/basic-test.ts | 19 + .../test/progress-circle-memory.test.ts | 19 + .../test/progress-circle.test.ts | 161 + .../packages/progress-circle/tsconfig.json | 10 + 1st-gen/packages/radio/.npmrc | 3 + 1st-gen/packages/radio/CHANGELOG.md | 743 ++++ 1st-gen/packages/radio/README.md | 222 + 1st-gen/packages/radio/package.json | 87 + 1st-gen/packages/radio/radio-group.md | 268 ++ 1st-gen/packages/radio/sp-radio-group.ts | 21 + 1st-gen/packages/radio/sp-radio.ts | 21 + 1st-gen/packages/radio/src/Radio.ts | 155 + 1st-gen/packages/radio/src/RadioGroup.ts | 143 + 1st-gen/packages/radio/src/index.ts | 13 + .../packages/radio/src/radio-overrides.css | 105 + 1st-gen/packages/radio/src/radio.css | 33 + 1st-gen/packages/radio/src/spectrum-radio.css | 235 ++ .../radio/stories/radio-sizes.stories.ts | 92 + .../packages/radio/stories/radio.stories.ts | 183 + .../radio/test/benchmark/test-basic.ts | 24 + .../packages/radio/test/radio-group.test.ts | 674 +++ .../packages/radio/test/radio-memory.test.ts | 19 + 1st-gen/packages/radio/test/radio.test.ts | 181 + 1st-gen/packages/radio/tsconfig.json | 10 + 1st-gen/packages/search/.npmrc | 3 + 1st-gen/packages/search/CHANGELOG.md | 872 ++++ 1st-gen/packages/search/README.md | 161 + 1st-gen/packages/search/package.json | 79 + 1st-gen/packages/search/sp-search.ts | 21 + 1st-gen/packages/search/src/Search.ts | 153 + 1st-gen/packages/search/src/index.ts | 12 + .../packages/search/src/search-overrides.css | 34 + 1st-gen/packages/search/src/search.css | 51 + .../packages/search/src/spectrum-search.css | 191 + .../search/stories/search-sizes.stories.ts | 45 + .../packages/search/stories/search.stories.ts | 42 + .../search/test/benchmark/test-basic.ts | 25 + .../search/test/search-memory.test.ts | 19 + 1st-gen/packages/search/test/search.test.ts | 232 ++ 1st-gen/packages/search/tsconfig.json | 10 + 1st-gen/packages/sidenav/.npmrc | 3 + 1st-gen/packages/sidenav/CHANGELOG.md | 732 ++++ 1st-gen/packages/sidenav/README.md | 254 ++ 1st-gen/packages/sidenav/package.json | 97 + 1st-gen/packages/sidenav/sidenav-heading.md | 97 + 1st-gen/packages/sidenav/sidenav-item.md | 299 ++ .../packages/sidenav/sp-sidenav-heading.ts | 21 + 1st-gen/packages/sidenav/sp-sidenav-item.ts | 21 + 1st-gen/packages/sidenav/sp-sidenav.ts | 21 + 1st-gen/packages/sidenav/src/Sidenav.ts | 228 ++ .../packages/sidenav/src/SidenavHeading.ts | 58 + 1st-gen/packages/sidenav/src/SidenavItem.ts | 212 + 1st-gen/packages/sidenav/src/index.ts | 14 + .../sidenav/src/sidenav-heading-overrides.css | 21 + .../packages/sidenav/src/sidenav-heading.css | 18 + .../sidenav/src/sidenav-item-overrides.css | 21 + 1st-gen/packages/sidenav/src/sidenav-item.css | 26 + .../sidenav/src/sidenav-overrides.css | 21 + 1st-gen/packages/sidenav/src/sidenav.css | 25 + .../sidenav/src/spectrum-sidenav-heading.css | 93 + .../sidenav/src/spectrum-sidenav-item.css | 220 + .../packages/sidenav/src/spectrum-sidenav.css | 81 + .../sidenav/stories/sidenav.stories.ts | 197 + .../sidenav/test/benchmark/test-basic.ts | 92 + .../sidenav/test/sidenav-item.test.ts | 208 + .../sidenav/test/sidenav-memory.test.ts | 33 + 1st-gen/packages/sidenav/test/sidenav.test.ts | 502 +++ 1st-gen/packages/sidenav/tsconfig.json | 10 + 1st-gen/packages/slider/.npmrc | 3 + 1st-gen/packages/slider/CHANGELOG.md | 955 +++++ 1st-gen/packages/slider/README.md | 533 +++ 1st-gen/packages/slider/package.json | 99 + 1st-gen/packages/slider/slider-handle.md | 83 + 1st-gen/packages/slider/sp-slider-handle.ts | 21 + 1st-gen/packages/slider/sp-slider.ts | 22 + .../packages/slider/src/HandleController.ts | 714 ++++ 1st-gen/packages/slider/src/Slider.ts | 572 +++ 1st-gen/packages/slider/src/SliderHandle.ts | 230 ++ 1st-gen/packages/slider/src/index.ts | 14 + .../packages/slider/src/slider-overrides.css | 47 + 1st-gen/packages/slider/src/slider.css | 157 + .../packages/slider/src/spectrum-slider.css | 626 +++ .../slider/stories/slider-sizes.stories.ts | 54 + .../packages/slider/stories/slider.stories.ts | 1332 ++++++ 1st-gen/packages/slider/sync/sp-slider.ts | 14 + .../slider/test/benchmark/test-basic.ts | 26 + 1st-gen/packages/slider/test/index.ts | 428 ++ .../slider/test/slider-editable-sync.test.ts | 16 + .../slider/test/slider-editable.test.ts | 16 + .../slider/test/slider-handle-upgrade.test.ts | 42 + .../slider/test/slider-memory.test.ts | 19 + 1st-gen/packages/slider/test/slider.test.ts | 1789 ++++++++ 1st-gen/packages/slider/tsconfig.json | 10 + 1st-gen/packages/split-view/.npmrc | 3 + 1st-gen/packages/split-view/CHANGELOG.md | 474 +++ 1st-gen/packages/split-view/README.md | 281 ++ 1st-gen/packages/split-view/package.json | 80 + 1st-gen/packages/split-view/sp-split-view.ts | 22 + 1st-gen/packages/split-view/src/SplitView.ts | 461 +++ 1st-gen/packages/split-view/src/index.ts | 13 + .../split-view/src/spectrum-split-view.css | 198 + .../split-view/src/split-view-overrides.css | 17 + .../packages/split-view/src/split-view.css | 108 + 1st-gen/packages/split-view/src/types.ts | 33 + .../split-view/stories/split-view.stories.ts | 320 ++ .../split-view/test/benchmark/basic-test.ts | 22 + .../split-view/test/split-view-memory.test.ts | 19 + .../split-view/test/split-view.test.ts | 1066 +++++ 1st-gen/packages/split-view/tsconfig.json | 10 + 1st-gen/packages/status-light/.npmrc | 3 + 1st-gen/packages/status-light/CHANGELOG.md | 571 +++ 1st-gen/packages/status-light/README.md | 137 + 1st-gen/packages/status-light/package.json | 76 + .../packages/status-light/sp-status-light.ts | 21 + .../packages/status-light/src/StatusLight.ts | 119 + 1st-gen/packages/status-light/src/index.ts | 12 + .../src/spectrum-status-light.css | 215 + .../src/status-light-overrides.css | 11 + .../status-light/src/status-light.css | 20 + .../stories/status-light.stories.ts | 97 + .../test/status-light-memory.test.ts | 19 + .../status-light/test/status-light.test.ts | 82 + 1st-gen/packages/status-light/tsconfig.json | 9 + 1st-gen/packages/swatch/.npmignore | 2 + 1st-gen/packages/swatch/.npmrc | 3 + 1st-gen/packages/swatch/CHANGELOG.md | 392 ++ 1st-gen/packages/swatch/README.md | 278 ++ 1st-gen/packages/swatch/package.json | 91 + 1st-gen/packages/swatch/sp-swatch-group.ts | 21 + 1st-gen/packages/swatch/sp-swatch.ts | 21 + 1st-gen/packages/swatch/src/Swatch.ts | 265 ++ 1st-gen/packages/swatch/src/SwatchGroup.ts | 346 ++ 1st-gen/packages/swatch/src/index.ts | 13 + .../swatch/src/spectrum-swatch-group.css | 27 + .../packages/swatch/src/spectrum-swatch.css | 237 ++ .../swatch/src/swatch-group-overrides.css | 17 + 1st-gen/packages/swatch/src/swatch-group.css | 14 + .../packages/swatch/src/swatch-overrides.css | 58 + 1st-gen/packages/swatch/src/swatch.css | 34 + .../swatch/stories/swatch-group.stories.ts | 232 ++ .../swatch/stories/swatch-sizes.stories.ts | 61 + .../packages/swatch/stories/swatch.stories.ts | 139 + 1st-gen/packages/swatch/swatch-group.md | 339 ++ .../swatch/test/benchmark/basic-test.ts | 18 + .../packages/swatch/test/swatch-group.test.ts | 441 ++ .../swatch/test/swatch-memory.test.ts | 19 + 1st-gen/packages/swatch/test/swatch.test.ts | 192 + 1st-gen/packages/swatch/tsconfig.json | 10 + 1st-gen/packages/switch/.npmrc | 3 + 1st-gen/packages/switch/CHANGELOG.md | 710 ++++ 1st-gen/packages/switch/README.md | 175 + 1st-gen/packages/switch/package.json | 77 + 1st-gen/packages/switch/sp-switch.ts | 21 + 1st-gen/packages/switch/src/Switch.ts | 65 + 1st-gen/packages/switch/src/index.ts | 12 + .../packages/switch/src/spectrum-switch.css | 411 ++ 1st-gen/packages/switch/src/switch-legacy.css | 21 + .../packages/switch/src/switch-overrides.css | 25 + 1st-gen/packages/switch/src/switch.css | 42 + .../switch/stories/switch-sizes.stories.ts | 38 + .../packages/switch/stories/switch.stories.ts | 109 + .../switch/test/benchmark/test-basic.ts | 19 + .../switch/test/switch-memory.test.ts | 19 + 1st-gen/packages/switch/test/switch.test.ts | 88 + 1st-gen/packages/switch/tsconfig.json | 10 + 1st-gen/packages/table/.npmignore | 2 + 1st-gen/packages/table/.npmrc | 3 + 1st-gen/packages/table/CHANGELOG.md | 368 ++ 1st-gen/packages/table/README.md | 849 ++++ 1st-gen/packages/table/elements.ts | 19 + 1st-gen/packages/table/package.json | 144 + 1st-gen/packages/table/sp-table-body.ts | 21 + 1st-gen/packages/table/sp-table-cell.ts | 21 + .../packages/table/sp-table-checkbox-cell.ts | 21 + 1st-gen/packages/table/sp-table-head-cell.ts | 21 + 1st-gen/packages/table/sp-table-head.ts | 21 + 1st-gen/packages/table/sp-table-row.ts | 21 + 1st-gen/packages/table/sp-table.ts | 21 + 1st-gen/packages/table/src/Table.ts | 533 +++ 1st-gen/packages/table/src/TableBody.ts | 61 + 1st-gen/packages/table/src/TableCell.ts | 38 + .../packages/table/src/TableCheckboxCell.ts | 78 + 1st-gen/packages/table/src/TableHead.ts | 64 + 1st-gen/packages/table/src/TableHeadCell.ts | 153 + 1st-gen/packages/table/src/TableRow.ts | 134 + 1st-gen/packages/table/src/index.ts | 19 + .../table/src/spectrum-table-body.css | 25 + .../table/src/spectrum-table-cell.css | 63 + .../src/spectrum-table-checkbox-cell.css | 93 + .../table/src/spectrum-table-head-cell.css | 107 + .../table/src/spectrum-table-head.css | 21 + .../packages/table/src/spectrum-table-row.css | 276 ++ 1st-gen/packages/table/src/spectrum-table.css | 263 ++ .../table/src/table-body-overrides.css | 11 + 1st-gen/packages/table/src/table-body.css | 29 + .../table/src/table-cell-overrides.css | 11 + 1st-gen/packages/table/src/table-cell.css | 19 + .../src/table-checkbox-cell-overrides.css | 11 + .../table/src/table-checkbox-cell.css | 32 + .../table/src/table-head-cell-overrides.css | 11 + .../packages/table/src/table-head-cell.css | 19 + .../table/src/table-head-overrides.css | 11 + 1st-gen/packages/table/src/table-head.css | 17 + .../packages/table/src/table-overrides.css | 27 + .../table/src/table-row-overrides.css | 11 + 1st-gen/packages/table/src/table-row.css | 40 + 1st-gen/packages/table/src/table.css | 19 + 1st-gen/packages/table/stories/index.ts | 58 + .../table/stories/table-elements.stories.ts | 352 ++ .../stories/table-virtualized.stories.ts | 323 ++ .../table/test/benchmark/basic-test.ts | 56 + 1st-gen/packages/table/test/helpers.ts | 39 + .../packages/table/test/table-memory.test.ts | 17 + .../packages/table/test/table-selects.test.ts | 334 ++ 1st-gen/packages/table/test/table.test.ts | 286 ++ .../test/virtualized-table-selects.test.ts | 506 +++ .../table/test/virtualized-table.test.ts | 368 ++ 1st-gen/packages/table/tsconfig.json | 10 + 1st-gen/packages/tabs/.npmrc | 3 + 1st-gen/packages/tabs/CHANGELOG.md | 765 ++++ 1st-gen/packages/tabs/README.md | 324 ++ 1st-gen/packages/tabs/package.json | 110 + 1st-gen/packages/tabs/sp-tab-panel.ts | 22 + 1st-gen/packages/tabs/sp-tab.ts | 22 + 1st-gen/packages/tabs/sp-tabs-overflow.ts | 21 + 1st-gen/packages/tabs/sp-tabs.ts | 22 + 1st-gen/packages/tabs/src/Tab.ts | 104 + 1st-gen/packages/tabs/src/TabPanel.ts | 75 + 1st-gen/packages/tabs/src/Tabs.ts | 593 +++ 1st-gen/packages/tabs/src/TabsOverflow.ts | 194 + 1st-gen/packages/tabs/src/index.ts | 16 + 1st-gen/packages/tabs/src/spectrum-tab.css | 95 + .../packages/tabs/src/spectrum-tabs-sizes.css | 74 + 1st-gen/packages/tabs/src/spectrum-tabs.css | 203 + 1st-gen/packages/tabs/src/tab-overrides.css | 11 + 1st-gen/packages/tabs/src/tab-panel.css | 19 + 1st-gen/packages/tabs/src/tab.css | 71 + 1st-gen/packages/tabs/src/tabs-overflow.css | 107 + 1st-gen/packages/tabs/src/tabs-overrides.css | 16 + .../tabs/src/tabs-sizes-overrides.css | 11 + 1st-gen/packages/tabs/src/tabs-sizes.css | 13 + 1st-gen/packages/tabs/src/tabs.css | 76 + 1st-gen/packages/tabs/stories/index.ts | 74 + .../stories/tabs-horizontal-sizes.stories.ts | 114 + .../tabs-overflow-panel-sizes.stories.ts | 47 + .../stories/tabs-overflow-sizes.stories.ts | 43 + .../tabs/stories/tabs-overflow.stories.ts | 53 + .../tabs-vertical-right-sizes.stories.ts | 110 + .../stories/tabs-vertical-sizes.stories.ts | 110 + 1st-gen/packages/tabs/stories/tabs.stories.ts | 544 +++ 1st-gen/packages/tabs/tab-panel.md | 95 + 1st-gen/packages/tabs/tab.md | 149 + 1st-gen/packages/tabs/tabs-overflow.md | 63 + .../tabs/test/benchmark/basic-test.ts | 24 + 1st-gen/packages/tabs/test/tab.test.ts | 60 + .../packages/tabs/test/tabs-memory.test.ts | 24 + .../packages/tabs/test/tabs-overflow.test.ts | 513 +++ 1st-gen/packages/tabs/test/tabs.test.ts | 601 +++ 1st-gen/packages/tabs/tsconfig.json | 9 + 1st-gen/packages/tags/.npmrc | 3 + 1st-gen/packages/tags/CHANGELOG.md | 681 ++++ 1st-gen/packages/tags/README.md | 120 + 1st-gen/packages/tags/package.json | 88 + 1st-gen/packages/tags/sp-tag.ts | 21 + 1st-gen/packages/tags/sp-tags.ts | 21 + 1st-gen/packages/tags/src/Tag.ts | 140 + 1st-gen/packages/tags/src/Tags.ts | 121 + 1st-gen/packages/tags/src/index.ts | 14 + 1st-gen/packages/tags/src/spectrum-tag.css | 395 ++ 1st-gen/packages/tags/src/spectrum-tags.css | 26 + 1st-gen/packages/tags/src/tag-overrides.css | 45 + 1st-gen/packages/tags/src/tag.css | 56 + 1st-gen/packages/tags/src/tags-overrides.css | 11 + 1st-gen/packages/tags/src/tags.css | 22 + .../tags/stories/tags-sizes.stories.ts | 50 + 1st-gen/packages/tags/stories/tags.stories.ts | 156 + 1st-gen/packages/tags/tag.md | 149 + .../tags/test/benchmark/basic-test.ts | 24 + 1st-gen/packages/tags/test/tag.test.ts | 199 + .../packages/tags/test/tags-memory.test.ts | 24 + 1st-gen/packages/tags/test/tags.test.ts | 381 ++ 1st-gen/packages/tags/tsconfig.json | 10 + 1st-gen/packages/textfield/.npmrc | 3 + 1st-gen/packages/textfield/CHANGELOG.md | 939 +++++ 1st-gen/packages/textfield/README.md | 228 ++ 1st-gen/packages/textfield/package.json | 80 + 1st-gen/packages/textfield/sp-textfield.ts | 22 + 1st-gen/packages/textfield/src/Textfield.ts | 436 ++ 1st-gen/packages/textfield/src/index.ts | 12 + .../textfield/src/spectrum-textfield.css | 568 +++ .../textfield/src/textfield-overrides.css | 63 + 1st-gen/packages/textfield/src/textfield.css | 126 + .../stories/textarea-sizes.stories.ts | 50 + .../textfield/stories/textarea.stories.ts | 248 ++ .../stories/textfield-sizes.stories.ts | 45 + .../textfield/stories/textfield.stories.ts | 181 + .../textfield/test/benchmark/test-basic.ts | 19 + .../textfield/test/textfield-memory.test.ts | 19 + .../packages/textfield/test/textfield.test.ts | 1077 +++++ 1st-gen/packages/textfield/textarea.md | 348 ++ 1st-gen/packages/textfield/tsconfig.json | 16 + 1st-gen/packages/thumbnail/.npmrc | 3 + 1st-gen/packages/thumbnail/CHANGELOG.md | 430 ++ 1st-gen/packages/thumbnail/README.md | 239 ++ 1st-gen/packages/thumbnail/package.json | 76 + 1st-gen/packages/thumbnail/sp-thumbnail.ts | 22 + 1st-gen/packages/thumbnail/src/Thumbnail.ts | 118 + 1st-gen/packages/thumbnail/src/index.ts | 13 + .../thumbnail/src/spectrum-thumbnail.css | 202 + .../thumbnail/src/thumbnail-overrides.css | 15 + 1st-gen/packages/thumbnail/src/thumbnail.css | 18 + 1st-gen/packages/thumbnail/stories/images.ts | 20 + .../stories/thumbnail-sizes.stories.ts | 69 + .../thumbnail/stories/thumbnail.stories.ts | 111 + .../thumbnail/test/benchmark/basic-test.ts | 22 + .../thumbnail/test/thumbnail-memory.test.ts | 19 + .../packages/thumbnail/test/thumbnail.test.ts | 94 + 1st-gen/packages/thumbnail/tsconfig.json | 10 + 1st-gen/packages/toast/.npmrc | 3 + 1st-gen/packages/toast/CHANGELOG.md | 706 ++++ 1st-gen/packages/toast/README.md | 191 + 1st-gen/packages/toast/package.json | 79 + 1st-gen/packages/toast/sp-toast.ts | 21 + 1st-gen/packages/toast/src/Toast.ts | 285 ++ 1st-gen/packages/toast/src/index.ts | 12 + 1st-gen/packages/toast/src/spectrum-toast.css | 160 + .../packages/toast/src/toast-overrides.css | 16 + 1st-gen/packages/toast/src/toast.css | 46 + .../packages/toast/stories/toast.stories.ts | 238 ++ .../toast/test/benchmark/test-basic.ts | 19 + .../packages/toast/test/toast-memory.test.ts | 19 + 1st-gen/packages/toast/test/toast.test.ts | 300 ++ 1st-gen/packages/toast/tsconfig.json | 14 + 1st-gen/packages/tooltip/.npmrc | 3 + 1st-gen/packages/tooltip/CHANGELOG.md | 780 ++++ 1st-gen/packages/tooltip/README.md | 193 + 1st-gen/packages/tooltip/package.json | 82 + 1st-gen/packages/tooltip/sp-tooltip.ts | 21 + 1st-gen/packages/tooltip/src/Tooltip.ts | 347 ++ 1st-gen/packages/tooltip/src/index.ts | 12 + .../packages/tooltip/src/spectrum-tooltip.css | 424 ++ .../packages/tooltip/src/tooltip-directive.ts | 41 + .../tooltip/src/tooltip-overrides.css | 15 + 1st-gen/packages/tooltip/src/tooltip.css | 68 + .../stories/tooltip-directive.stories.ts | 139 + .../tooltip/stories/tooltip.stories.ts | 557 +++ .../tooltip/test/benchmark/test-basic.ts | 23 + .../tooltip/test/benchmark/test-directive.ts | 24 + .../tooltip/test/benchmark/test-element.ts | 24 + .../tooltip/test/benchmark/test-lazy.ts | 40 + .../tooltip/test/tooltip-directive.test.ts | 121 + .../tooltip/test/tooltip-memory.test.ts | 19 + 1st-gen/packages/tooltip/test/tooltip.test.ts | 293 ++ 1st-gen/packages/tooltip/tooltip-directive.md | 121 + 1st-gen/packages/tooltip/tsconfig.json | 10 + 1st-gen/packages/top-nav/.npmrc | 3 + 1st-gen/packages/top-nav/CHANGELOG.md | 594 +++ 1st-gen/packages/top-nav/README.md | 237 ++ 1st-gen/packages/top-nav/package.json | 85 + 1st-gen/packages/top-nav/sp-top-nav-item.ts | 22 + 1st-gen/packages/top-nav/sp-top-nav.ts | 22 + 1st-gen/packages/top-nav/src/TopNav.ts | 275 ++ 1st-gen/packages/top-nav/src/TopNavItem.ts | 78 + 1st-gen/packages/top-nav/src/index.ts | 14 + 1st-gen/packages/top-nav/src/top-nav-item.css | 58 + 1st-gen/packages/top-nav/stories/images.ts | 17 + .../top-nav/stories/top-nav-sizes.stories.ts | 76 + .../top-nav/stories/top-nav.stories.ts | 183 + .../top-nav/test/benchmark/basic-test.ts | 30 + .../top-nav/test/top-nav-memory.test.ts | 16 + 1st-gen/packages/top-nav/test/top-nav.test.ts | 137 + 1st-gen/packages/top-nav/top-nav-item.md | 178 + 1st-gen/packages/top-nav/tsconfig.json | 9 + 1st-gen/packages/tray/.npmrc | 3 + 1st-gen/packages/tray/CHANGELOG.md | 481 +++ 1st-gen/packages/tray/README.md | 72 + 1st-gen/packages/tray/package.json | 79 + 1st-gen/packages/tray/sp-tray.ts | 22 + 1st-gen/packages/tray/src/Tray.ts | 152 + 1st-gen/packages/tray/src/index.ts | 13 + .../tray/src/spectrum-tray-wrapper.css | 20 + 1st-gen/packages/tray/src/spectrum-tray.css | 71 + 1st-gen/packages/tray/src/tray-overrides.css | 11 + .../tray/src/tray-wrapper-overrides.css | 11 + 1st-gen/packages/tray/src/tray.css | 44 + 1st-gen/packages/tray/stories/tray.stories.ts | 72 + .../tray/test/benchmark/basic-test.ts | 25 + .../packages/tray/test/tray-memory.test.ts | 19 + 1st-gen/packages/tray/test/tray.test.ts | 103 + 1st-gen/packages/tray/tsconfig.json | 10 + 1st-gen/packages/underlay/.npmrc | 3 + 1st-gen/packages/underlay/CHANGELOG.md | 482 +++ 1st-gen/packages/underlay/README.md | 99 + 1st-gen/packages/underlay/package.json | 75 + 1st-gen/packages/underlay/sp-underlay.ts | 21 + 1st-gen/packages/underlay/src/Underlay.ts | 61 + 1st-gen/packages/underlay/src/index.ts | 12 + .../underlay/src/spectrum-underlay.css | 41 + .../underlay/src/underlay-overrides.css | 11 + 1st-gen/packages/underlay/src/underlay.css | 14 + .../underlay/stories/underlay.stories.ts | 26 + .../underlay/test/benchmark/basic-test.ts | 19 + .../underlay/test/underlay-memory.test.ts | 19 + .../packages/underlay/test/underlay.test.ts | 52 + 1st-gen/packages/underlay/tsconfig.json | 9 + .../playwright.config.ts | 0 .../css-custom-vars-viewer/.gitignore | 28 + .../projects/css-custom-vars-viewer/.npmrc | 3 + .../css-custom-vars-viewer/.storybook/main.js | 55 + .../.storybook/preview.js | 26 + .../css-custom-vars-viewer/CHANGELOG.md | 333 ++ .../projects/css-custom-vars-viewer/README.md | 13 + .../css-custom-vars-viewer/package.json | 90 + .../scripts/parse-json.js | 81 + .../css-custom-vars-viewer/src/CssTable.ts | 182 + .../src/CustomVarsViewer.ts | 222 + .../src/color-palette.json | 3150 ++++++++++++++ .../src/custom-vars-viewer.ts | 14 + .../css-custom-vars-viewer/src/index.ts | 13 + .../src/sp-css-table.ts | 14 + .../stories/index.stories.ts | 27 + .../css-custom-vars-viewer/tsconfig.json | 10 + .../web-dev-server.config.mjs | 44 + .../web-test-runner.config.mjs | 56 + 1st-gen/projects/documentation/.eleventy.js | 272 ++ 1st-gen/projects/documentation/.gitignore | 28 + 1st-gen/projects/documentation/.npmrc | 3 + 1st-gen/projects/documentation/CHANGELOG.md | 500 +++ 1st-gen/projects/documentation/README.md | 52 + .../projects/documentation/content/404.html | 8 + .../documentation/content/_data/site.js | 33 + .../documentation/content/_includes/api.njk | 12 + .../content/_includes/changelog.njk | 12 + .../content/_includes/component-partial.njk | 37 + .../content/_includes/component.njk | 41 + .../content/_includes/deprecation.njk | 11 + .../content/_includes/dev-mode.njk | 11 + .../documentation/content/_includes/guide.njk | 11 + .../documentation/content/_includes/home.njk | 11 + .../content/_includes/introduction.njk | 10 + .../content/_includes/layout.njk | 32 + .../content/_includes/overview.njk | 28 + .../content/_includes/partial.njk | 3 + .../content/_includes/partials/demo.njk | 138 + .../_includes/partials/deprecation.njk | 13 + .../content/_includes/partials/logo.njk | 23 + .../content/_includes/partials/meta-info.njk | 50 + .../content/_includes/partials/sidenav.njk | 183 + .../documentation/content/_includes/root.njk | 12 + .../content/_includes/using-swc-react.njk | 11 + .../documentation/content/deprecation.md | 110 + .../documentation/content/dev-mode.md | 94 + .../documentation/content/favicon.ico | Bin 0 -> 9662 bytes .../documentation/content/favicon.svg | 1 + .../documentation/content/getting-started.md | 45 + .../content/guides/adding-component.md | 178 + .../content/guides/configuring-openwc.md | 100 + .../content/guides/generating-components.md | 62 + .../content/guides/styling-components.md | 70 + .../content/guides/writing-changesets.md | 140 + .../content/images/icons/icon-128x128.png | Bin 0 -> 1310 bytes .../content/images/icons/icon-144x144.png | Bin 0 -> 1458 bytes .../content/images/icons/icon-152x152.png | Bin 0 -> 1569 bytes .../content/images/icons/icon-192x192.png | Bin 0 -> 1848 bytes .../content/images/icons/icon-384x384.png | Bin 0 -> 4247 bytes .../content/images/icons/icon-512x512.png | Bin 0 -> 5991 bytes .../content/images/icons/icon-72x72.png | Bin 0 -> 890 bytes .../content/images/icons/icon-96x96.png | Bin 0 -> 1023 bytes .../projects/documentation/content/index.md | 78 + .../content/manifest.webmanifest | 53 + .../content/migrating-to-spectrum2.md | 35 + .../content/migrations/2021-8-11.11tydata.cjs | 326 ++ .../content/migrations/2021-8-11.md | 147 + .../content/migrations/2023-8-18.md | 110 + .../content/migrations/2024-10-31 (1.0.0).md | 193 + .../content/registry-conflicts.md | 66 + .../documentation/content/serviceWorker.js | 145 + .../documentation/content/shell-end.njk | 14 + .../documentation/content/shell-start.njk | 32 + .../content/support-and-compatibility.md | 51 + .../typekit/adobe-clean-italic-400.woff2 | Bin 0 -> 49344 bytes .../typekit/adobe-clean-normal-400.woff2 | Bin 0 -> 63292 bytes .../typekit/adobe-clean-normal-500.woff2 | Bin 0 -> 64472 bytes .../typekit/adobe-clean-normal-700.woff2 | Bin 0 -> 63048 bytes .../documentation/content/typekit/styles.css | 216 + .../documentation/content/using-swc-react.md | 256 ++ .../documentation/content/what-is-a-theme.md | 44 + .../documentation/e2e/published.spec.ts | 86 + 1st-gen/projects/documentation/package.json | 284 ++ .../projects/documentation/rollup.config.js | 252 ++ .../documentation/scripts/build-css.js | 68 + .../scripts/build-search-index.js | 184 + .../documentation/scripts/build-ts.js | 88 + .../scripts/component-template-parts.js | 288 ++ .../scripts/copy-component-docs.js | 310 ++ .../scripts/gather-spectrum-urls.js | 80 + .../scripts/gather-storybook-urls.js | 64 + .../documentation/scripts/gather-wcd-urls.js | 68 + .../documentation/scripts/watch-readme.js | 28 + .../projects/documentation/src/components.ts | 110 + .../src/components/adobe-logo.css | 15 + .../src/components/adobe-logo.ts | 53 + .../src/components/code-example-dark.css | 13 + .../src/components/code-example-light.css | 30 + .../src/components/code-example.css | 97 + .../src/components/code-example.ts | 227 ++ .../src/components/copy-to-clipboard.ts | 102 + .../documentation/src/components/dark.css | 14 + .../src/components/demo-container.css | 22 + .../src/components/demo-container.ts | 60 + .../documentation/src/components/extras.ts | 15 + .../documentation/src/components/fonts.css | 115 + .../src/components/inline-alert.css | 239 ++ .../documentation/src/components/large.css | 18 + .../documentation/src/components/layout.css | 303 ++ .../documentation/src/components/layout.ts | 526 +++ .../documentation/src/components/light.css | 14 + .../documentation/src/components/markup.css | 27 + .../documentation/src/components/medium.css | 18 + .../src/components/search-index.ts | 130 + .../documentation/src/components/settings.ts | 16 + .../src/components/side-nav-search.css | 26 + .../src/components/side-nav-search.ts | 222 + .../documentation/src/components/side-nav.css | 120 + .../documentation/src/components/side-nav.ts | 101 + .../documentation/src/components/styles.css | 1081 +++++ .../documentation/src/getting-started.ts | 14 + .../projects/documentation/src/global.d.ts | 76 + 1st-gen/projects/documentation/src/index.ts | 31 + 1st-gen/projects/documentation/src/router.ts | 49 + .../src/utils/posthtml-loading.js | 53 + .../utils/posthtml-spectrum-docs-markdown.js | 152 + .../src/utils/posthtml-spectrum-typography.js | 38 + .../documentation/src/utils/templates.ts | 30 + 1st-gen/projects/documentation/tsconfig.json | 13 + .../documentation/web-dev-server.config.js | 59 + .../example-project-rollup/.editorconfig | 29 + .../example-project-rollup/.gitignore | 25 + .../projects/example-project-rollup/.npmrc | 3 + .../example-project-rollup/CHANGELOG.md | 603 +++ .../projects/example-project-rollup/LICENSE | 21 + .../projects/example-project-rollup/README.md | 30 + .../example-project-rollup/index.html | 54 + .../example-project-rollup/package.json | 73 + .../example-project-rollup/rollup.config.js | 63 + .../example-project-rollup/src/example-app.ts | 29 + .../example-project-rollup/src/styles.css | 21 + .../example-project-rollup/tsconfig.json | 20 + .../example-project-rollup/wds.config.js | 21 + .../example-project-webpack/.gitignore | 3 + .../projects/example-project-webpack/.npmrc | 3 + .../example-project-webpack/CHANGELOG.md | 656 +++ .../example-project-webpack/README.md | 7 + .../example-project-webpack/package.json | 59 + .../example-project-webpack/src/index.html | 41 + .../example-project-webpack/src/index.js | 24 + .../example-project-webpack/src/styles.css | 14 + .../example-project-webpack/webpack.config.js | 117 + 1st-gen/projects/story-decorator/.npmrc | 3 + 1st-gen/projects/story-decorator/CHANGELOG.md | 638 +++ 1st-gen/projects/story-decorator/README.md | 28 + 1st-gen/projects/story-decorator/decorator.ts | 99 + 1st-gen/projects/story-decorator/package.json | 92 + .../story-decorator/sp-story-decorator.ts | 21 + .../story-decorator/src/StoryDecorator.ts | 442 ++ 1st-gen/projects/story-decorator/src/index.ts | 13 + .../projects/story-decorator/src/locales.ts | 43 + 1st-gen/projects/story-decorator/src/types.ts | 27 + .../projects/story-decorator/tsconfig.json | 8 + 1st-gen/projects/templates/.npmrc | 3 + 1st-gen/projects/templates/CHANGELOG.md | 325 ++ 1st-gen/projects/templates/package.json | 35 + .../templates/plop-templates/.npmrc.hbs | 3 + .../templates/plop-templates/README.md.hbs | 68 + .../templates/plop-templates/args.ts.hbs | 3 + .../templates/plop-templates/benchmark.ts.hbs | 7 + .../component-overrides.css.hbs | 13 + .../component-registration.ts.hbs | 10 + .../plop-templates/component.css.hbs | 14 + .../templates/plop-templates/component.ts.hbs | 23 + .../templates/plop-templates/index.ts.hbs | 1 + .../templates/plop-templates/package.json.hbs | 49 + .../templates/plop-templates/stories.ts.hbs | 12 + .../templates/plop-templates/template.ts.hbs | 13 + .../templates/plop-templates/test.ts.hbs | 24 + .../plop-templates/tsconfig.json.hbs | 12 + 1st-gen/projects/templates/plopfile.js | 157 + 1st-gen/projects/types/.npmrc | 3 + 1st-gen/projects/types/CHANGELOG.md | 196 + 1st-gen/projects/types/global.d.ts | 50 + 1st-gen/projects/types/package.json | 29 + 1st-gen/projects/vrt-compare/.npmrc | 3 + 1st-gen/projects/vrt-compare/CHANGELOG.md | 519 +++ 1st-gen/projects/vrt-compare/README.md | 28 + 1st-gen/projects/vrt-compare/onion-skinner.ts | 21 + 1st-gen/projects/vrt-compare/package.json | 82 + .../projects/vrt-compare/src/OnionSkinner.ts | 133 + .../projects/vrt-compare/src/VrtCompare.ts | 441 ++ 1st-gen/projects/vrt-compare/src/index.ts | 13 + 1st-gen/projects/vrt-compare/tsconfig.json | 8 + 1st-gen/projects/vrt-compare/vrt-compare.ts | 21 + 1st-gen/rollup.checksize.js | 32 + 1st-gen/scripts/build-css.js | 39 + 1st-gen/scripts/build-react.js | 90 + 1st-gen/scripts/build-ts.js | 17 + 1st-gen/scripts/cem-plugin-react-wrapper.js | 457 +++ 1st-gen/scripts/cem-tools.js | 132 + 1st-gen/scripts/confirm-build.js | 151 + 1st-gen/scripts/create-git-tag.js | 33 + 1st-gen/scripts/css-tools.js | 108 + 1st-gen/scripts/custom-element-json.js | 93 + 1st-gen/scripts/define-element-plugin.js | 46 + 1st-gen/scripts/escape-changelog-tags.js | 30 + 1st-gen/scripts/process-icons.js | 90 + 1st-gen/scripts/test-changes.js | 147 + 1st-gen/scripts/ts-tools.js | 135 + 1st-gen/scripts/update-global-changelog.js | 410 ++ 1st-gen/scripts/watch-css.js | 36 + 1st-gen/scripts/watch-ts.js | 54 + 1st-gen/storybook/DocumentationTemplate.mdx | 23 + 1st-gen/storybook/main.js | 72 + 1st-gen/storybook/manager.js | 21 + 1st-gen/storybook/preview-head.html | 33 + 1st-gen/storybook/preview.js | 169 + 1st-gen/storybook/theme.js | 21 + 1st-gen/storybook/tsconfig.json | 21 + 1st-gen/storybook/types.d.ts | 17 + 1st-gen/test/benchmark/.gitignore | 1 + 1st-gen/test/benchmark/bench-runner.html | 25 + 1st-gen/test/benchmark/cli.ts | 323 ++ 1st-gen/test/benchmark/helpers.ts | 183 + 1st-gen/test/lit-helpers.ts | 221 + 1st-gen/test/plugins/browser.ts | 92 + .../test/plugins/grant-permissions-plugin.ts | 47 + 1st-gen/test/plugins/send-mouse-plugin.ts | 148 + 1st-gen/test/testing-helpers-a11y.ts | 58 + 1st-gen/test/testing-helpers.ts | 484 +++ 1st-gen/test/tsconfig-node.json | 11 + 1st-gen/test/tsconfig-plugins.json | 9 + 1st-gen/test/tsconfig-test.json | 24 + 1st-gen/test/tsconfig.json | 14 + 1st-gen/test/visual/create.js | 70 + 1st-gen/test/visual/index.html | 52 + 1st-gen/test/visual/review.js | 222 + 1st-gen/test/visual/rollup.config.js | 45 + 1st-gen/test/visual/src/index.html | 34 + 1st-gen/test/visual/src/review.js | 184 + 1st-gen/test/visual/test.ts | 343 ++ 1st-gen/test/visual/wds-vrt.config.js | 22 + 1st-gen/tools/.eslintrc.json | 203 + 1st-gen/tools/base/.npmrc | 3 + 1st-gen/tools/base/CHANGELOG.md | 415 ++ 1st-gen/tools/base/README.md | 45 + 1st-gen/tools/base/package.json | 130 + 1st-gen/tools/base/src/Base.ts | 13 + 1st-gen/tools/base/src/async-directive.ts | 13 + .../base/src/condition-attribute-with-id.ts | 47 + 1st-gen/tools/base/src/constants.ts | 30 + 1st-gen/tools/base/src/decorators.ts | 13 + 1st-gen/tools/base/src/define-element.ts | 13 + 1st-gen/tools/base/src/directive.ts | 13 + 1st-gen/tools/base/src/directives.ts | 24 + 1st-gen/tools/base/src/html.ts | 13 + 1st-gen/tools/base/src/index.ts | 16 + 1st-gen/tools/base/src/sizedMixin.ts | 12 + 1st-gen/tools/base/src/streaming-listener.ts | 199 + 1st-gen/tools/base/src/version.d.ts | 12 + 1st-gen/tools/base/src/version.js | 2 + 1st-gen/tools/base/test/base-devmode.test.ts | 50 + 1st-gen/tools/base/test/base.test.ts | 38 + .../tools/base/test/define-element.test.ts | 210 + 1st-gen/tools/base/test/sizedMixin.test.ts | 83 + 1st-gen/tools/base/tsconfig.json | 9 + 1st-gen/tools/bundle/.npmrc | 3 + 1st-gen/tools/bundle/CHANGELOG.md | 1371 +++++++ 1st-gen/tools/bundle/README.md | 56 + 1st-gen/tools/bundle/elements.ts | 101 + 1st-gen/tools/bundle/package.json | 149 + 1st-gen/tools/bundle/src/icons.ts | 16 + 1st-gen/tools/bundle/src/index.ts | 70 + 1st-gen/tools/bundle/tsconfig.json | 203 + 1st-gen/tools/grid/.npmignore | 2 + 1st-gen/tools/grid/.npmrc | 3 + 1st-gen/tools/grid/CHANGELOG.md | 352 ++ 1st-gen/tools/grid/README.md | 342 ++ 1st-gen/tools/grid/package.json | 83 + 1st-gen/tools/grid/sp-grid.ts | 21 + 1st-gen/tools/grid/src/Grid.ts | 193 + 1st-gen/tools/grid/src/GridController.ts | 238 ++ 1st-gen/tools/grid/src/grid.css | 22 + 1st-gen/tools/grid/src/index.ts | 13 + 1st-gen/tools/grid/stories/grid.stories.ts | 334 ++ .../tools/grid/test/benchmark/basic-test.ts | 19 + 1st-gen/tools/grid/test/grid-memory.test.ts | 16 + 1st-gen/tools/grid/test/grid.test.ts | 398 ++ 1st-gen/tools/grid/tsconfig.json | 10 + 1st-gen/tools/opacity-checkerboard/.npmrc | 3 + .../tools/opacity-checkerboard/CHANGELOG.md | 226 ++ 1st-gen/tools/opacity-checkerboard/README.md | 132 + .../tools/opacity-checkerboard/package.json | 61 + .../src/is-opacity-checkerboard-overrides.css | 11 + .../src/is-opacity-checkerboard.css | 14 + .../src/opacity-checkerboard-overrides.css | 11 + .../src/opacity-checkerboard.css | 14 + .../src/spectrum-is-opacity-checkerboard.css | 27 + .../src/spectrum-opacity-checkerboard.css | 27 + .../tools/opacity-checkerboard/tsconfig.json | 10 + 1st-gen/tools/reactive-controllers/.npmignore | 2 + 1st-gen/tools/reactive-controllers/.npmrc | 3 + .../tools/reactive-controllers/CHANGELOG.md | 384 ++ 1st-gen/tools/reactive-controllers/README.md | 14 + .../reactive-controllers/color-controller.md | 191 + .../dependency-manager.md | 66 + .../element-resolution.md | 82 + .../tools/reactive-controllers/match-media.md | 47 + .../tools/reactive-controllers/package.json | 101 + .../reactive-controllers/pending-state.md | 67 + .../reactive-controllers/roving-tab-index.md | 92 + .../src/ColorController.ts | 730 ++++ .../src/DependencyManger.ts | 73 + .../src/ElementResolution.ts | 139 + .../reactive-controllers/src/FocusGroup.ts | 448 ++ .../src/LanguageResolution.ts | 65 + .../reactive-controllers/src/MatchMedia.ts | 49 + .../reactive-controllers/src/PendingState.ts | 126 + .../src/RovingTabindex.ts | 100 + .../src/SystemContextResolution.ts | 64 + .../tools/reactive-controllers/src/index.ts | 14 + .../test/color-controller.test.ts | 263 ++ .../test/dependency-manager.test.ts | 36 + .../test/element-resolution.test.ts | 48 + .../reactive-controllers/test/helpers.ts | 37 + .../test/match-media.test.ts | 41 + .../test/pending-state.test.ts | 173 + .../test/roving-tabindex-integration.test.ts | 271 ++ .../test/roving-tabindex.test.ts | 29 + .../tools/reactive-controllers/tsconfig.json | 9 + 1st-gen/tools/shared/.npmrc | 3 + 1st-gen/tools/shared/CHANGELOG.md | 629 +++ 1st-gen/tools/shared/README.md | 251 ++ 1st-gen/tools/shared/package.json | 118 + .../tools/shared/src/first-focusable-in.ts | 34 + 1st-gen/tools/shared/src/focus-visible.ts | 157 + .../tools/shared/src/focusable-selectors.ts | 35 + 1st-gen/tools/shared/src/focusable.ts | 326 ++ .../tools/shared/src/get-active-element.ts | 16 + .../shared/src/get-deep-element-from-point.ts | 30 + .../tools/shared/src/get-label-from-slot.ts | 12 + 1st-gen/tools/shared/src/index.ts | 24 + 1st-gen/tools/shared/src/like-anchor.ts | 120 + .../tools/shared/src/observe-slot-presence.ts | 12 + 1st-gen/tools/shared/src/observe-slot-text.ts | 12 + 1st-gen/tools/shared/src/platform.ts | 71 + 1st-gen/tools/shared/src/random-id.ts | 19 + 1st-gen/tools/shared/src/reparent-children.ts | 89 + 1st-gen/tools/shared/test/focusable.test.ts | 33 + .../shared/test/observe-slot-presence.test.ts | 44 + .../shared/test/observe-slot-text.test.ts | 42 + 1st-gen/tools/shared/test/random-id.test.ts | 42 + .../shared/test/reparent-children.test.ts | 310 ++ 1st-gen/tools/shared/tsconfig.json | 10 + 1st-gen/tools/styles/.npmrc | 3 + 1st-gen/tools/styles/CHANGELOG.md | 809 ++++ 1st-gen/tools/styles/README.md | 124 + 1st-gen/tools/styles/all-large-dark.css | 16 + 1st-gen/tools/styles/all-large-darkest.css | 16 + 1st-gen/tools/styles/all-large-light.css | 16 + 1st-gen/tools/styles/all-large-lightest.css | 16 + 1st-gen/tools/styles/all-medium-dark.css | 16 + 1st-gen/tools/styles/all-medium-darkest.css | 16 + 1st-gen/tools/styles/all-medium-light.css | 16 + 1st-gen/tools/styles/all-medium-lightest.css | 16 + 1st-gen/tools/styles/body.ts | 17 + 1st-gen/tools/styles/code.ts | 17 + 1st-gen/tools/styles/core-global.css | 18 + 1st-gen/tools/styles/detail.ts | 17 + 1st-gen/tools/styles/express/core-global.css | 18 + 1st-gen/tools/styles/express/scale-large.css | 19 + 1st-gen/tools/styles/express/scale-medium.css | 19 + .../styles/express/spectrum-core-global.css | 1321 ++++++ .../styles/express/spectrum-scale-large.css | 147 + .../styles/express/spectrum-scale-medium.css | 147 + .../styles/express/spectrum-theme-dark.css | 170 + .../styles/express/spectrum-theme-light.css | 170 + 1st-gen/tools/styles/express/theme-dark.css | 18 + 1st-gen/tools/styles/express/theme-light.css | 18 + 1st-gen/tools/styles/fonts.css | 779 ++++ 1st-gen/tools/styles/heading.ts | 17 + 1st-gen/tools/styles/package.json | 132 + 1st-gen/tools/styles/scale-large.css | 19 + 1st-gen/tools/styles/scale-medium.css | 19 + 1st-gen/tools/styles/spectrum-core-global.css | 1321 ++++++ 1st-gen/tools/styles/spectrum-scale-large.css | 150 + .../tools/styles/spectrum-scale-medium.css | 150 + 1st-gen/tools/styles/spectrum-theme-dark.css | 161 + .../tools/styles/spectrum-theme-darkest.css | 161 + 1st-gen/tools/styles/spectrum-theme-light.css | 161 + .../tools/styles/spectrum-theme-lightest.css | 161 + .../tools/styles/spectrum-two/core-global.css | 18 + .../tools/styles/spectrum-two/scale-large.css | 19 + .../styles/spectrum-two/scale-medium.css | 19 + .../spectrum-two/spectrum-core-global.css | 1321 ++++++ .../spectrum-two/spectrum-scale-large.css | 150 + .../spectrum-two/spectrum-scale-medium.css | 150 + .../spectrum-two/spectrum-theme-dark.css | 161 + .../spectrum-two/spectrum-theme-light.css | 161 + .../tools/styles/spectrum-two/theme-dark.css | 18 + .../tools/styles/spectrum-two/theme-light.css | 18 + 1st-gen/tools/styles/spectrum-two/themes.ts | 16 + 1st-gen/tools/styles/src/body-overrides.css | 11 + 1st-gen/tools/styles/src/code-overrides.css | 11 + 1st-gen/tools/styles/src/detail-overrides.css | 11 + .../tools/styles/src/heading-overrides.css | 11 + 1st-gen/tools/styles/src/lang-overrides.css | 11 + 1st-gen/tools/styles/src/spectrum-base.css | 19 + 1st-gen/tools/styles/src/spectrum-body.css | 163 + 1st-gen/tools/styles/src/spectrum-code.css | 114 + 1st-gen/tools/styles/src/spectrum-detail.css | 224 + 1st-gen/tools/styles/src/spectrum-heading.css | 343 ++ 1st-gen/tools/styles/src/spectrum-lang.css | 305 ++ .../tools/styles/src/spectrum-typography.css | 39 + .../tools/styles/src/typography-overrides.css | 11 + .../tools/styles/stories/styles.stories.ts | 57 + 1st-gen/tools/styles/theme-dark.css | 18 + 1st-gen/tools/styles/theme-darkest.css | 18 + 1st-gen/tools/styles/theme-light.css | 18 + 1st-gen/tools/styles/theme-lightest.css | 18 + 1st-gen/tools/styles/tokens-v2/dark-vars.css | 829 ++++ .../tools/styles/tokens-v2/global-vars.css | 654 +++ 1st-gen/tools/styles/tokens-v2/index.css | 3562 ++++++++++++++++ 1st-gen/tools/styles/tokens-v2/large-vars.css | 625 +++ 1st-gen/tools/styles/tokens-v2/light-vars.css | 829 ++++ .../tools/styles/tokens-v2/medium-vars.css | 625 +++ .../tokens-v2/spectrum/custom-dark-vars.css | 58 + .../spectrum/custom-darkest-vars.css | 58 + .../tokens-v2/spectrum/custom-large-vars.css | 117 + .../tokens-v2/spectrum/custom-light-vars.css | 58 + .../tokens-v2/spectrum/custom-medium-vars.css | 116 + .../styles/tokens-v2/spectrum/custom-vars.css | 44 + .../styles/tokens-v2/system-theme-bridge.css | 681 ++++ 1st-gen/tools/styles/tokens/dark-vars.css | 460 +++ 1st-gen/tools/styles/tokens/darkest-vars.css | 460 +++ .../tokens/express/custom-dark-vars.css | 10 + .../tokens/express/custom-darkest-vars.css | 10 + .../tokens/express/custom-large-vars.css | 12 + .../tokens/express/custom-light-vars.css | 10 + .../tokens/express/custom-medium-vars.css | 12 + .../styles/tokens/express/custom-vars.css | 5 + .../tools/styles/tokens/express/dark-vars.css | 9 + .../styles/tokens/express/darkest-vars.css | 9 + .../styles/tokens/express/global-vars.css | 41 + 1st-gen/tools/styles/tokens/express/index.css | 175 + .../styles/tokens/express/large-vars.css | 58 + .../styles/tokens/express/light-vars.css | 9 + .../styles/tokens/express/medium-vars.css | 58 + .../tokens/express/system-theme-bridge.css | 680 ++++ 1st-gen/tools/styles/tokens/global-vars.css | 574 +++ 1st-gen/tools/styles/tokens/index.css | 3614 +++++++++++++++++ 1st-gen/tools/styles/tokens/large-vars.css | 492 +++ 1st-gen/tools/styles/tokens/light-vars.css | 460 +++ 1st-gen/tools/styles/tokens/medium-vars.css | 492 +++ .../tokens/spectrum/custom-dark-vars.css | 44 + .../tokens/spectrum/custom-darkest-vars.css | 44 + .../tokens/spectrum/custom-large-vars.css | 108 + .../tokens/spectrum/custom-light-vars.css | 44 + .../tokens/spectrum/custom-medium-vars.css | 107 + .../styles/tokens/spectrum/custom-vars.css | 39 + .../styles/tokens/spectrum/dark-vars.css | 50 + .../styles/tokens/spectrum/darkest-vars.css | 50 + .../styles/tokens/spectrum/global-vars.css | 79 + .../tools/styles/tokens/spectrum/index.css | 501 +++ .../styles/tokens/spectrum/large-vars.css | 136 + .../styles/tokens/spectrum/light-vars.css | 50 + .../styles/tokens/spectrum/medium-vars.css | 136 + .../tokens/spectrum/system-theme-bridge.css | 680 ++++ 1st-gen/tools/styles/tsconfig.json | 9 + 1st-gen/tools/styles/typography.css | 779 ++++ 1st-gen/tools/styles/typography.ts | 15 + 1st-gen/tools/theme/.npmrc | 3 + 1st-gen/tools/theme/CHANGELOG.md | 647 +++ 1st-gen/tools/theme/README.md | 404 ++ 1st-gen/tools/theme/core-tokens.md | 108 + 1st-gen/tools/theme/core-tokens.ts | 16 + 1st-gen/tools/theme/core.ts | 17 + .../theme/express/scale-large-core-tokens.ts | 17 + 1st-gen/tools/theme/express/scale-large.ts | 17 + .../theme/express/scale-medium-core-tokens.ts | 17 + 1st-gen/tools/theme/express/scale-medium.ts | 17 + .../theme/express/theme-dark-core-tokens.ts | 17 + 1st-gen/tools/theme/express/theme-dark.ts | 17 + .../express/theme-darkest-core-tokens.ts | 17 + 1st-gen/tools/theme/express/theme-darkest.ts | 17 + .../theme/express/theme-light-core-tokens.ts | 17 + 1st-gen/tools/theme/express/theme-light.ts | 17 + .../express/theme-lightest-core-tokens.ts | 17 + 1st-gen/tools/theme/express/theme-lightest.ts | 17 + 1st-gen/tools/theme/package.json | 320 ++ .../tools/theme/scale-large-core-tokens.ts | 17 + 1st-gen/tools/theme/scale-large.ts | 17 + .../tools/theme/scale-medium-core-tokens.ts | 17 + 1st-gen/tools/theme/scale-medium.ts | 17 + 1st-gen/tools/theme/sp-theme.ts | 20 + .../spectrum-two/scale-large-core-tokens.ts | 17 + .../tools/theme/spectrum-two/scale-large.ts | 17 + .../spectrum-two/scale-medium-core-tokens.ts | 17 + .../tools/theme/spectrum-two/scale-medium.ts | 17 + .../spectrum-two/theme-dark-core-tokens.ts | 17 + .../tools/theme/spectrum-two/theme-dark.ts | 17 + .../spectrum-two/theme-darkest-core-tokens.ts | 17 + .../tools/theme/spectrum-two/theme-darkest.ts | 17 + .../spectrum-two/theme-light-core-tokens.ts | 17 + .../tools/theme/spectrum-two/theme-light.ts | 17 + .../theme-lightest-core-tokens.ts | 17 + .../theme/spectrum-two/theme-lightest.ts | 17 + 1st-gen/tools/theme/src/Theme.ts | 494 +++ .../tools/theme/src/express/core-tokens.ts | 17 + 1st-gen/tools/theme/src/express/core.ts | 17 + .../src/express/scale-large-core-tokens.css | 21 + .../tools/theme/src/express/scale-large.css | 21 + .../src/express/scale-medium-core-tokens.css | 21 + .../tools/theme/src/express/scale-medium.css | 21 + .../theme/src/express/theme-core-tokens.css | 47 + .../src/express/theme-dark-core-tokens.css | 20 + .../tools/theme/src/express/theme-dark.css | 16 + .../src/express/theme-light-core-tokens.css | 20 + .../tools/theme/src/express/theme-light.css | 16 + 1st-gen/tools/theme/src/express/theme.css | 48 + .../theme/src/express/themes-core-tokens.ts | 18 + 1st-gen/tools/theme/src/express/themes.ts | 18 + 1st-gen/tools/theme/src/index.ts | 12 + .../theme/src/scale-large-core-tokens.css | 20 + 1st-gen/tools/theme/src/scale-large.css | 21 + .../theme/src/scale-medium-core-tokens.css | 20 + 1st-gen/tools/theme/src/scale-medium.css | 21 + .../theme/src/spectrum-two/core-tokens.ts | 17 + 1st-gen/tools/theme/src/spectrum-two/core.ts | 17 + .../spectrum-two/scale-large-core-tokens.css | 19 + .../theme/src/spectrum-two/scale-large.css | 20 + .../spectrum-two/scale-medium-core-tokens.css | 19 + .../theme/src/spectrum-two/scale-medium.css | 20 + .../src/spectrum-two/theme-core-tokens.css | 41 + .../spectrum-two/theme-dark-core-tokens.css | 18 + .../theme/src/spectrum-two/theme-dark.css | 14 + .../spectrum-two/theme-light-core-tokens.css | 18 + .../theme/src/spectrum-two/theme-light.css | 14 + .../tools/theme/src/spectrum-two/theme.css | 37 + .../src/spectrum-two/themes-core-tokens.ts | 18 + .../tools/theme/src/spectrum-two/themes.ts | 18 + 1st-gen/tools/theme/src/theme-core-tokens.css | 42 + .../theme/src/theme-dark-core-tokens.css | 19 + 1st-gen/tools/theme/src/theme-dark.css | 15 + .../theme/src/theme-darkest-core-tokens.css | 19 + 1st-gen/tools/theme/src/theme-darkest.css | 15 + 1st-gen/tools/theme/src/theme-interfaces.ts | 78 + .../theme/src/theme-light-core-tokens.css | 19 + 1st-gen/tools/theme/src/theme-light.css | 15 + .../theme/src/theme-lightest-core-tokens.css | 19 + 1st-gen/tools/theme/src/theme-lightest.css | 15 + 1st-gen/tools/theme/src/theme.css | 43 + 1st-gen/tools/theme/src/themes-core-tokens.ts | 18 + 1st-gen/tools/theme/src/themes.ts | 18 + 1st-gen/tools/theme/src/typography.css | 13 + 1st-gen/tools/theme/stories/theme.stories.ts | 281 ++ .../tools/theme/test/theme-devmode.test.ts | 64 + 1st-gen/tools/theme/test/theme-lazy.test.ts | 152 + 1st-gen/tools/theme/test/theme.test.ts | 24 + 1st-gen/tools/theme/test/themes.test.ts | 231 ++ 1st-gen/tools/theme/theme-dark-core-tokens.ts | 17 + 1st-gen/tools/theme/theme-dark.ts | 17 + .../tools/theme/theme-darkest-core-tokens.ts | 17 + 1st-gen/tools/theme/theme-darkest.ts | 17 + .../tools/theme/theme-light-core-tokens.ts | 17 + 1st-gen/tools/theme/theme-light.ts | 17 + .../tools/theme/theme-lightest-core-tokens.ts | 17 + 1st-gen/tools/theme/theme-lightest.ts | 17 + 1st-gen/tools/theme/tsconfig.json | 10 + 1st-gen/tools/truncated/.npmignore | 2 + 1st-gen/tools/truncated/.npmrc | 3 + 1st-gen/tools/truncated/CHANGELOG.md | 174 + 1st-gen/tools/truncated/README.md | 49 + 1st-gen/tools/truncated/package.json | 78 + 1st-gen/tools/truncated/sp-truncated.ts | 21 + 1st-gen/tools/truncated/src/Truncated.ts | 196 + 1st-gen/tools/truncated/src/index.ts | 12 + 1st-gen/tools/truncated/src/truncated.css | 20 + .../truncated/stories/truncated.stories.ts | 54 + .../truncated/test/benchmark/basic-test.ts | 23 + .../tools/truncated/test/truncated.test.ts | 101 + 1st-gen/tools/truncated/tsconfig.json | 12 + 1st-gen/tsconfig-all.json | 248 ++ 1st-gen/tsconfig-react-wrapper.json | 212 + 1st-gen/tsconfig.json | 32 + ...eb-test-runner.config.ci-chromium-flags.js | 18 + ...b-test-runner.config.ci-chromium-memory.js | 20 + 1st-gen/web-test-runner.config.ci-chromium.js | 20 + 1st-gen/web-test-runner.config.ci-firefox.js | 20 + 1st-gen/web-test-runner.config.ci-webkit.js | 20 + 1st-gen/web-test-runner.config.ci.js | 36 + 1st-gen/web-test-runner.config.js | 180 + 1st-gen/web-test-runner.config.vrt.js | 20 + 1st-gen/web-test-runner.utils.js | 308 ++ PULL_REQUESTS.md | 217 - RELEASE_PROCESS.md | 129 - 2049 files changed, 268815 insertions(+), 346 deletions(-) create mode 100644 1st-gen/.eslintignore create mode 100755 1st-gen/.eslintrc.json create mode 100644 1st-gen/.prettierignore create mode 100644 1st-gen/.prettierrc.yaml rename CHANGELOG.md => 1st-gen/CHANGELOG.md (100%) rename INVENTORY.md => 1st-gen/INVENTORY.md (100%) create mode 100644 1st-gen/README.md rename cem-react-wrapper.config.js => 1st-gen/cem-react-wrapper.config.js (100%) rename custom-elements-manifest.config.js => 1st-gen/custom-elements-manifest.config.js (95%) create mode 100644 1st-gen/linters/eslint/.npmrc create mode 100644 1st-gen/linters/eslint/CHANGELOG.md create mode 100644 1st-gen/linters/eslint/index.js create mode 100644 1st-gen/linters/eslint/package.json create mode 100644 1st-gen/linters/ts-rules/fileShouldContainHeaderRule.js create mode 100755 1st-gen/linters/ts-rules/fileShouldContainHeaderRule.ts create mode 100755 1st-gen/linters/ts-rules/tsconfig.json create mode 100755 1st-gen/linters/ts-rules/tslint.json create mode 100644 1st-gen/package.json create mode 100644 1st-gen/packages/.eslintrc.json create mode 100644 1st-gen/packages/accordion/.npmrc create mode 100644 1st-gen/packages/accordion/CHANGELOG.md create mode 100644 1st-gen/packages/accordion/README.md create mode 100644 1st-gen/packages/accordion/accordion-item.md create mode 100644 1st-gen/packages/accordion/package.json create mode 100644 1st-gen/packages/accordion/sp-accordion-item.ts create mode 100644 1st-gen/packages/accordion/sp-accordion.ts create mode 100644 1st-gen/packages/accordion/src/Accordion.ts create mode 100644 1st-gen/packages/accordion/src/AccordionItem.ts create mode 100644 1st-gen/packages/accordion/src/accordion-item-overrides.css create mode 100644 1st-gen/packages/accordion/src/accordion-item.css create mode 100644 1st-gen/packages/accordion/src/accordion-overrides.css create mode 100644 1st-gen/packages/accordion/src/accordion.css create mode 100644 1st-gen/packages/accordion/src/index.ts create mode 100644 1st-gen/packages/accordion/src/spectrum-accordion-item.css create mode 100644 1st-gen/packages/accordion/src/spectrum-accordion.css create mode 100644 1st-gen/packages/accordion/stories/accordion-densities-compact.stories.ts create mode 100644 1st-gen/packages/accordion/stories/accordion-densities-spacious.stories.ts create mode 100644 1st-gen/packages/accordion/stories/accordion-sizes.stories.ts create mode 100644 1st-gen/packages/accordion/stories/accordion.stories.ts create mode 100644 1st-gen/packages/accordion/stories/args.ts create mode 100644 1st-gen/packages/accordion/stories/index.ts create mode 100644 1st-gen/packages/accordion/stories/template.ts create mode 100644 1st-gen/packages/accordion/test/a11y-tree.test.ts create mode 100644 1st-gen/packages/accordion/test/accordion-memory.test.ts create mode 100644 1st-gen/packages/accordion/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/accordion/test/controlled.test.ts create mode 100644 1st-gen/packages/accordion/test/declarative.test.ts create mode 100644 1st-gen/packages/accordion/test/dev-mode.test.ts create mode 100644 1st-gen/packages/accordion/test/imperative.test.ts create mode 100644 1st-gen/packages/accordion/test/keyboard.test.ts create mode 100644 1st-gen/packages/accordion/test/memory.test.ts create mode 100644 1st-gen/packages/accordion/tsconfig.json create mode 100644 1st-gen/packages/action-bar/.npmrc create mode 100644 1st-gen/packages/action-bar/CHANGELOG.md create mode 100644 1st-gen/packages/action-bar/README.md create mode 100644 1st-gen/packages/action-bar/package.json create mode 100644 1st-gen/packages/action-bar/sp-action-bar.ts create mode 100644 1st-gen/packages/action-bar/src/ActionBar.ts create mode 100644 1st-gen/packages/action-bar/src/action-bar-overrides.css create mode 100644 1st-gen/packages/action-bar/src/action-bar.css create mode 100644 1st-gen/packages/action-bar/src/index.ts create mode 100644 1st-gen/packages/action-bar/src/spectrum-action-bar.css create mode 100644 1st-gen/packages/action-bar/stories/action-bar.stories.ts create mode 100644 1st-gen/packages/action-bar/stories/args.ts create mode 100644 1st-gen/packages/action-bar/stories/template.ts create mode 100644 1st-gen/packages/action-bar/test/action-bar-memory.test.ts create mode 100644 1st-gen/packages/action-bar/test/action-bar.test.ts create mode 100644 1st-gen/packages/action-bar/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/action-bar/tsconfig.json create mode 100644 1st-gen/packages/action-button/.npmrc create mode 100644 1st-gen/packages/action-button/CHANGELOG.md create mode 100644 1st-gen/packages/action-button/README.md create mode 100644 1st-gen/packages/action-button/package.json create mode 100644 1st-gen/packages/action-button/sp-action-button.ts create mode 100644 1st-gen/packages/action-button/src/ActionButton.ts create mode 100644 1st-gen/packages/action-button/src/action-button-overrides.css create mode 100644 1st-gen/packages/action-button/src/action-button.css create mode 100644 1st-gen/packages/action-button/src/index.ts create mode 100644 1st-gen/packages/action-button/src/spectrum-action-button.css create mode 100644 1st-gen/packages/action-button/stories/action-button-black-quiet.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-black.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-emphasized-quiet.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-emphasized.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-quiet.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-standard.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-white-quiet.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button-white.stories.ts create mode 100644 1st-gen/packages/action-button/stories/action-button.stories.ts create mode 100644 1st-gen/packages/action-button/stories/index.ts create mode 100644 1st-gen/packages/action-button/test/action-button-memory.test.ts create mode 100644 1st-gen/packages/action-button/test/action-button.test.ts create mode 100644 1st-gen/packages/action-button/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/action-button/tsconfig.json create mode 100644 1st-gen/packages/action-group/.npmrc create mode 100644 1st-gen/packages/action-group/CHANGELOG.md create mode 100644 1st-gen/packages/action-group/README.md create mode 100644 1st-gen/packages/action-group/package.json create mode 100644 1st-gen/packages/action-group/sp-action-group.ts create mode 100644 1st-gen/packages/action-group/src/ActionGroup.ts create mode 100644 1st-gen/packages/action-group/src/action-group-overrides.css create mode 100644 1st-gen/packages/action-group/src/action-group.css create mode 100644 1st-gen/packages/action-group/src/index.ts create mode 100644 1st-gen/packages/action-group/src/spectrum-action-group.css create mode 100644 1st-gen/packages/action-group/stories/action-group-sizes.stories.ts create mode 100644 1st-gen/packages/action-group/stories/action-group-tooltip.stories.ts create mode 100644 1st-gen/packages/action-group/stories/action-group.stories.ts create mode 100644 1st-gen/packages/action-group/test/action-group-memory.test.ts create mode 100644 1st-gen/packages/action-group/test/action-group.test.ts create mode 100644 1st-gen/packages/action-group/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/action-group/tsconfig.json create mode 100644 1st-gen/packages/action-menu/.npmrc create mode 100644 1st-gen/packages/action-menu/CHANGELOG.md create mode 100644 1st-gen/packages/action-menu/README.md create mode 100644 1st-gen/packages/action-menu/package.json create mode 100644 1st-gen/packages/action-menu/sp-action-menu.ts create mode 100644 1st-gen/packages/action-menu/src/ActionMenu.ts create mode 100644 1st-gen/packages/action-menu/src/action-menu.css create mode 100644 1st-gen/packages/action-menu/src/index.ts create mode 100644 1st-gen/packages/action-menu/stories/action-menu-sizes.stories.ts create mode 100644 1st-gen/packages/action-menu/stories/action-menu.stories.ts create mode 100644 1st-gen/packages/action-menu/stories/index.ts create mode 100644 1st-gen/packages/action-menu/sync/sp-action-menu.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu-directive.test.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu-groups.test.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu-memory.test.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu-responsive.test.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu-sync.test.ts create mode 100644 1st-gen/packages/action-menu/test/action-menu.test.ts create mode 100644 1st-gen/packages/action-menu/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/action-menu/test/benchmark/test-directive.ts create mode 100644 1st-gen/packages/action-menu/test/benchmark/test-lazy.ts create mode 100644 1st-gen/packages/action-menu/test/benchmark/test-open-close-directive.ts create mode 100644 1st-gen/packages/action-menu/test/benchmark/test-open-close.ts create mode 100644 1st-gen/packages/action-menu/test/index.ts create mode 100644 1st-gen/packages/action-menu/tsconfig.json create mode 100644 1st-gen/packages/alert-banner/.npmignore create mode 100644 1st-gen/packages/alert-banner/.npmrc create mode 100644 1st-gen/packages/alert-banner/CHANGELOG.md create mode 100644 1st-gen/packages/alert-banner/README.md create mode 100644 1st-gen/packages/alert-banner/package.json create mode 100644 1st-gen/packages/alert-banner/sp-alert-banner.ts create mode 100644 1st-gen/packages/alert-banner/src/AlertBanner.ts create mode 100644 1st-gen/packages/alert-banner/src/alert-banner-overrides.css create mode 100644 1st-gen/packages/alert-banner/src/alert-banner.css create mode 100644 1st-gen/packages/alert-banner/src/index.ts create mode 100644 1st-gen/packages/alert-banner/src/spectrum-alert-banner.css create mode 100644 1st-gen/packages/alert-banner/stories/alert-banner.stories.ts create mode 100644 1st-gen/packages/alert-banner/stories/args.ts create mode 100644 1st-gen/packages/alert-banner/stories/index.ts create mode 100644 1st-gen/packages/alert-banner/stories/template.ts create mode 100644 1st-gen/packages/alert-banner/test/alert-banner-memory.test.ts create mode 100644 1st-gen/packages/alert-banner/test/alert-banner.test.ts create mode 100644 1st-gen/packages/alert-banner/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/alert-banner/tsconfig.json create mode 100644 1st-gen/packages/alert-dialog/.npmignore create mode 100644 1st-gen/packages/alert-dialog/.npmrc create mode 100644 1st-gen/packages/alert-dialog/CHANGELOG.md create mode 100644 1st-gen/packages/alert-dialog/README.md create mode 100644 1st-gen/packages/alert-dialog/package.json create mode 100644 1st-gen/packages/alert-dialog/sp-alert-dialog.ts create mode 100644 1st-gen/packages/alert-dialog/src/AlertDialog.ts create mode 100644 1st-gen/packages/alert-dialog/src/alert-dialog-overrides.css create mode 100644 1st-gen/packages/alert-dialog/src/alert-dialog.css create mode 100644 1st-gen/packages/alert-dialog/src/index.ts create mode 100644 1st-gen/packages/alert-dialog/src/spectrum-alert-dialog.css create mode 100644 1st-gen/packages/alert-dialog/stories/alert-dialog.stories.ts create mode 100644 1st-gen/packages/alert-dialog/test/alert-dialog-memory.test.ts create mode 100644 1st-gen/packages/alert-dialog/test/alert-dialog.test.ts create mode 100644 1st-gen/packages/alert-dialog/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/alert-dialog/tsconfig.json create mode 100644 1st-gen/packages/asset/.npmrc create mode 100644 1st-gen/packages/asset/CHANGELOG.md create mode 100644 1st-gen/packages/asset/README.md create mode 100644 1st-gen/packages/asset/package.json create mode 100644 1st-gen/packages/asset/sp-asset.ts create mode 100644 1st-gen/packages/asset/src/Asset.ts create mode 100644 1st-gen/packages/asset/src/asset-overrides.css create mode 100644 1st-gen/packages/asset/src/asset.css create mode 100644 1st-gen/packages/asset/src/index.ts create mode 100644 1st-gen/packages/asset/src/spectrum-asset.css create mode 100644 1st-gen/packages/asset/stories/asset.stories.ts create mode 100644 1st-gen/packages/asset/test/asset-memory.test.ts create mode 100644 1st-gen/packages/asset/test/asset.test.ts create mode 100644 1st-gen/packages/asset/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/asset/tsconfig.json create mode 100644 1st-gen/packages/avatar/.npmrc create mode 100644 1st-gen/packages/avatar/CHANGELOG.md create mode 100644 1st-gen/packages/avatar/README.md create mode 100644 1st-gen/packages/avatar/package.json create mode 100644 1st-gen/packages/avatar/sp-avatar.ts create mode 100644 1st-gen/packages/avatar/src/Avatar.ts create mode 100644 1st-gen/packages/avatar/src/avatar-overrides.css create mode 100644 1st-gen/packages/avatar/src/avatar.css create mode 100755 1st-gen/packages/avatar/src/index.ts create mode 100644 1st-gen/packages/avatar/src/spectrum-avatar.css create mode 100644 1st-gen/packages/avatar/stories/avatar.stories.ts create mode 100644 1st-gen/packages/avatar/stories/images.ts create mode 100644 1st-gen/packages/avatar/test/avatar-memory.test.ts create mode 100644 1st-gen/packages/avatar/test/avatar.test.ts create mode 100644 1st-gen/packages/avatar/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/avatar/tsconfig.json create mode 100644 1st-gen/packages/badge/.npmignore create mode 100644 1st-gen/packages/badge/.npmrc create mode 100644 1st-gen/packages/badge/CHANGELOG.md create mode 100644 1st-gen/packages/badge/README.md create mode 100644 1st-gen/packages/badge/package.json create mode 100644 1st-gen/packages/badge/sp-badge.ts create mode 100644 1st-gen/packages/badge/src/Badge.ts create mode 100644 1st-gen/packages/badge/src/badge-overrides.css create mode 100644 1st-gen/packages/badge/src/badge.css create mode 100644 1st-gen/packages/badge/src/index.ts create mode 100644 1st-gen/packages/badge/src/spectrum-badge.css create mode 100644 1st-gen/packages/badge/stories/badge.stories.ts create mode 100644 1st-gen/packages/badge/test/badge-memory.test.ts create mode 100644 1st-gen/packages/badge/test/badge.test.ts create mode 100644 1st-gen/packages/badge/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/badge/tsconfig.json create mode 100644 1st-gen/packages/breadcrumbs/.npmignore create mode 100644 1st-gen/packages/breadcrumbs/.npmrc create mode 100644 1st-gen/packages/breadcrumbs/CHANGELOG.md create mode 100644 1st-gen/packages/breadcrumbs/README.md create mode 100644 1st-gen/packages/breadcrumbs/breadcrumb-item.md create mode 100644 1st-gen/packages/breadcrumbs/package.json create mode 100644 1st-gen/packages/breadcrumbs/sp-breadcrumb-item.ts create mode 100644 1st-gen/packages/breadcrumbs/sp-breadcrumbs.ts create mode 100644 1st-gen/packages/breadcrumbs/src/BreadcrumbItem.ts create mode 100644 1st-gen/packages/breadcrumbs/src/Breadcrumbs.ts create mode 100644 1st-gen/packages/breadcrumbs/src/breadcrumb-item.css create mode 100644 1st-gen/packages/breadcrumbs/src/breadcrumbs-item-overrides.css create mode 100644 1st-gen/packages/breadcrumbs/src/breadcrumbs-overrides.css create mode 100644 1st-gen/packages/breadcrumbs/src/breadcrumbs.css create mode 100644 1st-gen/packages/breadcrumbs/src/index.ts create mode 100644 1st-gen/packages/breadcrumbs/src/spectrum-breadcrumbs-item.css create mode 100644 1st-gen/packages/breadcrumbs/src/spectrum-breadcrumbs.css create mode 100644 1st-gen/packages/breadcrumbs/stories/args.ts create mode 100644 1st-gen/packages/breadcrumbs/stories/breadcrumbs.stories.ts create mode 100644 1st-gen/packages/breadcrumbs/stories/template.ts create mode 100644 1st-gen/packages/breadcrumbs/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/breadcrumbs/test/breadcrumb-item.test.ts create mode 100644 1st-gen/packages/breadcrumbs/test/breadcrumbs.test.ts create mode 100644 1st-gen/packages/breadcrumbs/tsconfig.json create mode 100644 1st-gen/packages/button-group/.npmrc create mode 100644 1st-gen/packages/button-group/CHANGELOG.md create mode 100644 1st-gen/packages/button-group/README.md create mode 100644 1st-gen/packages/button-group/package.json create mode 100644 1st-gen/packages/button-group/sp-button-group.ts create mode 100644 1st-gen/packages/button-group/src/ButtonGroup.ts create mode 100644 1st-gen/packages/button-group/src/button-group-overrides.css create mode 100644 1st-gen/packages/button-group/src/button-group.css create mode 100644 1st-gen/packages/button-group/src/index.ts create mode 100644 1st-gen/packages/button-group/src/spectrum-button-group.css create mode 100644 1st-gen/packages/button-group/stories/button-group-sizes.stories.ts create mode 100644 1st-gen/packages/button-group/stories/button-group.stories.ts create mode 100644 1st-gen/packages/button-group/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/button-group/test/button-group-memory.test.ts create mode 100644 1st-gen/packages/button-group/test/button-group.test.ts create mode 100644 1st-gen/packages/button-group/tsconfig.json create mode 100644 1st-gen/packages/button/.npmrc create mode 100644 1st-gen/packages/button/CHANGELOG.md create mode 100644 1st-gen/packages/button/README.md create mode 100644 1st-gen/packages/button/clear-button.md create mode 100644 1st-gen/packages/button/close-button.md create mode 100644 1st-gen/packages/button/package.json create mode 100644 1st-gen/packages/button/sp-button.ts create mode 100644 1st-gen/packages/button/sp-clear-button.ts create mode 100644 1st-gen/packages/button/sp-close-button.ts create mode 100644 1st-gen/packages/button/src/Button.ts create mode 100644 1st-gen/packages/button/src/ButtonBase.ts create mode 100644 1st-gen/packages/button/src/ClearButton.ts create mode 100644 1st-gen/packages/button/src/CloseButton.ts create mode 100644 1st-gen/packages/button/src/StyledButton.ts create mode 100644 1st-gen/packages/button/src/button-base.css create mode 100644 1st-gen/packages/button/src/button-overrides.css create mode 100644 1st-gen/packages/button/src/button.css create mode 100644 1st-gen/packages/button/src/index.ts create mode 100644 1st-gen/packages/button/src/spectrum-button-base.css create mode 100644 1st-gen/packages/button/src/spectrum-button.css create mode 100644 1st-gen/packages/button/stories/button-accent-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-accent-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-accent-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-accent-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-accent-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-accent-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-black-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-negative-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-primary-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-secondary-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-fill-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-fill-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-fill.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-outline-pending.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-outline-sizes.stories.ts create mode 100644 1st-gen/packages/button/stories/button-white-outline.stories.ts create mode 100644 1st-gen/packages/button/stories/index.ts create mode 100644 1st-gen/packages/button/stories/template.ts create mode 100644 1st-gen/packages/button/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/button/test/button-memory.test.ts create mode 100644 1st-gen/packages/button/test/button.test.ts create mode 100644 1st-gen/packages/button/test/clear-button.test.ts create mode 100644 1st-gen/packages/button/test/close-button.test.ts create mode 100644 1st-gen/packages/button/tsconfig.json create mode 100644 1st-gen/packages/card/.npmrc create mode 100644 1st-gen/packages/card/CHANGELOG.md create mode 100644 1st-gen/packages/card/README.md create mode 100644 1st-gen/packages/card/package.json create mode 100644 1st-gen/packages/card/sp-card.ts create mode 100644 1st-gen/packages/card/src/Card.ts create mode 100644 1st-gen/packages/card/src/card-overrides.css create mode 100644 1st-gen/packages/card/src/card.css create mode 100755 1st-gen/packages/card/src/index.ts create mode 100644 1st-gen/packages/card/src/spectrum-card.css create mode 100644 1st-gen/packages/card/stories/card.stories.ts create mode 100644 1st-gen/packages/card/stories/images.ts create mode 100644 1st-gen/packages/card/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/card/test/card-memory.test.ts create mode 100644 1st-gen/packages/card/test/card.test.ts create mode 100644 1st-gen/packages/card/tsconfig.json create mode 100644 1st-gen/packages/checkbox/.npmrc create mode 100644 1st-gen/packages/checkbox/CHANGELOG.md create mode 100644 1st-gen/packages/checkbox/README.md create mode 100644 1st-gen/packages/checkbox/package.json create mode 100644 1st-gen/packages/checkbox/sp-checkbox.ts create mode 100644 1st-gen/packages/checkbox/src/Checkbox.ts create mode 100644 1st-gen/packages/checkbox/src/CheckboxBase.ts create mode 100644 1st-gen/packages/checkbox/src/CheckboxMixin.ts create mode 100644 1st-gen/packages/checkbox/src/checkbox-overrides.css create mode 100644 1st-gen/packages/checkbox/src/checkbox.css create mode 100644 1st-gen/packages/checkbox/src/index.ts create mode 100644 1st-gen/packages/checkbox/src/spectrum-checkbox.css create mode 100644 1st-gen/packages/checkbox/stories/checkbox-sizes.stories.ts create mode 100644 1st-gen/packages/checkbox/stories/checkbox.stories.ts create mode 100644 1st-gen/packages/checkbox/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/checkbox/test/checkbox-memory.test.ts create mode 100644 1st-gen/packages/checkbox/test/checkbox.test.ts create mode 100644 1st-gen/packages/checkbox/tsconfig.json create mode 100644 1st-gen/packages/clear-button/.npmignore create mode 100644 1st-gen/packages/clear-button/.npmrc create mode 100644 1st-gen/packages/clear-button/CHANGELOG.md create mode 100644 1st-gen/packages/clear-button/package.json create mode 100644 1st-gen/packages/clear-button/src/clear-button-overrides.css create mode 100644 1st-gen/packages/clear-button/src/clear-button.css create mode 100644 1st-gen/packages/clear-button/tsconfig.json create mode 100644 1st-gen/packages/close-button/.npmignore create mode 100644 1st-gen/packages/close-button/.npmrc create mode 100644 1st-gen/packages/close-button/CHANGELOG.md create mode 100644 1st-gen/packages/close-button/package.json create mode 100644 1st-gen/packages/close-button/src/close-button-overrides.css create mode 100644 1st-gen/packages/close-button/src/close-button.css create mode 100644 1st-gen/packages/close-button/src/spectrum-close-button.css create mode 100644 1st-gen/packages/close-button/tsconfig.json create mode 100644 1st-gen/packages/coachmark/.npmrc create mode 100644 1st-gen/packages/coachmark/CHANGELOG.md create mode 100644 1st-gen/packages/coachmark/README.md create mode 100644 1st-gen/packages/coachmark/coach-indicator.md create mode 100644 1st-gen/packages/coachmark/package.json create mode 100644 1st-gen/packages/coachmark/sp-coach-indicator.ts create mode 100644 1st-gen/packages/coachmark/sp-coachmark.ts create mode 100644 1st-gen/packages/coachmark/src/CoachIndicator.ts create mode 100644 1st-gen/packages/coachmark/src/Coachmark.ts create mode 100644 1st-gen/packages/coachmark/src/CoachmarkItem.ts create mode 100644 1st-gen/packages/coachmark/src/coach-indicator-overrides.css create mode 100644 1st-gen/packages/coachmark/src/coach-indicator.css create mode 100644 1st-gen/packages/coachmark/src/coachmark-overrides.css create mode 100644 1st-gen/packages/coachmark/src/coachmark.css create mode 100644 1st-gen/packages/coachmark/src/index.ts create mode 100644 1st-gen/packages/coachmark/src/spectrum-coach-indicator.css create mode 100644 1st-gen/packages/coachmark/src/spectrum-coachmark.css create mode 100644 1st-gen/packages/coachmark/stories/coach-indicator-static.stories.ts create mode 100644 1st-gen/packages/coachmark/stories/coach-indicator.stories.ts create mode 100644 1st-gen/packages/coachmark/stories/coachmark.stories.ts create mode 100644 1st-gen/packages/coachmark/stories/images.ts create mode 100644 1st-gen/packages/coachmark/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/coachmark/test/coach-indicator-memory.test.ts create mode 100644 1st-gen/packages/coachmark/test/coach-indicator.test.ts create mode 100644 1st-gen/packages/coachmark/test/coach-mark-memory.test.ts create mode 100644 1st-gen/packages/coachmark/test/coachmark.test.ts create mode 100644 1st-gen/packages/coachmark/tsconfig.json create mode 100644 1st-gen/packages/color-area/.npmrc create mode 100644 1st-gen/packages/color-area/CHANGELOG.md create mode 100644 1st-gen/packages/color-area/README.md create mode 100644 1st-gen/packages/color-area/package.json create mode 100644 1st-gen/packages/color-area/sp-color-area.ts create mode 100644 1st-gen/packages/color-area/src/ColorArea.ts create mode 100644 1st-gen/packages/color-area/src/color-area-overrides.css create mode 100644 1st-gen/packages/color-area/src/color-area.css create mode 100644 1st-gen/packages/color-area/src/index.ts create mode 100644 1st-gen/packages/color-area/src/spectrum-color-area.css create mode 100644 1st-gen/packages/color-area/src/types.ts create mode 100644 1st-gen/packages/color-area/stories/color-area.stories.ts create mode 100644 1st-gen/packages/color-area/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-area/test/color-area-memory.test.ts create mode 100644 1st-gen/packages/color-area/test/color-area.test.ts create mode 100644 1st-gen/packages/color-area/tsconfig.json create mode 100644 1st-gen/packages/color-field/.npmignore create mode 100644 1st-gen/packages/color-field/.npmrc create mode 100644 1st-gen/packages/color-field/CHANGELOG.md create mode 100644 1st-gen/packages/color-field/README.md create mode 100644 1st-gen/packages/color-field/package.json create mode 100644 1st-gen/packages/color-field/sp-color-field.ts create mode 100644 1st-gen/packages/color-field/src/ColorField.ts create mode 100644 1st-gen/packages/color-field/src/color-field.css create mode 100644 1st-gen/packages/color-field/src/index.ts create mode 100644 1st-gen/packages/color-field/stories/args.ts create mode 100644 1st-gen/packages/color-field/stories/color-field-sizes.stories.ts create mode 100644 1st-gen/packages/color-field/stories/color-field.stories.ts create mode 100644 1st-gen/packages/color-field/stories/colors.ts create mode 100644 1st-gen/packages/color-field/stories/template.ts create mode 100644 1st-gen/packages/color-field/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-field/test/color-field-memory.test.ts create mode 100644 1st-gen/packages/color-field/test/color-field.test.ts create mode 100644 1st-gen/packages/color-field/tsconfig.json create mode 100644 1st-gen/packages/color-handle/.npmrc create mode 100644 1st-gen/packages/color-handle/CHANGELOG.md create mode 100644 1st-gen/packages/color-handle/README.md create mode 100644 1st-gen/packages/color-handle/package.json create mode 100644 1st-gen/packages/color-handle/sp-color-handle.ts create mode 100644 1st-gen/packages/color-handle/src/ColorHandle.ts create mode 100644 1st-gen/packages/color-handle/src/color-handle-overrides.css create mode 100644 1st-gen/packages/color-handle/src/color-handle.css create mode 100644 1st-gen/packages/color-handle/src/index.ts create mode 100644 1st-gen/packages/color-handle/src/spectrum-color-handle.css create mode 100644 1st-gen/packages/color-handle/stories/color-handle.stories.ts create mode 100644 1st-gen/packages/color-handle/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-handle/test/color-handle-memory.test.ts create mode 100644 1st-gen/packages/color-handle/test/color-handle.test.ts create mode 100644 1st-gen/packages/color-handle/tsconfig.json create mode 100644 1st-gen/packages/color-loupe/.npmrc create mode 100644 1st-gen/packages/color-loupe/CHANGELOG.md create mode 100644 1st-gen/packages/color-loupe/README.md create mode 100644 1st-gen/packages/color-loupe/package.json create mode 100644 1st-gen/packages/color-loupe/sp-color-loupe.ts create mode 100644 1st-gen/packages/color-loupe/src/ColorLoupe.ts create mode 100644 1st-gen/packages/color-loupe/src/color-loupe-overrides.css create mode 100644 1st-gen/packages/color-loupe/src/color-loupe.css create mode 100644 1st-gen/packages/color-loupe/src/index.ts create mode 100644 1st-gen/packages/color-loupe/src/spectrum-color-loupe.css create mode 100644 1st-gen/packages/color-loupe/stories/color-loupe.stories.ts create mode 100644 1st-gen/packages/color-loupe/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-loupe/test/color-loupe-memory.test.ts create mode 100644 1st-gen/packages/color-loupe/test/color-loupe.test.ts create mode 100644 1st-gen/packages/color-loupe/tsconfig.json create mode 100644 1st-gen/packages/color-slider/.npmrc create mode 100644 1st-gen/packages/color-slider/CHANGELOG.md create mode 100644 1st-gen/packages/color-slider/README.md create mode 100644 1st-gen/packages/color-slider/package.json create mode 100644 1st-gen/packages/color-slider/sp-color-slider.ts create mode 100644 1st-gen/packages/color-slider/src/ColorSlider.ts create mode 100644 1st-gen/packages/color-slider/src/color-slider-overrides.css create mode 100644 1st-gen/packages/color-slider/src/color-slider.css create mode 100644 1st-gen/packages/color-slider/src/index.ts create mode 100644 1st-gen/packages/color-slider/src/spectrum-color-slider.css create mode 100644 1st-gen/packages/color-slider/src/types.ts create mode 100644 1st-gen/packages/color-slider/stories/color-slider.stories.ts create mode 100644 1st-gen/packages/color-slider/stories/images.ts create mode 100644 1st-gen/packages/color-slider/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-slider/test/color-slider-memory.test.ts create mode 100644 1st-gen/packages/color-slider/test/color-slider.test.ts create mode 100644 1st-gen/packages/color-slider/tsconfig.json create mode 100644 1st-gen/packages/color-wheel/.npmrc create mode 100644 1st-gen/packages/color-wheel/CHANGELOG.md create mode 100644 1st-gen/packages/color-wheel/README.md create mode 100644 1st-gen/packages/color-wheel/package.json create mode 100644 1st-gen/packages/color-wheel/sp-color-wheel.ts create mode 100644 1st-gen/packages/color-wheel/src/ColorWheel.ts create mode 100644 1st-gen/packages/color-wheel/src/color-wheel-overrides.css create mode 100644 1st-gen/packages/color-wheel/src/color-wheel.css create mode 100644 1st-gen/packages/color-wheel/src/index.ts create mode 100644 1st-gen/packages/color-wheel/src/spectrum-color-wheel.css create mode 100644 1st-gen/packages/color-wheel/src/types.ts create mode 100644 1st-gen/packages/color-wheel/stories/color-wheel.stories.ts create mode 100644 1st-gen/packages/color-wheel/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/color-wheel/test/color-wheel-memory.test.ts create mode 100644 1st-gen/packages/color-wheel/test/color-wheel.test.ts create mode 100644 1st-gen/packages/color-wheel/tsconfig.json create mode 100644 1st-gen/packages/combobox/.npmrc create mode 100644 1st-gen/packages/combobox/CHANGELOG.md create mode 100644 1st-gen/packages/combobox/README.md create mode 100644 1st-gen/packages/combobox/package.json create mode 100644 1st-gen/packages/combobox/sp-combobox.ts create mode 100644 1st-gen/packages/combobox/src/Combobox.ts create mode 100644 1st-gen/packages/combobox/src/combobox-overrides.css create mode 100644 1st-gen/packages/combobox/src/combobox.css create mode 100644 1st-gen/packages/combobox/src/index.ts create mode 100644 1st-gen/packages/combobox/src/spectrum-combobox.css create mode 100644 1st-gen/packages/combobox/stories/args.ts create mode 100644 1st-gen/packages/combobox/stories/combobox-sizes.stories.ts create mode 100644 1st-gen/packages/combobox/stories/combobox.stories.ts create mode 100644 1st-gen/packages/combobox/stories/index.ts create mode 100644 1st-gen/packages/combobox/stories/template.ts create mode 100644 1st-gen/packages/combobox/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/combobox/test/benchmark/light-dom-test.ts create mode 100644 1st-gen/packages/combobox/test/combobox-a11y.test.ts create mode 100644 1st-gen/packages/combobox/test/combobox-memory.test.ts create mode 100644 1st-gen/packages/combobox/test/combobox.data.test.ts create mode 100644 1st-gen/packages/combobox/test/combobox.test.ts create mode 100644 1st-gen/packages/combobox/test/helpers.ts create mode 100644 1st-gen/packages/combobox/test/index.ts create mode 100644 1st-gen/packages/combobox/tsconfig.json create mode 100644 1st-gen/packages/contextual-help/.npmignore create mode 100644 1st-gen/packages/contextual-help/.npmrc create mode 100644 1st-gen/packages/contextual-help/CHANGELOG.md create mode 100644 1st-gen/packages/contextual-help/README.md create mode 100644 1st-gen/packages/contextual-help/package.json create mode 100644 1st-gen/packages/contextual-help/sp-contextual-help.ts create mode 100644 1st-gen/packages/contextual-help/src/ContextualHelp.ts create mode 100644 1st-gen/packages/contextual-help/src/contextual-help-overrides.css create mode 100644 1st-gen/packages/contextual-help/src/contextual-help.css create mode 100644 1st-gen/packages/contextual-help/src/index.ts create mode 100644 1st-gen/packages/contextual-help/src/spectrum-contextual-help.css create mode 100644 1st-gen/packages/contextual-help/stories/args.ts create mode 100644 1st-gen/packages/contextual-help/stories/contextual-help.stories.ts create mode 100644 1st-gen/packages/contextual-help/stories/index.ts create mode 100644 1st-gen/packages/contextual-help/stories/template.ts create mode 100644 1st-gen/packages/contextual-help/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/contextual-help/test/contextual-help-memory.test.ts create mode 100644 1st-gen/packages/contextual-help/test/contextual-help.test.ts create mode 100644 1st-gen/packages/contextual-help/tsconfig.json create mode 100644 1st-gen/packages/dialog/.npmrc create mode 100644 1st-gen/packages/dialog/CHANGELOG.md create mode 100644 1st-gen/packages/dialog/README.md create mode 100644 1st-gen/packages/dialog/dialog-base.md create mode 100644 1st-gen/packages/dialog/dialog-wrapper.md create mode 100644 1st-gen/packages/dialog/package.json create mode 100644 1st-gen/packages/dialog/sp-dialog-base.ts create mode 100644 1st-gen/packages/dialog/sp-dialog-wrapper.ts create mode 100644 1st-gen/packages/dialog/sp-dialog.ts create mode 100644 1st-gen/packages/dialog/src/Dialog.ts create mode 100644 1st-gen/packages/dialog/src/DialogBase.ts create mode 100644 1st-gen/packages/dialog/src/DialogWrapper.ts create mode 100644 1st-gen/packages/dialog/src/dialog-overrides.css create mode 100644 1st-gen/packages/dialog/src/dialog.css create mode 100644 1st-gen/packages/dialog/src/index.ts create mode 100644 1st-gen/packages/dialog/src/spectrum-dialog.css create mode 100644 1st-gen/packages/dialog/stories/dialog-base.stories.ts create mode 100644 1st-gen/packages/dialog/stories/dialog-wrapper.stories.ts create mode 100644 1st-gen/packages/dialog/stories/dialog.stories.ts create mode 100644 1st-gen/packages/dialog/stories/images.ts create mode 100644 1st-gen/packages/dialog/stories/index.ts create mode 100644 1st-gen/packages/dialog/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/dialog/test/dialog-base.test.ts create mode 100644 1st-gen/packages/dialog/test/dialog-memory.test.ts create mode 100644 1st-gen/packages/dialog/test/dialog-wrapper.test.ts create mode 100644 1st-gen/packages/dialog/test/dialog.test.ts create mode 100644 1st-gen/packages/dialog/tsconfig.json create mode 100644 1st-gen/packages/divider/.npmrc create mode 100644 1st-gen/packages/divider/CHANGELOG.md create mode 100644 1st-gen/packages/divider/README.md create mode 100644 1st-gen/packages/divider/package.json create mode 100644 1st-gen/packages/divider/sp-divider.ts create mode 100644 1st-gen/packages/divider/src/Divider.ts create mode 100644 1st-gen/packages/divider/src/divider-overrides.css create mode 100644 1st-gen/packages/divider/src/divider.css create mode 100644 1st-gen/packages/divider/src/index.ts create mode 100644 1st-gen/packages/divider/src/spectrum-divider.css create mode 100644 1st-gen/packages/divider/stories/divider.stories.ts create mode 100644 1st-gen/packages/divider/stories/typography-decorator.ts create mode 100644 1st-gen/packages/divider/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/divider/test/divider-memory.test.ts create mode 100644 1st-gen/packages/divider/test/divider.test.ts create mode 100644 1st-gen/packages/divider/tsconfig.json create mode 100644 1st-gen/packages/dropzone/.npmrc create mode 100644 1st-gen/packages/dropzone/CHANGELOG.md create mode 100644 1st-gen/packages/dropzone/README.md create mode 100644 1st-gen/packages/dropzone/package.json create mode 100644 1st-gen/packages/dropzone/sp-dropzone.ts create mode 100644 1st-gen/packages/dropzone/src/Dropzone.ts create mode 100644 1st-gen/packages/dropzone/src/dropzone-overrides.css create mode 100644 1st-gen/packages/dropzone/src/dropzone.css create mode 100644 1st-gen/packages/dropzone/src/index.ts create mode 100644 1st-gen/packages/dropzone/src/spectrum-dropzone.css create mode 100644 1st-gen/packages/dropzone/stories/dropzone.stories.ts create mode 100644 1st-gen/packages/dropzone/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/dropzone/test/dropzone-memory.test.ts create mode 100644 1st-gen/packages/dropzone/test/dropzone.test.ts create mode 100644 1st-gen/packages/dropzone/test/test-svg.ts create mode 100644 1st-gen/packages/dropzone/tsconfig.json create mode 100644 1st-gen/packages/field-group/.npmrc create mode 100644 1st-gen/packages/field-group/CHANGELOG.md create mode 100644 1st-gen/packages/field-group/README.md create mode 100644 1st-gen/packages/field-group/package.json create mode 100644 1st-gen/packages/field-group/sp-field-group.ts create mode 100644 1st-gen/packages/field-group/src/FieldGroup.ts create mode 100644 1st-gen/packages/field-group/src/field-group-overrides.css create mode 100644 1st-gen/packages/field-group/src/field-group.css create mode 100644 1st-gen/packages/field-group/src/index.ts create mode 100644 1st-gen/packages/field-group/src/spectrum-field-group.css create mode 100644 1st-gen/packages/field-group/stories/field-group.stories.ts create mode 100644 1st-gen/packages/field-group/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/field-group/test/field-group-memory.test.ts create mode 100644 1st-gen/packages/field-group/test/field-group.test.ts create mode 100644 1st-gen/packages/field-group/tsconfig.json create mode 100644 1st-gen/packages/field-label/.npmrc create mode 100644 1st-gen/packages/field-label/CHANGELOG.md create mode 100644 1st-gen/packages/field-label/README.md create mode 100644 1st-gen/packages/field-label/package.json create mode 100644 1st-gen/packages/field-label/sp-field-label.ts create mode 100644 1st-gen/packages/field-label/src/FieldLabel.ts create mode 100644 1st-gen/packages/field-label/src/field-label-overrides.css create mode 100644 1st-gen/packages/field-label/src/field-label.css create mode 100644 1st-gen/packages/field-label/src/index.ts create mode 100644 1st-gen/packages/field-label/src/spectrum-field-label.css create mode 100644 1st-gen/packages/field-label/stories/field-label.stories.ts create mode 100644 1st-gen/packages/field-label/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/field-label/test/field-label-memory.test.ts create mode 100644 1st-gen/packages/field-label/test/field-label.test.ts create mode 100644 1st-gen/packages/field-label/tsconfig.json create mode 100644 1st-gen/packages/help-text/.npmignore create mode 100644 1st-gen/packages/help-text/.npmrc create mode 100644 1st-gen/packages/help-text/CHANGELOG.md create mode 100644 1st-gen/packages/help-text/README.md create mode 100644 1st-gen/packages/help-text/help-text-mixin.md create mode 100644 1st-gen/packages/help-text/package.json create mode 100644 1st-gen/packages/help-text/sp-help-text.ts create mode 100644 1st-gen/packages/help-text/src/HelpText.ts create mode 100644 1st-gen/packages/help-text/src/HelpTextManagedElement.ts create mode 100644 1st-gen/packages/help-text/src/HelpTextManager.ts create mode 100644 1st-gen/packages/help-text/src/help-text-overrides.css create mode 100644 1st-gen/packages/help-text/src/help-text.css create mode 100644 1st-gen/packages/help-text/src/index.ts create mode 100644 1st-gen/packages/help-text/src/manage-help-text.ts create mode 100644 1st-gen/packages/help-text/src/spectrum-help-text.css create mode 100644 1st-gen/packages/help-text/stories/help-text-sizes.stories.ts create mode 100644 1st-gen/packages/help-text/stories/help-text.stories.ts create mode 100644 1st-gen/packages/help-text/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/help-text/test/help-test-memory.test.ts create mode 100644 1st-gen/packages/help-text/test/help-text.test.ts create mode 100644 1st-gen/packages/help-text/tsconfig.json create mode 100644 1st-gen/packages/icon/.npmrc create mode 100644 1st-gen/packages/icon/CHANGELOG.md create mode 100644 1st-gen/packages/icon/README.md create mode 100644 1st-gen/packages/icon/package.json create mode 100644 1st-gen/packages/icon/sp-icon.ts create mode 100644 1st-gen/packages/icon/src/Icon.ts create mode 100644 1st-gen/packages/icon/src/IconBase.ts create mode 100644 1st-gen/packages/icon/src/icon-arrow-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-asterisk-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-checkmark-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-chevron-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-corner-triangle-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-cross-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-dash-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-double-gripper-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-single-gripper-overrides.css create mode 100644 1st-gen/packages/icon/src/icon-triple-gripper-overrides.css create mode 100644 1st-gen/packages/icon/src/icon.css create mode 100644 1st-gen/packages/icon/src/index.ts create mode 100644 1st-gen/packages/icon/src/spectrum-icon-arrow.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-asterisk.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-checkmark.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-chevron.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-corner-triangle.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-cross.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-dash.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-double-gripper.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-single-gripper.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon-triple-gripper.css create mode 100644 1st-gen/packages/icon/src/spectrum-icon.css create mode 100644 1st-gen/packages/icon/stories/icon.stories.ts create mode 100644 1st-gen/packages/icon/stories/images.ts create mode 100644 1st-gen/packages/icon/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/icon/test/icon-memory.test.ts create mode 100644 1st-gen/packages/icon/test/icon.test.ts create mode 100644 1st-gen/packages/icon/tsconfig.json create mode 100644 1st-gen/packages/icons-ui/.gitignore create mode 100644 1st-gen/packages/icons-ui/.npmrc create mode 100644 1st-gen/packages/icons-ui/CHANGELOG.md create mode 100644 1st-gen/packages/icons-ui/README.md create mode 100644 1st-gen/packages/icons-ui/bin/build.js create mode 100644 1st-gen/packages/icons-ui/package.json create mode 100644 1st-gen/packages/icons-ui/src/custom-tag.ts create mode 100644 1st-gen/packages/icons-ui/src/index.ts create mode 100644 1st-gen/packages/icons-ui/stories/icons-ui.stories.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-attribute-many.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-attribute.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-injected-many.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-injected.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-registered-many.ts create mode 100644 1st-gen/packages/icons-ui/test/benchmark/test-registered.ts create mode 100644 1st-gen/packages/icons-ui/tsconfig.json create mode 100644 1st-gen/packages/icons-workflow/.gitignore create mode 100644 1st-gen/packages/icons-workflow/.npmrc create mode 100644 1st-gen/packages/icons-workflow/CHANGELOG.md create mode 100644 1st-gen/packages/icons-workflow/README.md create mode 100644 1st-gen/packages/icons-workflow/bin/build-icons-mapping.js create mode 100644 1st-gen/packages/icons-workflow/bin/build.js create mode 100644 1st-gen/packages/icons-workflow/bin/icons-mapping.json create mode 100644 1st-gen/packages/icons-workflow/package.json create mode 100644 1st-gen/packages/icons-workflow/src/DefaultIcon.ts create mode 100644 1st-gen/packages/icons-workflow/src/custom-tag.ts create mode 100644 1st-gen/packages/icons-workflow/src/index.ts create mode 100644 1st-gen/packages/icons-workflow/stories/icons-workflow.stories.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-attribute-many.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-attribute.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-injected-many.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-injected.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-registered-many.ts create mode 100644 1st-gen/packages/icons-workflow/test/benchmark/test-registered.ts create mode 100644 1st-gen/packages/icons-workflow/tsconfig.json create mode 100644 1st-gen/packages/icons/.npmrc create mode 100644 1st-gen/packages/icons/CHANGELOG.md create mode 100644 1st-gen/packages/icons/README.md create mode 100644 1st-gen/packages/icons/package.json create mode 100644 1st-gen/packages/icons/sp-icons-large.ts create mode 100644 1st-gen/packages/icons/sp-icons-medium.ts create mode 100644 1st-gen/packages/icons/src/IconsLarge.ts create mode 100644 1st-gen/packages/icons/src/IconsMedium.ts create mode 100644 1st-gen/packages/icons/src/icons-large.svg.ts create mode 100644 1st-gen/packages/icons/src/icons-medium.svg.ts create mode 100644 1st-gen/packages/icons/src/index.ts create mode 100644 1st-gen/packages/icons/stories/icons.stories.ts create mode 100644 1st-gen/packages/icons/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/icons/test/icons-memory.test.ts create mode 100644 1st-gen/packages/icons/test/icons.test.ts create mode 100644 1st-gen/packages/icons/tsconfig.json create mode 100644 1st-gen/packages/iconset/.gitignore create mode 100644 1st-gen/packages/iconset/.npmrc create mode 100644 1st-gen/packages/iconset/CHANGELOG.md create mode 100644 1st-gen/packages/iconset/README.md create mode 100644 1st-gen/packages/iconset/package.json create mode 100644 1st-gen/packages/iconset/src/iconset-registry.ts create mode 100644 1st-gen/packages/iconset/src/iconset-svg.ts create mode 100644 1st-gen/packages/iconset/src/iconset.ts create mode 100644 1st-gen/packages/iconset/src/index.ts create mode 100644 1st-gen/packages/iconset/stories/icons-demo.ts create mode 100644 1st-gen/packages/iconset/stories/iconsList.json create mode 100644 1st-gen/packages/iconset/test/iconset.test.ts create mode 100644 1st-gen/packages/iconset/tsconfig.json create mode 100644 1st-gen/packages/illustrated-message/.npmrc create mode 100644 1st-gen/packages/illustrated-message/CHANGELOG.md create mode 100644 1st-gen/packages/illustrated-message/README.md create mode 100644 1st-gen/packages/illustrated-message/package.json create mode 100644 1st-gen/packages/illustrated-message/sp-illustrated-message.ts create mode 100644 1st-gen/packages/illustrated-message/src/IllustratedMessage.ts create mode 100644 1st-gen/packages/illustrated-message/src/illustrated-message.css create mode 100644 1st-gen/packages/illustrated-message/src/illustratedmessage-overrides.css create mode 100644 1st-gen/packages/illustrated-message/src/index.ts create mode 100644 1st-gen/packages/illustrated-message/src/spectrum-illustratedmessage.css create mode 100644 1st-gen/packages/illustrated-message/stories/illustrated-message.stories.ts create mode 100644 1st-gen/packages/illustrated-message/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/illustrated-message/test/illustrated-message-memory.test.ts create mode 100644 1st-gen/packages/illustrated-message/test/illustrated-message.test.ts create mode 100644 1st-gen/packages/illustrated-message/tsconfig.json create mode 100644 1st-gen/packages/infield-button/.npmignore create mode 100644 1st-gen/packages/infield-button/.npmrc create mode 100644 1st-gen/packages/infield-button/CHANGELOG.md create mode 100644 1st-gen/packages/infield-button/README.md create mode 100644 1st-gen/packages/infield-button/package.json create mode 100644 1st-gen/packages/infield-button/sp-infield-button.ts create mode 100644 1st-gen/packages/infield-button/src/InfieldButton.ts create mode 100644 1st-gen/packages/infield-button/src/index.ts create mode 100644 1st-gen/packages/infield-button/src/infield-button-overrides.css create mode 100644 1st-gen/packages/infield-button/src/infield-button.css create mode 100644 1st-gen/packages/infield-button/src/spectrum-infield-button.css create mode 100644 1st-gen/packages/infield-button/stories/index.ts create mode 100644 1st-gen/packages/infield-button/stories/infield-button-sizes.stories.ts create mode 100644 1st-gen/packages/infield-button/stories/infield-button.stories.ts create mode 100644 1st-gen/packages/infield-button/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/infield-button/test/infield-button-memory.test.ts create mode 100644 1st-gen/packages/infield-button/test/infield-button.test.ts create mode 100644 1st-gen/packages/infield-button/tsconfig.json create mode 100644 1st-gen/packages/link/.npmrc create mode 100644 1st-gen/packages/link/CHANGELOG.md create mode 100644 1st-gen/packages/link/README.md create mode 100644 1st-gen/packages/link/package.json create mode 100644 1st-gen/packages/link/sp-link.ts create mode 100644 1st-gen/packages/link/src/Link.ts create mode 100644 1st-gen/packages/link/src/index.ts create mode 100644 1st-gen/packages/link/src/link-overrides.css create mode 100644 1st-gen/packages/link/src/link.css create mode 100644 1st-gen/packages/link/src/spectrum-link.css create mode 100644 1st-gen/packages/link/stories/link.stories.ts create mode 100644 1st-gen/packages/link/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/link/test/link-memory.test.ts create mode 100644 1st-gen/packages/link/test/link.test.ts create mode 100644 1st-gen/packages/link/tsconfig.json create mode 100644 1st-gen/packages/menu/.npmrc create mode 100644 1st-gen/packages/menu/CHANGELOG.md create mode 100644 1st-gen/packages/menu/README.md create mode 100644 1st-gen/packages/menu/menu-group.md create mode 100644 1st-gen/packages/menu/menu-item.md create mode 100644 1st-gen/packages/menu/package.json create mode 100644 1st-gen/packages/menu/sp-menu-divider.ts create mode 100644 1st-gen/packages/menu/sp-menu-group.ts create mode 100644 1st-gen/packages/menu/sp-menu-item.ts create mode 100644 1st-gen/packages/menu/sp-menu.ts create mode 100644 1st-gen/packages/menu/src/Menu.ts create mode 100644 1st-gen/packages/menu/src/MenuDivider.ts create mode 100644 1st-gen/packages/menu/src/MenuGroup.ts create mode 100644 1st-gen/packages/menu/src/MenuItem.ts create mode 100644 1st-gen/packages/menu/src/checkmark-overrides.css create mode 100644 1st-gen/packages/menu/src/chevron-overrides.css create mode 100644 1st-gen/packages/menu/src/index.ts create mode 100644 1st-gen/packages/menu/src/menu-divider-overrides.css create mode 100644 1st-gen/packages/menu/src/menu-divider.css create mode 100644 1st-gen/packages/menu/src/menu-group.css create mode 100644 1st-gen/packages/menu/src/menu-item-overrides.css create mode 100644 1st-gen/packages/menu/src/menu-item.css create mode 100644 1st-gen/packages/menu/src/menu-overrides.css create mode 100644 1st-gen/packages/menu/src/menu-sectionHeading-overrides.css create mode 100644 1st-gen/packages/menu/src/menu.css create mode 100644 1st-gen/packages/menu/src/spectrum-checkmark.css create mode 100644 1st-gen/packages/menu/src/spectrum-chevron.css create mode 100644 1st-gen/packages/menu/src/spectrum-menu-divider.css create mode 100644 1st-gen/packages/menu/src/spectrum-menu-item.css create mode 100644 1st-gen/packages/menu/src/spectrum-menu-sectionHeading.css create mode 100644 1st-gen/packages/menu/src/spectrum-menu.css create mode 100644 1st-gen/packages/menu/stories/index.ts create mode 100644 1st-gen/packages/menu/stories/menu-divider.stories.ts create mode 100644 1st-gen/packages/menu/stories/menu-group.stories.ts create mode 100644 1st-gen/packages/menu/stories/menu-item.disconnected.stories.ts create mode 100644 1st-gen/packages/menu/stories/menu-item.stories.ts create mode 100644 1st-gen/packages/menu/stories/menu-sizes.stories.ts create mode 100644 1st-gen/packages/menu/stories/menu.stories.ts create mode 100644 1st-gen/packages/menu/stories/submenu.stories.ts create mode 100644 1st-gen/packages/menu/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/menu/test/menu-group.test.ts create mode 100644 1st-gen/packages/menu/test/menu-item.test.ts create mode 100644 1st-gen/packages/menu/test/menu-memory.test.ts create mode 100644 1st-gen/packages/menu/test/menu-selects.test.ts create mode 100644 1st-gen/packages/menu/test/menu.test.ts create mode 100644 1st-gen/packages/menu/test/submenu.test.ts create mode 100644 1st-gen/packages/menu/tsconfig.json create mode 100644 1st-gen/packages/meter/.npmrc create mode 100644 1st-gen/packages/meter/CHANGELOG.md create mode 100644 1st-gen/packages/meter/README.md create mode 100644 1st-gen/packages/meter/package.json create mode 100644 1st-gen/packages/meter/sp-meter.ts create mode 100644 1st-gen/packages/meter/src/Meter.ts create mode 100644 1st-gen/packages/meter/src/index.ts create mode 100644 1st-gen/packages/meter/src/meter-overrides.css create mode 100644 1st-gen/packages/meter/src/meter.css create mode 100644 1st-gen/packages/meter/src/progress-bar-overrides.css create mode 100644 1st-gen/packages/meter/src/spectrum-meter.css create mode 100644 1st-gen/packages/meter/src/spectrum-progress-bar.css create mode 100644 1st-gen/packages/meter/stories/meter-sizes.stories.ts create mode 100644 1st-gen/packages/meter/stories/meter.stories.ts create mode 100644 1st-gen/packages/meter/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/meter/test/meter-memory.test.ts create mode 100644 1st-gen/packages/meter/test/meter.test.ts create mode 100644 1st-gen/packages/meter/tsconfig.json create mode 100644 1st-gen/packages/modal/.npmrc create mode 100644 1st-gen/packages/modal/CHANGELOG.md create mode 100644 1st-gen/packages/modal/package.json create mode 100644 1st-gen/packages/modal/src/modal-overrides.css create mode 100644 1st-gen/packages/modal/src/modal-wrapper-overrides.css create mode 100644 1st-gen/packages/modal/src/modal-wrapper.css create mode 100644 1st-gen/packages/modal/src/modal.css create mode 100644 1st-gen/packages/modal/src/spectrum-modal-wrapper.css create mode 100644 1st-gen/packages/modal/src/spectrum-modal.css create mode 100644 1st-gen/packages/modal/tsconfig.json create mode 100644 1st-gen/packages/number-field/.npmrc create mode 100644 1st-gen/packages/number-field/CHANGELOG.md create mode 100644 1st-gen/packages/number-field/README.md create mode 100644 1st-gen/packages/number-field/package.json create mode 100644 1st-gen/packages/number-field/sp-number-field.ts create mode 100644 1st-gen/packages/number-field/src/NumberField.ts create mode 100644 1st-gen/packages/number-field/src/index.ts create mode 100644 1st-gen/packages/number-field/src/number-field-overrides.css create mode 100644 1st-gen/packages/number-field/src/number-field.css create mode 100644 1st-gen/packages/number-field/src/spectrum-number-field.css create mode 100644 1st-gen/packages/number-field/stories/number-field-sizes.stories.ts create mode 100644 1st-gen/packages/number-field/stories/number-field.stories.ts create mode 100644 1st-gen/packages/number-field/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/number-field/test/helpers.ts create mode 100644 1st-gen/packages/number-field/test/inputs.test.ts create mode 100644 1st-gen/packages/number-field/test/number-field-memory.test.ts create mode 100644 1st-gen/packages/number-field/test/number-field.test.ts create mode 100644 1st-gen/packages/number-field/tsconfig.json create mode 100644 1st-gen/packages/overlay/.npmrc create mode 100644 1st-gen/packages/overlay/CHANGELOG.md create mode 100644 1st-gen/packages/overlay/README.md create mode 100644 1st-gen/packages/overlay/imperative-api.md create mode 100644 1st-gen/packages/overlay/local.d.ts create mode 100644 1st-gen/packages/overlay/overlay-trigger.md create mode 100644 1st-gen/packages/overlay/overlay-trigger.ts create mode 100644 1st-gen/packages/overlay/package.json create mode 100644 1st-gen/packages/overlay/slottable-request.md create mode 100644 1st-gen/packages/overlay/sp-overlay.ts create mode 100644 1st-gen/packages/overlay/src/AbstractOverlay.ts create mode 100644 1st-gen/packages/overlay/src/ClickController.ts create mode 100644 1st-gen/packages/overlay/src/HoverController.ts create mode 100644 1st-gen/packages/overlay/src/InteractionController.ts create mode 100644 1st-gen/packages/overlay/src/LongpressController.ts create mode 100644 1st-gen/packages/overlay/src/Overlay.ts create mode 100644 1st-gen/packages/overlay/src/OverlayNoPopover.ts create mode 100644 1st-gen/packages/overlay/src/OverlayPopover.ts create mode 100644 1st-gen/packages/overlay/src/OverlayStack.ts create mode 100644 1st-gen/packages/overlay/src/OverlayTrigger.ts create mode 100644 1st-gen/packages/overlay/src/PlacementController.ts create mode 100644 1st-gen/packages/overlay/src/VirtualTrigger.ts create mode 100644 1st-gen/packages/overlay/src/events.ts create mode 100644 1st-gen/packages/overlay/src/fullSizePlugin.ts create mode 100644 1st-gen/packages/overlay/src/index.ts create mode 100644 1st-gen/packages/overlay/src/loader.ts create mode 100644 1st-gen/packages/overlay/src/overlay-events.ts create mode 100644 1st-gen/packages/overlay/src/overlay-timer.ts create mode 100644 1st-gen/packages/overlay/src/overlay-trigger-directive.ts create mode 100644 1st-gen/packages/overlay/src/overlay-trigger.css create mode 100644 1st-gen/packages/overlay/src/overlay-types.ts create mode 100644 1st-gen/packages/overlay/src/overlay.css create mode 100644 1st-gen/packages/overlay/src/slottable-request-directive.ts create mode 100644 1st-gen/packages/overlay/src/slottable-request-event.ts create mode 100644 1st-gen/packages/overlay/src/strategies.ts create mode 100644 1st-gen/packages/overlay/stories/index.ts create mode 100644 1st-gen/packages/overlay/stories/overlay-directive.stories.ts create mode 100644 1st-gen/packages/overlay/stories/overlay-element.stories.ts create mode 100644 1st-gen/packages/overlay/stories/overlay-story-components.ts create mode 100644 1st-gen/packages/overlay/stories/overlay.stories.ts create mode 100644 1st-gen/packages/overlay/sync/overlay-trigger.ts create mode 100644 1st-gen/packages/overlay/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/overlay/test/benchmark/directive-test.ts create mode 100644 1st-gen/packages/overlay/test/benchmark/element-test.ts create mode 100644 1st-gen/packages/overlay/test/benchmark/lazy-test.ts create mode 100644 1st-gen/packages/overlay/test/index.ts create mode 100644 1st-gen/packages/overlay/test/overlay-directive.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-element.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-lifecycle.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-memory.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-testing-helpers.ts create mode 100644 1st-gen/packages/overlay/test/overlay-timer.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-click.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-directive.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-extended.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-hover-click.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-hover.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-longpress.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-optimization.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger-sync.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-trigger.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-update.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay-v1.test.ts create mode 100644 1st-gen/packages/overlay/test/overlay.test.ts create mode 100644 1st-gen/packages/overlay/trigger-directive.md create mode 100644 1st-gen/packages/overlay/tsconfig.json create mode 100644 1st-gen/packages/picker-button/.npmignore create mode 100644 1st-gen/packages/picker-button/.npmrc create mode 100644 1st-gen/packages/picker-button/CHANGELOG.md create mode 100644 1st-gen/packages/picker-button/README.md create mode 100644 1st-gen/packages/picker-button/package.json create mode 100644 1st-gen/packages/picker-button/sp-picker-button.ts create mode 100644 1st-gen/packages/picker-button/src/PickerButton.ts create mode 100644 1st-gen/packages/picker-button/src/index.ts create mode 100644 1st-gen/packages/picker-button/src/picker-button-overrides.css create mode 100644 1st-gen/packages/picker-button/src/picker-button.css create mode 100644 1st-gen/packages/picker-button/src/spectrum-picker-button-modifier.css create mode 100644 1st-gen/packages/picker-button/src/spectrum-picker-button.css create mode 100644 1st-gen/packages/picker-button/stories/index.ts create mode 100644 1st-gen/packages/picker-button/stories/picker-button-sizes.stories.ts create mode 100644 1st-gen/packages/picker-button/stories/picker-button.stories.ts create mode 100644 1st-gen/packages/picker-button/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/picker-button/test/picker-button-memory.test.ts create mode 100644 1st-gen/packages/picker-button/test/picker-button.test.ts create mode 100644 1st-gen/packages/picker-button/tsconfig.json create mode 100644 1st-gen/packages/picker/.npmrc create mode 100644 1st-gen/packages/picker/CHANGELOG.md create mode 100644 1st-gen/packages/picker/README.md create mode 100644 1st-gen/packages/picker/package.json create mode 100644 1st-gen/packages/picker/sp-picker.ts create mode 100644 1st-gen/packages/picker/src/DesktopController.ts create mode 100644 1st-gen/packages/picker/src/InteractionController.ts create mode 100644 1st-gen/packages/picker/src/MobileController.ts create mode 100644 1st-gen/packages/picker/src/Picker.ts create mode 100644 1st-gen/packages/picker/src/index.ts create mode 100644 1st-gen/packages/picker/src/picker-overrides.css create mode 100644 1st-gen/packages/picker/src/picker.css create mode 100644 1st-gen/packages/picker/src/spectrum-picker.css create mode 100644 1st-gen/packages/picker/src/strategies.ts create mode 100644 1st-gen/packages/picker/stories/args.ts create mode 100644 1st-gen/packages/picker/stories/picker-pending.stories.ts create mode 100644 1st-gen/packages/picker/stories/picker-sizes.stories.ts create mode 100644 1st-gen/packages/picker/stories/picker.stories.ts create mode 100644 1st-gen/packages/picker/stories/states.ts create mode 100644 1st-gen/packages/picker/stories/template.ts create mode 100644 1st-gen/packages/picker/sync/index.ts create mode 100644 1st-gen/packages/picker/sync/sp-picker.ts create mode 100644 1st-gen/packages/picker/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/picker/test/index.ts create mode 100644 1st-gen/packages/picker/test/picker-memory.test.ts create mode 100644 1st-gen/packages/picker/test/picker-reparenting.test.ts create mode 100644 1st-gen/packages/picker/test/picker-responsive.test.ts create mode 100644 1st-gen/packages/picker/test/picker-sync.test.ts create mode 100644 1st-gen/packages/picker/test/picker.test.ts create mode 100644 1st-gen/packages/picker/tsconfig.json create mode 100644 1st-gen/packages/popover/.npmrc create mode 100644 1st-gen/packages/popover/CHANGELOG.md create mode 100644 1st-gen/packages/popover/README.md create mode 100644 1st-gen/packages/popover/package.json create mode 100644 1st-gen/packages/popover/sp-popover.ts create mode 100644 1st-gen/packages/popover/src/Popover.ts create mode 100644 1st-gen/packages/popover/src/index.ts create mode 100644 1st-gen/packages/popover/src/popover-overrides.css create mode 100644 1st-gen/packages/popover/src/popover.css create mode 100644 1st-gen/packages/popover/src/spectrum-popover.css create mode 100644 1st-gen/packages/popover/stories/popover.stories.ts create mode 100644 1st-gen/packages/popover/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/popover/test/popover-memory.test.ts create mode 100644 1st-gen/packages/popover/test/popover.test.ts create mode 100644 1st-gen/packages/popover/tsconfig.json create mode 100644 1st-gen/packages/progress-bar/.npmrc create mode 100644 1st-gen/packages/progress-bar/CHANGELOG.md create mode 100644 1st-gen/packages/progress-bar/README.md create mode 100644 1st-gen/packages/progress-bar/package.json create mode 100644 1st-gen/packages/progress-bar/sp-progress-bar.ts create mode 100644 1st-gen/packages/progress-bar/src/ProgressBar.ts create mode 100644 1st-gen/packages/progress-bar/src/index.ts create mode 100644 1st-gen/packages/progress-bar/src/progress-bar-overrides.css create mode 100644 1st-gen/packages/progress-bar/src/progress-bar.css create mode 100644 1st-gen/packages/progress-bar/src/spectrum-progress-bar.css create mode 100644 1st-gen/packages/progress-bar/stories/progress-bar-sizes.stories.ts create mode 100644 1st-gen/packages/progress-bar/stories/progress-bar.stories.ts create mode 100644 1st-gen/packages/progress-bar/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/progress-bar/test/progress-bar-memory.test.ts create mode 100644 1st-gen/packages/progress-bar/test/progress-bar.test.ts create mode 100644 1st-gen/packages/progress-bar/tsconfig.json create mode 100644 1st-gen/packages/progress-circle/.npmrc create mode 100644 1st-gen/packages/progress-circle/CHANGELOG.md create mode 100644 1st-gen/packages/progress-circle/README.md create mode 100644 1st-gen/packages/progress-circle/package.json create mode 100644 1st-gen/packages/progress-circle/sp-progress-circle.ts create mode 100644 1st-gen/packages/progress-circle/src/ProgressCircle.ts create mode 100644 1st-gen/packages/progress-circle/src/index.ts create mode 100644 1st-gen/packages/progress-circle/src/progress-circle-overrides.css create mode 100644 1st-gen/packages/progress-circle/src/progress-circle.css create mode 100644 1st-gen/packages/progress-circle/src/spectrum-progress-circle.css create mode 100644 1st-gen/packages/progress-circle/stories/progress-circle.stories.ts create mode 100644 1st-gen/packages/progress-circle/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/progress-circle/test/progress-circle-memory.test.ts create mode 100644 1st-gen/packages/progress-circle/test/progress-circle.test.ts create mode 100644 1st-gen/packages/progress-circle/tsconfig.json create mode 100644 1st-gen/packages/radio/.npmrc create mode 100644 1st-gen/packages/radio/CHANGELOG.md create mode 100644 1st-gen/packages/radio/README.md create mode 100644 1st-gen/packages/radio/package.json create mode 100644 1st-gen/packages/radio/radio-group.md create mode 100644 1st-gen/packages/radio/sp-radio-group.ts create mode 100644 1st-gen/packages/radio/sp-radio.ts create mode 100644 1st-gen/packages/radio/src/Radio.ts create mode 100644 1st-gen/packages/radio/src/RadioGroup.ts create mode 100644 1st-gen/packages/radio/src/index.ts create mode 100644 1st-gen/packages/radio/src/radio-overrides.css create mode 100644 1st-gen/packages/radio/src/radio.css create mode 100644 1st-gen/packages/radio/src/spectrum-radio.css create mode 100644 1st-gen/packages/radio/stories/radio-sizes.stories.ts create mode 100644 1st-gen/packages/radio/stories/radio.stories.ts create mode 100644 1st-gen/packages/radio/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/radio/test/radio-group.test.ts create mode 100644 1st-gen/packages/radio/test/radio-memory.test.ts create mode 100644 1st-gen/packages/radio/test/radio.test.ts create mode 100644 1st-gen/packages/radio/tsconfig.json create mode 100644 1st-gen/packages/search/.npmrc create mode 100644 1st-gen/packages/search/CHANGELOG.md create mode 100644 1st-gen/packages/search/README.md create mode 100644 1st-gen/packages/search/package.json create mode 100644 1st-gen/packages/search/sp-search.ts create mode 100644 1st-gen/packages/search/src/Search.ts create mode 100644 1st-gen/packages/search/src/index.ts create mode 100644 1st-gen/packages/search/src/search-overrides.css create mode 100644 1st-gen/packages/search/src/search.css create mode 100644 1st-gen/packages/search/src/spectrum-search.css create mode 100644 1st-gen/packages/search/stories/search-sizes.stories.ts create mode 100644 1st-gen/packages/search/stories/search.stories.ts create mode 100644 1st-gen/packages/search/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/search/test/search-memory.test.ts create mode 100644 1st-gen/packages/search/test/search.test.ts create mode 100644 1st-gen/packages/search/tsconfig.json create mode 100644 1st-gen/packages/sidenav/.npmrc create mode 100644 1st-gen/packages/sidenav/CHANGELOG.md create mode 100644 1st-gen/packages/sidenav/README.md create mode 100644 1st-gen/packages/sidenav/package.json create mode 100644 1st-gen/packages/sidenav/sidenav-heading.md create mode 100644 1st-gen/packages/sidenav/sidenav-item.md create mode 100644 1st-gen/packages/sidenav/sp-sidenav-heading.ts create mode 100644 1st-gen/packages/sidenav/sp-sidenav-item.ts create mode 100644 1st-gen/packages/sidenav/sp-sidenav.ts create mode 100644 1st-gen/packages/sidenav/src/Sidenav.ts create mode 100644 1st-gen/packages/sidenav/src/SidenavHeading.ts create mode 100644 1st-gen/packages/sidenav/src/SidenavItem.ts create mode 100644 1st-gen/packages/sidenav/src/index.ts create mode 100644 1st-gen/packages/sidenav/src/sidenav-heading-overrides.css create mode 100644 1st-gen/packages/sidenav/src/sidenav-heading.css create mode 100644 1st-gen/packages/sidenav/src/sidenav-item-overrides.css create mode 100644 1st-gen/packages/sidenav/src/sidenav-item.css create mode 100644 1st-gen/packages/sidenav/src/sidenav-overrides.css create mode 100644 1st-gen/packages/sidenav/src/sidenav.css create mode 100644 1st-gen/packages/sidenav/src/spectrum-sidenav-heading.css create mode 100644 1st-gen/packages/sidenav/src/spectrum-sidenav-item.css create mode 100644 1st-gen/packages/sidenav/src/spectrum-sidenav.css create mode 100644 1st-gen/packages/sidenav/stories/sidenav.stories.ts create mode 100644 1st-gen/packages/sidenav/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/sidenav/test/sidenav-item.test.ts create mode 100644 1st-gen/packages/sidenav/test/sidenav-memory.test.ts create mode 100644 1st-gen/packages/sidenav/test/sidenav.test.ts create mode 100644 1st-gen/packages/sidenav/tsconfig.json create mode 100644 1st-gen/packages/slider/.npmrc create mode 100644 1st-gen/packages/slider/CHANGELOG.md create mode 100644 1st-gen/packages/slider/README.md create mode 100644 1st-gen/packages/slider/package.json create mode 100644 1st-gen/packages/slider/slider-handle.md create mode 100644 1st-gen/packages/slider/sp-slider-handle.ts create mode 100644 1st-gen/packages/slider/sp-slider.ts create mode 100644 1st-gen/packages/slider/src/HandleController.ts create mode 100644 1st-gen/packages/slider/src/Slider.ts create mode 100644 1st-gen/packages/slider/src/SliderHandle.ts create mode 100644 1st-gen/packages/slider/src/index.ts create mode 100644 1st-gen/packages/slider/src/slider-overrides.css create mode 100644 1st-gen/packages/slider/src/slider.css create mode 100644 1st-gen/packages/slider/src/spectrum-slider.css create mode 100644 1st-gen/packages/slider/stories/slider-sizes.stories.ts create mode 100644 1st-gen/packages/slider/stories/slider.stories.ts create mode 100644 1st-gen/packages/slider/sync/sp-slider.ts create mode 100644 1st-gen/packages/slider/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/slider/test/index.ts create mode 100644 1st-gen/packages/slider/test/slider-editable-sync.test.ts create mode 100644 1st-gen/packages/slider/test/slider-editable.test.ts create mode 100644 1st-gen/packages/slider/test/slider-handle-upgrade.test.ts create mode 100644 1st-gen/packages/slider/test/slider-memory.test.ts create mode 100644 1st-gen/packages/slider/test/slider.test.ts create mode 100644 1st-gen/packages/slider/tsconfig.json create mode 100644 1st-gen/packages/split-view/.npmrc create mode 100644 1st-gen/packages/split-view/CHANGELOG.md create mode 100644 1st-gen/packages/split-view/README.md create mode 100644 1st-gen/packages/split-view/package.json create mode 100644 1st-gen/packages/split-view/sp-split-view.ts create mode 100644 1st-gen/packages/split-view/src/SplitView.ts create mode 100644 1st-gen/packages/split-view/src/index.ts create mode 100644 1st-gen/packages/split-view/src/spectrum-split-view.css create mode 100644 1st-gen/packages/split-view/src/split-view-overrides.css create mode 100644 1st-gen/packages/split-view/src/split-view.css create mode 100644 1st-gen/packages/split-view/src/types.ts create mode 100644 1st-gen/packages/split-view/stories/split-view.stories.ts create mode 100644 1st-gen/packages/split-view/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/split-view/test/split-view-memory.test.ts create mode 100644 1st-gen/packages/split-view/test/split-view.test.ts create mode 100644 1st-gen/packages/split-view/tsconfig.json create mode 100644 1st-gen/packages/status-light/.npmrc create mode 100644 1st-gen/packages/status-light/CHANGELOG.md create mode 100644 1st-gen/packages/status-light/README.md create mode 100644 1st-gen/packages/status-light/package.json create mode 100644 1st-gen/packages/status-light/sp-status-light.ts create mode 100644 1st-gen/packages/status-light/src/StatusLight.ts create mode 100644 1st-gen/packages/status-light/src/index.ts create mode 100644 1st-gen/packages/status-light/src/spectrum-status-light.css create mode 100644 1st-gen/packages/status-light/src/status-light-overrides.css create mode 100644 1st-gen/packages/status-light/src/status-light.css create mode 100644 1st-gen/packages/status-light/stories/status-light.stories.ts create mode 100644 1st-gen/packages/status-light/test/status-light-memory.test.ts create mode 100644 1st-gen/packages/status-light/test/status-light.test.ts create mode 100644 1st-gen/packages/status-light/tsconfig.json create mode 100644 1st-gen/packages/swatch/.npmignore create mode 100644 1st-gen/packages/swatch/.npmrc create mode 100644 1st-gen/packages/swatch/CHANGELOG.md create mode 100644 1st-gen/packages/swatch/README.md create mode 100644 1st-gen/packages/swatch/package.json create mode 100644 1st-gen/packages/swatch/sp-swatch-group.ts create mode 100644 1st-gen/packages/swatch/sp-swatch.ts create mode 100644 1st-gen/packages/swatch/src/Swatch.ts create mode 100644 1st-gen/packages/swatch/src/SwatchGroup.ts create mode 100644 1st-gen/packages/swatch/src/index.ts create mode 100644 1st-gen/packages/swatch/src/spectrum-swatch-group.css create mode 100644 1st-gen/packages/swatch/src/spectrum-swatch.css create mode 100644 1st-gen/packages/swatch/src/swatch-group-overrides.css create mode 100644 1st-gen/packages/swatch/src/swatch-group.css create mode 100644 1st-gen/packages/swatch/src/swatch-overrides.css create mode 100644 1st-gen/packages/swatch/src/swatch.css create mode 100644 1st-gen/packages/swatch/stories/swatch-group.stories.ts create mode 100644 1st-gen/packages/swatch/stories/swatch-sizes.stories.ts create mode 100644 1st-gen/packages/swatch/stories/swatch.stories.ts create mode 100644 1st-gen/packages/swatch/swatch-group.md create mode 100644 1st-gen/packages/swatch/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/swatch/test/swatch-group.test.ts create mode 100644 1st-gen/packages/swatch/test/swatch-memory.test.ts create mode 100644 1st-gen/packages/swatch/test/swatch.test.ts create mode 100644 1st-gen/packages/swatch/tsconfig.json create mode 100644 1st-gen/packages/switch/.npmrc create mode 100644 1st-gen/packages/switch/CHANGELOG.md create mode 100644 1st-gen/packages/switch/README.md create mode 100644 1st-gen/packages/switch/package.json create mode 100644 1st-gen/packages/switch/sp-switch.ts create mode 100644 1st-gen/packages/switch/src/Switch.ts create mode 100644 1st-gen/packages/switch/src/index.ts create mode 100644 1st-gen/packages/switch/src/spectrum-switch.css create mode 100644 1st-gen/packages/switch/src/switch-legacy.css create mode 100644 1st-gen/packages/switch/src/switch-overrides.css create mode 100644 1st-gen/packages/switch/src/switch.css create mode 100644 1st-gen/packages/switch/stories/switch-sizes.stories.ts create mode 100644 1st-gen/packages/switch/stories/switch.stories.ts create mode 100644 1st-gen/packages/switch/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/switch/test/switch-memory.test.ts create mode 100644 1st-gen/packages/switch/test/switch.test.ts create mode 100644 1st-gen/packages/switch/tsconfig.json create mode 100644 1st-gen/packages/table/.npmignore create mode 100644 1st-gen/packages/table/.npmrc create mode 100644 1st-gen/packages/table/CHANGELOG.md create mode 100644 1st-gen/packages/table/README.md create mode 100644 1st-gen/packages/table/elements.ts create mode 100644 1st-gen/packages/table/package.json create mode 100644 1st-gen/packages/table/sp-table-body.ts create mode 100644 1st-gen/packages/table/sp-table-cell.ts create mode 100644 1st-gen/packages/table/sp-table-checkbox-cell.ts create mode 100644 1st-gen/packages/table/sp-table-head-cell.ts create mode 100644 1st-gen/packages/table/sp-table-head.ts create mode 100644 1st-gen/packages/table/sp-table-row.ts create mode 100644 1st-gen/packages/table/sp-table.ts create mode 100644 1st-gen/packages/table/src/Table.ts create mode 100644 1st-gen/packages/table/src/TableBody.ts create mode 100644 1st-gen/packages/table/src/TableCell.ts create mode 100644 1st-gen/packages/table/src/TableCheckboxCell.ts create mode 100644 1st-gen/packages/table/src/TableHead.ts create mode 100644 1st-gen/packages/table/src/TableHeadCell.ts create mode 100644 1st-gen/packages/table/src/TableRow.ts create mode 100644 1st-gen/packages/table/src/index.ts create mode 100644 1st-gen/packages/table/src/spectrum-table-body.css create mode 100644 1st-gen/packages/table/src/spectrum-table-cell.css create mode 100644 1st-gen/packages/table/src/spectrum-table-checkbox-cell.css create mode 100644 1st-gen/packages/table/src/spectrum-table-head-cell.css create mode 100644 1st-gen/packages/table/src/spectrum-table-head.css create mode 100644 1st-gen/packages/table/src/spectrum-table-row.css create mode 100644 1st-gen/packages/table/src/spectrum-table.css create mode 100644 1st-gen/packages/table/src/table-body-overrides.css create mode 100644 1st-gen/packages/table/src/table-body.css create mode 100644 1st-gen/packages/table/src/table-cell-overrides.css create mode 100644 1st-gen/packages/table/src/table-cell.css create mode 100644 1st-gen/packages/table/src/table-checkbox-cell-overrides.css create mode 100644 1st-gen/packages/table/src/table-checkbox-cell.css create mode 100644 1st-gen/packages/table/src/table-head-cell-overrides.css create mode 100644 1st-gen/packages/table/src/table-head-cell.css create mode 100644 1st-gen/packages/table/src/table-head-overrides.css create mode 100644 1st-gen/packages/table/src/table-head.css create mode 100644 1st-gen/packages/table/src/table-overrides.css create mode 100644 1st-gen/packages/table/src/table-row-overrides.css create mode 100644 1st-gen/packages/table/src/table-row.css create mode 100644 1st-gen/packages/table/src/table.css create mode 100644 1st-gen/packages/table/stories/index.ts create mode 100644 1st-gen/packages/table/stories/table-elements.stories.ts create mode 100644 1st-gen/packages/table/stories/table-virtualized.stories.ts create mode 100644 1st-gen/packages/table/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/table/test/helpers.ts create mode 100644 1st-gen/packages/table/test/table-memory.test.ts create mode 100644 1st-gen/packages/table/test/table-selects.test.ts create mode 100644 1st-gen/packages/table/test/table.test.ts create mode 100644 1st-gen/packages/table/test/virtualized-table-selects.test.ts create mode 100644 1st-gen/packages/table/test/virtualized-table.test.ts create mode 100644 1st-gen/packages/table/tsconfig.json create mode 100644 1st-gen/packages/tabs/.npmrc create mode 100644 1st-gen/packages/tabs/CHANGELOG.md create mode 100644 1st-gen/packages/tabs/README.md create mode 100644 1st-gen/packages/tabs/package.json create mode 100644 1st-gen/packages/tabs/sp-tab-panel.ts create mode 100644 1st-gen/packages/tabs/sp-tab.ts create mode 100644 1st-gen/packages/tabs/sp-tabs-overflow.ts create mode 100644 1st-gen/packages/tabs/sp-tabs.ts create mode 100644 1st-gen/packages/tabs/src/Tab.ts create mode 100644 1st-gen/packages/tabs/src/TabPanel.ts create mode 100644 1st-gen/packages/tabs/src/Tabs.ts create mode 100644 1st-gen/packages/tabs/src/TabsOverflow.ts create mode 100644 1st-gen/packages/tabs/src/index.ts create mode 100644 1st-gen/packages/tabs/src/spectrum-tab.css create mode 100644 1st-gen/packages/tabs/src/spectrum-tabs-sizes.css create mode 100644 1st-gen/packages/tabs/src/spectrum-tabs.css create mode 100644 1st-gen/packages/tabs/src/tab-overrides.css create mode 100644 1st-gen/packages/tabs/src/tab-panel.css create mode 100644 1st-gen/packages/tabs/src/tab.css create mode 100644 1st-gen/packages/tabs/src/tabs-overflow.css create mode 100644 1st-gen/packages/tabs/src/tabs-overrides.css create mode 100644 1st-gen/packages/tabs/src/tabs-sizes-overrides.css create mode 100644 1st-gen/packages/tabs/src/tabs-sizes.css create mode 100644 1st-gen/packages/tabs/src/tabs.css create mode 100644 1st-gen/packages/tabs/stories/index.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-horizontal-sizes.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-overflow-panel-sizes.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-overflow-sizes.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-overflow.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-vertical-right-sizes.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs-vertical-sizes.stories.ts create mode 100644 1st-gen/packages/tabs/stories/tabs.stories.ts create mode 100644 1st-gen/packages/tabs/tab-panel.md create mode 100644 1st-gen/packages/tabs/tab.md create mode 100644 1st-gen/packages/tabs/tabs-overflow.md create mode 100644 1st-gen/packages/tabs/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/tabs/test/tab.test.ts create mode 100644 1st-gen/packages/tabs/test/tabs-memory.test.ts create mode 100644 1st-gen/packages/tabs/test/tabs-overflow.test.ts create mode 100644 1st-gen/packages/tabs/test/tabs.test.ts create mode 100644 1st-gen/packages/tabs/tsconfig.json create mode 100644 1st-gen/packages/tags/.npmrc create mode 100644 1st-gen/packages/tags/CHANGELOG.md create mode 100644 1st-gen/packages/tags/README.md create mode 100644 1st-gen/packages/tags/package.json create mode 100644 1st-gen/packages/tags/sp-tag.ts create mode 100644 1st-gen/packages/tags/sp-tags.ts create mode 100644 1st-gen/packages/tags/src/Tag.ts create mode 100644 1st-gen/packages/tags/src/Tags.ts create mode 100644 1st-gen/packages/tags/src/index.ts create mode 100644 1st-gen/packages/tags/src/spectrum-tag.css create mode 100644 1st-gen/packages/tags/src/spectrum-tags.css create mode 100644 1st-gen/packages/tags/src/tag-overrides.css create mode 100644 1st-gen/packages/tags/src/tag.css create mode 100644 1st-gen/packages/tags/src/tags-overrides.css create mode 100644 1st-gen/packages/tags/src/tags.css create mode 100644 1st-gen/packages/tags/stories/tags-sizes.stories.ts create mode 100644 1st-gen/packages/tags/stories/tags.stories.ts create mode 100644 1st-gen/packages/tags/tag.md create mode 100644 1st-gen/packages/tags/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/tags/test/tag.test.ts create mode 100644 1st-gen/packages/tags/test/tags-memory.test.ts create mode 100644 1st-gen/packages/tags/test/tags.test.ts create mode 100644 1st-gen/packages/tags/tsconfig.json create mode 100644 1st-gen/packages/textfield/.npmrc create mode 100644 1st-gen/packages/textfield/CHANGELOG.md create mode 100644 1st-gen/packages/textfield/README.md create mode 100644 1st-gen/packages/textfield/package.json create mode 100644 1st-gen/packages/textfield/sp-textfield.ts create mode 100644 1st-gen/packages/textfield/src/Textfield.ts create mode 100644 1st-gen/packages/textfield/src/index.ts create mode 100644 1st-gen/packages/textfield/src/spectrum-textfield.css create mode 100644 1st-gen/packages/textfield/src/textfield-overrides.css create mode 100644 1st-gen/packages/textfield/src/textfield.css create mode 100644 1st-gen/packages/textfield/stories/textarea-sizes.stories.ts create mode 100644 1st-gen/packages/textfield/stories/textarea.stories.ts create mode 100644 1st-gen/packages/textfield/stories/textfield-sizes.stories.ts create mode 100644 1st-gen/packages/textfield/stories/textfield.stories.ts create mode 100644 1st-gen/packages/textfield/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/textfield/test/textfield-memory.test.ts create mode 100644 1st-gen/packages/textfield/test/textfield.test.ts create mode 100644 1st-gen/packages/textfield/textarea.md create mode 100644 1st-gen/packages/textfield/tsconfig.json create mode 100644 1st-gen/packages/thumbnail/.npmrc create mode 100644 1st-gen/packages/thumbnail/CHANGELOG.md create mode 100644 1st-gen/packages/thumbnail/README.md create mode 100644 1st-gen/packages/thumbnail/package.json create mode 100644 1st-gen/packages/thumbnail/sp-thumbnail.ts create mode 100644 1st-gen/packages/thumbnail/src/Thumbnail.ts create mode 100644 1st-gen/packages/thumbnail/src/index.ts create mode 100644 1st-gen/packages/thumbnail/src/spectrum-thumbnail.css create mode 100644 1st-gen/packages/thumbnail/src/thumbnail-overrides.css create mode 100644 1st-gen/packages/thumbnail/src/thumbnail.css create mode 100644 1st-gen/packages/thumbnail/stories/images.ts create mode 100644 1st-gen/packages/thumbnail/stories/thumbnail-sizes.stories.ts create mode 100644 1st-gen/packages/thumbnail/stories/thumbnail.stories.ts create mode 100644 1st-gen/packages/thumbnail/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/thumbnail/test/thumbnail-memory.test.ts create mode 100644 1st-gen/packages/thumbnail/test/thumbnail.test.ts create mode 100644 1st-gen/packages/thumbnail/tsconfig.json create mode 100644 1st-gen/packages/toast/.npmrc create mode 100644 1st-gen/packages/toast/CHANGELOG.md create mode 100644 1st-gen/packages/toast/README.md create mode 100644 1st-gen/packages/toast/package.json create mode 100644 1st-gen/packages/toast/sp-toast.ts create mode 100644 1st-gen/packages/toast/src/Toast.ts create mode 100644 1st-gen/packages/toast/src/index.ts create mode 100644 1st-gen/packages/toast/src/spectrum-toast.css create mode 100644 1st-gen/packages/toast/src/toast-overrides.css create mode 100644 1st-gen/packages/toast/src/toast.css create mode 100644 1st-gen/packages/toast/stories/toast.stories.ts create mode 100644 1st-gen/packages/toast/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/toast/test/toast-memory.test.ts create mode 100644 1st-gen/packages/toast/test/toast.test.ts create mode 100644 1st-gen/packages/toast/tsconfig.json create mode 100644 1st-gen/packages/tooltip/.npmrc create mode 100644 1st-gen/packages/tooltip/CHANGELOG.md create mode 100644 1st-gen/packages/tooltip/README.md create mode 100644 1st-gen/packages/tooltip/package.json create mode 100644 1st-gen/packages/tooltip/sp-tooltip.ts create mode 100644 1st-gen/packages/tooltip/src/Tooltip.ts create mode 100644 1st-gen/packages/tooltip/src/index.ts create mode 100644 1st-gen/packages/tooltip/src/spectrum-tooltip.css create mode 100644 1st-gen/packages/tooltip/src/tooltip-directive.ts create mode 100644 1st-gen/packages/tooltip/src/tooltip-overrides.css create mode 100644 1st-gen/packages/tooltip/src/tooltip.css create mode 100644 1st-gen/packages/tooltip/stories/tooltip-directive.stories.ts create mode 100644 1st-gen/packages/tooltip/stories/tooltip.stories.ts create mode 100644 1st-gen/packages/tooltip/test/benchmark/test-basic.ts create mode 100644 1st-gen/packages/tooltip/test/benchmark/test-directive.ts create mode 100644 1st-gen/packages/tooltip/test/benchmark/test-element.ts create mode 100644 1st-gen/packages/tooltip/test/benchmark/test-lazy.ts create mode 100644 1st-gen/packages/tooltip/test/tooltip-directive.test.ts create mode 100644 1st-gen/packages/tooltip/test/tooltip-memory.test.ts create mode 100644 1st-gen/packages/tooltip/test/tooltip.test.ts create mode 100644 1st-gen/packages/tooltip/tooltip-directive.md create mode 100644 1st-gen/packages/tooltip/tsconfig.json create mode 100644 1st-gen/packages/top-nav/.npmrc create mode 100644 1st-gen/packages/top-nav/CHANGELOG.md create mode 100644 1st-gen/packages/top-nav/README.md create mode 100644 1st-gen/packages/top-nav/package.json create mode 100644 1st-gen/packages/top-nav/sp-top-nav-item.ts create mode 100644 1st-gen/packages/top-nav/sp-top-nav.ts create mode 100644 1st-gen/packages/top-nav/src/TopNav.ts create mode 100644 1st-gen/packages/top-nav/src/TopNavItem.ts create mode 100644 1st-gen/packages/top-nav/src/index.ts create mode 100644 1st-gen/packages/top-nav/src/top-nav-item.css create mode 100644 1st-gen/packages/top-nav/stories/images.ts create mode 100644 1st-gen/packages/top-nav/stories/top-nav-sizes.stories.ts create mode 100644 1st-gen/packages/top-nav/stories/top-nav.stories.ts create mode 100644 1st-gen/packages/top-nav/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/top-nav/test/top-nav-memory.test.ts create mode 100644 1st-gen/packages/top-nav/test/top-nav.test.ts create mode 100644 1st-gen/packages/top-nav/top-nav-item.md create mode 100644 1st-gen/packages/top-nav/tsconfig.json create mode 100644 1st-gen/packages/tray/.npmrc create mode 100644 1st-gen/packages/tray/CHANGELOG.md create mode 100644 1st-gen/packages/tray/README.md create mode 100644 1st-gen/packages/tray/package.json create mode 100644 1st-gen/packages/tray/sp-tray.ts create mode 100644 1st-gen/packages/tray/src/Tray.ts create mode 100644 1st-gen/packages/tray/src/index.ts create mode 100644 1st-gen/packages/tray/src/spectrum-tray-wrapper.css create mode 100644 1st-gen/packages/tray/src/spectrum-tray.css create mode 100644 1st-gen/packages/tray/src/tray-overrides.css create mode 100644 1st-gen/packages/tray/src/tray-wrapper-overrides.css create mode 100644 1st-gen/packages/tray/src/tray.css create mode 100644 1st-gen/packages/tray/stories/tray.stories.ts create mode 100644 1st-gen/packages/tray/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/tray/test/tray-memory.test.ts create mode 100644 1st-gen/packages/tray/test/tray.test.ts create mode 100644 1st-gen/packages/tray/tsconfig.json create mode 100644 1st-gen/packages/underlay/.npmrc create mode 100644 1st-gen/packages/underlay/CHANGELOG.md create mode 100644 1st-gen/packages/underlay/README.md create mode 100644 1st-gen/packages/underlay/package.json create mode 100644 1st-gen/packages/underlay/sp-underlay.ts create mode 100644 1st-gen/packages/underlay/src/Underlay.ts create mode 100644 1st-gen/packages/underlay/src/index.ts create mode 100644 1st-gen/packages/underlay/src/spectrum-underlay.css create mode 100644 1st-gen/packages/underlay/src/underlay-overrides.css create mode 100644 1st-gen/packages/underlay/src/underlay.css create mode 100644 1st-gen/packages/underlay/stories/underlay.stories.ts create mode 100644 1st-gen/packages/underlay/test/benchmark/basic-test.ts create mode 100644 1st-gen/packages/underlay/test/underlay-memory.test.ts create mode 100644 1st-gen/packages/underlay/test/underlay.test.ts create mode 100644 1st-gen/packages/underlay/tsconfig.json rename playwright.config.ts => 1st-gen/playwright.config.ts (100%) create mode 100644 1st-gen/projects/css-custom-vars-viewer/.gitignore create mode 100644 1st-gen/projects/css-custom-vars-viewer/.npmrc create mode 100644 1st-gen/projects/css-custom-vars-viewer/.storybook/main.js create mode 100644 1st-gen/projects/css-custom-vars-viewer/.storybook/preview.js create mode 100644 1st-gen/projects/css-custom-vars-viewer/CHANGELOG.md create mode 100644 1st-gen/projects/css-custom-vars-viewer/README.md create mode 100644 1st-gen/projects/css-custom-vars-viewer/package.json create mode 100644 1st-gen/projects/css-custom-vars-viewer/scripts/parse-json.js create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/CssTable.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/CustomVarsViewer.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/color-palette.json create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/custom-vars-viewer.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/index.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/src/sp-css-table.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/stories/index.stories.ts create mode 100644 1st-gen/projects/css-custom-vars-viewer/tsconfig.json create mode 100644 1st-gen/projects/css-custom-vars-viewer/web-dev-server.config.mjs create mode 100644 1st-gen/projects/css-custom-vars-viewer/web-test-runner.config.mjs create mode 100644 1st-gen/projects/documentation/.eleventy.js create mode 100644 1st-gen/projects/documentation/.gitignore create mode 100644 1st-gen/projects/documentation/.npmrc create mode 100644 1st-gen/projects/documentation/CHANGELOG.md create mode 100644 1st-gen/projects/documentation/README.md create mode 100644 1st-gen/projects/documentation/content/404.html create mode 100644 1st-gen/projects/documentation/content/_data/site.js create mode 100644 1st-gen/projects/documentation/content/_includes/api.njk create mode 100644 1st-gen/projects/documentation/content/_includes/changelog.njk create mode 100644 1st-gen/projects/documentation/content/_includes/component-partial.njk create mode 100644 1st-gen/projects/documentation/content/_includes/component.njk create mode 100644 1st-gen/projects/documentation/content/_includes/deprecation.njk create mode 100644 1st-gen/projects/documentation/content/_includes/dev-mode.njk create mode 100644 1st-gen/projects/documentation/content/_includes/guide.njk create mode 100644 1st-gen/projects/documentation/content/_includes/home.njk create mode 100644 1st-gen/projects/documentation/content/_includes/introduction.njk create mode 100644 1st-gen/projects/documentation/content/_includes/layout.njk create mode 100644 1st-gen/projects/documentation/content/_includes/overview.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partial.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partials/demo.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partials/deprecation.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partials/logo.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partials/meta-info.njk create mode 100644 1st-gen/projects/documentation/content/_includes/partials/sidenav.njk create mode 100644 1st-gen/projects/documentation/content/_includes/root.njk create mode 100644 1st-gen/projects/documentation/content/_includes/using-swc-react.njk create mode 100644 1st-gen/projects/documentation/content/deprecation.md create mode 100644 1st-gen/projects/documentation/content/dev-mode.md create mode 100644 1st-gen/projects/documentation/content/favicon.ico create mode 100644 1st-gen/projects/documentation/content/favicon.svg create mode 100644 1st-gen/projects/documentation/content/getting-started.md create mode 100644 1st-gen/projects/documentation/content/guides/adding-component.md create mode 100644 1st-gen/projects/documentation/content/guides/configuring-openwc.md create mode 100644 1st-gen/projects/documentation/content/guides/generating-components.md create mode 100644 1st-gen/projects/documentation/content/guides/styling-components.md create mode 100644 1st-gen/projects/documentation/content/guides/writing-changesets.md create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-128x128.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-144x144.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-152x152.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-192x192.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-384x384.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-512x512.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-72x72.png create mode 100755 1st-gen/projects/documentation/content/images/icons/icon-96x96.png create mode 100644 1st-gen/projects/documentation/content/index.md create mode 100644 1st-gen/projects/documentation/content/manifest.webmanifest create mode 100644 1st-gen/projects/documentation/content/migrating-to-spectrum2.md create mode 100644 1st-gen/projects/documentation/content/migrations/2021-8-11.11tydata.cjs create mode 100644 1st-gen/projects/documentation/content/migrations/2021-8-11.md create mode 100644 1st-gen/projects/documentation/content/migrations/2023-8-18.md create mode 100644 1st-gen/projects/documentation/content/migrations/2024-10-31 (1.0.0).md create mode 100644 1st-gen/projects/documentation/content/registry-conflicts.md create mode 100644 1st-gen/projects/documentation/content/serviceWorker.js create mode 100644 1st-gen/projects/documentation/content/shell-end.njk create mode 100644 1st-gen/projects/documentation/content/shell-start.njk create mode 100644 1st-gen/projects/documentation/content/support-and-compatibility.md create mode 100644 1st-gen/projects/documentation/content/typekit/adobe-clean-italic-400.woff2 create mode 100644 1st-gen/projects/documentation/content/typekit/adobe-clean-normal-400.woff2 create mode 100644 1st-gen/projects/documentation/content/typekit/adobe-clean-normal-500.woff2 create mode 100644 1st-gen/projects/documentation/content/typekit/adobe-clean-normal-700.woff2 create mode 100644 1st-gen/projects/documentation/content/typekit/styles.css create mode 100644 1st-gen/projects/documentation/content/using-swc-react.md create mode 100644 1st-gen/projects/documentation/content/what-is-a-theme.md create mode 100644 1st-gen/projects/documentation/e2e/published.spec.ts create mode 100644 1st-gen/projects/documentation/package.json create mode 100644 1st-gen/projects/documentation/rollup.config.js create mode 100644 1st-gen/projects/documentation/scripts/build-css.js create mode 100644 1st-gen/projects/documentation/scripts/build-search-index.js create mode 100644 1st-gen/projects/documentation/scripts/build-ts.js create mode 100644 1st-gen/projects/documentation/scripts/component-template-parts.js create mode 100644 1st-gen/projects/documentation/scripts/copy-component-docs.js create mode 100644 1st-gen/projects/documentation/scripts/gather-spectrum-urls.js create mode 100644 1st-gen/projects/documentation/scripts/gather-storybook-urls.js create mode 100644 1st-gen/projects/documentation/scripts/gather-wcd-urls.js create mode 100644 1st-gen/projects/documentation/scripts/watch-readme.js create mode 100644 1st-gen/projects/documentation/src/components.ts create mode 100644 1st-gen/projects/documentation/src/components/adobe-logo.css create mode 100644 1st-gen/projects/documentation/src/components/adobe-logo.ts create mode 100644 1st-gen/projects/documentation/src/components/code-example-dark.css create mode 100644 1st-gen/projects/documentation/src/components/code-example-light.css create mode 100644 1st-gen/projects/documentation/src/components/code-example.css create mode 100644 1st-gen/projects/documentation/src/components/code-example.ts create mode 100644 1st-gen/projects/documentation/src/components/copy-to-clipboard.ts create mode 100644 1st-gen/projects/documentation/src/components/dark.css create mode 100644 1st-gen/projects/documentation/src/components/demo-container.css create mode 100644 1st-gen/projects/documentation/src/components/demo-container.ts create mode 100644 1st-gen/projects/documentation/src/components/extras.ts create mode 100644 1st-gen/projects/documentation/src/components/fonts.css create mode 100644 1st-gen/projects/documentation/src/components/inline-alert.css create mode 100644 1st-gen/projects/documentation/src/components/large.css create mode 100644 1st-gen/projects/documentation/src/components/layout.css create mode 100644 1st-gen/projects/documentation/src/components/layout.ts create mode 100644 1st-gen/projects/documentation/src/components/light.css create mode 100644 1st-gen/projects/documentation/src/components/markup.css create mode 100644 1st-gen/projects/documentation/src/components/medium.css create mode 100644 1st-gen/projects/documentation/src/components/search-index.ts create mode 100644 1st-gen/projects/documentation/src/components/settings.ts create mode 100644 1st-gen/projects/documentation/src/components/side-nav-search.css create mode 100644 1st-gen/projects/documentation/src/components/side-nav-search.ts create mode 100644 1st-gen/projects/documentation/src/components/side-nav.css create mode 100644 1st-gen/projects/documentation/src/components/side-nav.ts create mode 100644 1st-gen/projects/documentation/src/components/styles.css create mode 100644 1st-gen/projects/documentation/src/getting-started.ts create mode 100644 1st-gen/projects/documentation/src/global.d.ts create mode 100644 1st-gen/projects/documentation/src/index.ts create mode 100644 1st-gen/projects/documentation/src/router.ts create mode 100644 1st-gen/projects/documentation/src/utils/posthtml-loading.js create mode 100644 1st-gen/projects/documentation/src/utils/posthtml-spectrum-docs-markdown.js create mode 100644 1st-gen/projects/documentation/src/utils/posthtml-spectrum-typography.js create mode 100644 1st-gen/projects/documentation/src/utils/templates.ts create mode 100644 1st-gen/projects/documentation/tsconfig.json create mode 100644 1st-gen/projects/documentation/web-dev-server.config.js create mode 100644 1st-gen/projects/example-project-rollup/.editorconfig create mode 100644 1st-gen/projects/example-project-rollup/.gitignore create mode 100644 1st-gen/projects/example-project-rollup/.npmrc create mode 100644 1st-gen/projects/example-project-rollup/CHANGELOG.md create mode 100644 1st-gen/projects/example-project-rollup/LICENSE create mode 100644 1st-gen/projects/example-project-rollup/README.md create mode 100644 1st-gen/projects/example-project-rollup/index.html create mode 100644 1st-gen/projects/example-project-rollup/package.json create mode 100644 1st-gen/projects/example-project-rollup/rollup.config.js create mode 100644 1st-gen/projects/example-project-rollup/src/example-app.ts create mode 100755 1st-gen/projects/example-project-rollup/src/styles.css create mode 100644 1st-gen/projects/example-project-rollup/tsconfig.json create mode 100644 1st-gen/projects/example-project-rollup/wds.config.js create mode 100755 1st-gen/projects/example-project-webpack/.gitignore create mode 100644 1st-gen/projects/example-project-webpack/.npmrc create mode 100644 1st-gen/projects/example-project-webpack/CHANGELOG.md create mode 100755 1st-gen/projects/example-project-webpack/README.md create mode 100644 1st-gen/projects/example-project-webpack/package.json create mode 100644 1st-gen/projects/example-project-webpack/src/index.html create mode 100755 1st-gen/projects/example-project-webpack/src/index.js create mode 100755 1st-gen/projects/example-project-webpack/src/styles.css create mode 100755 1st-gen/projects/example-project-webpack/webpack.config.js create mode 100644 1st-gen/projects/story-decorator/.npmrc create mode 100644 1st-gen/projects/story-decorator/CHANGELOG.md create mode 100644 1st-gen/projects/story-decorator/README.md create mode 100644 1st-gen/projects/story-decorator/decorator.ts create mode 100644 1st-gen/projects/story-decorator/package.json create mode 100644 1st-gen/projects/story-decorator/sp-story-decorator.ts create mode 100644 1st-gen/projects/story-decorator/src/StoryDecorator.ts create mode 100644 1st-gen/projects/story-decorator/src/index.ts create mode 100644 1st-gen/projects/story-decorator/src/locales.ts create mode 100644 1st-gen/projects/story-decorator/src/types.ts create mode 100644 1st-gen/projects/story-decorator/tsconfig.json create mode 100644 1st-gen/projects/templates/.npmrc create mode 100644 1st-gen/projects/templates/CHANGELOG.md create mode 100644 1st-gen/projects/templates/package.json create mode 100644 1st-gen/projects/templates/plop-templates/.npmrc.hbs create mode 100644 1st-gen/projects/templates/plop-templates/README.md.hbs create mode 100644 1st-gen/projects/templates/plop-templates/args.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/benchmark.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/component-overrides.css.hbs create mode 100644 1st-gen/projects/templates/plop-templates/component-registration.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/component.css.hbs create mode 100644 1st-gen/projects/templates/plop-templates/component.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/index.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/package.json.hbs create mode 100644 1st-gen/projects/templates/plop-templates/stories.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/template.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/test.ts.hbs create mode 100644 1st-gen/projects/templates/plop-templates/tsconfig.json.hbs create mode 100644 1st-gen/projects/templates/plopfile.js create mode 100644 1st-gen/projects/types/.npmrc create mode 100644 1st-gen/projects/types/CHANGELOG.md create mode 100644 1st-gen/projects/types/global.d.ts create mode 100644 1st-gen/projects/types/package.json create mode 100644 1st-gen/projects/vrt-compare/.npmrc create mode 100644 1st-gen/projects/vrt-compare/CHANGELOG.md create mode 100644 1st-gen/projects/vrt-compare/README.md create mode 100644 1st-gen/projects/vrt-compare/onion-skinner.ts create mode 100644 1st-gen/projects/vrt-compare/package.json create mode 100644 1st-gen/projects/vrt-compare/src/OnionSkinner.ts create mode 100644 1st-gen/projects/vrt-compare/src/VrtCompare.ts create mode 100644 1st-gen/projects/vrt-compare/src/index.ts create mode 100644 1st-gen/projects/vrt-compare/tsconfig.json create mode 100644 1st-gen/projects/vrt-compare/vrt-compare.ts create mode 100644 1st-gen/rollup.checksize.js create mode 100755 1st-gen/scripts/build-css.js create mode 100644 1st-gen/scripts/build-react.js create mode 100644 1st-gen/scripts/build-ts.js create mode 100644 1st-gen/scripts/cem-plugin-react-wrapper.js create mode 100644 1st-gen/scripts/cem-tools.js create mode 100644 1st-gen/scripts/confirm-build.js create mode 100644 1st-gen/scripts/create-git-tag.js create mode 100644 1st-gen/scripts/css-tools.js create mode 100644 1st-gen/scripts/custom-element-json.js create mode 100644 1st-gen/scripts/define-element-plugin.js create mode 100644 1st-gen/scripts/escape-changelog-tags.js create mode 100644 1st-gen/scripts/process-icons.js create mode 100644 1st-gen/scripts/test-changes.js create mode 100644 1st-gen/scripts/ts-tools.js create mode 100644 1st-gen/scripts/update-global-changelog.js create mode 100644 1st-gen/scripts/watch-css.js create mode 100644 1st-gen/scripts/watch-ts.js create mode 100644 1st-gen/storybook/DocumentationTemplate.mdx create mode 100644 1st-gen/storybook/main.js create mode 100644 1st-gen/storybook/manager.js create mode 100644 1st-gen/storybook/preview-head.html create mode 100644 1st-gen/storybook/preview.js create mode 100644 1st-gen/storybook/theme.js create mode 100644 1st-gen/storybook/tsconfig.json create mode 100644 1st-gen/storybook/types.d.ts create mode 100644 1st-gen/test/benchmark/.gitignore create mode 100644 1st-gen/test/benchmark/bench-runner.html create mode 100644 1st-gen/test/benchmark/cli.ts create mode 100644 1st-gen/test/benchmark/helpers.ts create mode 100644 1st-gen/test/lit-helpers.ts create mode 100644 1st-gen/test/plugins/browser.ts create mode 100644 1st-gen/test/plugins/grant-permissions-plugin.ts create mode 100644 1st-gen/test/plugins/send-mouse-plugin.ts create mode 100644 1st-gen/test/testing-helpers-a11y.ts create mode 100644 1st-gen/test/testing-helpers.ts create mode 100644 1st-gen/test/tsconfig-node.json create mode 100644 1st-gen/test/tsconfig-plugins.json create mode 100644 1st-gen/test/tsconfig-test.json create mode 100644 1st-gen/test/tsconfig.json create mode 100644 1st-gen/test/visual/create.js create mode 100644 1st-gen/test/visual/index.html create mode 100644 1st-gen/test/visual/review.js create mode 100644 1st-gen/test/visual/rollup.config.js create mode 100644 1st-gen/test/visual/src/index.html create mode 100644 1st-gen/test/visual/src/review.js create mode 100644 1st-gen/test/visual/test.ts create mode 100644 1st-gen/test/visual/wds-vrt.config.js create mode 100644 1st-gen/tools/.eslintrc.json create mode 100644 1st-gen/tools/base/.npmrc create mode 100644 1st-gen/tools/base/CHANGELOG.md create mode 100644 1st-gen/tools/base/README.md create mode 100644 1st-gen/tools/base/package.json create mode 100644 1st-gen/tools/base/src/Base.ts create mode 100644 1st-gen/tools/base/src/async-directive.ts create mode 100644 1st-gen/tools/base/src/condition-attribute-with-id.ts create mode 100644 1st-gen/tools/base/src/constants.ts create mode 100644 1st-gen/tools/base/src/decorators.ts create mode 100644 1st-gen/tools/base/src/define-element.ts create mode 100644 1st-gen/tools/base/src/directive.ts create mode 100644 1st-gen/tools/base/src/directives.ts create mode 100644 1st-gen/tools/base/src/html.ts create mode 100644 1st-gen/tools/base/src/index.ts create mode 100644 1st-gen/tools/base/src/sizedMixin.ts create mode 100644 1st-gen/tools/base/src/streaming-listener.ts create mode 100644 1st-gen/tools/base/src/version.d.ts create mode 100755 1st-gen/tools/base/src/version.js create mode 100644 1st-gen/tools/base/test/base-devmode.test.ts create mode 100644 1st-gen/tools/base/test/base.test.ts create mode 100644 1st-gen/tools/base/test/define-element.test.ts create mode 100644 1st-gen/tools/base/test/sizedMixin.test.ts create mode 100644 1st-gen/tools/base/tsconfig.json create mode 100644 1st-gen/tools/bundle/.npmrc create mode 100644 1st-gen/tools/bundle/CHANGELOG.md create mode 100644 1st-gen/tools/bundle/README.md create mode 100644 1st-gen/tools/bundle/elements.ts create mode 100644 1st-gen/tools/bundle/package.json create mode 100644 1st-gen/tools/bundle/src/icons.ts create mode 100644 1st-gen/tools/bundle/src/index.ts create mode 100644 1st-gen/tools/bundle/tsconfig.json create mode 100644 1st-gen/tools/grid/.npmignore create mode 100644 1st-gen/tools/grid/.npmrc create mode 100644 1st-gen/tools/grid/CHANGELOG.md create mode 100644 1st-gen/tools/grid/README.md create mode 100644 1st-gen/tools/grid/package.json create mode 100644 1st-gen/tools/grid/sp-grid.ts create mode 100644 1st-gen/tools/grid/src/Grid.ts create mode 100644 1st-gen/tools/grid/src/GridController.ts create mode 100644 1st-gen/tools/grid/src/grid.css create mode 100644 1st-gen/tools/grid/src/index.ts create mode 100644 1st-gen/tools/grid/stories/grid.stories.ts create mode 100644 1st-gen/tools/grid/test/benchmark/basic-test.ts create mode 100644 1st-gen/tools/grid/test/grid-memory.test.ts create mode 100644 1st-gen/tools/grid/test/grid.test.ts create mode 100644 1st-gen/tools/grid/tsconfig.json create mode 100644 1st-gen/tools/opacity-checkerboard/.npmrc create mode 100644 1st-gen/tools/opacity-checkerboard/CHANGELOG.md create mode 100644 1st-gen/tools/opacity-checkerboard/README.md create mode 100644 1st-gen/tools/opacity-checkerboard/package.json create mode 100644 1st-gen/tools/opacity-checkerboard/src/is-opacity-checkerboard-overrides.css create mode 100644 1st-gen/tools/opacity-checkerboard/src/is-opacity-checkerboard.css create mode 100644 1st-gen/tools/opacity-checkerboard/src/opacity-checkerboard-overrides.css create mode 100644 1st-gen/tools/opacity-checkerboard/src/opacity-checkerboard.css create mode 100644 1st-gen/tools/opacity-checkerboard/src/spectrum-is-opacity-checkerboard.css create mode 100644 1st-gen/tools/opacity-checkerboard/src/spectrum-opacity-checkerboard.css create mode 100644 1st-gen/tools/opacity-checkerboard/tsconfig.json create mode 100644 1st-gen/tools/reactive-controllers/.npmignore create mode 100644 1st-gen/tools/reactive-controllers/.npmrc create mode 100644 1st-gen/tools/reactive-controllers/CHANGELOG.md create mode 100644 1st-gen/tools/reactive-controllers/README.md create mode 100644 1st-gen/tools/reactive-controllers/color-controller.md create mode 100644 1st-gen/tools/reactive-controllers/dependency-manager.md create mode 100644 1st-gen/tools/reactive-controllers/element-resolution.md create mode 100644 1st-gen/tools/reactive-controllers/match-media.md create mode 100644 1st-gen/tools/reactive-controllers/package.json create mode 100644 1st-gen/tools/reactive-controllers/pending-state.md create mode 100644 1st-gen/tools/reactive-controllers/roving-tab-index.md create mode 100644 1st-gen/tools/reactive-controllers/src/ColorController.ts create mode 100644 1st-gen/tools/reactive-controllers/src/DependencyManger.ts create mode 100644 1st-gen/tools/reactive-controllers/src/ElementResolution.ts create mode 100644 1st-gen/tools/reactive-controllers/src/FocusGroup.ts create mode 100644 1st-gen/tools/reactive-controllers/src/LanguageResolution.ts create mode 100644 1st-gen/tools/reactive-controllers/src/MatchMedia.ts create mode 100644 1st-gen/tools/reactive-controllers/src/PendingState.ts create mode 100644 1st-gen/tools/reactive-controllers/src/RovingTabindex.ts create mode 100644 1st-gen/tools/reactive-controllers/src/SystemContextResolution.ts create mode 100644 1st-gen/tools/reactive-controllers/src/index.ts create mode 100644 1st-gen/tools/reactive-controllers/test/color-controller.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/dependency-manager.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/element-resolution.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/helpers.ts create mode 100644 1st-gen/tools/reactive-controllers/test/match-media.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/pending-state.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/roving-tabindex-integration.test.ts create mode 100644 1st-gen/tools/reactive-controllers/test/roving-tabindex.test.ts create mode 100644 1st-gen/tools/reactive-controllers/tsconfig.json create mode 100644 1st-gen/tools/shared/.npmrc create mode 100644 1st-gen/tools/shared/CHANGELOG.md create mode 100644 1st-gen/tools/shared/README.md create mode 100644 1st-gen/tools/shared/package.json create mode 100644 1st-gen/tools/shared/src/first-focusable-in.ts create mode 100644 1st-gen/tools/shared/src/focus-visible.ts create mode 100644 1st-gen/tools/shared/src/focusable-selectors.ts create mode 100644 1st-gen/tools/shared/src/focusable.ts create mode 100644 1st-gen/tools/shared/src/get-active-element.ts create mode 100644 1st-gen/tools/shared/src/get-deep-element-from-point.ts create mode 100644 1st-gen/tools/shared/src/get-label-from-slot.ts create mode 100644 1st-gen/tools/shared/src/index.ts create mode 100644 1st-gen/tools/shared/src/like-anchor.ts create mode 100644 1st-gen/tools/shared/src/observe-slot-presence.ts create mode 100644 1st-gen/tools/shared/src/observe-slot-text.ts create mode 100644 1st-gen/tools/shared/src/platform.ts create mode 100644 1st-gen/tools/shared/src/random-id.ts create mode 100644 1st-gen/tools/shared/src/reparent-children.ts create mode 100644 1st-gen/tools/shared/test/focusable.test.ts create mode 100644 1st-gen/tools/shared/test/observe-slot-presence.test.ts create mode 100644 1st-gen/tools/shared/test/observe-slot-text.test.ts create mode 100644 1st-gen/tools/shared/test/random-id.test.ts create mode 100644 1st-gen/tools/shared/test/reparent-children.test.ts create mode 100644 1st-gen/tools/shared/tsconfig.json create mode 100644 1st-gen/tools/styles/.npmrc create mode 100644 1st-gen/tools/styles/CHANGELOG.md create mode 100644 1st-gen/tools/styles/README.md create mode 100755 1st-gen/tools/styles/all-large-dark.css create mode 100755 1st-gen/tools/styles/all-large-darkest.css create mode 100755 1st-gen/tools/styles/all-large-light.css create mode 100755 1st-gen/tools/styles/all-large-lightest.css create mode 100755 1st-gen/tools/styles/all-medium-dark.css create mode 100755 1st-gen/tools/styles/all-medium-darkest.css create mode 100755 1st-gen/tools/styles/all-medium-light.css create mode 100755 1st-gen/tools/styles/all-medium-lightest.css create mode 100644 1st-gen/tools/styles/body.ts create mode 100644 1st-gen/tools/styles/code.ts create mode 100644 1st-gen/tools/styles/core-global.css create mode 100644 1st-gen/tools/styles/detail.ts create mode 100644 1st-gen/tools/styles/express/core-global.css create mode 100644 1st-gen/tools/styles/express/scale-large.css create mode 100644 1st-gen/tools/styles/express/scale-medium.css create mode 100644 1st-gen/tools/styles/express/spectrum-core-global.css create mode 100644 1st-gen/tools/styles/express/spectrum-scale-large.css create mode 100644 1st-gen/tools/styles/express/spectrum-scale-medium.css create mode 100644 1st-gen/tools/styles/express/spectrum-theme-dark.css create mode 100644 1st-gen/tools/styles/express/spectrum-theme-light.css create mode 100644 1st-gen/tools/styles/express/theme-dark.css create mode 100644 1st-gen/tools/styles/express/theme-light.css create mode 100755 1st-gen/tools/styles/fonts.css create mode 100644 1st-gen/tools/styles/heading.ts create mode 100755 1st-gen/tools/styles/package.json create mode 100644 1st-gen/tools/styles/scale-large.css create mode 100644 1st-gen/tools/styles/scale-medium.css create mode 100644 1st-gen/tools/styles/spectrum-core-global.css create mode 100644 1st-gen/tools/styles/spectrum-scale-large.css create mode 100644 1st-gen/tools/styles/spectrum-scale-medium.css create mode 100644 1st-gen/tools/styles/spectrum-theme-dark.css create mode 100644 1st-gen/tools/styles/spectrum-theme-darkest.css create mode 100644 1st-gen/tools/styles/spectrum-theme-light.css create mode 100644 1st-gen/tools/styles/spectrum-theme-lightest.css create mode 100644 1st-gen/tools/styles/spectrum-two/core-global.css create mode 100644 1st-gen/tools/styles/spectrum-two/scale-large.css create mode 100644 1st-gen/tools/styles/spectrum-two/scale-medium.css create mode 100644 1st-gen/tools/styles/spectrum-two/spectrum-core-global.css create mode 100644 1st-gen/tools/styles/spectrum-two/spectrum-scale-large.css create mode 100644 1st-gen/tools/styles/spectrum-two/spectrum-scale-medium.css create mode 100644 1st-gen/tools/styles/spectrum-two/spectrum-theme-dark.css create mode 100644 1st-gen/tools/styles/spectrum-two/spectrum-theme-light.css create mode 100644 1st-gen/tools/styles/spectrum-two/theme-dark.css create mode 100644 1st-gen/tools/styles/spectrum-two/theme-light.css create mode 100644 1st-gen/tools/styles/spectrum-two/themes.ts create mode 100644 1st-gen/tools/styles/src/body-overrides.css create mode 100644 1st-gen/tools/styles/src/code-overrides.css create mode 100644 1st-gen/tools/styles/src/detail-overrides.css create mode 100644 1st-gen/tools/styles/src/heading-overrides.css create mode 100644 1st-gen/tools/styles/src/lang-overrides.css create mode 100644 1st-gen/tools/styles/src/spectrum-base.css create mode 100644 1st-gen/tools/styles/src/spectrum-body.css create mode 100644 1st-gen/tools/styles/src/spectrum-code.css create mode 100644 1st-gen/tools/styles/src/spectrum-detail.css create mode 100644 1st-gen/tools/styles/src/spectrum-heading.css create mode 100644 1st-gen/tools/styles/src/spectrum-lang.css create mode 100644 1st-gen/tools/styles/src/spectrum-typography.css create mode 100644 1st-gen/tools/styles/src/typography-overrides.css create mode 100644 1st-gen/tools/styles/stories/styles.stories.ts create mode 100644 1st-gen/tools/styles/theme-dark.css create mode 100644 1st-gen/tools/styles/theme-darkest.css create mode 100644 1st-gen/tools/styles/theme-light.css create mode 100644 1st-gen/tools/styles/theme-lightest.css create mode 100644 1st-gen/tools/styles/tokens-v2/dark-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/global-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/index.css create mode 100644 1st-gen/tools/styles/tokens-v2/large-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/light-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/medium-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-dark-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-large-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-light-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-medium-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/spectrum/custom-vars.css create mode 100644 1st-gen/tools/styles/tokens-v2/system-theme-bridge.css create mode 100644 1st-gen/tools/styles/tokens/dark-vars.css create mode 100644 1st-gen/tools/styles/tokens/darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-dark-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-large-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-light-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-medium-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/custom-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/dark-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/global-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/index.css create mode 100644 1st-gen/tools/styles/tokens/express/large-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/light-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/medium-vars.css create mode 100644 1st-gen/tools/styles/tokens/express/system-theme-bridge.css create mode 100644 1st-gen/tools/styles/tokens/global-vars.css create mode 100644 1st-gen/tools/styles/tokens/index.css create mode 100644 1st-gen/tools/styles/tokens/large-vars.css create mode 100644 1st-gen/tools/styles/tokens/light-vars.css create mode 100644 1st-gen/tools/styles/tokens/medium-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-dark-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-large-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-light-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-medium-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/custom-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/dark-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/darkest-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/global-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/index.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/large-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/light-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/medium-vars.css create mode 100644 1st-gen/tools/styles/tokens/spectrum/system-theme-bridge.css create mode 100644 1st-gen/tools/styles/tsconfig.json create mode 100644 1st-gen/tools/styles/typography.css create mode 100644 1st-gen/tools/styles/typography.ts create mode 100644 1st-gen/tools/theme/.npmrc create mode 100644 1st-gen/tools/theme/CHANGELOG.md create mode 100644 1st-gen/tools/theme/README.md create mode 100644 1st-gen/tools/theme/core-tokens.md create mode 100644 1st-gen/tools/theme/core-tokens.ts create mode 100644 1st-gen/tools/theme/core.ts create mode 100644 1st-gen/tools/theme/express/scale-large-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/scale-large.ts create mode 100644 1st-gen/tools/theme/express/scale-medium-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/scale-medium.ts create mode 100644 1st-gen/tools/theme/express/theme-dark-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/theme-dark.ts create mode 100644 1st-gen/tools/theme/express/theme-darkest-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/theme-darkest.ts create mode 100644 1st-gen/tools/theme/express/theme-light-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/theme-light.ts create mode 100644 1st-gen/tools/theme/express/theme-lightest-core-tokens.ts create mode 100644 1st-gen/tools/theme/express/theme-lightest.ts create mode 100755 1st-gen/tools/theme/package.json create mode 100644 1st-gen/tools/theme/scale-large-core-tokens.ts create mode 100644 1st-gen/tools/theme/scale-large.ts create mode 100644 1st-gen/tools/theme/scale-medium-core-tokens.ts create mode 100644 1st-gen/tools/theme/scale-medium.ts create mode 100644 1st-gen/tools/theme/sp-theme.ts create mode 100755 1st-gen/tools/theme/spectrum-two/scale-large-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/scale-large.ts create mode 100755 1st-gen/tools/theme/spectrum-two/scale-medium-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/scale-medium.ts create mode 100755 1st-gen/tools/theme/spectrum-two/theme-dark-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-dark.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-darkest-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-darkest.ts create mode 100755 1st-gen/tools/theme/spectrum-two/theme-light-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-light.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-lightest-core-tokens.ts create mode 100644 1st-gen/tools/theme/spectrum-two/theme-lightest.ts create mode 100755 1st-gen/tools/theme/src/Theme.ts create mode 100644 1st-gen/tools/theme/src/express/core-tokens.ts create mode 100644 1st-gen/tools/theme/src/express/core.ts create mode 100644 1st-gen/tools/theme/src/express/scale-large-core-tokens.css create mode 100644 1st-gen/tools/theme/src/express/scale-large.css create mode 100644 1st-gen/tools/theme/src/express/scale-medium-core-tokens.css create mode 100644 1st-gen/tools/theme/src/express/scale-medium.css create mode 100644 1st-gen/tools/theme/src/express/theme-core-tokens.css create mode 100644 1st-gen/tools/theme/src/express/theme-dark-core-tokens.css create mode 100644 1st-gen/tools/theme/src/express/theme-dark.css create mode 100644 1st-gen/tools/theme/src/express/theme-light-core-tokens.css create mode 100644 1st-gen/tools/theme/src/express/theme-light.css create mode 100644 1st-gen/tools/theme/src/express/theme.css create mode 100644 1st-gen/tools/theme/src/express/themes-core-tokens.ts create mode 100644 1st-gen/tools/theme/src/express/themes.ts create mode 100644 1st-gen/tools/theme/src/index.ts create mode 100644 1st-gen/tools/theme/src/scale-large-core-tokens.css create mode 100644 1st-gen/tools/theme/src/scale-large.css create mode 100644 1st-gen/tools/theme/src/scale-medium-core-tokens.css create mode 100644 1st-gen/tools/theme/src/scale-medium.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/core-tokens.ts create mode 100644 1st-gen/tools/theme/src/spectrum-two/core.ts create mode 100755 1st-gen/tools/theme/src/spectrum-two/scale-large-core-tokens.css create mode 100644 1st-gen/tools/theme/src/spectrum-two/scale-large.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/scale-medium-core-tokens.css create mode 100644 1st-gen/tools/theme/src/spectrum-two/scale-medium.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/theme-core-tokens.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/theme-dark-core-tokens.css create mode 100644 1st-gen/tools/theme/src/spectrum-two/theme-dark.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/theme-light-core-tokens.css create mode 100644 1st-gen/tools/theme/src/spectrum-two/theme-light.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/theme.css create mode 100755 1st-gen/tools/theme/src/spectrum-two/themes-core-tokens.ts create mode 100644 1st-gen/tools/theme/src/spectrum-two/themes.ts create mode 100644 1st-gen/tools/theme/src/theme-core-tokens.css create mode 100644 1st-gen/tools/theme/src/theme-dark-core-tokens.css create mode 100644 1st-gen/tools/theme/src/theme-dark.css create mode 100644 1st-gen/tools/theme/src/theme-darkest-core-tokens.css create mode 100644 1st-gen/tools/theme/src/theme-darkest.css create mode 100644 1st-gen/tools/theme/src/theme-interfaces.ts create mode 100644 1st-gen/tools/theme/src/theme-light-core-tokens.css create mode 100644 1st-gen/tools/theme/src/theme-light.css create mode 100644 1st-gen/tools/theme/src/theme-lightest-core-tokens.css create mode 100644 1st-gen/tools/theme/src/theme-lightest.css create mode 100644 1st-gen/tools/theme/src/theme.css create mode 100644 1st-gen/tools/theme/src/themes-core-tokens.ts create mode 100644 1st-gen/tools/theme/src/themes.ts create mode 100644 1st-gen/tools/theme/src/typography.css create mode 100644 1st-gen/tools/theme/stories/theme.stories.ts create mode 100644 1st-gen/tools/theme/test/theme-devmode.test.ts create mode 100644 1st-gen/tools/theme/test/theme-lazy.test.ts create mode 100644 1st-gen/tools/theme/test/theme.test.ts create mode 100644 1st-gen/tools/theme/test/themes.test.ts create mode 100644 1st-gen/tools/theme/theme-dark-core-tokens.ts create mode 100644 1st-gen/tools/theme/theme-dark.ts create mode 100644 1st-gen/tools/theme/theme-darkest-core-tokens.ts create mode 100644 1st-gen/tools/theme/theme-darkest.ts create mode 100644 1st-gen/tools/theme/theme-light-core-tokens.ts create mode 100644 1st-gen/tools/theme/theme-light.ts create mode 100644 1st-gen/tools/theme/theme-lightest-core-tokens.ts create mode 100644 1st-gen/tools/theme/theme-lightest.ts create mode 100755 1st-gen/tools/theme/tsconfig.json create mode 100644 1st-gen/tools/truncated/.npmignore create mode 100644 1st-gen/tools/truncated/.npmrc create mode 100644 1st-gen/tools/truncated/CHANGELOG.md create mode 100644 1st-gen/tools/truncated/README.md create mode 100644 1st-gen/tools/truncated/package.json create mode 100644 1st-gen/tools/truncated/sp-truncated.ts create mode 100644 1st-gen/tools/truncated/src/Truncated.ts create mode 100644 1st-gen/tools/truncated/src/index.ts create mode 100644 1st-gen/tools/truncated/src/truncated.css create mode 100644 1st-gen/tools/truncated/stories/truncated.stories.ts create mode 100644 1st-gen/tools/truncated/test/benchmark/basic-test.ts create mode 100644 1st-gen/tools/truncated/test/truncated.test.ts create mode 100644 1st-gen/tools/truncated/tsconfig.json create mode 100644 1st-gen/tsconfig-all.json create mode 100644 1st-gen/tsconfig-react-wrapper.json create mode 100644 1st-gen/tsconfig.json create mode 100644 1st-gen/web-test-runner.config.ci-chromium-flags.js create mode 100644 1st-gen/web-test-runner.config.ci-chromium-memory.js create mode 100644 1st-gen/web-test-runner.config.ci-chromium.js create mode 100644 1st-gen/web-test-runner.config.ci-firefox.js create mode 100644 1st-gen/web-test-runner.config.ci-webkit.js create mode 100644 1st-gen/web-test-runner.config.ci.js create mode 100644 1st-gen/web-test-runner.config.js create mode 100644 1st-gen/web-test-runner.config.vrt.js create mode 100644 1st-gen/web-test-runner.utils.js delete mode 100644 PULL_REQUESTS.md delete mode 100644 RELEASE_PROCESS.md diff --git a/1st-gen/.eslintignore b/1st-gen/.eslintignore new file mode 100644 index 00000000000..d57f09885eb --- /dev/null +++ b/1st-gen/.eslintignore @@ -0,0 +1,6 @@ +packages/**/*.d.ts +packages/*/node_modules/**/* +tools/**/*.d.ts +tools/*/node_modules/**/* +config/* +tools/base/src/version.js diff --git a/1st-gen/.eslintrc.json b/1st-gen/.eslintrc.json new file mode 100755 index 00000000000..61d9acef760 --- /dev/null +++ b/1st-gen/.eslintrc.json @@ -0,0 +1,162 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "plugin:lit-a11y/recommended", + "plugin:require-extensions/recommended" + ], + "overrides": [ + { + "extends": ["plugin:jsonc/recommended-with-jsonc"], + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "jsonc/sort-keys": ["warn"], + "notice/notice": "off" + } + }, + { + "extends": ["plugin:jsonc/recommended-with-jsonc"], + "files": ["package.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "jsonc/sort-keys": [ + "warn", + { + "hasProperties": ["type"], + "order": [ + "$schema", + "name", + "version", + "private", + "description", + "license", + "author", + "maintainers", + "contributors", + "homepage", + "repository", + "bugs", + "type", + "exports", + "main", + "module", + "browser", + "man", + "preferGlobal", + "bin", + "files", + "directories", + "scripts", + "config", + "sideEffects", + "types", + "typings", + "workspaces", + "resolutions", + "dependencies", + "bundleDependencies", + "bundledDependencies", + "peerDependencies", + "peerDependenciesMeta", + "optionalDependencies", + "devDependencies", + "keywords", + "engines", + "engineStrict", + "os", + "cpu", + "publishConfig" + ], + "pathPattern": "^$" // Top-level properties + }, + { + /* + * This rule excludes export conditions from alphabetical sorting. + * Since node.js processes export conditions in order and chooses the + * first match, they need to be ordered logically, not alphabetically. + */ + "order": { "type": "asc" }, + "pathPattern": "^(?!exports\\[).*" // All properties except export conditions + } + ] + } + }, + { + "files": ["scripts/*"], + "rules": { + "no-console": ["off"] + } + }, + { + "files": ["react/**/*.ts"], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } + } + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "@spectrum-web-components", + "import", + "require-extensions" + ], + "root": true, + "rules": { + "@spectrum-web-components/prevent-argument-names": [ + "error", + ["e", "ev", "evt", "err"] + ], + "curly": ["error", "all"], + "import/extensions": [ + "error", + "ignorePackages", + { + "ts": "never" + } + ], + "import/prefer-default-export": "off", + "lit-a11y/click-events-have-key-events": [ + "error", + { + "allowList": [ + "sp-button", + "sp-action-button", + "sp-checkbox", + "sp-radio", + "sp-switch", + "sp-menu-item", + "sp-clear-button", + "sp-underlay" + ] + } + ], + "no-console": [ + "error", + { + "allow": ["warn", "error"] + } + ], + "no-debugger": 2, + "sort-imports": [ + "error", + { + "allowSeparatedGroups": false, + "ignoreCase": true, + "ignoreDeclarationSort": true, + "ignoreMemberSort": false + } + ] + } +} diff --git a/1st-gen/.prettierignore b/1st-gen/.prettierignore new file mode 100644 index 00000000000..d948b0be115 --- /dev/null +++ b/1st-gen/.prettierignore @@ -0,0 +1,3 @@ +__snapshots__ +node_modules +*.hbs diff --git a/1st-gen/.prettierrc.yaml b/1st-gen/.prettierrc.yaml new file mode 100644 index 00000000000..049d720f05a --- /dev/null +++ b/1st-gen/.prettierrc.yaml @@ -0,0 +1,13 @@ +printWidth: 80 +tabWidth: 4 +semi: true +singleQuote: true +trailingComma: es5 +bracketSpacing: true +arrowParens: always +htmlWhitespaceSensitivity: ignore +overrides: + - files: '*.css' + options: + printWidth: 500 + singleQuote: false diff --git a/CHANGELOG.md b/1st-gen/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to 1st-gen/CHANGELOG.md diff --git a/INVENTORY.md b/1st-gen/INVENTORY.md similarity index 100% rename from INVENTORY.md rename to 1st-gen/INVENTORY.md diff --git a/1st-gen/README.md b/1st-gen/README.md new file mode 100644 index 00000000000..f9c60ee2d09 --- /dev/null +++ b/1st-gen/README.md @@ -0,0 +1,223 @@ +# Spectrum Web Components + +## Who are we? + +Spectrum Web Components is a future-looking project to develop Adobe Spectrum design language based around web components, ES-Modules, and modern browser standards. + +To this end, Spectrum Web Components only targets _modern_, evergreen browsers that fully implement the Custom Elements V1 specification, e.g. Chrome, Firefox, Safari. Polyfills will be avoided as much as possible but documented if necessary. + +## Requirements + +- NodeJS >= 20.0.0 +- Yarn >= 4.6.0 +- Typescript +- Supported desktop browsers: + - Last 2 versions of Chrome + - Last 2 versions of Firefox + - Last 2 versions of Safari + - Last 2 versions of Edge +- Or appropriate [polyfills](https://github.com/webcomponents/webcomponentsjs) in older browsers. +- We support all viewport sizes across supported desktop browsers. +- While our components are designed to be responsive and mobile-friendly, we do not yet fully support mobile browsers due to limited testing in mobile hardware. We advise testing updates on mobile devices before updating and are happy to address any reported issues. + +## Getting started + +```bash +git clone https://github.com/adobe/spectrum-web-components.git +cd spectrum-web-components +yarn +``` + +The call to `yarn` will install and setup everything you need for developing and running the packages in this library. + +Typical development will involve running `yarn storybook`, `yarn test`, and `yarn docs:start` if you're making documentation changes (see below for additional details). + +### Building a new component + +Creating a new component from the command line can be done by running the following: + +```bash +yarn new-package +``` + +This will scaffold your component's required architecture by prompting you for the desired name for your package. + +```bash +? **SWC package name (i.e. color-area)** +``` + +_Note_ that your component name should be provided in kebab case and should relate as closely as possible to the Spectrum core naming. + +For additional information, please see the [generating components documentation](https://opensource.adobe.com/spectrum-web-components/guides/generating-components). + +## Storybook + +Testing & reviewing changes can be done using the Storybook instance. Running `yarn storybook` will spin up a local instance of Storybook, triggering the browser to open at completion. From there you can make changes to your code and the browser will automatically refresh. + +You can run [Storybook](https://storybook.js.org) through the command: + +```bash +yarn storybook +``` + +By default, the resulting site will be available at [http://localhost:8000](http://localhost:8000). + +## Documentation + +The Spectrum Web Components documentation site is available via the following command: + +```bash +yarn docs:start +``` + +By default, the resulting site will be available at [http://localhost:8080](http://localhost:8080). + +The documentation site provides comprehensive guides, API references, and examples to help you understand and use Spectrum Web Components effectively. It includes: + +- Component API documentation +- Usage guidelines +- Accessibility information +- Code examples +- Design system principles + +In the case that you'd like to serve and test a static build of the documentation from the root directory (`localhost` or otherwise), use: + +```bash +yarn docs:build +``` + +## Using Stackblitz for reproductions + +We provide Stackblitz demos for all our components to help you quickly test, experiment, and create reproductions. These interactive environments are perfect for: + +- **Bug reports**: Create a minimal reproduction of issues you encounter +- **Experiment**: Test and experiment with components in a live environment to understand their features and behavior + +### Finding component demos + +Each component's README includes a "Try it on Stackblitz" badge that links to a pre-configured demo environment. You can also find links to all component demos in our [documentation site](https://opensource.adobe.com/spectrum-web-components/). + +### Creating reproductions + +When reporting bugs or requesting features: + +1. **Start with the component demo**: Click the Stackblitz badge in the relevant component's README +2. **Fork the demo**: Click "Fork" in Stackblitz to create your own copy +3. **Reproduce the issue**: Modify the code to demonstrate the problem or desired behavior +4. **Share the link**: Include the Stackblitz URL in your GitHub issue + +## Spectrum CSS and Icons + +While we've moved away from using Spectrum CSS for component styling, we still maintain a dependency on Spectrum CSS for icons. We aim to keep the icon packages as current as possible to track the Spectrum design system closely. + +## Testing + +### Unit tests + +Unit tests are run with [Web Test Runner](https://modern-web.dev/docs/test-runner/overview/) in Playwright using the Chai, Mocha and Sinon helper libraries. These tests can be executed with: + +```bash +yarn test +``` + +During development you may wish to use `yarn test:watch` to automatically build and re-run the test suites. + +### Visual regression testing + +Visual regressions are tracked via screenshot testing. To run visual regression tests: + +```bash +yarn test:visual +``` + +For testing specific components: + +```bash +yarn test:visual vrt-${component name} +# Example: yarn test:visual vrt-accordion +``` + +For more details about visual regression testing, see the README section on Screenshot Testing. + +### Benchmarking + +You can measure the performance of individual elements with: + +```bash +yarn build:tests +yarn test:bench +``` + +This will run the defined [Tachometer](https://www.npmjs.com/package/tachometer) tests and report the current runtime cost of each individual element. + +## Contributing + +We'd be very grateful if you contributed to the project! Check out our [contribution guidelines](CONTRIBUTING.md) and [pull request best practices](PULL_REQUESTS.md) for more information. + +### Writing changesets + +Spectrum Web Components uses [changesets](https://opensource.adobe.com/spectrum-web-components/guides/writing-changesets/) to manage versioning and changelogs. When making changes that impact users, you should include a changeset file that describes the change and indicates the type of version bump needed (patch, minor, or major). + +To create a changeset: + +```bash +yarn changeset +``` + +## Release process + +For information about our release process, including publishing to NPM, please see our [Release Process documentation](RELEASE_PROCESS.md). + +## Advanced development + +There are several commands that can be useful in specific scenarios: + +- `yarn build:clear-cache` to remove previously created artifacts of the `tsc build` process. +- `yarn process-icons` to make sure that the most recent icons are included. +- `yarn build` to make sure the available JS has been built from the current TS source. + +### Linting + +The project will be linted on a pre-commit hook, but you can also run the lint suite with `yarn lint`. It uses ESLint to lint the JS / TS files, and StyleLint to lint the CSS files. + +#### Dependency linting + +There are downstream issues that can arise from multiple packages in this mono-repo using dependencies with mismatched version strings. By default, [changesets](https://opensource.adobe.com/spectrum-web-components/guides/writing-changesets/) will bump version numbers of internal dependencies when the various packages are published and the depended version is pointing to the latest release, which can help to mitigate this issue. Running `yarn constraints` will check that all version strings for each dependency match across the repo. + +`yarn constraints --fix` will modify the `package.json` files, updating all dependencies to the latest version available in the library — _a potentially dangerous operation_. If this is what you want to do when `yarn constraints` discovers mismatched versions, this step can greatly reduce the amount of work to achieve matching version numbers. + +### Anatomy of a component + +There is extended documentation on adding a new component to the library in the [documentation site](https://opensource.adobe.com/spectrum-web-components/guides/generating-components). However, at a high level, you will be building the following structure: + +```json +- packages + - [new-component-name] + - src + - index.ts + - spectrum-[new-component-name].css + - [new-component-name]-overrides.css + - [new-component-name].css + - [NewComponentName].ts + - stories + - [new-component-name].stories.ts + - args.ts + - template.ts + - test + - benchmark + - basic-test.ts + - [new-component-name].test.ts + - .npmrc + - CHANGELOG.md + - custom-elements.json + - package.json + - README.md + - sp-[new-component-name].ts + - tsconfig.json +``` + +For a list of component waiting to be implemented, visit our [`missing components`](https://github.com/adobe/spectrum-web-components/labels/missing%20components) tag. + +### IDE Notes + +The build process compiles `.css` files using PostCSS and wraps them in the `lit-html` `css` template tag and writes out a `.css.ts` file for easy import into TypeScript files. This file should not be edited, and is ignored by `.gitignore`, but you may also wish to hide the files in your IDE. diff --git a/cem-react-wrapper.config.js b/1st-gen/cem-react-wrapper.config.js similarity index 100% rename from cem-react-wrapper.config.js rename to 1st-gen/cem-react-wrapper.config.js diff --git a/custom-elements-manifest.config.js b/1st-gen/custom-elements-manifest.config.js similarity index 95% rename from custom-elements-manifest.config.js rename to 1st-gen/custom-elements-manifest.config.js index 365d5acb588..3c485b4f01e 100644 --- a/custom-elements-manifest.config.js +++ b/1st-gen/custom-elements-manifest.config.js @@ -20,6 +20,7 @@ export default { '**/src/[A-Z]*.ts', '**/src/elements/[A-Z]*.ts', '**/tools/shared/src/*.ts', + '../2nd-gen/packages/core/components/**/*.ts', ], exclude: [ '**/*.d.ts', diff --git a/1st-gen/linters/eslint/.npmrc b/1st-gen/linters/eslint/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/linters/eslint/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/linters/eslint/CHANGELOG.md b/1st-gen/linters/eslint/CHANGELOG.md new file mode 100644 index 00000000000..5b28393394f --- /dev/null +++ b/1st-gen/linters/eslint/CHANGELOG.md @@ -0,0 +1,178 @@ +# Change Log + +## 1.9.0 + +## 1.8.0 + +## 1.7.0 + +## 1.6.0 + +## 1.5.0 + +## 1.4.0 + +## 1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/eslint-plugin diff --git a/1st-gen/linters/eslint/index.js b/1st-gen/linters/eslint/index.js new file mode 100644 index 00000000000..03b0a5e31c5 --- /dev/null +++ b/1st-gen/linters/eslint/index.js @@ -0,0 +1,62 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +module.exports = { + rules: { + 'prevent-argument-names': { + create: function (context) { + const argumentNames = context.options[0]; + function preventArgumentNames(node) { + if (!argumentNames) { + return; + } + argumentNames.forEach((name) => { + if (node.name === name) { + context.report({ + node, + message: `"${name}" shouldn't be used as an argument name`, + data: { + identifier: node.name, + }, + }); + } + }); + } + + return { + Identifier: preventArgumentNames, + }; + }, + }, + 'document-active-element': { + create: function (context) { + function preventDocumentActiveElement(node) { + if ( + node.object.name === 'document' && + node.property.name === 'activeElement' + ) { + context.report({ + node, + message: `"document.activeElement" can be incorrect across shadow boundaries`, + data: { + identifier: node.name, + }, + }); + } + } + return { + MemberExpression: preventDocumentActiveElement, + }; + }, + }, + }, +}; diff --git a/1st-gen/linters/eslint/package.json b/1st-gen/linters/eslint/package.json new file mode 100644 index 00000000000..7e9ffa1e8d4 --- /dev/null +++ b/1st-gen/linters/eslint/package.json @@ -0,0 +1,27 @@ +{ + "private": true, + "name": "@spectrum-web-components/eslint-plugin", + "version": "1.9.0", + "license": "Apache-2.0", + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/linters/eslint" + }, + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "index.js", + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html" + ] +} diff --git a/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.js b/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.js new file mode 100644 index 00000000000..ee971e0bda2 --- /dev/null +++ b/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.js @@ -0,0 +1,114 @@ +'use strict'; +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +var __extends = + (this && this.__extends) || + (function () { + var extendStatics = function (d, b) { + extendStatics = + Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && + function (d, b) { + d.__proto__ = b; + }) || + function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = + b === null + ? Object.create(b) + : ((__.prototype = b.prototype), new __()); + }; + })(); +Object.defineProperty(exports, '__esModule', { value: true }); +var fs = require('fs'); +var Lint = require('tslint'); +var Rule = /** @class */ (function (_super) { + __extends(Rule, _super); + function Rule(options) { + var _this = _super.call(this, options) || this; + if (options.ruleArguments.length === 0) { + throw new Error( + '[file-should-container-header] Must specify template path as rule option!, e.g. "file-should-container-header: [true, pathToFile]"' + ); + } + var templatePath = options.ruleArguments[0]; + if (!fs.existsSync(templatePath)) { + throw new Error( + '[file-should-container-header] Template path ' + + templatePath + + ' does not exist!' + ); + } + _this.templateString = fs + .readFileSync(templatePath, { encoding: 'utf8' }) + .toString() + .trim(); + return _this; + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker( + new NoFileWithoutCopyrightHeader( + sourceFile, + this.getOptions(), + this.templateString + ) + ); + }; + Rule.FAILURE_STRING = 'File should contain header'; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoFileWithoutCopyrightHeader = /** @class */ (function (_super) { + __extends(NoFileWithoutCopyrightHeader, _super); + function NoFileWithoutCopyrightHeader(sourceFile, options, templateString) { + var _this = _super.call(this, sourceFile, options) || this; + _this.templateString = templateString; + return _this; + } + NoFileWithoutCopyrightHeader.prototype.visitSourceFile = function ( + sourceFile + ) { + if (sourceFile && sourceFile.fileName) { + var fullText = sourceFile.getFullText(); + if (fullText) { + // is the file starting with templateString? + if (fullText.startsWith(this.templateString)) { + return _super.prototype.visitSourceFile.call( + this, + sourceFile + ); + } + // create a fix replacement with the template text + var fixer = new Lint.Replacement( + 0, + 0, + this.templateString + '\n' + ); + this.addFailure( + this.createFailure(0, 1, Rule.FAILURE_STRING, fixer) + ); + return _super.prototype.visitSourceFile.call(this, sourceFile); + } + } + _super.prototype.visitSourceFile.call(this, sourceFile); + }; + return NoFileWithoutCopyrightHeader; +})(Lint.RuleWalker); diff --git a/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.ts b/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.ts new file mode 100755 index 00000000000..b7028497a95 --- /dev/null +++ b/1st-gen/linters/ts-rules/fileShouldContainHeaderRule.ts @@ -0,0 +1,85 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import * as fs from 'fs'; +import * as Lint from 'tslint'; +import * as ts from 'typescript'; + +export class Rule extends Lint.Rules.AbstractRule { + public static FAILURE_STRING = 'File should contain header'; + private templateString: string; + + constructor(options: Lint.IOptions) { + super(options); + if (options.ruleArguments.length === 0) { + throw new Error( + '[file-should-container-header] Must specify template path as rule option!, e.g. "file-should-container-header: [true, pathToFile]"' + ); + } + const templatePath = options.ruleArguments[0] as string; + if (!fs.existsSync(templatePath)) { + throw new Error( + `[file-should-container-header] Template path ${templatePath} does not exist!` + ); + } + this.templateString = fs + .readFileSync(templatePath, { encoding: 'utf8' }) + .toString() + .trim(); + } + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithWalker( + new NoFileWithoutCopyrightHeader( + sourceFile, + this.getOptions(), + this.templateString + ) + ); + } +} + +class NoFileWithoutCopyrightHeader extends Lint.RuleWalker { + private templateString: string; + constructor( + sourceFile: ts.SourceFile, + options: Lint.IOptions, + templateString: string + ) { + super(sourceFile, options); + this.templateString = templateString; + } + public visitSourceFile(sourceFile: ts.SourceFile) { + if (sourceFile && sourceFile.fileName) { + const fullText = sourceFile.getFullText(); + if (fullText) { + // is the file starting with templateString? + if (fullText.startsWith(this.templateString)) { + return super.visitSourceFile(sourceFile); + } + + // create a fix replacement with the template text + const fixer = new Lint.Replacement( + 0, + 0, + this.templateString + '\n' + ); + + this.addFailure( + this.createFailure(0, 1, Rule.FAILURE_STRING, fixer) + ); + return super.visitSourceFile(sourceFile); + } + } + + super.visitSourceFile(sourceFile); + } +} diff --git a/1st-gen/linters/ts-rules/tsconfig.json b/1st-gen/linters/ts-rules/tsconfig.json new file mode 100755 index 00000000000..5c17c776a30 --- /dev/null +++ b/1st-gen/linters/ts-rules/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "allowJs": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "lib": ["es6", "dom"], + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "outDir": ".", + "rootDir": ".", + "skipLibCheck": false, + "sourceMap": false, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "target": "es5" + }, + "exclude": ["nothing"], + "include": ["*.ts"] +} diff --git a/1st-gen/linters/ts-rules/tslint.json b/1st-gen/linters/ts-rules/tslint.json new file mode 100755 index 00000000000..be9652a28a6 --- /dev/null +++ b/1st-gen/linters/ts-rules/tslint.json @@ -0,0 +1,8 @@ +{ + "extends": "../tslint.json", + "rules": { + "no-implicit-dependencies": [true, "dev"], + "max-classes-per-file": false, + "no-console": false + } +} diff --git a/1st-gen/package.json b/1st-gen/package.json new file mode 100644 index 00000000000..feeb3b17cf5 --- /dev/null +++ b/1st-gen/package.json @@ -0,0 +1,434 @@ +{ + "name": "@spectrum-web-components/1st-gen", + "version": "0.0.9", + "private": true, + "description": "Spectrum Web Components are a set of reusable, accessible, and customizable web components following the design language of Adobe Spectrum.", + "license": "Apache-2.0", + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen" + }, + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "type": "module", + "scripts": { + "analyze": "lit-analyzer \"{packages,tools}/*/src/**/!(*.css).ts\"", + "build": "wireit", + "prebuild": "wireit", + "build:clear-cache": "rimraf packages/*/tsconfig.tsbuildinfo && rimraf tools/*/tsconfig.tsbuildinfo", + "build:confirm": "node ./scripts/confirm-build.js", + "build:css": "wireit", + "build:css:watch": "wireit", + "build:react": "rimraf react && node ./scripts/build-react.js && tsc --build tsconfig-react-wrapper.json", + "build:tests": "tsc --build test/tsconfig.json && tsc --build test/tsconfig-node.json", + "build:ts": "wireit", + "build:ts:watch": "wireit", + "build:types": "wireit", + "build:watch": "wireit", + "changelog:global": "node ./scripts/update-global-changelog.js", + "changeset-publish": "yarn prepublishOnly && yarn changeset version && yarn constraints --fix && yarn install --refresh-lockfile && yarn version:update && yarn changeset publish --no-git-tag && yarn push-to-remote && yarn create-git-tag && yarn postpublish", + "changeset-snapshot-publish": "yarn prepublishOnly && yarn changeset version --snapshot snapshot && yarn constraints --fix && yarn install --refresh-lockfile && yarn version:update && yarn changeset publish --no-git-tag --tag snapshot", + "chromatic": "chromatic --build-script-name storybook:build # note that --project-token must be set in your env variables", + "create-git-tag": "node --no-warnings ./scripts/create-git-tag.js", + "custom-element-json": "node ./scripts/custom-element-json.js", + "docs:analyze": "cem analyze --globs \"packages/**/*.ts\" --exclude \"**/*.d.ts\" --exclude \"**/stories/**\" --exclude \"**/icons/**\" --exclude \"**/elements/**\" --outdir projects/documentation --litelement", + "docs:build": "yarn workspace documentation build", + "docs:ci": "yarn docs:analyze && run-p docs:production storybook:build && cp projects/documentation/custom-elements.json projects/documentation/dist/storybook", + "docs:preview": "yarn docs:analyze && run-p docs:build storybook:build && cp projects/documentation/custom-elements.json projects/documentation/dist/storybook", + "docs:production": "yarn workspace documentation build:production", + "docs:review": "alex packages/**/*.md", + "docs:start": "yarn workspace documentation serve --watch", + "find": "test -f custom-elements.json", + "icons": "wireit", + "icons:ui": "wireit", + "icons:workflow": "wireit", + "lint": "git status --porcelain && git add . && lint-staged --config ../lint-staged.config.js --cwd .. --allow-empty", + "new-package": "yarn workspace swc-templates plop", + "postinstall": "husky || true", + "postpack": "pinst --enable", + "postpublish": "yarn prepublish:react && yarn publish:react && yarn postpublish:react", + "postpublish:react": "git reset --hard HEAD^ && git prune && rimraf react", + "preeleventy": "yarn docs:analyze", + "prepack": "pinst --disable", + "prepublish:react": "yarn build:react && sed -i \"\" \"s/react/# react/g\" .gitignore && git commit -am \"Commit React Wrappers\" --no-verify", + "prepublishOnly": "rimraf react && yarn build && yarn custom-element-json && yarn build:confirm && yarn changelog:global", + "prestorybook": "wireit", + "prestorybook:build": "cem analyze --outdir storybook/", + "pretest:bench": "yarn build:tests && test -f test/benchmark/cli.js ||:", + "pretest:visual": "yarn build && yarn build", + "process-icons": "wireit", + "publish:react": "yarn changeset publish --no-git-tag --tag latest --no-push", + "push-to-remote": "git add . && git commit -m \"chore: release new versions #publish\" && git push", + "dev:core": "yarn workspace @spectrum-web-components/core dev", + "start": "run-p dev:core storybook", + "storybook": "wireit", + "storybook:build": "NODE_ENV=production storybook build -o projects/documentation/dist/storybook -c storybook", + "storybook:quick": "run-p build:watch storybook:run", + "storybook:run": "web-dev-server --config wds-storybook.config.js", + "test": "yarn test:focus unit", + "test:bench": "yarn build:tests && node test/benchmark/cli.js", + "test:changed": "node ./scripts/test-changes.js", + "test:ci": "yarn test:start", + "test:create": "wireit", + "test:errors": "yarn test | grep -A 32 ❌", + "test:focus": "yarn build && yarn test:ci --group", + "test:start": "web-test-runner", + "test:visual": "yarn test:visual:ci", + "test:visual:ci": "yarn test:start --group", + "test:visual:clean": "yarn test:visual:clean:baseline && yarn test:visual:clean:current", + "test:visual:clean:baseline": "rimraf test/visual/screenshots-baseline", + "test:visual:clean:current": "rimraf test/visual/screenshots-current", + "test:watch": "yarn test:watch:focus unit", + "test:watch:flags:focus": "yarn build && run-p build:watch \"test:start --watch --group {1} --config web-test-runner.config.ci-chromium-flags.js\" --", + "test:watch:focus": "yarn dev:core & yarn build && run-p build:watch \"test:start --watch --group {1}\" --", + "version:update": "genversion --verbose --semi --esm ./tools/base/src/version.js", + "vrt:preview": "yarn wds --config test/visual/wds-vrt.config.js" + }, + "workspaces": [ + "linters/*", + "packages/*", + "projects/*", + "tools/*", + "react/*" + ], + "devDependencies": { + "@changesets/changelog-github": "0.5.1", + "@changesets/cli": "2.29.7", + "@commitlint/cli": "19.8.1", + "@commitlint/config-conventional": "^19.8.1", + "@custom-elements-manifest/analyzer": "0.10.6", + "@geometricpanda/storybook-addon-badges": "2.0.5", + "@lit/react": "1.0.8", + "@open-wc/dev-server-hmr": "0.2.0", + "@open-wc/testing": "4.0.0", + "@playwright/test": "1.53.1", + "@rollup/plugin-commonjs": "25.0.8", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-node-resolve": "15.3.1", + "@sindresorhus/slugify": "2.2.1", + "@spectrum-web-components/eslint-plugin": "file:./linters/eslint", + "@storybook/addon-a11y": "8.6.14", + "@storybook/addon-designs": "8.2.1", + "@storybook/addon-essentials": "8.6.14", + "@storybook/addon-interactions": "8.6.14", + "@storybook/addon-links": "8.6.14", + "@storybook/blocks": "8.6.14", + "@storybook/manager-api": "8.6.14", + "@storybook/theming": "8.6.14", + "@storybook/types": "8.6.14", + "@storybook/web-components-webpack5": "8.6.14", + "@types/chai": "4.3.20", + "@types/command-line-args": "5.2.3", + "@types/command-line-usage": "5.0.4", + "@types/common-tags": "1.8.4", + "@types/mocha": "10.0.10", + "@types/node": "20.19.17", + "@types/react": "18.3.24", + "@types/sinon": "17.0.4", + "@types/webpack": "5.28.5", + "@types/webpack-env": "1.18.8", + "@typescript-eslint/eslint-plugin": "7.18.0", + "@typescript-eslint/parser": "7.18.0", + "@web/dev-server": "0.4.6", + "@web/dev-server-rollup": "0.6.4", + "@web/rollup-plugin-copy": "0.5.1", + "@web/rollup-plugin-html": "2.3.0", + "@web/test-runner": "0.20.2", + "@web/test-runner-commands": "0.9.0", + "@web/test-runner-junit-reporter": "0.8.0", + "@web/test-runner-playwright": "patch:@web/test-runner-playwright@npm%3A0.11.1#~/.yarn/patches/@web-test-runner-playwright-npm-0.11.1-280696080b.patch", + "@web/test-runner-visual-regression": "patch:@web/test-runner-visual-regression@npm%3A0.10.0#~/.yarn/patches/@web-test-runner-visual-regression-npm-0.10.0-00f19f4c70.patch", + "@webcomponents/webcomponentsjs": "2.8.0", + "@yarnpkg/types": "4.0.1", + "alex": "11.0.1", + "cem-plugin-module-file-extensions": "0.0.5", + "chromatic": "13.2.0", + "chromedriver": "140.0.3", + "colors": "1.4.0", + "common-tags": "1.8.2", + "crypto": "1.0.1", + "custom-elements-manifest": "2.1.0", + "debounce": "2.2.0", + "deepmerge": "4.3.1", + "esbuild": "0.21.5", + "eslint": "8.57.1", + "eslint-config-prettier": "9.1.2", + "eslint-formatter-pretty": "5.0.0", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-jsonc": "2.20.1", + "eslint-plugin-lit-a11y": "2.4.1", + "eslint-plugin-notice": "0.9.10", + "eslint-plugin-prettier": "5.5.4", + "eslint-plugin-require-extensions": "0.1.3", + "eslint-plugin-storybook": "0.8.0", + "express": "4.21.2", + "fast-glob": "3.3.3", + "fs-extra": "11.3.2", + "geckodriver": "4.4.0", + "genversion": "3.2.0", + "gh-pages": "6.3.0", + "gunzip-maybe": "1.4.2", + "husky": "9.1.7", + "jsonc-eslint-parser": "2.4.1", + "latest-version": "9.0.0", + "lightningcss": "1.30.1", + "lint-staged": "^16.1.2", + "lit": "^2.5.0 || ^3.1.3", + "lit-analyzer": "2.0.3", + "lit-html": "^2.4.0 || ^3.1.3", + "mocha-junit-reporter": "2.2.1", + "next": "14.2.33", + "node-fetch": "3.3.2", + "npm-run-all2": "8.0.4", + "patch-package": "^8.0.0", + "pinst": "3.0.0", + "prettier": "3.6.2", + "prettier-plugin-package": "1.4.0", + "pretty-bytes": "7.1.0", + "re-template-tag": "2.0.1", + "replace-in-file": "^8.3.0", + "rimraf": "6.0.1", + "rollup": "4.52.2", + "sinon": "17.0.2", + "storybook": "8.6.14", + "stylelint": "16.24.0", + "stylelint-config-standard": "38.0.0", + "stylelint-header": "3.0.0", + "tachometer": "0.7.2", + "tar-stream": "3.1.7", + "terser": "4.8.1", + "typescript": "5.3.3", + "webpack-merge": "6.0.1", + "wireit": "0.14.12", + "yargs": "17.7.2" + }, + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html" + ], + "engines": { + "node": ">=20", + "yarn": ">=4.6.0" + }, + "wireit": { + "build": { + "dependencies": [ + "prebuild", + "build:ts", + "build:types" + ] + }, + "prebuild": { + "command": "yarn workspace @spectrum-web-components/core build", + "files": [ + "../2nd-gen/packages/core/components/**/*", + "../2nd-gen/packages/core/shared/**/*", + "../2nd-gen/packages/core/package.json", + "../2nd-gen/packages/core/vite.config.js", + "../2nd-gen/packages/core/tsconfig.json" + ] + }, + "build:css": { + "clean": "if-file-deleted", + "command": "node ./scripts/build-css.js", + "files": [ + "packages/**/*.css", + "tools/**/*.css", + "scripts/build-css.js", + "scripts/css-tools.js" + ], + "output": [ + "packages/**/*.css.ts", + "tools/**/*.css.ts" + ] + }, + "build:css:watch": { + "command": "node ./scripts/watch-css.js", + "service": true + }, + "build:ts": { + "clean": "if-file-deleted", + "command": "node ./scripts/build-ts.js", + "dependencies": [ + "process-icons", + "test:create", + "build:css" + ], + "files": [ + "packages/**/*.ts", + "!packages/**/*.d.ts", + "projects/**/*.ts", + "!projects/**/*.d.ts", + "!projects/documentation/**/*", + "!projects/css-custom-vars-viewer/**/*", + "!projects/example-project-rollup/**/*", + "!projects/example-project-webpack/**/*", + "!projects/templates/**/*", + "tools/**/*.ts", + "!tools/**/*.d.ts", + "scripts/build-ts.js", + "packages/**/exports.json", + "tools/**/exports.json", + "test/**/*.ts" + ], + "output": [ + "packages/**/*.js", + "packages/**/*.dev.js", + "projects/**/*.js", + "packages/**/*.js.map", + "projects/**/*.js.map", + "!projects/documentation/**/*.js", + "!projects/css-custom-vars-viewer/**/*", + "!projects/example-project-rollup", + "!projects/example-project-webpack", + "!projects/templates", + "tools/**/*.js", + "tools/**/*.js.map", + "!**/build.js", + "!**/build-icons-mapping.js", + "test/**/*.js", + "test/**/*.js.map", + "!test/visual/create.js", + "!test/visual/review.js", + "!test/visual/rollup.config.js", + "!test/visual/src/review.js", + "!test/visual/src/index.html", + "!test/visual/wds-vrt.config.js", + "!tools/base/src/version.js" + ] + }, + "build:ts:watch": { + "command": "node ./scripts/watch-ts.js", + "service": true + }, + "build:types": { + "clean": "if-file-deleted", + "command": "tsc --build tsconfig-all.json --pretty", + "dependencies": [ + "process-icons", + "test:create", + "build:css" + ], + "files": [ + "tsconfig-all.json", + "packages/**/*.ts", + "packages/**/tsconfig.json", + "tools/**/*.ts", + "tools/**/tsconfig.json" + ], + "output": [ + "packages/**/*.d.ts", + "packages/**/tsconfig.tsbuildinfo", + "tools/**/*.d.ts", + "tools/**/tsconfig.tsbuildinfo", + "!**/local.d.ts", + "!tools/base/src/version.d.ts" + ] + }, + "build:watch": { + "dependencies": [ + "build:css:watch", + "build:ts:watch" + ] + }, + "icons": { + "command": "node ./scripts/process-icons.js && yarn lint", + "files": [ + "scripts/process-icons.js" + ], + "output": [ + "packages/**/*.svg.ts" + ] + }, + "icons:ui": { + "clean": "if-file-deleted", + "command": "yarn workspace @spectrum-web-components/icons-ui build", + "files": [ + "packages/icons-ui/bin/build.js", + "packages/icons-ui/packages.json", + "node_modules/@spectrum-css/ui-icons/dist/medium/**.svg", + "node_modules/@spectrum-css/ui-icons-s2/dist/medium/**.svg" + ], + "output": [ + "packages/icons-ui/**/*.ts", + "!packages/icons-ui/**/*.d.ts", + "!packages/icons-ui/stories/**/*.ts", + "packages/icons-ui/stories/icon-manifest.ts", + "!packages/icons-ui/test/**/*.ts", + "!packages/icons-ui/src/index.ts", + "!packages/icons-ui/src/custom-tag.ts", + "!packages/icons-workflow/src/DefaultIcon.ts" + ] + }, + "icons:workflow": { + "clean": "if-file-deleted", + "command": "yarn workspace @spectrum-web-components/icons-workflow build", + "files": [ + "!packages/icons-workflow/bin/build.js", + "packages/icons-workflow/bin/build-icons-mapping.js" + ], + "output": [ + "packages/icons-workflow/**/*.ts", + "!packages/icons-workflow/**/*.d.ts", + "!packages/icons-workflow/stories/**/*.ts", + "packages/icons-workflow/stories/icon-manifest.ts", + "!packages/icons-workflow/test/**/*.ts", + "!packages/icons-workflow/src/index.ts", + "!packages/icons-workflow/src/custom-tag.ts", + "!packages/icons-workflow/src/DefaultIcon.ts", + "!packages/icons-workflow/bin/icons-mapping.json" + ] + }, + "prestorybook": { + "command": "cem analyze --outdir storybook/", + "dependencies": [ + "build:ts" + ], + "files": [ + "packages/**/*.ts", + "tools/**/*.ts" + ], + "output": [ + "storybook/custom-elements.json" + ] + }, + "process-icons": { + "dependencies": [ + "icons", + "icons:ui", + "icons:workflow" + ] + }, + "storybook": { + "command": "storybook dev -p 8080 -c storybook", + "dependencies": [ + "prestorybook", + "build:watch" + ], + "service": true + }, + "test:create": { + "clean": "if-file-deleted", + "command": "node test/visual/create.js", + "files": [ + "packages/*/stories/*.stories.ts", + "tools/*/stories/*.stories.ts" + ], + "output": [ + "packages/*/test/*.test-vrt.ts", + "tools/*/test/*.test-vrt.ts" + ] + } + }, + "packageManager": "yarn@4.9.2" +} diff --git a/1st-gen/packages/.eslintrc.json b/1st-gen/packages/.eslintrc.json new file mode 100644 index 00000000000..ec0a155288c --- /dev/null +++ b/1st-gen/packages/.eslintrc.json @@ -0,0 +1,210 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": false + }, + "extends": [ + "plugin:@typescript-eslint/recommended", + "prettier", + "plugin:lit-a11y/recommended" + ], + "overrides": [ + { + "files": [ + "*.test.ts", + "*.stories.ts", + "**/benchmark/*.ts", + "**/test/*.ts", + "**/stories/*.ts" + ], + "rules": { + "@spectrum-web-components/document-active-element": ["off"], + "import/no-extraneous-dependencies": ["off"], + "lit-a11y/no-autofocus": ["off"], + "lit-a11y/tabindex-no-positive": ["off"] + } + }, + { + "files": ["**/icons/*.ts", "**/src/elements/*.ts"], + "rules": { + "sort-imports": ["off"] + } + }, + { + "files": ["*.stories.ts"], + "rules": { + "no-console": ["off"] + } + }, + { + "files": ["Picker.ts"], + "rules": { + "lit-a11y/click-events-have-key-events": [ + "error", + { + "allowList": [ + "sp-button", + "sp-action-button", + "sp-checkbox", + "sp-radio", + "sp-switch", + "sp-menu-item", + "sp-clear-button", + "sp-underlay", + "sp-popover" + ] + } + ] + } + }, + { + "extends": ["plugin:jsonc/recommended-with-jsonc"], + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "jsonc/sort-keys": ["warn"], + "notice/notice": "off" + } + }, + { + "extends": ["plugin:jsonc/recommended-with-jsonc"], + "files": ["package.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "jsonc/sort-keys": [ + "warn", + { + "hasProperties": ["type"], + "order": [ + "$schema", + "name", + "version", + "private", + "description", + "license", + "author", + "maintainers", + "contributors", + "homepage", + "repository", + "bugs", + "type", + "exports", + "main", + "module", + "browser", + "man", + "preferGlobal", + "bin", + "files", + "directories", + "scripts", + "config", + "sideEffects", + "types", + "typings", + "workspaces", + "resolutions", + "dependencies", + "bundleDependencies", + "bundledDependencies", + "peerDependencies", + "peerDependenciesMeta", + "optionalDependencies", + "devDependencies", + "keywords", + "engines", + "engineStrict", + "os", + "cpu", + "publishConfig" + ], + "pathPattern": "^$" // Top-level properties + }, + { + /* + * This rule excludes export conditions from alphabetical sorting. + * Since node.js processes export conditions in order and chooses the + * first match, they need to be ordered logically, not alphabetically. + */ + "order": { "type": "asc" }, + "pathPattern": "^(?!exports\\[).*" // All properties except export conditions + } + ] + } + } + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "notice", + "@spectrum-web-components", + "import" + ], + "rules": { + "@spectrum-web-components/document-active-element": ["error"], + "@spectrum-web-components/prevent-argument-names": [ + "error", + ["e", "ev", "evt", "err"] + ], + "@typescript-eslint/explicit-function-return-type": [ + 1, + { + "allowExpressions": true + } + ], + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" + } + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": false, + "optionalDependencies": false, + "peerDependencies": false + } + ], + "lit-a11y/click-events-have-key-events": [ + "error", + { + "allowList": [ + "sp-button", + "sp-action-button", + "sp-checkbox", + "sp-radio", + "sp-switch", + "sp-menu-item", + "sp-clear-button", + "sp-underlay" + ] + } + ], + "no-console": [ + "error", + { + "allow": ["warn", "error"] + } + ], + "no-debugger": 2, + "notice/notice": [ + "error", + { + "mustMatch": "Copyright [0-9]{0,4} Adobe. All rights reserved.", + "templateFile": "config/license.js" + } + ], + "sort-imports": [ + "error", + { + "allowSeparatedGroups": false, + "ignoreCase": true, + "ignoreDeclarationSort": true, + "ignoreMemberSort": false + } + ] + } +} diff --git a/1st-gen/packages/accordion/.npmrc b/1st-gen/packages/accordion/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/accordion/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/accordion/CHANGELOG.md b/1st-gen/packages/accordion/CHANGELOG.md new file mode 100644 index 00000000000..aa8c972f986 --- /dev/null +++ b/1st-gen/packages/accordion/CHANGELOG.md @@ -0,0 +1,606 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Features + +- **accordion:** core token migration ([#3300](https://github.com/adobe/spectrum-web-components/issues/3300)) ([9650b71](https://github.com/adobe/spectrum-web-components/commit/9650b71dd7cf7b93c351ac7b369aaf424c82f47d)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +### Bug Fixes + +- removed usage of id in accordion ([c26c81f](https://github.com/adobe/spectrum-web-components/commit/c26c81f7dfb8a29e7c3019adda5d0faee9fffe11)) + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- **accordion:** ensure item toggle events can be prevented from the outside ([30dbfc8](https://github.com/adobe/spectrum-web-components/commit/30dbfc8435c298e8f68083553ddc0fca1309fdf8)) +- **accordion:** update a11y tree to not double label ([cc91a6b](https://github.com/adobe/spectrum-web-components/commit/cc91a6bc597582ef08a5d3cf1a329b9866b3cbf1)) +- add missing dependency ([9f74e7d](https://github.com/adobe/spectrum-web-components/commit/9f74e7de9dbf37046b1957d708bd9fdd6d8dec0b)) +- contain activation to header content ([10183ce](https://github.com/adobe/spectrum-web-components/commit/10183ceb08745b544b5f338324ff7eeea1b3589d)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- correctly apply tab order to Accordion Items ([fd7a7f9](https://github.com/adobe/spectrum-web-components/commit/fd7a7f91769ab5bf0e22afb4cfab51329f5b198d)) +- ensure item exists when attempting to acquire next item to focus ([fb52cea](https://github.com/adobe/spectrum-web-components/commit/fb52ceac75f76943788411b206fd39739ff66a54)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- **accordion:** add accordion pattern ([97529d8](https://github.com/adobe/spectrum-web-components/commit/97529d848eaa1ea4c0d0a7770f7c73927687256b)) +- **accordion:** allow accordion items to close ([3c715ab](https://github.com/adobe/spectrum-web-components/commit/3c715abc4038b1baeb2412613cc0acdd194c0e2d)) +- **accordion:** update spectrum css input ([d94e059](https://github.com/adobe/spectrum-web-components/commit/d94e059a8735405fedc5615bc9c66e4f71120e4d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.7.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.12...@spectrum-web-components/accordion@0.7.13) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.11...@spectrum-web-components/accordion@0.7.12) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.10...@spectrum-web-components/accordion@0.7.11) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.9...@spectrum-web-components/accordion@0.7.10) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.8...@spectrum-web-components/accordion@0.7.9) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.7...@spectrum-web-components/accordion@0.7.8) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.6...@spectrum-web-components/accordion@0.7.7) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.5...@spectrum-web-components/accordion@0.7.6) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.4...@spectrum-web-components/accordion@0.7.5) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.3...@spectrum-web-components/accordion@0.7.4) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.2...@spectrum-web-components/accordion@0.7.3) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.1...@spectrum-web-components/accordion@0.7.2) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.7.0...@spectrum-web-components/accordion@0.7.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.15...@spectrum-web-components/accordion@0.7.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.6.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.14...@spectrum-web-components/accordion@0.6.15) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.13...@spectrum-web-components/accordion@0.6.14) (2022-07-18) + +### Bug Fixes + +- add missing dependency ([9f74e7d](https://github.com/adobe/spectrum-web-components/commit/9f74e7de9dbf37046b1957d708bd9fdd6d8dec0b)) + +## [0.6.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.12...@spectrum-web-components/accordion@0.6.13) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.11...@spectrum-web-components/accordion@0.6.12) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.10...@spectrum-web-components/accordion@0.6.11) (2022-05-27) + +### Bug Fixes + +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.9...@spectrum-web-components/accordion@0.6.10) (2022-05-12) + +### Bug Fixes + +- contain activation to header content ([10183ce](https://github.com/adobe/spectrum-web-components/commit/10183ceb08745b544b5f338324ff7eeea1b3589d)) +- correctly apply tab order to Accordion Items ([fd7a7f9](https://github.com/adobe/spectrum-web-components/commit/fd7a7f91769ab5bf0e22afb4cfab51329f5b198d)) + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.8...@spectrum-web-components/accordion@0.6.9) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.7...@spectrum-web-components/accordion@0.6.8) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.6...@spectrum-web-components/accordion@0.6.7) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.5...@spectrum-web-components/accordion@0.6.6) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.4...@spectrum-web-components/accordion@0.6.5) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.3...@spectrum-web-components/accordion@0.6.4) (2022-02-02) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.2...@spectrum-web-components/accordion@0.6.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.1...@spectrum-web-components/accordion@0.6.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.6.0...@spectrum-web-components/accordion@0.6.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.5.1...@spectrum-web-components/accordion@0.6.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.5.0...@spectrum-web-components/accordion@0.5.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.18...@spectrum-web-components/accordion@0.5.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.4.18](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.17...@spectrum-web-components/accordion@0.4.18) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.16...@spectrum-web-components/accordion@0.4.17) (2021-10-05) + +### Bug Fixes + +- **accordion:** ensure item toggle events can be prevented from the outside ([30dbfc8](https://github.com/adobe/spectrum-web-components/commit/30dbfc8435c298e8f68083553ddc0fca1309fdf8)) + +## [0.4.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.15...@spectrum-web-components/accordion@0.4.16) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.14...@spectrum-web-components/accordion@0.4.15) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.13...@spectrum-web-components/accordion@0.4.14) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.4.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.12...@spectrum-web-components/accordion@0.4.13) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.11...@spectrum-web-components/accordion@0.4.12) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.10...@spectrum-web-components/accordion@0.4.11) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.9...@spectrum-web-components/accordion@0.4.10) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.8...@spectrum-web-components/accordion@0.4.9) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.7...@spectrum-web-components/accordion@0.4.8) (2021-05-24) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.6...@spectrum-web-components/accordion@0.4.7) (2021-05-12) + +### Bug Fixes + +- ensure item exists when attempting to acquire next item to focus ([fb52cea](https://github.com/adobe/spectrum-web-components/commit/fb52ceac75f76943788411b206fd39739ff66a54)) + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.5...@spectrum-web-components/accordion@0.4.6) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.4...@spectrum-web-components/accordion@0.4.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.3...@spectrum-web-components/accordion@0.4.4) (2021-03-29) + +### Bug Fixes + +- **accordion:** update a11y tree to not double label ([cc91a6b](https://github.com/adobe/spectrum-web-components/commit/cc91a6bc597582ef08a5d3cf1a329b9866b3cbf1)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.2...@spectrum-web-components/accordion@0.4.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.1...@spectrum-web-components/accordion@0.4.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.4.0...@spectrum-web-components/accordion@0.4.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.3.3...@spectrum-web-components/accordion@0.4.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.3.2...@spectrum-web-components/accordion@0.3.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.3.1...@spectrum-web-components/accordion@0.3.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.3.0...@spectrum-web-components/accordion@0.3.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.4...@spectrum-web-components/accordion@0.3.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- **accordion:** allow accordion items to close ([3c715ab](https://github.com/adobe/spectrum-web-components/commit/3c715abc4038b1baeb2412613cc0acdd194c0e2d)) +- **accordion:** update spectrum css input ([d94e059](https://github.com/adobe/spectrum-web-components/commit/d94e059a8735405fedc5615bc9c66e4f71120e4d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.4...@spectrum-web-components/accordion@0.2.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled](<[2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)>) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **accordion:** allow accordion items to close ([3c715ab](https://github.com/adobe/spectrum-web-components/commit/3c715abc4038b1baeb2412613cc0acdd194c0e2d)) +- **accordion:** update spectrum css input ([d94e059](https://github.com/adobe/spectrum-web-components/commit/d94e059a8735405fedc5615bc9c66e4f71120e4d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.3...@spectrum-web-components/accordion@0.1.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.1.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.2...@spectrum-web-components/accordion@0.1.3) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.1...@spectrum-web-components/accordion@0.1.2) (2020-09-25) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/accordion@0.1.0...@spectrum-web-components/accordion@0.1.1) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/accordion + +# 0.1.0 (2020-08-31) + +### Features + +- **accordion:** add accordion pattern ([97529d8](https://github.com/adobe/spectrum-web-components/commit/97529d848eaa1ea4c0d0a7770f7c73927687256b)) diff --git a/1st-gen/packages/accordion/README.md b/1st-gen/packages/accordion/README.md new file mode 100644 index 00000000000..276607ca7ed --- /dev/null +++ b/1st-gen/packages/accordion/README.md @@ -0,0 +1,359 @@ +## Overview + +The `` element contains a list of items that can be expanded or collapsed to reveal additional content or information associated with each item. There can be zero expanded items, exactly one expanded item, or more than one item expanded at a time, depending on the configuration. This list of items is defined by child [``](../accordion-item/) elements that are targeted to the default slot of their `` parent. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/accordion?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/accordion) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/accordion?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/accordion) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-gbdet9lz) + +```bash +yarn add @spectrum-web-components/accordion +``` + +Import the side effectful registration of `` and `` via: + +```js +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +``` + +When looking to leverage the `Accordion` and `AccordionItem` base class as a type and/or for extension purposes, do so via: + +```js +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; +``` + +### Anatomy + +The accordion consists of several key parts: + +- A container element that manages the accordion behavior +- Individual accordion items that can be expanded or collapsed +- Each item has a header with a label and chevron icon +- Content that is revealed when an item is expanded + +```html + + +
+ The bellows is the expandable section in the middle of the + accordion. +
+
+ +
+ The treble section of the accordion is the right-hand section for + playing melodies. +
+
+ +
+ The bass section of the accordion is the left-hand section for + playing accompaniment. +
+
+
+``` + +### Options + +#### Sizes + + +Small + + +```html + + +
+ A key accordion, or a chromatic piano accordion, includes a keyboard + for the right hand. +
+
+ +
+ A button accoridon, or a chromatic accordion, has buttons instead of + keys. +
+
+ +
+ Produces two different tones or notes depending on whether the + bellows is pulled or pushed. +
+
+ +
+ A concertina has buttons on both sides and each button makes two + different notes or tones depending on whether the bellows is pulled + or pushed. +
+
+
+``` + +
+Medium + + +```html + + +
+ A key accordion, or a chromatic piano accordion, includes a keyboard + for the right hand. +
+
+ +
+ A button accoridon, or a chromatic accordion, has buttons instead of + keys. +
+
+ +
+ Produces two different tones or notes depending on whether the + bellows is pulled or pushed. +
+
+ +
+ A concertina has buttons on both sides and each button makes two + different notes or tones depending on whether the bellows is pulled + or pushed. +
+
+
+``` + +
+Large + + +```html + + +
+ A key accordion, or a chromatic piano accordion, includes a keyboard + for the right hand. +
+
+ +
+ A button accoridon, or a chromatic accordion, has buttons instead of + keys. +
+
+ +
+ Produces two different tones or notes depending on whether the + bellows is pulled or pushed. +
+
+ +
+ A concertina has buttons on both sides and each button makes two + different notes or tones depending on whether the bellows is pulled + or pushed. +
+
+
+``` + +
+Extra Large + + +```html + + +
+ A key accordion, or a chromatic piano accordion, includes a keyboard + for the right hand. +
+
+ +
+ A button accoridon, or a chromatic accordion, has buttons instead of + keys. +
+
+ +
+ Produces two different tones or notes depending on whether the + bellows is pulled or pushed. +
+
+ +
+ A concertina has buttons on both sides and each button makes two + different notes or tones depending on whether the bellows is pulled + or pushed. +
+
+
+``` + +
+
+ +#### Density + +The `density` property, when applied, accepts the values of `compact` or `spacious`. + + +Compact + + +```html +
+ + +
This accordion is compact.
+
+ +
This accordion is also small.
+
+
+ + +
This accordion is compact.
+
+ +
This accordion is also medium.
+
+
+ + +
This accordion is compact.
+
+ +
This accordion is also large.
+
+
+ + +
This accordion is compact.
+
+ +
This accordion is also extra large.
+
+
+
+``` + +
+Spacious + + +```html +
+ + +
This accordion is spacious.
+
+ +
This accordion is also small.
+
+
+ + +
This accordion is spacious.
+
+ +
This accordion is also medium.
+
+
+ + +
This accordion is spacious.
+
+ +
This accordion is also large.
+
+
+ + +
This accordion is spacious.
+
+ +
This accordion is also extra large.
+
+
+
+``` + +
+
+ +### States + +#### Allow Multiple + +By default, only one accordion item can be expanded at a time. Use the `allow-multiple` attribute to allow multiple items to be expanded simultaneously. + +```html + + +
Kermit is a frog.
+
+ +
Fozzie is a bear.
+
+ +
Miss Piggy is a pig.
+
+
+``` + +#### Disabled + +Individual accordion items can be disabled using the `disabled` attribute. Disabled items cannot be expanded or collapsed. + +```html + + +
+ We have some of the most popular varieties include Red Delicious, + Gala, Granny Smith, Honeycrisp, and Fuji. +
+
+ +
We have the Gros Michel.
+
+ +
We have Mandarins, Seville Oranges, and Clementines.
+
+
+``` + +### Accessibility + +The accordion component provides proper ARIA attributes and keyboard navigation: + +- Each accordion item header has `aria-expanded` to indicate its current state +- The header button has `aria-controls` pointing to the content region +- The content region has `role="region"` and `aria-labelledby` pointing to the header +- Disabled items have `aria-disabled="true"` applied +- The accordion supports keyboard navigation with arrow keys and Enter/Space for activation + +#### Include descriptive labels + +Each accordion item should have a clear, descriptive label that indicates what content will be revealed when expanded. + +#### Use appropriate content + +Accordion content should be related to the header label and provide additional information or functionality that users can access when needed. diff --git a/1st-gen/packages/accordion/accordion-item.md b/1st-gen/packages/accordion/accordion-item.md new file mode 100644 index 00000000000..949433e4d78 --- /dev/null +++ b/1st-gen/packages/accordion/accordion-item.md @@ -0,0 +1,89 @@ +## Overview + +The `` element represents a single item in an [``](../accordion/) parent element. Its `label` attribute and default slot content make up the "headline" and "body" of the toggleable content item. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/accordion?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/accordion) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/accordion?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/accordion) + +```zsh +yarn add @spectrum-web-components/accordion +``` + +Import the side effectful registration of `` via: + +```javascript +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +``` + +When looking to leverage the `AccordionItem` base class as a type and/or for extension purposes, do so via: + +```javascript +import { AccordionItem } from '@spectrum-web-components/accordion'; +``` + +### Anatomy + +The accordion item consists of two key parts: + +- A header button with a label and chevron icon +- Content that is revealed when the item is expanded + +```html + + +
Accordion item content can be toggled visible.
+
+
+``` + +### States + +#### Opened + +An accordion item can be opened by default using the `open` attribute: + +```html + + +
This accordion item content is visible by default.
+
+
+``` + +#### Disabled + +Individual accordion items can be disabled using the `disabled` attribute. Disabled items cannot be expanded or collapsed: + +```html + + +
You can not toggle this content visible.
+
+
+``` + +### Behaviors + +#### Events + +An `` element will dispatch `sp-accordion-item-toggle` events when it is opened or closed. By default, these events are dispatched to allow the parent `` to manage which of its item children are expanded at any given time. Consumers can also listen for this event and check `event.target.open` to determine whether the item is currently expanded. + +### Accessibility + +The accordion component provides proper ARIA attributes and keyboard navigation: + +- Each accordion item header has `aria-expanded` to indicate its current state +- The header button has `aria-controls` pointing to the content region +- The content region has `role="region"` and `aria-labelledby` pointing to the header +- Disabled items have `aria-disabled="true"` applied +- The accordion supports keyboard navigation with Enter/Space for activation + +#### Include descriptive labels + +Each accordion item should have a clear, descriptive label that indicates what content will be revealed when expanded. + +#### Use appropriate content + +Accordion content should be related to the header label and provide additional information or functionality that users can access when needed. diff --git a/1st-gen/packages/accordion/package.json b/1st-gen/packages/accordion/package.json new file mode 100644 index 00000000000..d49b54ceb46 --- /dev/null +++ b/1st-gen/packages/accordion/package.json @@ -0,0 +1,89 @@ +{ + "name": "@spectrum-web-components/accordion", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/accordion" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/accordion", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Accordion.js": { + "development": "./src/Accordion.dev.js", + "default": "./src/Accordion.js" + }, + "./src/AccordionItem.js": { + "development": "./src/AccordionItem.dev.js", + "default": "./src/AccordionItem.js" + }, + "./src/accordion-item-overrides.css.js": "./src/accordion-item-overrides.css.js", + "./src/accordion-item.css.js": "./src/accordion-item.css.js", + "./src/accordion-overrides.css.js": "./src/accordion-overrides.css.js", + "./src/accordion.css.js": "./src/accordion.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-accordion.js": { + "development": "./sp-accordion.dev.js", + "default": "./sp-accordion.js" + }, + "./sp-accordion-item.js": { + "development": "./sp-accordion-item.dev.js", + "default": "./sp-accordion-item.js" + } + }, + "scripts": { + "test": "karma start --coverage" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-ui": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/accordion/sp-accordion-item.ts b/1st-gen/packages/accordion/sp-accordion-item.ts new file mode 100644 index 00000000000..2a93ec5aa8c --- /dev/null +++ b/1st-gen/packages/accordion/sp-accordion-item.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { AccordionItem } from './src/AccordionItem.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-accordion-item', AccordionItem); + +declare global { + interface HTMLElementTagNameMap { + 'sp-accordion-item': AccordionItem; + } +} diff --git a/1st-gen/packages/accordion/sp-accordion.ts b/1st-gen/packages/accordion/sp-accordion.ts new file mode 100644 index 00000000000..bca2a316984 --- /dev/null +++ b/1st-gen/packages/accordion/sp-accordion.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Accordion } from './src/Accordion.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-accordion', Accordion); + +declare global { + interface HTMLElementTagNameMap { + 'sp-accordion': Accordion; + } +} diff --git a/1st-gen/packages/accordion/src/Accordion.ts b/1st-gen/packages/accordion/src/Accordion.ts new file mode 100644 index 00000000000..0a331cd2915 --- /dev/null +++ b/1st-gen/packages/accordion/src/Accordion.ts @@ -0,0 +1,123 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + queryAssignedNodes, +} from '@spectrum-web-components/base/src/decorators.js'; +import { FocusGroupController } from '@spectrum-web-components/reactive-controllers/src/FocusGroup.js'; + +import { AccordionItem } from './AccordionItem.js'; + +import styles from './accordion.css.js'; + +/** + * @element sp-accordion + * @slot - The sp-accordion-item children to display. + */ +export class Accordion extends SizedMixin(SpectrumElement, { + noDefaultSize: true, +}) { + public static override get styles(): CSSResultArray { + return [styles]; + } + + /** + * Allows multiple accordion items to be opened at the same time + */ + @property({ type: Boolean, reflect: true, attribute: 'allow-multiple' }) + public allowMultiple = false; + + /** + * Sets the spacing between the content to borders of an accordion item + */ + @property({ type: String, reflect: true }) + public density?: 'compact' | 'spacious'; + + @queryAssignedNodes() + private defaultNodes!: NodeListOf; + + private get items(): AccordionItem[] { + return [...(this.defaultNodes || [])].filter( + (node: HTMLElement) => typeof node.tagName !== 'undefined' + ) as AccordionItem[]; + } + + focusGroupController = new FocusGroupController(this, { + direction: 'vertical', + elements: () => this.items, + isFocusableElement: (el: AccordionItem) => !el.disabled, + }); + + public override focus(): void { + this.focusGroupController.focus(); + } + + private async onToggle(event: Event): Promise { + const target = event.target as AccordionItem; + // Let the event pass through the DOM so that it can be + // prevented from the outside if a user so desires. + await 0; + if (this.allowMultiple || event.defaultPrevented) { + // No toggling when `allowMultiple` or the user prevents it. + return; + } + const items = [...this.items] as AccordionItem[]; + /* c8 ignore next 3 */ + if (items && !items.length) { + // no toggling when there aren't items. + return; + } + items.forEach((item) => { + if (item !== target) { + // Close all the items that didn't dispatch the event. + item.open = false; + } + }); + } + + private handleSlotchange(): void { + this.focusGroupController.clearElementCache(); + this.items.forEach((item) => { + item.size = this.size; + }); + } + + protected override updated(changed: PropertyValues): void { + super.updated(changed); + if ( + changed.has('size') && + (!!changed.get('size') || this.size !== 'm') + ) { + this.items.forEach((item) => { + item.size = this.size; + }); + } + } + + protected override render(): TemplateResult { + return html` + + `; + } +} diff --git a/1st-gen/packages/accordion/src/AccordionItem.ts b/1st-gen/packages/accordion/src/AccordionItem.ts new file mode 100644 index 00000000000..ac96bb408f8 --- /dev/null +++ b/1st-gen/packages/accordion/src/AccordionItem.ts @@ -0,0 +1,144 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SizedMixin, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { Focusable } from '@spectrum-web-components/shared/src/focusable.js'; +import { when } from '@spectrum-web-components/base/src/directives.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js'; +import chevronIconStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js'; + +import styles from './accordion-item.css.js'; + +const chevronIcon: Record TemplateResult> = { + s: () => html` + + + + `, + m: () => html` + + + + `, + l: () => html` + + + + `, + xl: () => html` + + + + `, +}; + +/** + * @element sp-accordion-item + * @slot - The content of the item that is hidden when the item is not open + * @fires sp-accordion-item-toggle - Announce that an accordion item has been toggled while allowing the event to be cancelled. + */ +export class AccordionItem extends SizedMixin(Focusable, { + noDefaultSize: true, +}) { + public static override get styles(): CSSResultArray { + return [styles, chevronIconStyles]; + } + + @property({ type: Boolean, reflect: true }) + public open = false; + + @property({ type: String, reflect: true }) + public label = ''; + + @property({ type: Boolean, reflect: true }) + public override disabled = false; + + public override get focusElement(): HTMLElement { + return this.shadowRoot.querySelector('#header') as HTMLElement; + } + + private onClick(): void { + /* c8 ignore next 3 */ + if (this.disabled) { + return; + } + this.toggle(); + } + + private toggle(): void { + this.open = !this.open; + const applyDefault = this.dispatchEvent( + new CustomEvent('sp-accordion-item-toggle', { + bubbles: true, + composed: true, + cancelable: true, + }) + ); + if (!applyDefault) { + this.open = !this.open; + } + } + + protected renderChevronIcon = (): TemplateResult => { + return chevronIcon[this.size || 'm'](); + }; + + protected override render(): TemplateResult { + return html` +

+ ${when(this.size, this.renderChevronIcon)} + +

+
+ +
+ `; + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if (changes.has('disabled')) { + if (this.disabled) { + this.setAttribute('aria-disabled', 'true'); + } else { + this.removeAttribute('aria-disabled'); + } + } + } +} diff --git a/1st-gen/packages/accordion/src/accordion-item-overrides.css b/1st-gen/packages/accordion/src/accordion-item-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/accordion/src/accordion-item-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/accordion/src/accordion-item.css b/1st-gen/packages/accordion/src/accordion-item.css new file mode 100644 index 00000000000..dece669def1 --- /dev/null +++ b/1st-gen/packages/accordion/src/accordion-item.css @@ -0,0 +1,27 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-accordion-item.css"); + +:host { + display: block; +} + +#heading { + /* .spectrum-Accordion-itemHeading */ + height: auto; + position: relative; +} + +:host([disabled]) #heading .indicator { + color: var(--mod-accordion-item-header-disabled-color, var(--spectrum-accordion-item-header-disabled-color)); +} diff --git a/1st-gen/packages/accordion/src/accordion-overrides.css b/1st-gen/packages/accordion/src/accordion-overrides.css new file mode 100644 index 00000000000..37a584bcd35 --- /dev/null +++ b/1st-gen/packages/accordion/src/accordion-overrides.css @@ -0,0 +1,17 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-accordion-divider-color: var(--system-accordion-divider-color); + --spectrum-accordion-item-content-disabled-color: var(--system-accordion-item-content-disabled-color); + --spectrum-accordion-item-content-color: var(--system-accordion-item-content-color); +} diff --git a/1st-gen/packages/accordion/src/accordion.css b/1st-gen/packages/accordion/src/accordion.css new file mode 100644 index 00000000000..81f0bd473f6 --- /dev/null +++ b/1st-gen/packages/accordion/src/accordion.css @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-accordion.css"); +@import url("./accordion-overrides.css"); + +:host { + --spectrum-logical-rotation: ; +} diff --git a/1st-gen/packages/accordion/src/index.ts b/1st-gen/packages/accordion/src/index.ts new file mode 100644 index 00000000000..320bca5a829 --- /dev/null +++ b/1st-gen/packages/accordion/src/index.ts @@ -0,0 +1,14 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './Accordion.js'; +export * from './AccordionItem.js'; diff --git a/1st-gen/packages/accordion/src/spectrum-accordion-item.css b/1st-gen/packages/accordion/src/spectrum-accordion-item.css new file mode 100644 index 00000000000..12bf0f834b6 --- /dev/null +++ b/1st-gen/packages/accordion/src/spectrum-accordion-item.css @@ -0,0 +1,168 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + z-index: inherit; + min-block-size: var(--mod-accordion-item-height, var(--spectrum-accordion-item-height)); + min-inline-size: var(--mod-accordion-item-width, var(--spectrum-accordion-item-width)); + border-block-end: 1px solid #0000; + border-color: var(--mod-accordion-divider-color, var(--spectrum-accordion-divider-color)); + border-width: var(--mod-accordion-divider-thickness, var(--spectrum-divider-thickness-small)); + margin: 0; + position: relative; +} + +:host(:first-child) { + border-block-start: 1px solid #0000; + border-color: var(--mod-accordion-divider-color, var(--spectrum-accordion-divider-color)); + border-width: var(--mod-accordion-divider-thickness, var(--spectrum-divider-thickness-small)); +} + +#heading { + box-sizing: border-box; + margin: 0; + position: relative; +} + +.iconContainer { + inline-size: var(--mod-accordion-disclosure-indicator-height, var(--spectrum-accordion-disclosure-indicator-height)); + block-size: var(--mod-accordion-disclosure-indicator-height, var(--spectrum-accordion-disclosure-indicator-height)); + color: var(--mod-accordion-item-header-color-default, var(--spectrum-accordion-item-header-color-default)); + justify-content: center; + align-items: center; + padding-inline-start: var(--mod-accordion-edge-to-disclosure-indicator-space, var(--spectrum-accordion-edge-to-disclosure-indicator-space)); + display: flex; + position: absolute; + inset-block-start: max(0px, calc((var(--mod-accordion-min-block-size, var(--spectrum-accordion-min-block-size)) - var(--mod-accordion-disclosure-indicator-height, var(--spectrum-accordion-disclosure-indicator-height))) / 2)); +} + +.iconContainer:dir(rtl), +:host([dir="rtl"]) .iconContainer { + transform: scaleX(-1); +} + +#content { + padding-block: var(--mod-accordion-item-content-area-top-to-content, var(--spectrum-accordion-item-content-area-top-to-content)) var(--mod-accordion-item-content-area-bottom-to-content, var(--spectrum-accordion-item-content-area-bottom-to-content)); + padding-inline: var(--mod-accordion-component-edge-to-text, var(--spectrum-accordion-component-edge-to-text)) var(--mod-accordion-component-edge-to-text, var(--spectrum-accordion-component-edge-to-text)); + color: var(--mod-accordion-item-content-color, var(--spectrum-accordion-item-content-color)); + font-weight: var(--mod-accordion-item-content-font-weight, var(--spectrum-accordion-item-content-font-weight)); + font-style: var(--mod-accordion-item-content-font-style, var(--spectrum-accordion-item-content-font-style)); + font-size: var(--mod-accordion-item-content-font-size, var(--spectrum-accordion-item-content-font-size)); + font-family: var(--mod-accordion-item-content-font, var(--spectrum-accordion-item-content-font)); + line-height: var(--mod-accordion-item-content-line-height, var(--spectrum-accordion-item-content-line-height)); + display: none; +} + +#header { + box-sizing: border-box; + padding-block: var(--mod-accordion-item-header-top-to-text-space, var(--spectrum-accordion-item-header-top-to-text-space)) var(--mod-accordion-item-header-bottom-to-text-space, var(--spectrum-accordion-item-header-bottom-to-text-space)); + min-block-size: var(--mod-accordion-min-block-size, var(--spectrum-accordion-min-block-size)); + line-height: var(--mod-accordion-item-header-line-height, var(--spectrum-accordion-item-header-line-height)); + text-overflow: ellipsis; + cursor: pointer; + font-size: var(--mod-accordion-item-header-font-size, var(--spectrum-accordion-item-header-font-size)); + font-weight: var(--mod-accordion-item-header-font-weight, var(--spectrum-accordion-item-header-font-weight)); + font-style: var(--mod-accordion-item-header-font-style, var(--spectrum-accordion-item-header-font-style)); + font-family: var(--mod-accordion-item-header-font, var(--spectrum-accordion-item-header-font)); + appearance: none; + text-align: start; + inline-size: 100%; + color: var(--mod-accordion-item-header-color-default, var(--spectrum-accordion-item-header-color-default)); + background-color: var(--mod-accordion-background-color-default, var(--spectrum-accordion-background-color-default)); + border: 0; + justify-content: flex-start; + align-items: center; + padding-inline-start: calc(var(--mod-accordion-disclosure-indicator-to-text-space, var(--spectrum-accordion-disclosure-indicator-to-text-space)) + var(--mod-accordion-disclosure-indicator-height, var(--spectrum-accordion-disclosure-indicator-height))); + padding-inline-end: var(--mod-accordion-edge-to-text-space, var(--spectrum-accordion-edge-to-text-space)); + display: flex; + position: relative; +} + +#header:focus { + outline: none; +} + +#header:focus:after { + content: ""; + position: absolute; + inset-inline-start: 0; +} + +#header:focus-visible { + border-radius: var(--mod-accordion-corner-radius, var(--spectrum-accordion-corner-radius)); + outline: var(--mod-accordion-focus-indicator-thickness, var(--spectrum-accordion-focus-indicator-thickness)) solid var(--mod-accordion-focus-indicator-color, var(--spectrum-accordion-focus-indicator-color)); + background-color: var(--mod-accordion-background-color-key-focus, var(--spectrum-accordion-background-color-key-focus)); + color: var(--mod-accordion-item-header-color-key-focus, var(--spectrum-accordion-item-header-color-key-focus)); + outline-offset: calc(var(--mod-accordion-focus-indicator-gap, var(--spectrum-accordion-focus-indicator-gap)) * -1); +} + +#header:active { + background-color: var(--mod-accordion-background-color-down, var(--spectrum-accordion-background-color-down)); + color: var(--mod-accordion-item-header-color-down, var(--spectrum-accordion-item-header-color-down)); +} + +:host([disabled]) #header, +:host([disabled]) #header:focus-visible { + color: var(--mod-accordion-item-header-disabled-color, var(--spectrum-accordion-item-header-disabled-color)); + background-color: initial; +} + +@media (hover: hover) { + #header:hover { + background-color: var(--mod-accordion-background-color-hover, var(--spectrum-accordion-background-color-hover)); + } + + #header:hover, + #header:hover + .iconContainer { + color: var(--mod-accordion-item-header-color-hover, var(--spectrum-accordion-item-header-color-hover)); + } + + :host([open]) #header:hover { + background-color: var(--mod-accordion-background-color-hover, var(--spectrum-accordion-background-color-hover)); + } + + :host([disabled]) #header:hover { + color: var(--mod-accordion-item-header-disabled-color, var(--spectrum-accordion-item-header-disabled-color)); + background-color: initial; + } +} + +:host([disabled]) #header + .iconContainer { + color: var(--mod-accordion-item-header-disabled-color, var(--spectrum-accordion-item-header-disabled-color)); +} + +:host([disabled]) #content { + color: var(--mod-accordion-item-content-disabled-color, var(--spectrum-accordion-item-content-disabled-color)); +} + +@media (forced-colors: active) { + #header:after { + forced-color-adjust: none; + content: ""; + position: absolute; + inset-inline-start: 0; + } +} + +:host([open]) > #heading > .iconContainer > .indicator, +:host([open]) > .iconContainer > .indicator { + transform: rotate(90deg); + transform: var(--spectrum-logical-rotation,) rotate(90deg); +} + +:host([open]) > #content { + display: block; +} + +:host([disabled]) #header { + cursor: default; +} diff --git a/1st-gen/packages/accordion/src/spectrum-accordion.css b/1st-gen/packages/accordion/src/spectrum-accordion.css new file mode 100644 index 00000000000..c4f79e97ee4 --- /dev/null +++ b/1st-gen/packages/accordion/src/spectrum-accordion.css @@ -0,0 +1,149 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-accordion-item-height: var(--spectrum-component-height-200); + --spectrum-accordion-item-width: var(--spectrum-accordion-minimum-width); + --spectrum-accordion-disclosure-indicator-height: var(--spectrum-component-height-100); + --spectrum-accordion-disclosure-indicator-to-text-space: var(--spectrum-accordion-disclosure-indicator-to-text); + --spectrum-accordion-edge-to-disclosure-indicator-space: var(--spectrum-accordion-edge-to-disclosure-indicator); + --spectrum-accordion-edge-to-text-space: var(--spectrum-accordion-edge-to-text); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-regular-medium); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-regular-medium); + --spectrum-accordion-focus-indicator-gap: var(--spectrum-focus-indicator-gap); + --spectrum-accordion-focus-indicator-thickness: var(--spectrum-focus-indicator-thickness); + --spectrum-accordion-corner-radius: var(--spectrum-corner-radius-100); + --spectrum-accordion-item-content-area-top-to-content: var(--spectrum-accordion-content-area-top-to-content); + --spectrum-accordion-item-content-area-bottom-to-content: var(--spectrum-accordion-content-area-bottom-to-content); + --spectrum-accordion-component-edge-to-text: var(--spectrum-component-edge-to-text-75); + --spectrum-accordion-item-header-font: var(--spectrum-sans-font-family-stack); + --spectrum-accordion-item-header-font-weight: var(--spectrum-bold-font-weight); + --spectrum-accordion-item-header-font-style: var(--spectrum-default-font-style); + --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-300); + --spectrum-accordion-item-header-line-height: 1.25; + --spectrum-accordion-item-content-font: var(--spectrum-sans-font-family-stack); + --spectrum-accordion-item-content-font-weight: var(--spectrum-body-sans-serif-font-weight); + --spectrum-accordion-item-content-font-style: var(--spectrum-body-sans-serif-font-style); + --spectrum-accordion-item-content-font-size: var(--spectrum-body-size-s); + --spectrum-accordion-item-content-line-height: var(--spectrum-line-height-100); + --spectrum-accordion-background-color-default: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-background-opacity-default)); + --spectrum-accordion-background-color-hover: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-background-opacity-hover)); + --spectrum-accordion-background-color-down: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-background-opacity-down)); + --spectrum-accordion-background-color-key-focus: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-background-opacity-key-focus)); + --spectrum-accordion-item-header-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-accordion-item-header-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-accordion-item-header-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-accordion-item-header-color-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-accordion-item-header-disabled-color: var(--spectrum-disabled-content-color); + --spectrum-accordion-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-accordion-min-block-size: max( + var(--mod-accordion-item-height, var(--spectrum-accordion-item-height)), + calc(var(--mod-accordion-item-header-top-to-text-space, var(--spectrum-accordion-item-header-top-to-text-space)) + var(--mod-accordion-item-header-bottom-to-text-space, var(--spectrum-accordion-item-header-bottom-to-text-space)) + var(--mod-accordion-item-header-font-size, var(--spectrum-accordion-item-header-font-size)) * var(--mod-accordion-item-header-line-height, var(--spectrum-accordion-item-header-line-height))) + ); +} + +:host:dir(rtl), +:host([dir="rtl"]) { + --spectrum-logical-rotation: matrix(-1, 0, 0, 1, 0, 0); +} + +:host:lang(ja), +:host:lang(ko), +:host:lang(zh) { + --spectrum-accordion-item-header-line-height: var(--spectrum-cjk-line-height-100); + --spectrum-accordion-item-content-line-height: var(--spectrum-cjk-line-height-100); +} + +:host([density="compact"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-100); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-compact-medium); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-compact-medium); +} + +:host([density="compact"][size="s"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-75); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-compact-small); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-compact-small); +} + +:host([density="compact"][size="l"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-200); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-compact-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-compact-large); +} + +:host([density="compact"][size="xl"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-300); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-compact-extra-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-compact-extra-large); +} + +:host([density="spacious"]) { + --spectrum-accordion-item-header-line-height: 1.278; + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-spacious-medium); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-spacious-medium); +} + +:host([density="spacious"][size="s"]) { + --spectrum-accordion-item-header-line-height: 1.25; + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-small-top-to-text-spacious); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-spacious-small); +} + +:host([density="spacious"][size="l"]) { + --spectrum-accordion-item-header-line-height: 1.273; + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-spacious-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-spacious-large); +} + +:host([density="spacious"][size="xl"]) { + --spectrum-accordion-item-header-line-height: 1.25; + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-spacious-extra-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-spacious-extra-large); +} + +:host([size="s"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-100); + --spectrum-accordion-disclosure-indicator-height: var(--spectrum-component-height-75); + --spectrum-accordion-component-edge-to-text: var(--spectrum-component-edge-to-text-50); + --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-200); + --spectrum-accordion-item-content-font-size: var(--spectrum-body-size-xs); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-regular-small); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-regular-small); +} + +:host([size="l"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-300); + --spectrum-accordion-disclosure-indicator-height: var(--spectrum-component-height-200); + --spectrum-accordion-component-edge-to-text: var(--spectrum-component-edge-to-text-100); + --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-500); + --spectrum-accordion-item-content-font-size: var(--spectrum-body-size-m); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-regular-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-regular-large); +} + +:host([size="xl"]) { + --spectrum-accordion-item-height: var(--spectrum-component-height-400); + --spectrum-accordion-disclosure-indicator-height: var(--spectrum-component-height-300); + --spectrum-accordion-component-edge-to-text: var(--spectrum-component-edge-to-text-200); + --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-700); + --spectrum-accordion-item-content-font-size: var(--spectrum-body-size-l); + --spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-regular-extra-large); + --spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-regular-extra-large); +} + +:host { + margin: 0; + padding: 0; + list-style: none; + display: block; +} diff --git a/1st-gen/packages/accordion/stories/accordion-densities-compact.stories.ts b/1st-gen/packages/accordion/stories/accordion-densities-compact.stories.ts new file mode 100644 index 00000000000..4eaf3433a4e --- /dev/null +++ b/1st-gen/packages/accordion/stories/accordion-densities-compact.stories.ts @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; +import { AccordionMarkup } from './'; + +export default { + title: 'Accordion/Densities/Compact', + component: 'sp-accordion', +}; + +export const s = (): TemplateResult => + AccordionMarkup({ density: 'compact', size: 's' }); +export const m = (): TemplateResult => + AccordionMarkup({ density: 'compact', size: 'm' }); +export const l = (): TemplateResult => + AccordionMarkup({ density: 'compact', size: 'l' }); +export const xl = (): TemplateResult => + AccordionMarkup({ density: 'compact', size: 'xl' }); diff --git a/1st-gen/packages/accordion/stories/accordion-densities-spacious.stories.ts b/1st-gen/packages/accordion/stories/accordion-densities-spacious.stories.ts new file mode 100644 index 00000000000..2e807da1455 --- /dev/null +++ b/1st-gen/packages/accordion/stories/accordion-densities-spacious.stories.ts @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; +import { AccordionMarkup } from './'; + +export default { + title: 'Accordion/Densities/Spacious', + component: 'sp-accordion', +}; + +export const s = (): TemplateResult => + AccordionMarkup({ density: 'spacious', size: 's' }); +export const m = (): TemplateResult => + AccordionMarkup({ density: 'spacious', size: 'm' }); +export const l = (): TemplateResult => + AccordionMarkup({ density: 'spacious', size: 'l' }); +export const xl = (): TemplateResult => + AccordionMarkup({ density: 'spacious', size: 'xl' }); diff --git a/1st-gen/packages/accordion/stories/accordion-sizes.stories.ts b/1st-gen/packages/accordion/stories/accordion-sizes.stories.ts new file mode 100644 index 00000000000..e0bdb4fb155 --- /dev/null +++ b/1st-gen/packages/accordion/stories/accordion-sizes.stories.ts @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; +import { AccordionMarkup } from './'; + +export default { + title: 'Accordion/Sizes', + component: 'sp-accordion', +}; + +export const s = (): TemplateResult => AccordionMarkup({ size: 's' }); +export const m = (): TemplateResult => AccordionMarkup({ size: 'm' }); +export const l = (): TemplateResult => AccordionMarkup({ size: 'l' }); +export const xl = (): TemplateResult => AccordionMarkup({ size: 'xl' }); diff --git a/1st-gen/packages/accordion/stories/accordion.stories.ts b/1st-gen/packages/accordion/stories/accordion.stories.ts new file mode 100644 index 00000000000..483c58aed7a --- /dev/null +++ b/1st-gen/packages/accordion/stories/accordion.stories.ts @@ -0,0 +1,61 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; +import { AccordionMarkup } from './'; +import { argTypes } from './args.js'; + +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import '@spectrum-web-components/link/sp-link.js'; + +export default { + title: 'Accordion', + component: 'sp-accordion', + args: { + open: false, + size: 'm', + density: undefined, + }, + argTypes, +}; + +type Properties = { + allowMultiple?: boolean; + disabled?: boolean; + open?: boolean; + density?: 'compact' | 'spacious' | undefined; + size?: 's' | 'm' | 'l' | 'xl'; +}; + +export const Default = (args?: Properties): TemplateResult => + AccordionMarkup(args); + +export const Open = (args?: Properties): TemplateResult => + AccordionMarkup(args); +Open.args = { + open: true, + allowMultiple: false, + disabled: false, +}; + +export const AllowMultiple = (args?: Properties): TemplateResult => + AccordionMarkup(args); +AllowMultiple.args = { + allowMultiple: true, +}; + +export const Disabled = (args?: Properties): TemplateResult => + AccordionMarkup(args); +Disabled.args = { + disabled: true, +}; diff --git a/1st-gen/packages/accordion/stories/args.ts b/1st-gen/packages/accordion/stories/args.ts new file mode 100644 index 00000000000..b2d7be1450a --- /dev/null +++ b/1st-gen/packages/accordion/stories/args.ts @@ -0,0 +1,72 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const argTypes = { + open: { + name: 'open', + type: { name: 'boolean', required: false }, + description: 'Whether the second accordion item is open.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + allowMultiple: { + name: 'allowMultiple', + type: { name: 'boolean', required: false }, + description: + 'Whether multipel Accordion Items can be open at the same time.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + density: { + name: 'density', + type: { name: 'string', required: false }, + description: 'The density at which to display accordion items.', + table: { + defaultValue: { summary: 'default' }, + }, + control: { + labels: { + compact: 'Compact', + spacious: 'Spacious', + default: 'Default', + }, + type: 'select', + }, + }, + size: { + name: 'size', + type: { name: 'string', required: false }, + description: 'The size at which to display accordion items.', + table: { + defaultValue: { summary: 'm' }, + }, + control: { + labels: { + s: 'Small', + m: 'Medium', + l: 'Large', + xl: 'Extra large', + }, + type: 'select', + }, + }, +}; diff --git a/1st-gen/packages/accordion/stories/index.ts b/1st-gen/packages/accordion/stories/index.ts new file mode 100644 index 00000000000..91406705178 --- /dev/null +++ b/1st-gen/packages/accordion/stories/index.ts @@ -0,0 +1,54 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import '@spectrum-web-components/link/sp-link.js'; + +export const AccordionMarkup = ({ + allowMultiple = false, + disabled = false, + open = false, + size = 'm', + density = undefined as unknown, +} = {}): TemplateResult => { + return html` + + +
Item 1
+
+ + Item 2 + + +

+ This is content that has a + + link back to Spectrum Web Components + + so that it is easy to test that "Space" and "Enter" + interactions on focusable content does NOT toggle the + Accordion Item. +

+
+
+ `; +}; diff --git a/1st-gen/packages/accordion/stories/template.ts b/1st-gen/packages/accordion/stories/template.ts new file mode 100644 index 00000000000..894f637f2bf --- /dev/null +++ b/1st-gen/packages/accordion/stories/template.ts @@ -0,0 +1,15 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { AccordionMarkup } from './'; + +export const Template = AccordionMarkup; diff --git a/1st-gen/packages/accordion/test/a11y-tree.test.ts b/1st-gen/packages/accordion/test/a11y-tree.test.ts new file mode 100644 index 00000000000..0d8d23f6697 --- /dev/null +++ b/1st-gen/packages/accordion/test/a11y-tree.test.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@spectrum-web-components/base'; +import { elementUpdated, expect, fixture } from '@open-wc/testing'; + +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; + +import { Default } from '../stories/accordion.stories.js'; + +describe('Accordion - a11y tree', () => { + it('renders with items accessibly', async () => { + const el = await fixture(Default()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); +}); + +describe('Accordion Item - a11y tree', () => { + it('can exist with no parent accessibly', async () => { + const el = await fixture(html` + +
Item 1
+
+ `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); +}); diff --git a/1st-gen/packages/accordion/test/accordion-memory.test.ts b/1st-gen/packages/accordion/test/accordion-memory.test.ts new file mode 100644 index 00000000000..21ac7187e1d --- /dev/null +++ b/1st-gen/packages/accordion/test/accordion-memory.test.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Default } from '../stories/accordion.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +describe('Accordion - memory usage', () => { + testForMemoryLeaks(Default()); +}); diff --git a/1st-gen/packages/accordion/test/benchmark/basic-test.ts b/1st-gen/packages/accordion/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..5004facdc8f --- /dev/null +++ b/1st-gen/packages/accordion/test/benchmark/basic-test.ts @@ -0,0 +1,39 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + +
Item 1
+
+ +
Item 2
+
+ +
Item 3
+
+ +
Item 4
+
+ +
Item 5
+
+ +
Item 6
+
+
+`); diff --git a/1st-gen/packages/accordion/test/controlled.test.ts b/1st-gen/packages/accordion/test/controlled.test.ts new file mode 100644 index 00000000000..b6b1dabde5a --- /dev/null +++ b/1st-gen/packages/accordion/test/controlled.test.ts @@ -0,0 +1,47 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture } from '@open-wc/testing'; + +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; + +import { Default } from '../stories/accordion.stories.js'; + +describe('Accordion - controlled', () => { + it('can have `toggle` events canceled', async () => { + const el = await fixture(Default()); + await elementUpdated(el); + const firstItem = el.querySelector( + 'sp-accordion-item:nth-of-type(1)' + ) as AccordionItem; + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + + const firstButton = firstItem.focusElement; + const secondButton = secondItem.focusElement; + + firstButton.click(); + await elementUpdated(el); + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + + el.addEventListener('sp-accordion-item-toggle', (event: Event) => + event.preventDefault() + ); + + secondButton.click(); + await elementUpdated(el); + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + }); +}); diff --git a/1st-gen/packages/accordion/test/declarative.test.ts b/1st-gen/packages/accordion/test/declarative.test.ts new file mode 100644 index 00000000000..652bdb84de5 --- /dev/null +++ b/1st-gen/packages/accordion/test/declarative.test.ts @@ -0,0 +1,94 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@spectrum-web-components/base'; +import { elementUpdated, expect, fixture } from '@open-wc/testing'; +import { spy } from 'sinon'; + +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; + +describe('Accordion - declarative', () => { + it('does not accept focus when empty', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + }); + it('does not accept focus when all children [disabled]', async () => { + const el = await fixture(html` + + +
Item 1
+
+ +
Item 2
+
+
+ `); + + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + }); +}); + +describe('Accordion Item - declarative', () => { + it('can be `[disabled]`', async () => { + const toggleSpy = spy(); + const handleToggle = (): void => toggleSpy(); + const el = await fixture(html` + +
Item 1
+
+ `); + + const root = el.shadowRoot as ShadowRoot; + const button = root.querySelector('#header') as HTMLElement; + + await elementUpdated(el); + + expect(toggleSpy.callCount).to.equal(0); + + button.click(); + + await elementUpdated(el); + + expect(toggleSpy.callCount).to.equal(0); + + el.disabled = false; + await elementUpdated(el); + + button.click(); + + await elementUpdated(el); + + expect(toggleSpy.callCount).to.equal(1); + }); +}); diff --git a/1st-gen/packages/accordion/test/dev-mode.test.ts b/1st-gen/packages/accordion/test/dev-mode.test.ts new file mode 100644 index 00000000000..fc3ced297dd --- /dev/null +++ b/1st-gen/packages/accordion/test/dev-mode.test.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { fixture } from '@open-wc/testing'; + +import { Accordion } from '@spectrum-web-components/accordion'; + +import { Default } from '../stories/accordion.stories.js'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('Accordion - dev mode', () => { + testForLitDevWarnings(async () => await fixture(Default())); +}); diff --git a/1st-gen/packages/accordion/test/imperative.test.ts b/1st-gen/packages/accordion/test/imperative.test.ts new file mode 100644 index 00000000000..3ce779062bf --- /dev/null +++ b/1st-gen/packages/accordion/test/imperative.test.ts @@ -0,0 +1,149 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture } from '@open-wc/testing'; + +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; + +import { Default } from '../stories/accordion.stories.js'; +import { AccordionMarkup } from '../stories/index.js'; + +describe('Accordion - imperative interactions', () => { + it('manages item size', async () => { + const el = await fixture( + AccordionMarkup({ + size: 'l', + }) + ); + const item = el.querySelector('sp-accordion-item') as AccordionItem; + expect(el.size).to.equal('l'); + expect(item.size).to.equal('l'); + + el.size = 's'; + await elementUpdated(el); + await elementUpdated(item); + expect(el.size).to.equal('s'); + expect(item.size).to.equal('s'); + }); + it('only allows one open item by default', async () => { + const el = await fixture(Default()); + await elementUpdated(el); + const firstItem = el.querySelector( + 'sp-accordion-item:nth-of-type(1)' + ) as AccordionItem; + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + + const firstButton = firstItem.focusElement; + const secondButton = secondItem.focusElement; + + firstButton.click(); + await elementUpdated(el); + let openItems = el.querySelectorAll('sp-accordion-item[open]'); + expect(openItems.length).to.equal(1); + + secondButton.click(); + await elementUpdated(el); + openItems = el.querySelectorAll('sp-accordion-item[open]'); + expect(openItems.length).to.equal(1); + }); + it('allows more than one open item when `[allow-multiple]`', async () => { + const el = await fixture(Default()); + el.allowMultiple = true; + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-accordion-item:nth-of-type(1)' + ) as AccordionItem; + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + + const firstButton = firstItem.focusElement; + const secondButton = secondItem.focusElement; + + firstButton.click(); + await elementUpdated(el); + + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + + secondButton.click(); + await elementUpdated(el); + + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.true; + }); + it('ensures that the correct item is open and that items can be closed', async () => { + const el = await fixture(Default()); + + await elementUpdated(el); + const firstItem = el.querySelector( + 'sp-accordion-item:nth-of-type(1)' + ) as AccordionItem; + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + + const firstButton = firstItem.focusElement; + const secondButton = secondItem.focusElement; + + firstButton.click(); + await elementUpdated(el); + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + + secondButton.click(); + await elementUpdated(el); + expect(firstItem.open).to.be.false; + expect(secondItem.open).to.be.true; + + secondButton.click(); + await elementUpdated(el); + expect(firstItem.open).to.be.false; + expect(secondItem.open).to.be.false; + }); + it('ensures that the correct item is open and that items can be closed when [allow-multiple]', async () => { + const el = await fixture(Default()); + el.allowMultiple = true; + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-accordion-item:nth-of-type(1)' + ) as AccordionItem; + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + + const firstButton = firstItem.focusElement; + const secondButton = secondItem.focusElement; + + firstButton.click(); + await elementUpdated(el); + + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + + secondButton.click(); + await elementUpdated(el); + + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.true; + + secondButton.click(); + await elementUpdated(el); + + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; + }); +}); diff --git a/1st-gen/packages/accordion/test/keyboard.test.ts b/1st-gen/packages/accordion/test/keyboard.test.ts new file mode 100644 index 00000000000..0f3ab470f9e --- /dev/null +++ b/1st-gen/packages/accordion/test/keyboard.test.ts @@ -0,0 +1,226 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture } from '@open-wc/testing'; +import { html } from '@spectrum-web-components/base'; +import { sendKeys } from '@web/test-runner-commands'; +import { spy } from 'sinon'; + +import { Accordion, AccordionItem } from '@spectrum-web-components/accordion'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import '@spectrum-web-components/accordion/sp-accordion.js'; +import { sendShiftTabKey, sendTabKey } from '../../../test/testing-helpers'; + +describe('Accordion - keyboard', () => { + it('does not accept keyboard events when items are not present', async () => { + const errorSpy = spy(); + const el = await fixture(html` + + +
Item 2
+
+
+ `); + + await elementUpdated(el); + const item = el.querySelector('sp-accordion-item') as AccordionItem; + window.addEventListener('error', () => errorSpy()); + + el.focus(); + item.remove(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + + expect(errorSpy.callCount).to.equal(0); + }); + it('handles focus and keyboard input and ignores disabled items', async () => { + const el = await fixture(html` + + +
Item 1
+
+ +
Item 2
+
+ +
Item 3
+
+ +
Item 4
+
+ +
Item 5
+
+ +
Item 6
+
+
+ `); + + await elementUpdated(el); + + const secondItem = el.querySelector( + 'sp-accordion-item:nth-of-type(2)' + ) as AccordionItem; + const thirdItem = el.querySelector( + 'sp-accordion-item:nth-of-type(3)' + ) as AccordionItem; + const fourthItem = el.querySelector( + 'sp-accordion-item:nth-of-type(4)' + ) as AccordionItem; + + el.focus(); + + await elementUpdated(el); + expect( + document.activeElement === secondItem, + document.activeElement?.localName + ).to.be.true; + + await sendTabKey(); + + expect(document.activeElement === thirdItem).to.be.true; + + await sendTabKey(); + + expect(document.activeElement === fourthItem).to.be.true; + + await sendShiftTabKey(); + await sendShiftTabKey(); + + expect(document.activeElement === secondItem).to.be.true; + + document.body.focus(); + + el.focus(); + expect(document.activeElement === secondItem).to.be.true; + + await sendShiftTabKey(); + await elementUpdated(el); + + const outsideFocused = document.activeElement as HTMLElement; + + expect(typeof outsideFocused).not.to.equal(AccordionItem); + expect(typeof outsideFocused).not.to.equal(Accordion); + }); +}); + +describe('Accordion Item - keyboard', () => { + it('dispatches toggle event on enter key', async () => { + let open = false; + const onAccordionToggle = (): void => { + open = true; + }; + const el = await fixture(html` + +
Item 1
+
+ `); + + await elementUpdated(el); + + expect(open).to.be.false; + + el.focus(); + await sendKeys({ press: 'Enter' }); + + await elementUpdated(el); + + expect(open).to.be.false; + + el.disabled = false; + await elementUpdated(el); + + el.focus(); + await sendKeys({ press: 'Enter' }); + + await elementUpdated(el); + + expect(open).to.be.true; + }); + it('dispatches toggle event on space key', async () => { + let open = false; + const onAccordionToggle = (): void => { + open = true; + }; + const el = await fixture(html` + +
Item 1
+
+ `); + + await elementUpdated(el); + + expect(open).to.be.false; + + el.focus(); + await sendKeys({ press: 'Space' }); + + await elementUpdated(el); + + expect(open).to.be.false; + + el.disabled = false; + await elementUpdated(el); + + el.focus(); + await sendKeys({ press: 'Space' }); + + await elementUpdated(el); + + expect(open).to.be.true; + }); + it('does not dispatch toggle events on key events in Item content', async () => { + let closed = false; + const onAccordionToggle = (): void => { + closed = true; + }; + const el = await fixture(html` + +
+ +
+
+ `); + + const button = el.querySelector('button') as HTMLButtonElement; + await elementUpdated(el); + + expect(el.open).to.be.true; + expect(closed).to.be.false; + + button.focus(); + await sendKeys({ press: 'Space' }); + + await elementUpdated(el); + + expect(closed).to.be.false; + + await elementUpdated(el); + + await sendKeys({ press: 'Enter' }); + + await elementUpdated(el); + + expect(closed).to.be.false; + expect(el.open).to.be.true; + }); +}); diff --git a/1st-gen/packages/accordion/test/memory.test.ts b/1st-gen/packages/accordion/test/memory.test.ts new file mode 100644 index 00000000000..21ac7187e1d --- /dev/null +++ b/1st-gen/packages/accordion/test/memory.test.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Default } from '../stories/accordion.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +describe('Accordion - memory usage', () => { + testForMemoryLeaks(Default()); +}); diff --git a/1st-gen/packages/accordion/tsconfig.json b/1st-gen/packages/accordion/tsconfig.json new file mode 100644 index 00000000000..b3fe0b41b7f --- /dev/null +++ b/1st-gen/packages/accordion/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../icons-ui" }, + { "path": "../../tools/base" }, + { "path": "../../tools/shared" } + ] +} diff --git a/1st-gen/packages/action-bar/.npmrc b/1st-gen/packages/action-bar/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/action-bar/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/action-bar/CHANGELOG.md b/1st-gen/packages/action-bar/CHANGELOG.md new file mode 100644 index 00000000000..66f28ebc347 --- /dev/null +++ b/1st-gen/packages/action-bar/CHANGELOG.md @@ -0,0 +1,552 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/field-label@1.9.0 + - @spectrum-web-components/action-group@1.9.0 + - @spectrum-web-components/popover@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/popover@1.8.0 + - @spectrum-web-components/action-group@1.8.0 + - @spectrum-web-components/field-label@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/popover@1.7.0 + - @spectrum-web-components/action-group@1.7.0 + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/field-label@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies [[`03a4439`](https://github.com/adobe/spectrum-web-components/commit/03a443946b760aedc668630f33ac660443ff915e), [`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e)]: + - @spectrum-web-components/popover@1.6.0 + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/action-group@1.6.0 + - @spectrum-web-components/field-label@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies [[`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0), [`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5)]: + - @spectrum-web-components/field-label@1.5.0 + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/popover@1.5.0 + - @spectrum-web-components/action-group@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/action-group@1.4.0 + - @spectrum-web-components/popover@1.4.0 + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/field-label@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/action-group@1.3.0 + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/field-label@1.3.0 + - @spectrum-web-components/popover@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Features + +- add `static-color` to replace `static` ([#4808](https://github.com/adobe/spectrum-web-components/issues/4808)) ([43cf086](https://github.com/adobe/spectrum-web-components/commit/43cf0865d902346568c755650f53410c7788f2a1)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +### Features + +- **action-bar:** support for action-menus ([#3780](https://github.com/adobe/spectrum-web-components/issues/3780)) ([4aff599](https://github.com/adobe/spectrum-web-components/commit/4aff5995f6a22eefae0dd8e580d743c27ceb2c2d)) + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **action-bar:** include focus-visible polyfilling ([#4273](https://github.com/adobe/spectrum-web-components/issues/4273)) ([fd71ca1](https://github.com/adobe/spectrum-web-components/commit/fd71ca1d8482026d8ddc9f6fa11553cdbecdac48)) +- **styles,theme:** add S2 tokens and theme ([#4241](https://github.com/adobe/spectrum-web-components/issues/4241)) ([a29e4a2](https://github.com/adobe/spectrum-web-components/commit/a29e4a298090e39e009c434e48113fb8a7e90d14)), closes [#4232](https://github.com/adobe/spectrum-web-components/issues/4232) [#4228](https://github.com/adobe/spectrum-web-components/issues/4228) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **action-bar:** allow "close" event to be cancelled ([17cf55e](https://github.com/adobe/spectrum-web-components/commit/17cf55e5117d632e612e2055c77f6fcc4dadbe4c)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +### Bug Fixes + +- update deps graph, update link docs ([#3709](https://github.com/adobe/spectrum-web-components/issues/3709)) ([2deb284](https://github.com/adobe/spectrum-web-components/commit/2deb2847e6ad458c3cbaec02732fffde133e0c54)) + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Features + +- **action-bar:** use core tokens ([4e21edf](https://github.com/adobe/spectrum-web-components/commit/4e21edfa369dcdbba823e3cfc1b35d65f48cab6f)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) +- propogate open to child sp-popover ([ae97677](https://github.com/adobe/spectrum-web-components/commit/ae97677d0db26f4ae68fa47fc561e58490adaf9b)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- **action-bar:** create sp-action-bar component to replace sp-actionbar ([38004b4](https://github.com/adobe/spectrum-web-components/commit/38004b472a69302e3592add04b746ca01e44557d)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.5.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.16...@spectrum-web-components/action-bar@0.5.17) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.15...@spectrum-web-components/action-bar@0.5.16) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.14...@spectrum-web-components/action-bar@0.5.15) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.13...@spectrum-web-components/action-bar@0.5.14) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.12...@spectrum-web-components/action-bar@0.5.13) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.11...@spectrum-web-components/action-bar@0.5.12) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.10...@spectrum-web-components/action-bar@0.5.11) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.9...@spectrum-web-components/action-bar@0.5.10) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.8...@spectrum-web-components/action-bar@0.5.9) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.7...@spectrum-web-components/action-bar@0.5.8) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.6...@spectrum-web-components/action-bar@0.5.7) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.5...@spectrum-web-components/action-bar@0.5.6) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.4...@spectrum-web-components/action-bar@0.5.5) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.3...@spectrum-web-components/action-bar@0.5.4) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.2...@spectrum-web-components/action-bar@0.5.3) (2022-09-15) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.1...@spectrum-web-components/action-bar@0.5.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.5.0...@spectrum-web-components/action-bar@0.5.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.17...@spectrum-web-components/action-bar@0.5.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.4.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.16...@spectrum-web-components/action-bar@0.4.17) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.15...@spectrum-web-components/action-bar@0.4.16) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.14...@spectrum-web-components/action-bar@0.4.15) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.13...@spectrum-web-components/action-bar@0.4.14) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.12...@spectrum-web-components/action-bar@0.4.13) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.11...@spectrum-web-components/action-bar@0.4.12) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.10...@spectrum-web-components/action-bar@0.4.11) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.9...@spectrum-web-components/action-bar@0.4.10) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.8...@spectrum-web-components/action-bar@0.4.9) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.7...@spectrum-web-components/action-bar@0.4.8) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.6...@spectrum-web-components/action-bar@0.4.7) (2022-03-04) + +### Bug Fixes + +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.5...@spectrum-web-components/action-bar@0.4.6) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.4...@spectrum-web-components/action-bar@0.4.5) (2022-02-02) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.3...@spectrum-web-components/action-bar@0.4.4) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.2...@spectrum-web-components/action-bar@0.4.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.1...@spectrum-web-components/action-bar@0.4.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.4.0...@spectrum-web-components/action-bar@0.4.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.3.1...@spectrum-web-components/action-bar@0.4.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.3.0...@spectrum-web-components/action-bar@0.3.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.18...@spectrum-web-components/action-bar@0.3.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.2.18](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.17...@spectrum-web-components/action-bar@0.2.18) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.16...@spectrum-web-components/action-bar@0.2.17) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.15...@spectrum-web-components/action-bar@0.2.16) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.14...@spectrum-web-components/action-bar@0.2.15) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- propogate open to child sp-popover ([ae97677](https://github.com/adobe/spectrum-web-components/commit/ae97677d0db26f4ae68fa47fc561e58490adaf9b)) + +## [0.2.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.13...@spectrum-web-components/action-bar@0.2.14) (2021-08-17) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.12...@spectrum-web-components/action-bar@0.2.13) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.11...@spectrum-web-components/action-bar@0.2.12) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.10...@spectrum-web-components/action-bar@0.2.11) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.9...@spectrum-web-components/action-bar@0.2.10) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.8...@spectrum-web-components/action-bar@0.2.9) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.7...@spectrum-web-components/action-bar@0.2.8) (2021-05-24) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.6...@spectrum-web-components/action-bar@0.2.7) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.5...@spectrum-web-components/action-bar@0.2.6) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.4...@spectrum-web-components/action-bar@0.2.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.3...@spectrum-web-components/action-bar@0.2.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.2...@spectrum-web-components/action-bar@0.2.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.1...@spectrum-web-components/action-bar@0.2.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.2.0...@spectrum-web-components/action-bar@0.2.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/action-bar + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.1.1...@spectrum-web-components/action-bar@0.2.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-bar@0.1.0...@spectrum-web-components/action-bar@0.1.1) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# 0.1.0 (2021-02-02) + +### Features + +- **action-bar:** create sp-action-bar component to replace sp-actionbar ([38004b4](https://github.com/adobe/spectrum-web-components/commit/38004b472a69302e3592add04b746ca01e44557d)) diff --git a/1st-gen/packages/action-bar/README.md b/1st-gen/packages/action-bar/README.md new file mode 100644 index 00000000000..13527d061cd --- /dev/null +++ b/1st-gen/packages/action-bar/README.md @@ -0,0 +1,104 @@ +## Overview + +A `` delivers a floating action bar that is a convenient way to deliver stateful actions in cases like selection mode. `` can be deployed in two variants beyond the default: `[varient="fixed"]` to position the element in relation to the page, and `[variant=sticky]` to position the content in relation to content that may scroll. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/action-bar?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/action-bar) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/action-bar?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/action-bar) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-d7tebfzk) + +``` +yarn add @spectrum-web-components/action-bar +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/action-bar/sp-action-bar.js'; +``` + +When looking to leverage the `ActionBar` base class as a type and/or for extension purposes, do so via: + +``` +import { ActionBar } from '@spectrum-web-components/action-bar'; +``` + +## Example + +```html + + 2 selected + + + + + + + +``` + +## Emphasized + +Use the `emphasized` attribute to add priority to the information that is delivered within your `` element: + +```html + + 2 selected + + + + + + + +``` + +## Variants + +### Fixed + +When using `[variant="fixed"]`, the `` will display by default at the bottom left of the window and can be customized via CSS from the outside. + +```html +

Look down and to the left when toggling.

+ + Toggle fixed action bar + +2 selected +``` + +### Sticky + +When using `[variant="sticky"]`, be sure you've spent some time touching up on [how `sticky` really works](https://medium.com/@elad/css-position-sticky-how-it-really-works-54cd01dc2d46) to ensure the most successful delivery of your content. + +```html +
+

Scroll down for toggle button

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea + commodo consequat. Duis aute irure dolor in reprehenderit in voluptate + velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + occaecat cupidatat non proident, sunt in culpa qui officia deserunt + mollit anim id est laborum. +

+ + Toggle sticky action bar + + + 2 selected + + + + + + + +
+``` diff --git a/1st-gen/packages/action-bar/package.json b/1st-gen/packages/action-bar/package.json new file mode 100644 index 00000000000..13847f10cab --- /dev/null +++ b/1st-gen/packages/action-bar/package.json @@ -0,0 +1,79 @@ +{ + "name": "@spectrum-web-components/action-bar", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/action-bar" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/action-bar", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/ActionBar.js": { + "development": "./src/ActionBar.dev.js", + "default": "./src/ActionBar.js" + }, + "./src/action-bar-overrides.css.js": "./src/action-bar-overrides.css.js", + "./src/action-bar.css.js": "./src/action-bar.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-action-bar.js": { + "development": "./sp-action-bar.dev.js", + "default": "./sp-action-bar.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/action-group": "1.9.0", + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/button": "1.9.0", + "@spectrum-web-components/field-label": "1.9.0", + "@spectrum-web-components/popover": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/action-bar/sp-action-bar.ts b/1st-gen/packages/action-bar/sp-action-bar.ts new file mode 100644 index 00000000000..11959b60ddf --- /dev/null +++ b/1st-gen/packages/action-bar/sp-action-bar.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { ActionBar } from './src/ActionBar.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-action-bar', ActionBar); + +declare global { + interface HTMLElementTagNameMap { + 'sp-action-bar': ActionBar; + } +} diff --git a/1st-gen/packages/action-bar/src/ActionBar.ts b/1st-gen/packages/action-bar/src/ActionBar.ts new file mode 100644 index 00000000000..16012c368ab --- /dev/null +++ b/1st-gen/packages/action-bar/src/ActionBar.ts @@ -0,0 +1,126 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import '@spectrum-web-components/button/sp-close-button.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import actionBarStyles from './action-bar.css.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import { FocusVisiblePolyfillMixin } from '@spectrum-web-components/shared/src/focus-visible.js'; +export const actionBarVariants = ['sticky', 'fixed']; + +/** + * @element sp-action-bar + * @slot - Content to display with the Action Bar + */ +export class ActionBar extends FocusVisiblePolyfillMixin(SpectrumElement) { + public static override get styles(): CSSResultArray { + return [actionBarStyles]; + } + + /** + * Deliver the Action Bar with additional visual emphasis. + */ + @property({ type: Boolean, reflect: true }) + public emphasized = false; + + /** + * When `flexible` the action bar sizes itself to its content + * rather than a specific width. + * + * @param {Boolean} flexible + */ + @property({ type: Boolean, reflect: true }) + public flexible = false; + + @property({ type: Boolean, reflect: true }) + public open = false; + + /** + * The variant applies specific styling when set to `sticky` or `fixed`. + * `variant` attribute is removed when not matching one of the above. + * + * @param {String} variant + */ + @property({ type: String }) + public set variant(variant: string) { + if (variant === this.variant) { + return; + } + if (actionBarVariants.includes(variant)) { + this.setAttribute('variant', variant); + this._variant = variant; + return; + } + this.removeAttribute('variant'); + this._variant = ''; + } + + public get variant(): string { + return this._variant; + } + + private _variant = ''; + + private handleClick(): void { + this.open = false; + + const applyDefault = this.dispatchEvent( + new Event('close', { + bubbles: true, + composed: true, + cancelable: true, + }) + ); + + if (!applyDefault) { + this.open = true; + } + } + + public override render(): TemplateResult { + return html` + + + + + + + + + + + + `; + } +} diff --git a/1st-gen/packages/action-bar/src/action-bar-overrides.css b/1st-gen/packages/action-bar/src/action-bar-overrides.css new file mode 100644 index 00000000000..1e7bdc91382 --- /dev/null +++ b/1st-gen/packages/action-bar/src/action-bar-overrides.css @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-actionbar-popover-background-color: var(--system-action-bar-popover-background-color); + --spectrum-actionbar-popover-border-color: var(--system-action-bar-popover-border-color); +} diff --git a/1st-gen/packages/action-bar/src/action-bar.css b/1st-gen/packages/action-bar/src/action-bar.css new file mode 100644 index 00000000000..9f4bcca1409 --- /dev/null +++ b/1st-gen/packages/action-bar/src/action-bar.css @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-action-bar.css"); +@import url("./action-bar-overrides.css"); + +:host { + display: block; +} + +:host([flexible]) { + display: inline-block; +} diff --git a/1st-gen/packages/action-bar/src/index.ts b/1st-gen/packages/action-bar/src/index.ts new file mode 100644 index 00000000000..c9d4ef3e130 --- /dev/null +++ b/1st-gen/packages/action-bar/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './ActionBar.js'; diff --git a/1st-gen/packages/action-bar/src/spectrum-action-bar.css b/1st-gen/packages/action-bar/src/spectrum-action-bar.css new file mode 100644 index 00000000000..dc491c2a631 --- /dev/null +++ b/1st-gen/packages/action-bar/src/spectrum-action-bar.css @@ -0,0 +1,128 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-actionbar-height: var(--spectrum-action-bar-height); + --spectrum-actionbar-corner-radius: var(--spectrum-corner-radius-100); + --spectrum-actionbar-item-counter-font-size: var(--spectrum-font-size-100); + --spectrum-actionbar-item-counter-line-height: var(--spectrum-line-height-100); + --spectrum-actionbar-item-counter-color: var(--spectrum-neutral-content-color-default); + --spectrum-actionbar-emphasized-background-color: var(--spectrum-informative-background-color-default); + --spectrum-actionbar-emphasized-item-counter-color: var(--spectrum-white); + --spectrum-actionbar-spacing-outer-edge: var(--spectrum-spacing-300); + --spectrum-actionbar-spacing-close-button-top: var(--spectrum-spacing-100); + --spectrum-actionbar-spacing-close-button-start: var(--spectrum-spacing-100); + --spectrum-actionbar-spacing-close-button-end: var(--spectrum-spacing-75); + --spectrum-actionbar-spacing-item-counter-top: var(--spectrum-action-bar-top-to-item-counter); + --spectrum-actionbar-spacing-item-counter-end: var(--spectrum-spacing-400); + --spectrum-actionbar-spacing-action-group-top: var(--spectrum-spacing-100); + --spectrum-actionbar-spacing-action-group-end: var(--spectrum-spacing-100); + --spectrum-actionbar-shadow-horizontal: var(--spectrum-drop-shadow-x); + --spectrum-actionbar-shadow-vertical: var(--spectrum-drop-shadow-y); + --spectrum-actionbar-shadow-blur: var(--spectrum-drop-shadow-blur); + --spectrum-actionbar-shadow-color: var(--spectrum-drop-shadow-color); +} + +:host:lang(ja), +:host:lang(ko), +:host:lang(zh) { + --spectrum-actionbar-item-counter-line-height-cjk: var(--spectrum-cjk-line-height-100); +} + +@media (forced-colors: active) { + :host, + :host([emphasized]) #popover { + --highcontrast-actionbar-popover-border-color: CanvasText; + } +} + +:host { + padding: 0 var(--mod-actionbar-spacing-outer-edge, var(--spectrum-actionbar-spacing-outer-edge)); + z-index: 1; + box-sizing: border-box; + pointer-events: none; + block-size: 0; + opacity: 0; + inset-block-end: 0; +} + +:host([open]) { + block-size: calc(var(--mod-actionbar-spacing-outer-edge, var(--spectrum-actionbar-spacing-outer-edge)) + var(--mod-actionbar-height, var(--spectrum-actionbar-height))); + opacity: 1; +} + +#popover { + block-size: var(--mod-actionbar-height, var(--spectrum-actionbar-height)); + box-sizing: border-box; + inline-size: 100%; + border-radius: var(--mod-actionbar-corner-radius, var(--spectrum-actionbar-corner-radius)); + border-color: var(--highcontrast-actionbar-popover-border-color, var(--mod-actionbar-popover-border-color, var(--spectrum-actionbar-popover-border-color))); + background-color: var(--mod-actionbar-popover-background-color, var(--spectrum-actionbar-popover-background-color)); + filter: drop-shadow(var(--mod-actionbar-shadow-horizontal, var(--spectrum-actionbar-shadow-horizontal)) var(--mod-actionbar-shadow-vertical, var(--spectrum-actionbar-shadow-vertical)) var(--mod-actionbar-shadow-blur, var(--spectrum-actionbar-shadow-blur)) var(--mod-actionbar-shadow-color, var(--spectrum-actionbar-shadow-color))); + pointer-events: auto; + flex-direction: row; + margin: auto; + padding-block: 0; + display: flex; + position: relative; +} + +.close-button { + flex-shrink: 0; + margin-block-start: var(--mod-actionbar-spacing-close-button-top, var(--spectrum-actionbar-spacing-close-button-top)); + margin-inline-start: var(--mod-actionbar-spacing-close-button-start, var(--spectrum-actionbar-spacing-close-button-start)); + margin-inline-end: var(--mod-actionbar-spacing-close-button-end, var(--spectrum-actionbar-spacing-close-button-end)); +} + +.field-label { + font-size: var(--mod-actionbar-item-counter-font-size, var(--spectrum-actionbar-item-counter-font-size)); + color: var(--mod-actionbar-item-counter-color, var(--spectrum-actionbar-item-counter-color)); + line-height: var(--mod-actionbar-item-counter-line-height, var(--spectrum-actionbar-item-counter-line-height)); + margin-block-start: var(--mod-actionbar-spacing-item-counter-top, var(--spectrum-actionbar-spacing-item-counter-top)); + margin-inline-end: var(--mod-actionbar-spacing-item-counter-end, var(--spectrum-actionbar-spacing-item-counter-end)); + padding: 0; +} + +.field-label:lang(ja), +.field-label:lang(ko), +.field-label:lang(zh) { + line-height: var(--mod-actionbar-item-counter-line-height-cjk, var(--spectrum-actionbar-item-counter-line-height-cjk)); +} + +.action-group { + margin-block-start: var(--mod-actionbar-spacing-action-group-top, var(--spectrum-actionbar-spacing-action-group-top)); + margin-inline-start: auto; + margin-inline-end: var(--mod-actionbar-spacing-action-group-end, var(--spectrum-actionbar-spacing-action-group-end)); +} + +:host([emphasized]) #popover { + filter: none; + background-color: var(--mod-actionbar-emphasized-background-color, var(--spectrum-actionbar-emphasized-background-color)); + border-color: #0000; +} + +:host([emphasized]) .field-label { + color: var(--mod-actionbar-emphasized-item-counter-color, var(--spectrum-actionbar-emphasized-item-counter-color)); +} + +:host([variant="sticky"]) { + position: sticky; + inset-inline: 0; +} + +:host([variant="fixed"]) { + position: fixed; +} + +:host([flexible]) #popover { + inline-size: auto; +} diff --git a/1st-gen/packages/action-bar/stories/action-bar.stories.ts b/1st-gen/packages/action-bar/stories/action-bar.stories.ts new file mode 100644 index 00000000000..af1f3fcd202 --- /dev/null +++ b/1st-gen/packages/action-bar/stories/action-bar.stories.ts @@ -0,0 +1,104 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/action-bar/sp-action-bar.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-edit.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-more.js'; +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; + +import { Template } from './template.js'; + +export default { + title: 'Action Bar', + component: 'sp-action-bar', + parameters: { + // Getting the Figma link: https://help.figma.com/hc/en-us/articles/360045003494-Storybook-and-Figma + design: { + type: 'figma', + url: 'https://www.figma.com/file/MPtRIVRzPp2VHiEplwXL2X/S-%2F-Manual?node-id=465%3A3127&t=xbooxCWItOFgG2xM-1', + }, + }, +}; + +export const Default = (): TemplateResult => + Template({ + open: true, + }); + +export const emphasized = (): TemplateResult => { + return html` + + 2 selected + + + + + `; +}; + +export const fixed = (): TemplateResult => { + return html` + + + 2 selected + + + + + `; +}; + +export const flexible = (): TemplateResult => { + return html` + + 2 selected + + + + + `; +}; + +export const hasActionMenuAsChild = (): TemplateResult => { + return html` + + 2 selected + + + + + One + Two + + Select some items + + A + B + C + + + + + `; +}; diff --git a/1st-gen/packages/action-bar/stories/args.ts b/1st-gen/packages/action-bar/stories/args.ts new file mode 100644 index 00000000000..2191d460a52 --- /dev/null +++ b/1st-gen/packages/action-bar/stories/args.ts @@ -0,0 +1,50 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const argTypes = { + open: { + name: 'open', + type: { name: 'boolean', required: false }, + description: 'Whether the Action Bar is open and visible.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: true }, + }, + control: { + type: 'boolean', + }, + }, + emphasized: { + name: 'emphasized', + type: { name: 'boolean', required: false }, + description: 'Whether the Action Bar is emphasized for the viewer.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + tools: { + name: 'tools', + type: { name: 'boolean', required: false }, + description: 'Whether to display tools in the action bar.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: true }, + }, + control: { + type: 'boolean', + }, + }, +}; diff --git a/1st-gen/packages/action-bar/stories/template.ts b/1st-gen/packages/action-bar/stories/template.ts new file mode 100644 index 00000000000..48b487f7f63 --- /dev/null +++ b/1st-gen/packages/action-bar/stories/template.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/action-bar/sp-action-bar.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-edit.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-share.js'; + +export interface Properties { + emphasized?: boolean; + open?: boolean; + tools?: boolean; +} + +export const Template = ({ + emphasized, + open, + tools = true, +}: Properties): TemplateResult => { + return html` + + 2 selected + ${tools + ? html` + + + + + + + ` + : html``} + + `; +}; diff --git a/1st-gen/packages/action-bar/test/action-bar-memory.test.ts b/1st-gen/packages/action-bar/test/action-bar-memory.test.ts new file mode 100644 index 00000000000..5db6314c701 --- /dev/null +++ b/1st-gen/packages/action-bar/test/action-bar-memory.test.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Default } from '../stories/action-bar.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(Default()); diff --git a/1st-gen/packages/action-bar/test/action-bar.test.ts b/1st-gen/packages/action-bar/test/action-bar.test.ts new file mode 100644 index 00000000000..8e9d294e444 --- /dev/null +++ b/1st-gen/packages/action-bar/test/action-bar.test.ts @@ -0,0 +1,113 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +import '@spectrum-web-components/action-bar/sp-action-bar.js'; +import { ActionBar } from '@spectrum-web-components/action-bar'; +import { Default, emphasized } from '../stories/action-bar.stories.js'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; +import { spy } from 'sinon'; + +describe('ActionBar', () => { + testForLitDevWarnings(async () => await fixture(Default())); + it('loads', async () => { + const el = await fixture(Default()); + + await elementUpdated(el); + + expect(el).to.not.be.undefined; + + await expect(el).to.be.accessible(); + }); + + it('accepts variants', async () => { + const el = await fixture(html` + Help text. + `); + + await elementUpdated(el); + + expect(el.variant).to.equal('sticky'); + expect(el.getAttribute('variant')).to.equal('sticky'); + + el.variant = 'fixed'; + + await elementUpdated(el); + + expect(el.variant).to.equal('fixed'); + expect(el.getAttribute('variant')).to.equal('fixed'); + + el.setAttribute('variant', 'sticky'); + + await elementUpdated(el); + + expect(el.variant).to.equal('sticky'); + expect(el.getAttribute('variant')).to.equal('sticky'); + + el.removeAttribute('variant'); + + await elementUpdated(el); + + expect(el.variant).to.equal(''); + expect(el.hasAttribute('variant')).to.be.false; + }); + it('validates variants', async () => { + const el = await fixture(html` + Help text. + `); + + await elementUpdated(el); + + expect(el.variant).to.equal(''); + expect(el.hasAttribute('variant')).to.be.false; + + el.variant = 'fixed'; + + await elementUpdated(el); + + expect(el.variant).to.equal('fixed'); + expect(el.getAttribute('variant')).to.equal('fixed'); + + el.variant = 'fixed'; + + await elementUpdated(el); + + expect(el.variant).to.equal('fixed'); + expect(el.getAttribute('variant')).to.equal('fixed'); + }); + it('dispatches close event', async () => { + const el = await fixture(emphasized()); + const closeSpy = spy(); + el.addEventListener('close', () => closeSpy()); + expect(closeSpy.callCount).to.equal(0); + expect(el.open).to.be.true; + const closeButton = el.shadowRoot.querySelector('sp-close-button'); + closeButton?.click(); + expect(closeSpy.callCount).to.equal(1); + expect(el.open).to.be.false; + }); + it('can have close event prevented', async () => { + const el = await fixture(emphasized()); + const closeSpy = spy(); + el.addEventListener('close', (event: Event) => { + event.preventDefault(); + closeSpy(); + }); + expect(closeSpy.callCount).to.equal(0); + expect(el.open).to.be.true; + const closeButton = el.shadowRoot.querySelector('sp-close-button'); + closeButton?.click(); + expect(closeSpy.callCount).to.equal(1); + expect(el.open).to.be.true; + }); +}); diff --git a/1st-gen/packages/action-bar/test/benchmark/basic-test.ts b/1st-gen/packages/action-bar/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..c6232fb8deb --- /dev/null +++ b/1st-gen/packages/action-bar/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/action-bar/sp-action-bar.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/action-bar/tsconfig.json b/1st-gen/packages/action-bar/tsconfig.json new file mode 100644 index 00000000000..25a02e74ac1 --- /dev/null +++ b/1st-gen/packages/action-bar/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../../tools/base" }, + { "path": "../action-button" }, + { "path": "../action-group" } + ] +} diff --git a/1st-gen/packages/action-button/.npmrc b/1st-gen/packages/action-button/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/action-button/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/action-button/CHANGELOG.md b/1st-gen/packages/action-button/CHANGELOG.md new file mode 100644 index 00000000000..8e73fc4fda7 --- /dev/null +++ b/1st-gen/packages/action-button/CHANGELOG.md @@ -0,0 +1,649 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Minor Changes + +- [#5204](https://github.com/adobe/spectrum-web-components/pull/5204) [`c1669d2`](https://github.com/adobe/spectrum-web-components/commit/c1669d2dc5e1ceeb84486ce49a428f86a3173caa) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - - **Fixed** : Action buttons with href attributes now properly detects modifier keys and skips the proxy click, allowing only native browser behavior to proceed. + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies [[`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e)]: + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5325](https://github.com/adobe/spectrum-web-components/pull/5325) [`6c58f50`](https://github.com/adobe/spectrum-web-components/commit/6c58f50f7b1f5489c11e0d3484e3f4a9d576f1c8) Thanks [@renovate](https://github.com/apps/renovate)! - [#​3644](https://github.com/adobe/spectrum-css/pull/3644) Thanks [@​marissahuysentruyt](https://github.com/marissahuysentruyt)! + + This patch update fixes support for `--mod-actionbutton-border-radius` to make sure it is accessible by consumers and overwrites the default border radius setting when used. + +- Updated dependencies [[`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5)]: + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- [#5190](https://github.com/adobe/spectrum-web-components/pull/5190) [`72dbe62`](https://github.com/adobe/spectrum-web-components/commit/72dbe629cddfc57171eaaadf7206df47c19d3c98) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - update action button fast follows for spectrum 2 + +- Updated dependencies []: + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +### Features + +- **reactive-controllers:** Migrate to Colorjs from Tinycolor ([#4713](https://github.com/adobe/spectrum-web-components/issues/4713)) ([9d740f0](https://github.com/adobe/spectrum-web-components/commit/9d740f0c830aa44273097181e761e9a92d3df4be)) + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +### Bug Fixes + +- **action-button:** action-button with href can be perceived by screen reader ([#4927](https://github.com/adobe/spectrum-web-components/issues/4927)) ([2a0b3a5](https://github.com/adobe/spectrum-web-components/commit/2a0b3a5b300d51c002db60c6d899694d74834d39)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +### BREAKING CHANGES + +- remove action-button variant property ([#4741](https://github.com/adobe/spectrum-web-components/issues/4741)) +- remove deprecated 'static' references ([#4818](https://github.com/adobe/spectrum-web-components/issues/4818)) + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Features + +- add `static-color` to replace `static` ([#4808](https://github.com/adobe/spectrum-web-components/issues/4808)) ([43cf086](https://github.com/adobe/spectrum-web-components/commit/43cf0865d902346568c755650f53410c7788f2a1)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +### Bug Fixes + +- **picker:** added a custom class to make `:focus-visible` styles consistent across all browsers ([#4724](https://github.com/adobe/spectrum-web-components/issues/4724)) ([d667d08](https://github.com/adobe/spectrum-web-components/commit/d667d0853b8122008ce8fe50c6c479a42dc96a9f)) + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **styles, theme:** surface exports that omit Spectrum Vars proactively ([#4142](https://github.com/adobe/spectrum-web-components/issues/4142)) ([5b524c1](https://github.com/adobe/spectrum-web-components/commit/5b524c1d54a64225cb3b2f71b92f581695985519)) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +### Bug Fixes + +- **action-button:** allow change events to bubble and pierce shadowdom ([#3614](https://github.com/adobe/spectrum-web-components/issues/3614)) ([3f76e04](https://github.com/adobe/spectrum-web-components/commit/3f76e04fb71ad263e067838050bd550c009b1a69)) + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +### Bug Fixes + +- handle longpress and over filter overlays ([483e52d](https://github.com/adobe/spectrum-web-components/commit/483e52df24f56be027d8417c1ae530211ef0deb1)) + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Features + +- **action-bar:** use core tokens ([4e21edf](https://github.com/adobe/spectrum-web-components/commit/4e21edfa369dcdbba823e3cfc1b35d65f48cab6f)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **action-button,action-menu,picker,split-button:** expand and update application of aria-\* attributes ([52c0156](https://github.com/adobe/spectrum-web-components/commit/52c015636d42f2baf1524446a0db9d5e5cfeb689)) +- **action-group:** ensure Action Button clicks are attributed to the right element ([#3292](https://github.com/adobe/spectrum-web-components/issues/3292)) ([ddccab7](https://github.com/adobe/spectrum-web-components/commit/ddccab766498a6da6ca29d9bbe9cebd7924e81e0)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- **action-button:** add support for XS t-shirt size ([75440ce](https://github.com/adobe/spectrum-web-components/commit/75440ced6f5cc5dbcd2c3bbfe650ca8c78514467)) +- **action-button:** all "selected" Action Buttons should be "aria-pressed=true" ([d85e235](https://github.com/adobe/spectrum-web-components/commit/d85e23552aa8f15dfdf069b7cba8fa7b8909190a)) +- **action-button:** ensure disabled buttons are not interactable ([b81c3ba](https://github.com/adobe/spectrum-web-components/commit/b81c3ba7961234ebfe83caec3e2b43d0d885cfbb)) +- **action-button:** expand Spectrum CSS processing ([ff1a424](https://github.com/adobe/spectrum-web-components/commit/ff1a4243c00b3774a6afa5e535c414f252dc87dd)) +- add t-shirt sizing to Thumbnail and support for "xxs"/"xs" sizes ([520a642](https://github.com/adobe/spectrum-web-components/commit/520a642b33e2ca5a4fdc67c15ace029d33e895ff)) +- correct specificity of webkit appearance work around ([f0d06bf](https://github.com/adobe/spectrum-web-components/commit/f0d06bf17bbf1d7d2a41a3008373a4b0f4097cf9)) +- correctly delivery visuals and mouse interactions for litAnchor and extensions ([0ae889a](https://github.com/adobe/spectrum-web-components/commit/0ae889a8aab9b3417a021b917dfc817a8310f50f)) +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- prevent default hoisting of custom pseudo elements ([7f66346](https://github.com/adobe/spectrum-web-components/commit/7f6634665fb9fdc530bd3009246e62c24cac1904)) +- prevent longpress when interacting with context menu ([f8b0732](https://github.com/adobe/spectrum-web-components/commit/f8b07321741ee44515fced9923167b96561cdd48)) +- support a wider number of sizes ([ee44978](https://github.com/adobe/spectrum-web-components/commit/ee4497830da0d3bc63d4414ad5548291a39588c7)) +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- allow activation of longpress content ([55e71fd](https://github.com/adobe/spectrum-web-components/commit/55e71fdf9fd5dde489871c3d9798ef8957f4e5b6)) +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- support Spectrum Token consumption and update Action Button to use them ([743ab16](https://github.com/adobe/spectrum-web-components/commit/743ab16d8f05335d320440effbdcb8cd4bffc97d)) +- support static white and static black variants of Action Button ([7f1e25b](https://github.com/adobe/spectrum-web-components/commit/7f1e25bce122bd3601c6aa5ed505cba436e8b952)) +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) + +### Performance Improvements + +- accept new Spectrum CSS featuring simpler DOM structure ([a0b042b](https://github.com/adobe/spectrum-web-components/commit/a0b042b1d05bc23b0b824123af94df5bc3e1e0d2)) + +## [0.10.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.15...@spectrum-web-components/action-button@0.10.16) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.14...@spectrum-web-components/action-button@0.10.15) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.13...@spectrum-web-components/action-button@0.10.14) (2023-03-22) + +### Bug Fixes + +- prevent default hoisting of custom pseudo elements ([7f66346](https://github.com/adobe/spectrum-web-components/commit/7f6634665fb9fdc530bd3009246e62c24cac1904)) + +### Performance Improvements + +- accept new Spectrum CSS featuring simpler DOM structure ([a0b042b](https://github.com/adobe/spectrum-web-components/commit/a0b042b1d05bc23b0b824123af94df5bc3e1e0d2)) + +## [0.10.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.12...@spectrum-web-components/action-button@0.10.13) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.11...@spectrum-web-components/action-button@0.10.12) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.10...@spectrum-web-components/action-button@0.10.11) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.9...@spectrum-web-components/action-button@0.10.10) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.8...@spectrum-web-components/action-button@0.10.9) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.7...@spectrum-web-components/action-button@0.10.8) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.6...@spectrum-web-components/action-button@0.10.7) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.5...@spectrum-web-components/action-button@0.10.6) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.4...@spectrum-web-components/action-button@0.10.5) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.3...@spectrum-web-components/action-button@0.10.4) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.2...@spectrum-web-components/action-button@0.10.3) (2022-10-10) + +### Bug Fixes + +- **action-button:** add support for XS t-shirt size ([75440ce](https://github.com/adobe/spectrum-web-components/commit/75440ced6f5cc5dbcd2c3bbfe650ca8c78514467)) + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.1...@spectrum-web-components/action-button@0.10.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.10.0...@spectrum-web-components/action-button@0.10.1) (2022-08-24) + +### Bug Fixes + +- prevent longpress when interacting with context menu ([f8b0732](https://github.com/adobe/spectrum-web-components/commit/f8b07321741ee44515fced9923167b96561cdd48)) + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.9.1...@spectrum-web-components/action-button@0.10.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.9.0...@spectrum-web-components/action-button@0.9.1) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.7...@spectrum-web-components/action-button@0.9.0) (2022-07-18) + +### Features + +- support Spectrum Token consumption and update Action Button to use them ([743ab16](https://github.com/adobe/spectrum-web-components/commit/743ab16d8f05335d320440effbdcb8cd4bffc97d)) + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.6...@spectrum-web-components/action-button@0.8.7) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.5...@spectrum-web-components/action-button@0.8.6) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.4...@spectrum-web-components/action-button@0.8.5) (2022-05-27) + +### Bug Fixes + +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.3...@spectrum-web-components/action-button@0.8.4) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.2...@spectrum-web-components/action-button@0.8.3) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.1...@spectrum-web-components/action-button@0.8.2) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.8.0...@spectrum-web-components/action-button@0.8.1) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.7.4...@spectrum-web-components/action-button@0.8.0) (2022-03-04) + +### Features + +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) +- support static white and static black variants of Action Button ([7f1e25b](https://github.com/adobe/spectrum-web-components/commit/7f1e25bce122bd3601c6aa5ed505cba436e8b952)) + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.7.3...@spectrum-web-components/action-button@0.7.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.7.2...@spectrum-web-components/action-button@0.7.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.7.1...@spectrum-web-components/action-button@0.7.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.7.0...@spectrum-web-components/action-button@0.7.1) (2021-12-13) + +### Bug Fixes + +- add t-shirt sizing to Thumbnail and support for "xxs"/"xs" sizes ([520a642](https://github.com/adobe/spectrum-web-components/commit/520a642b33e2ca5a4fdc67c15ace029d33e895ff)) +- **action-button:** all "selected" Action Buttons should be "aria-pressed=true" ([d85e235](https://github.com/adobe/spectrum-web-components/commit/d85e23552aa8f15dfdf069b7cba8fa7b8909190a)) + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.6.1...@spectrum-web-components/action-button@0.7.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.6.0...@spectrum-web-components/action-button@0.6.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.9...@spectrum-web-components/action-button@0.6.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.5.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.8...@spectrum-web-components/action-button@0.5.9) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.7...@spectrum-web-components/action-button@0.5.8) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.6...@spectrum-web-components/action-button@0.5.7) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.5...@spectrum-web-components/action-button@0.5.6) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.4...@spectrum-web-components/action-button@0.5.5) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.3...@spectrum-web-components/action-button@0.5.4) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.2...@spectrum-web-components/action-button@0.5.3) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.1...@spectrum-web-components/action-button@0.5.2) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.5.0...@spectrum-web-components/action-button@0.5.1) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.7...@spectrum-web-components/action-button@0.5.0) (2021-05-24) + +### Bug Fixes + +- **action-button:** ensure disabled buttons are not interactable ([b81c3ba](https://github.com/adobe/spectrum-web-components/commit/b81c3ba7961234ebfe83caec3e2b43d0d885cfbb)) + +### Features + +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.6...@spectrum-web-components/action-button@0.4.7) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.5...@spectrum-web-components/action-button@0.4.6) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.4...@spectrum-web-components/action-button@0.4.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.3...@spectrum-web-components/action-button@0.4.4) (2021-03-29) + +### Bug Fixes + +- **action-button:** expand Spectrum CSS processing ([ff1a424](https://github.com/adobe/spectrum-web-components/commit/ff1a4243c00b3774a6afa5e535c414f252dc87dd)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.2...@spectrum-web-components/action-button@0.4.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.1...@spectrum-web-components/action-button@0.4.2) (2021-03-22) + +### Bug Fixes + +- correctly delivery visuals and mouse interactions for litAnchor and extensions ([0ae889a](https://github.com/adobe/spectrum-web-components/commit/0ae889a8aab9b3417a021b917dfc817a8310f50f)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.4.0...@spectrum-web-components/action-button@0.4.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.3.0...@spectrum-web-components/action-button@0.4.0) (2021-03-04) + +### Bug Fixes + +- support a wider number of sizes ([ee44978](https://github.com/adobe/spectrum-web-components/commit/ee4497830da0d3bc63d4414ad5548291a39588c7)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.2.2...@spectrum-web-components/action-button@0.3.0) (2021-02-11) + +### Bug Fixes + +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- allow activation of longpress content ([55e71fd](https://github.com/adobe/spectrum-web-components/commit/55e71fdf9fd5dde489871c3d9798ef8957f4e5b6)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.2.1...@spectrum-web-components/action-button@0.2.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/action-button@0.2.0...@spectrum-web-components/action-button@0.2.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/action-button + +# 0.2.0 (2021-01-21) + +### Bug Fixes + +- correct specificity of webkit appearance work around ([f0d06bf](https://github.com/adobe/spectrum-web-components/commit/f0d06bf17bbf1d7d2a41a3008373a4b0f4097cf9)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +# 0.1.0 (2021-01-13) + +### Bug Fixes + +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) diff --git a/1st-gen/packages/action-button/README.md b/1st-gen/packages/action-button/README.md new file mode 100644 index 00000000000..ad9336e35a8 --- /dev/null +++ b/1st-gen/packages/action-button/README.md @@ -0,0 +1,740 @@ +## Overview + +An `` represents an action a user can take. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/action-button?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/action-button) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/action-button?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/action-button) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-alf1ticu) + +```bash +yarn add @spectrum-web-components/action-button +``` + +Import the side effectful registration of `` via: + +```ts +import '@spectrum-web-components/action-button/sp-action-button.js'; +``` + +When looking to leverage the `ActionButton` base class as a type and/or for extension purposes, do so via: + +```ts +import { ActionButton } from '@spectrum-web-components/action-button'; +``` + +### Anatomy + +```html +Try me +``` + +#### Content + +`` elements can be provided a visible label, +a label and an icon, or just an icon. + +An icon is provided by placing an icon element in the `icon` slot. + +If the button is `icon-only`, a non-visible label +can be provided via the `label` attribute on an `` +or on an `` element child to appropriately +fulfill the accessibility contract of the button. + + +Label only + + +```html demo +Label only +``` + + +Icon + label + + +```html demo + + + Icon + Label + +``` + + +SVG Icon + label + + +```html demo + + + SVG Icon + Label + +``` + + +Icon only + + +```html demo + + + +``` + + + + +### Options + +#### Sizes + + +Extra Small + + +```html demo + + Edit + + + Edit + + + + + + + + +``` + + +Small + + +```html demo + + Edit + + + Edit + + + + + + + + +``` + + +Medium + + +```html demo + + Edit + + + Edit + + + + + + + + +``` + + +Large + + +```html demo + + Edit + + + Edit + + + + + + + + +``` + + +Extra Large + + +```html demo + + Edit + + + Edit + + + + + + + + +``` + + + + +#### Variants + +The `` can be customized with either or both of the `emphasized` and `quiet` attributes. These will pair with either or both of the state attributes (`selected` and `disabled`) to decide the final visual delivery of the ``. Content addressed to the `icon` slot can also be provided and will be positioned just before the rest of the the supplied button content. + + +Default + + +```html demo +
+
+ Default + + Edit + + + Edit + + + + + + + + +
+ +
+ Selected + + Edit + + + Edit + + + + + + + + +
+ +
+ Disabled + + Edit + + + Edit + + + + + + + + +
+ +
+ + Disabled + Selected + + + Edit + + + Edit + + + + + + + + +
+
+``` + +
+Quiet + + +```html demo +
+
+ Default + + Edit + + + Edit + + + + + + + + +
+ +
+ Selected + + Edit + + + Edit + + + + + + + + +
+ +
+ Disabled + + Edit + + + Edit + + + + + + + + +
+ +
+ + Disabled + Selected + + + Edit + + + Edit + + + + + + + + +
+
+``` + +
+Emphasized + + +```html demo +
+
+ Default + + Edit + + + Edit + + + + + + + + +
+ +
+ Selected + + Edit + + + Edit + + + + + + + + +
+ +
+ Disabled + + Edit + + + Edit + + + + + + + + +
+ +
+ + Disabled + Selected + + + + Edit + + + + Edit + + + + + + + + +
+
+``` + +
+Emphasized + quiet + + +```html demo +
+
+ Default + + Edit + + + Edit + + + + + + + + +
+ +
+ Selected + + Edit + + + Edit + + + + + + + + +
+ +
+ Disabled + + Edit + + + Edit + + + + + + + + +
+ +
+ + Disabled + Selected + + + + Edit + + + + Edit + + + + + + + + +
+
+``` + +
+
+ +### Behaviors + +#### Action button with hold affordance + +The use of the `hold-affordance` attribute signifies that the `` in question will be delivered with a visual affordance outlining that special interaction with the button will dispatch a `longpress` event. Via a pointer input, this even will be dispatched when 300ms has passed after a `pointerdown` event without the presence of a `pointerup` or `pointercancel` event. Via the keyboard, an event with a code of `Space` or or `ArrowDown` while `altKey === true` will dispatch the event. + +```html demo +
+ + + + + +

+ This content is triggered by the "longpress" interaction. +

+
+
+ + + + Show Longpress Content + + +

+ This content is triggered by the "longpress" interaction. +

+
+
+ + + + + Extended Content with Longpress + + +

+ This content is triggered by the "longpress" interaction. +

+
+
+
+``` + +#### Toggles + +With the application of the `toggles` attribute, the button will self manage its `selected` property on `click`. When this value is updated, a cancellable `change` event will be dispatched to inform the parent application. + + +Default + + +```html demo +Toggle button + + Toggle button + +``` + + +Quiet + + +```html demo + + Toggle button + + + Toggle button + +``` + + +Emphasized + + +```html demo + + Toggle button + + + Toggle button + +``` + + +Emphasized + Quiet + + +```html demo + + Toggle button + + + Toggle button + +``` + + + + +#### Handling events + +Events handlers for clicks and other user actions can be registered on a +`` as on a standard HTML ` + + +`; +fullyCustom.decorators = [withOverlayDecorator]; + +export const lazyLoaded = (): TemplateResult => { + const template = (): TemplateResult => html` + { + if ((event.target as HTMLElement).localName === 'sp-button') { + (event.target as HTMLElement).dispatchEvent( + new Event('close', { bubbles: true, composed: true }) + ); + } + }} + > + +

This is a heading

+

+ The click on the "OK" button should close the overlay with + the correct animation (duration). +

+ + Ok + +
+
+ `; + + return html` + + Open dialog + + `; +}; + +lazyLoaded.swc_vrt = { + skip: true, +}; diff --git a/1st-gen/packages/dialog/stories/dialog-wrapper.stories.ts b/1st-gen/packages/dialog/stories/dialog-wrapper.stories.ts new file mode 100644 index 00000000000..10c1a2f0cfc --- /dev/null +++ b/1st-gen/packages/dialog/stories/dialog-wrapper.stories.ts @@ -0,0 +1,681 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/help-text/sp-help-text.js'; +import '@spectrum-web-components/textfield/sp-textfield.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; + +import '@spectrum-web-components/dialog/sp-dialog-wrapper.js'; +import { landscape } from './images.js'; +import { isOverlayOpen } from '../../overlay/stories/index.js'; +import '../../overlay/stories/index.js'; +import type { DialogWrapper } from '@spectrum-web-components/dialog'; + +export default { + title: 'Dialog Wrapper', + component: 'sp-dialog-wrapper', + argTypes: { + onClose: { action: 'close' }, + onConfirm: { action: 'confirm' }, + onSecondary: { action: 'secondary' }, + onCancel: { action: 'cancel' }, + }, +}; + +type StoryArgs = { + onClose?: (event: Event) => void; + onConfirm?: (event: Event) => void; + onSecondary?: (event: Event) => void; + onCancel?: (event: Event) => void; +}; + +const handleClose = + ({ onClose }: StoryArgs) => + (event: Event) => { + if (onClose) onClose(event); + }; + +const handleConfirm = + ({ onConfirm }: StoryArgs) => + (event: Event) => { + if (onConfirm) onConfirm(event); + }; + +const handleSecondary = + ({ onSecondary }: StoryArgs) => + (event: Event) => { + if (onSecondary) onSecondary(event); + }; + +const handleCancel = + ({ onCancel }: StoryArgs) => + (event: Event) => { + if (onCancel) onCancel(event); + }; + +export const wrapperLabeledHero = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + + Content of the dialog + + + Toggle Dialog + + `; +}; + +export const wrapperDismissable = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + + Toggle Dialog + + `; +}; + +export const wrapperDismissableUnderlay = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + + Toggle Dialog + + `; +}; + +export const form = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? undefined : 'click'; + return html` + + + Toggle Dialog + + { + target.dispatchEvent( + new Event('close', { bubbles: true, composed: true }) + ); + handleConfirm(args); + }} + @secondary=${({ target }: Event & { target: HTMLElement }) => { + target.dispatchEvent( + new Event('close', { bubbles: true, composed: true }) + ); + handleSecondary(args); + }} + @cancel=${({ target }: Event & { target: HTMLElement }) => { + target.dispatchEvent( + new Event('close', { bubbles: true, composed: true }) + ); + handleCancel(args); + }} + > + +
+ + Street: + + + + City: + + + + State: + + + + Zip: + + + + Special instructions: + + + + For example, gate code or other information to help + the driver find you + + +
+
+
+ `; +}; + +form.decorators = [isOverlayOpen]; + +export const longContent = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? undefined : 'click'; + return html` + + + Toggle Dialog + + +

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Sed ac dolor sit amet purus malesuada congue. Donec quis + nibh at felis congue commodo. Ut enim ad minima veniam, quis + nostrum exercitationem ullam corporis suscipit laboriosam, + nisi ut aliquid ex ea commodi consequatur? Sed ac dolor sit + amet purus malesuada congue. Nam libero tempore, cum soluta + nobis est eligendi optio cumque nihil impedit quo minus id + quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Nullam sit amet + magna in magna gravida vehicula. Itaque earum rerum hic + tenetur a sapiente delectus, ut aut reiciendis voluptatibus + maiores alias consequatur aut perferendis doloribus + asperiores repellat. Neque porro quisquam est, qui dolorem + ipsum quia dolor sit amet, consectetur, adipisci velit, sed + quia non numquam eius modi tempora incidunt ut labore et + dolore magnam aliquam quaerat voluptatem. Phasellus faucibus + molestie nisl. Vestibulum fermentum tortor id mi. Integer + rutrum, orci vestibulum ullamcorper ultricies, lacus quam + ultricies odio, vitae placerat pede sem sit amet enim. + Maecenas sollicitudin. Nullam rhoncus aliquam metus. +

+

+ Curabitur ligula sapien, pulvinar a vestibulum quis, + facilisis vel sapien. Fusce nibh. Proin pede metus, + vulputate nec, fermentum fringilla, vehicula vitae, justo. + Aenean placerat. Aliquam erat volutpat. Et harum quidem + rerum facilis est et expedita distinctio. Fusce nibh. + Temporibus autem quibusdam et aut officiis debitis aut rerum + necessitatibus saepe eveniet ut et voluptates repudiandae + sint et molestiae non recusandae. Vestibulum erat nulla, + ullamcorper nec, rutrum non, nonummy ac, erat. Etiam posuere + lacus quis dolor. Mauris elementum mauris vitae tortor. + Nulla turpis magna, cursus sit amet, suscipit a, interdum + id, felis. Nam libero tempore, cum soluta nobis est eligendi + optio cumque nihil impedit quo minus id quod maxime placeat + facere possimus, omnis voluptas assumenda est, omnis dolor + repellendus. Nulla accumsan, elit sit amet varius semper, + nulla mauris mollis quam, tempor suscipit diam nulla vel + leo. Pellentesque sapien. +

+

+ Curabitur vitae diam non enim vestibulum interdum. Sed elit + dui, pellentesque a, faucibus vel, interdum nec, diam. + Praesent vitae arcu tempor neque lacinia pretium. Ut tempus + purus at lorem. Phasellus rhoncus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus + saepe eveniet ut et voluptates repudiandae sint et molestiae + non recusandae. Duis ante orci, molestie vitae vehicula + venenatis, tincidunt ac pede. Integer vulputate sem a nibh + rutrum consequat. Aenean placerat. Cum sociis natoque + penatibus et magnis dis parturient montes, nascetur + ridiculus mus. Sed vel lectus. Donec odio tempus molestie, + porttitor ut, iaculis quis, sem. Class aptent taciti + sociosqu ad litora torquent per conubia nostra, per inceptos + hymenaeos. Integer in sapien. Nullam dapibus fermentum + ipsum. +

+

+ Integer vulputate sem a nibh rutrum consequat. Class aptent + taciti sociosqu ad litora torquent per conubia nostra, per + inceptos hymenaeos. Duis bibendum, lectus ut viverra + rhoncus, dolor nunc faucibus libero, eget facilisis enim + ipsum id lacus. Aliquam erat volutpat. Aenean id metus id + velit ullamcorper pulvinar. Morbi scelerisque luctus velit. + Aliquam erat volutpat. Temporibus autem quibusdam et aut + officiis debitis aut rerum necessitatibus saepe eveniet ut + et voluptates repudiandae sint et molestiae non recusandae. + Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, + orci. Suspendisse sagittis ultrices augue. Nullam justo + enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. + Praesent vitae arcu tempor neque lacinia pretium. Nullam + faucibus mi quis velit. Maecenas aliquet accumsan leo. Morbi + scelerisque luctus velit. Aliquam ornare wisi eu metus. +

+

+ Sed elit dui, pellentesque a, faucibus vel, interdum nec, + diam. Praesent vitae arcu tempor neque lacinia pretium. + Etiam dictum tincidunt diam. Et harum quidem rerum facilis + est et expedita distinctio. Duis ante orci, molestie vitae + vehicula venenatis, tincidunt ac pede. Integer lacinia. + Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + Mauris tincidunt sem sed arcu. Praesent in mauris eu tortor + porttitor accumsan. Aenean id metus id velit ullamcorper + pulvinar. Donec iaculis gravida nulla. Duis bibendum, lectus + ut viverra rhoncus, dolor nunc faucibus libero, eget + facilisis enim ipsum id lacus. Nulla quis diam. Quisque + porta. Integer rutrum, orci vestibulum ullamcorper + ultricies, lacus quam ultricies odio, vitae placerat pede + sem sit amet enim. Nam sed tellus id magna elementum + tincidunt. In enim a arcu imperdiet malesuada. +

+
+
+ `; +}; + +longContent.decorators = [isOverlayOpen]; + +export const longHeading = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? undefined : 'click'; + return html` + + + Content of the dialog + + + Toggle Dialog + + + `; +}; + +longHeading.decorators = [isOverlayOpen]; + +export const wrapperDismissableUnderlayError = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` +
+ + Content of the dialog + + + Toggle Dialog + +
+ `; +}; + +export const wrapperButtons = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const wrapperButtonsUnderlay = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const wrapperFullscreen = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const wrapperWithHeadline = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const wrapperWithHeadlineNoDivider = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const wrapperHeadlineVisibilityNone = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? false : true; + return html` + + Content of the dialog + + `; +}; + +export const tooltips = ( + args: StoryArgs = {}, + context: { viewMode?: string } = {} +): TemplateResult => { + const open = context.viewMode === 'docs' ? undefined : 'click'; + return html` + + + Toggle Dialog + + + ${[1, 2, 3, 4].map( + (index) => html` + + + Button with Tooltip ${index} + + + Tooltip ${index} + + + ` + )} + + + `; +}; + +tooltips.decorators = [isOverlayOpen]; + +export const lazyHero = ({ src }: { src: string }): TemplateResult => { + const handleOpened = (): void => { + (document.querySelector('sp-dialog-wrapper') as DialogWrapper).hero = + src; + }; + return html` + + Toggle Dialog + +

Content of the dialog

+
    +
  1. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  2. +
  3. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  4. +
  5. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  6. +
  7. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  8. +
  9. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  10. +
  11. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  12. +
  13. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  14. +
  15. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  16. +
  17. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  18. +
  19. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  20. +
  21. + Select the following checkbox to have the dialog close + when clicking one of its buttons. +
  22. +
+
+
+ `; +}; + +lazyHero.args = { + src: 'https://dummyimage.com/800x400/000/fff', +}; + +lazyHero.swc_vrt = { + skip: true, +}; + +lazyHero.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; diff --git a/1st-gen/packages/dialog/stories/dialog.stories.ts b/1st-gen/packages/dialog/stories/dialog.stories.ts new file mode 100644 index 00000000000..7c53c685e04 --- /dev/null +++ b/1st-gen/packages/dialog/stories/dialog.stories.ts @@ -0,0 +1,536 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/dialog/sp-dialog.js'; +import { landscape } from './images.js'; +import '@spectrum-web-components/button/sp-button.js'; + +export default { + title: 'Dialog', + component: 'sp-dialog', +}; + +export const small = (): TemplateResult => { + return html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const medium = (): TemplateResult => { + return html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const large = (): TemplateResult => { + return html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const dismissable = (): TemplateResult => { + return html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const noDivider = (): TemplateResult => { + return html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const hero = (): TemplateResult => { + return html` + +
+

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Auctor + augue mauris augue neque gravida. Libero volutpat sed ornare arcu. + Quisque egestas diam in arcu cursus euismod quis viverra. Posuere ac + ut consequat semper viverra nam libero justo laoreet. Enim ut tellus + elementum sagittis vitae et leo duis ut. Neque laoreet suspendisse + interdum consectetur libero id faucibus nisl. Diam volutpat commodo + sed egestas egestas. Dolor magna eget est lorem ipsum dolor. Vitae + suscipit tellus mauris a diam maecenas sed. Turpis in eu mi bibendum + neque egestas congue. Rhoncus est pellentesque elit ullamcorper + dignissim cras lobortis. +
+ `; +}; + +export const alertConfirmation = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+ Smart filters are nondestructive and will preserve your original + images. + + Cancel + + Enable +
+ `; +}; + +export const alertInformation = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+ Smart filters are nondestructive and will preserve your original + images. + + Cancel + + + Enable + +
+ `; +}; + +export const alertDestructive = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+ Smart filters are nondestructive and will preserve your original + images. + + Cancel + + Enable +
+ `; +}; + +export const alertError = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+ Smart filters are nondestructive and will preserve your original + images. + + Cancel + + + Enable + +
+ `; +}; + +export const alertErrorWithLongTitle = (): TemplateResult => { + return html` + +

Unable to Share Project to Behance Community

+ Smart filters are nondestructive and will preserve your original + images. + + Cancel + + + Enable + +
+ `; +}; + +export const fullscreen = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+
+ Anything in the footer is sticky and aligned right. +
+ + Cancel + + Enable +
+ `; +}; + +export const fullscreenTakeover = (): TemplateResult => { + return html` + +

Enable Smart Filters?

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, + sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae + vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia + voluptas sit aspernatur aut odit aut fugit, sed quia + consequuntur magni dolores eos qui ratione voluptatem sequi + nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius + modi tempora incidunt ut labore et dolore magnam aliquam quaerat + voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut + aliquid ex ea commodi consequatur? Quis autem vel eum iure + reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo + voluptas nulla pariatur? +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate + non provident, similique sunt in culpa qui officia deserunt + mollitia animi, id est laborum et dolorum fuga. Et harum quidem + rerum facilis est et expedita distinctio. Nam libero tempore, + cum soluta nobis est eligendi optio cumque nihil impedit quo + minus id quod maxime placeat facere possimus, omnis voluptas + assumenda est, omnis dolor repellendus. Temporibus autem + quibusdam et aut officiis debitis aut rerum necessitatibus saepe + eveniet ut et voluptates repudiandae sint et molestiae non + recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut + perferendis doloribus asperiores repellat. +

+
+ Anything in the footer is sticky and aligned right. +
+ + Cancel + + Enable +
+ `; +}; + +export const forcedScrolling = (): TemplateResult => html` + +
+ +

Disclaimer

+
+ The contents of this dialog is specifically prepared to force + scrolling, allowing us to test whether the scroll bar is + appopriately activated in this context. + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Auctor augue mauris augue neque gravida. Libero + volutpat sed ornare arcu. Quisque egestas diam in arcu + cursus euismod quis viverra. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Auctor augue mauris augue neque gravida. Libero + volutpat sed ornare arcu. Quisque egestas diam in arcu + cursus euismod quis viverra. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Auctor augue mauris augue neque gravida. Libero + volutpat sed ornare arcu. Quisque egestas diam in arcu + cursus euismod quis viverra. + +
+ Footer button +
+
+`; diff --git a/1st-gen/packages/dialog/stories/images.ts b/1st-gen/packages/dialog/stories/images.ts new file mode 100644 index 00000000000..24b7184a37e --- /dev/null +++ b/1st-gen/packages/dialog/stories/images.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const landscape = + 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCADAAhQDASIAAhEBAxEB/8QAHQAAAgMAAwEBAAAAAAAAAAAABAUDBgcAAggBCf/EAEIQAAIBAwMCBAQDBQYFBAIDAAECAwAEEQUSIQYxBxNBUSJhcZEUMoEIFSNCoRYzUrHB8BckctHhNFNikkPxGIKi/8QAHAEAAgMBAQEBAAAAAAAAAAAAAgQBAwUABgcI/8QALREAAgIBBAICAgEDBAMAAAAAAAECEQMEEiExE0EFUSJhFBUycSNCUoEGJJH/2gAMAwEAAhEDEQA/ANShuJbn4ssxPvTO0hcMCck571DpmmsFAJwfarBZ2WwrmvytOab4DVsZaTO8A74qyWl5nuaQxxKAKLSTyQNvf2rV0+rngXD4GYquB69wzdmwKjC7zk80uiujIwGaaQRkqMH60/j1EtVLgnoZW4wvwijoZ/LwDxSqF2jOB2Fdb2/EcZYdxXpsep8OPc/QJZFugEJzxXIbw471UIdcaUjJwKMTUwDgNnNXx+WjPmL4Oot0Go7PWjYrwFQwP2qjfvMZ4ep4dcKgDdWhp/mIXUmDRoFrqOwHBNS/vRufi/rVJt9Z3nIajk1EuBg4rdhrsc1wwUiyNqZIOWoZ9WVVbP3pHNekIeaVT6gNrAvSefX7P7Q0uC0proU/mH0o611kPzn7VnRvhuGG70xtL0xrndSmn+UlOVMhpF9TWWGcGirfWyTyaoS6t8Jy2D867Ra35X5myK1l8hD7Bo0ePVNwHNfTfZB+KqFH1RGucMa+nqbcpwcUT+Sw/wDI6mXR7tdxO6uW94M9+RVJTXtwxu+9FwayBxuzUw1cJ8pk0y7RXgY8n7V2N2qt8qq0GtLs713/AHqrg/Fz9adjmTXYJZRfISc18e9RRwcmqddasVU+W/xfKk79VXcLEE8fPmr4OWTiJDaXZoZ1QR5JYAfOhb/qmO3hJTDnHoazq76qupFOZBikk+uO2Sz5z7mnMWlyy7YvPUQiWTWepprxm/iOF9t1Vue63ElmLE+9ASaj5xPxE1F5gbJJOPnWri0ygjOyZ3N0MY593BBI+VdZRt+JeflUVnc7M4AHzqHUeobGyYJcSoHPZc81a0osrpyQbFMSPi7V1E6lyKQXXVVs4VIGDM35R70ZY75lDk4PfBokr5KpWhwJBtOOK7JIAaEBIyQT7EGvozjjviooFSoJkIZTjvUaPlBn3qOafHbucCvqjAFSnwQ5chK42n2qPdtPHauoYleDXHA2Yz6VXYadolM4dcUOZDu5OKWy3rWkoZ8CMnuT3+dGWV/bXx+BwT/nXcIsVy7J2u0QYLivkV5G7Y3g49KlktoyD8OfnQUkSRkkLxViUZEu0NYrvb+U4pna6mo/vWBH0qri4VF718F/Gez/AKCk82jhlVSRfDPKJfIdTtXX4nA+VdoNYtPN2KdxzgAD1qhyaiiJ+f8ATNH6VIZmDR5c/wBKws3x0cS3QHsefc6ZoyOksAx3r4AE+lLLS6eNQCmD71O1+Np7UmpxXY2FvIMHHaoGXjOaDa+DZxXEvRjBxUb4M6mTSA7T/nQzEkEDkVL+ID8ZrpkEnGcUhnjFrgJcA6hlxz+tThsjNd/KUrivmwDj0rHeNwCs6FQecUXEFZMe1RFfhzXxXI+VOYfwd0C0T7FAPFAagcowokzZWgbrLg5pzPtljpEJclZ1OEAE4zSKOYxyEY4q06i6bGA71W3jyx4r5zrdJsy7ol8Wcabd2HFCTS8GizEAvehZIwd3vSjwzkc3wAGTk8etcr60I3GuVT4ZlIstLUIgz3o+0jLPjtUEVwhAA71OtyiEmvPvHXIMaQe6qnrQksmGOD2oWXUVU/moS51SNASGq2lJUdKa9DK2vH83ANWa0ud8SEnn1rOrXV1WUktinVpr2wZDZFafx0PC7ZUsv2XU3AA5NLNSvUCOMgcdqR3PU6qh55qp6z1STkb+9ehzZN0NqQXkS6LKmqJCTlhj61Pb6wXJ2txWXTa7K2SGzUtj1K8eBn71krDKKoW8rRqZ1MjBzXUa8iN+cHHeqFJ1V/DxnBx6Gkdx1IUZiGxn50UYTT/E7zSZsdn1FGWyX4+VNE6mRF+GTj2NYHB1TIqk7zn2zRUXWMpXDGtTE80FwyxZn7Ntn61j2sCTx6ikF51lG7EK2P1rKrrq1ihUMcUpXXnMpYuTn51OSWTIqkwXmfo23TuoxMeHBOe2asFvqYZfzE1h2k695cud9XbS+o0ZMFhU4oyiTDI/ZoH49e+7AoK+11IkKhgTmqrc9RomQDSK71kyPkMe9NvfTRa5ui3ydRsGPxVJB1Pnu31FUf8AHGU5AoW4vnXIB+1LLE4O7KvJI1KLqRBg+Z/WjYer4ewkG761iT6rODy5ro2qTIwbcwPvmm4ZJrpk+Vm8L1Sg/wDyUysdcM5AVwQfnWAQ69LnLOSfmaf9PdYtbX8IYeZlgMc/6Uziz5IyV9HLL9m73F/5MIdpAvt86rOrdQpg7toz/M2BXfWZiywyu2IymcfOqtfWsRc3lwScflBHb6D3NfV9DhxvGpimXK9ziFtqDXOdp+H3qMr5xx3X3zQVrK11IVAwi/m57V9up3GVjbavof8AWtxVHoTa5D42SMlQwyPQeld42Z2zgY9TS+1jEUJ7/Mn/AH3o1WxEXP2zXWVVyDdQ63+6NKnmQDcqnGTjn3JrzW2qXk+sz3kuqBnZy2dhx357kVtniFE91oMwjUycgYHYnnv8h/3rzZ01YP1F1w4STzUtZNhLyNsJzzwKwNY3PPGKNvRxUcUpM9DeH0EupqtxcQK6DHxtgHPvtyfvWmKcIMY47VWNAsRp2mxxk7Nq/wAhJ/zppBLI4IVyy/8AyWtaKpJGNN7m2OIQZM9vrU8Q25VvvSaGWS3ctk8/0pms29A3oR29jXMp2+yS6jXgjk1yNsoAe/zqKWT4FPqOa+ROSCPY8fagZKSYQDwcc+grqxwMcH/WvoHbjtXQo2ck/SoC64Ata09b+ykR2fBHJizkfqKxfVeo77p/VpEWK7VVPdAT/wD5zmt0FyB8O/n5c1kfjP0jqFzYTalp1wEnj+IAKQfuKVzpuFx7Q9pZJTqXTNH6I6hPUGiJOTuYDBOCP86bTJuyQRz+lYj+z11zd6pLLpt+DHdKCCpOQcf1FbVPujkb/AeM+xq3TT3xTB1GPxzcQSaMlWCnB9qX+SRKSEIkHJX0Ye4pjKpIIHI9hQyXDF2jccjlW9cVoJiydEE4Xy87ih9GB7GoNM126sJnjclwp545x7/MVLqjhYid2xm9fQmobeMPCsxXEi/AfYg0EkmuS+EtqLro+vm4Jj3HGMjmiTqDknnNVDRrWSTUxIpxEq8n3/8ANWRYzISe1fNf/IMkcWRLH2aunbcLYxivD61Krl2yO1CRRgD3qeIHn2rzWLUzf4sdSGEA45NHwgY7UttQM801tm3YAGKfhmcnTBaOEb1IANDkOhIPIpokIAP+ddHiAyK0Y4XOPLBFwmPPFdWuAoOOKnmRY1ye/tS2eQHIFZ+Tfi4DSs4978R5oW5vtykZoedjzil43ST/AJvhFZM9bOP4olokwZWOe1QS2yLkYFH7lj4OB86HkKOx28/M1m58v32QhULRpJSoBouHRlOd2adW1siRhvlXd9uw8DitHRaOEY7pcgybKldaQUmYA8VymdzMolIyP1rlVyx4dzIRg83WCx8rIAPrQ8vXWOQ+76Vh7dYvMv5yBUJ6tZOA2f1rHfx25CG42m760eXH8TFLLnrTcceYWNZR/ax5PhLfavn783NkHPzqYaBJ8o5cmv2fUW9QQSPenNtrzMPz4FYdb9TPG2MnFWXTuqm2DgcepNPYtIlydRqN1rm2E85NVW+1N2clmPNJxrzXJ+I/ao7q43Ln1p7xxSOsapqmBtBqUXgUc8n3pBETjce9fZb/AGjHrj0oPEmCOp78oOG4NAT3+Rw2aVm5eQd6ieYAEE1bHHGKA6Gcd6xzzREN05yMZ+ZpPbtg9+9NYH+Dirtlom+DvJKxz6UK0rKDzRJy2c+1RfhjIjZ4ApOeO3SISslstSZHwTkVYoNaaOMYPNVSKJUzU6TnJB7elXwjwWRLhDrbSjLEmiUuTI3Haq3aMNvBpvaPkAE8Vc48Fq5G8c5AwDXx90h718hCgc0UoULnGaSmqKmgNrY98VDJD70zQAg5FQToASarhwAKpFKg4qK2OJwXlMaqc5Uc/pRcq5J9KhW153d8VepUgGbb0prKdR9PooGxYVARGbLYGR/pXTWv40YC9k7D/X/fvVE8N9TNhrflynCSIyDPqf8AYq76ypVJkQnDqNjfI85r6R8HrN+HbLtESW6pAenyqY9isFQfmapEBurgNysCn/7YpLps6F3UnMMZx3/M3oP9TTdbnzA7E4RV7j/KvVrJZTKFHaa58x9qj4BwAK+rP5pKE9uAF96HeQqECgB5OwHoPeitHtt9yCSBjtR3aKqoQ+LOqjpfw11O8ChrgxlYV93OQo++KzPwK6RuNN0uOWaJzK43M7kjJPerV4+3qX91oWgD4leT8RIvOML2zj54+1W3o7TooNNiiRcDaOTms2K8mdy+hxy8en2/8mMVkEI2kK7/ADamVnA0oDZ2/L0oiy0y3tMyMN7H1bn7Chb/AF6O2ZkGF9Mn0p667M/sapaB0Ib17E1EqNBvjPODx8xXLO9Se1jy4LEZ4NSPKJZgCfi9xQ3Z1UCpICEjPflc/XP/AGoqEDY5/wAIPPzpdORbXeCQASWGfSjreUCJ29z2+f8As1DOQVbyiZN47HipWRHBU0ot7wQYjOcLwB70vv8AqiC1uR/G5yFwOcn2HzquUorthxi30h5NbtANyIW+gpZqtoup6fLDKoyy8bsGmunaktxGCzAMf5TwftRFz5flFtozQ1fJK4PM1vat4eeJtlekmK3uZPJdmwqkk/DgYHrx+tekr1leESL2YA/LmsB8culIdXLyxFEnQ7g2du3HY9+DWxeHesDqToTTLt2WSRoQkhU5G4cEffNL6d7ZygP5v9TFHJ76YRJISuVO1lPIPp8q6T4ciQYHYZ9j/wBq5dR+WXPOV5BHr7ig1ukKlskr2YD2PrWjuM9ROuthZrJmxgj4WU/OoNBn87TlBJbb8JJ78H/ea+ahODA0TH4iMf8AUD2NQaTBJAyRKcyGTP1zQymopsuUbjRc9AtTFaPIeNxz+naiFn8tyPTNdbiZbK1SLPAAFJ21Vd3fI+tfFvnNV5tU69GziShBJllt5RIfbFMIl9u1VSHV0X8rDPrzTe01MOneszTZUnUmXpjiN9jZPamNvexqO9V5b0MucjFdPx6YPxdqeeojDmIXDLeLwMOGqN53IOM4pFZ3+VOTkUdFqSqMZ+9buDPvjbdANUd55HZTk0tYnmj5bpSpIGTQMrhsk8VTnakyU+AGd8AjuaFYbIyRwTXa8kWPJzzS83vBBPFeT1M4RbVnK2TG4LghjgivsdysYOWH3oGS4TB5yaW3V+oO1WGffNeZy5Zwe7thFot9bjcmMtg+lFCcMpyeKoX4+FvzNhx61Hc9ULZIymft8629H8nOEP8AUVlbos186Cc/HjiuVmN51k8lwxDnFcpGetm5NqIO5HizY3OCwxXEguGORkj2NWoaQpVhjmusdkIl/LXtN8ekLuKEMUEy4JQii4dxp7HYmSPBTvXDo7RnIHFBaqyvaLIbcnk88050yORyABxXeCxYDAX+lWLRdMwvxD7VCdkPgksbD4M8k0TNbtGuQpwKb29usS4AArrcL8DZFSyplf8AxRTIxigZrgtnmidQcICRSnzCxx3NVWwNwSLlgpyOa5ExmJBBr5BCznBFN7e0QLyMH3qYXIHdYPEhX9KOtpscGoJYio78e9Q+aUOKaXRy5G6uGHJqdnBjAXkCq+dQO7B4phZXgIwap92WrhhAXIIPeueXgD2qTerngVwfGwHoKtXAYZa9sU3sht780BZQqOSaZxTRxZwKsQadDK3kDcCj4vX1BpNBIoJOcZpik42cGqMiSQLGMZQIQf60vu5Ai8VE1xhuDQ8s27POaznJLgC6PpYFDk813hXjGeK5b2/ncntTCCFE4PFMYouRX2Q2+63lEqHa6g4I960Oy1B9a6ZaYY/EQ/w2x3x71RZFXado4p10bqpsLqWJj/ClAyD24rc0GZ6fKn6LYccM6QMYpvL42xj19z3P+/nTO2vI1t0DEsCdx/8AlQ/U2lm2kMkJ/gTDcDj09qg02NZUy+do5/T2H1r6Hgy71wHOKoaQ+ZcytM2AcbQB2A9hVg0qPa5JH8p5pbYQhIuDlm4HypqJBaWzyE4REJJ/39K026iIP6MG8QdXS+8V9soykKCNcjIzk/8Aitd6VuYo7IOwUKi5J9BXnXqeeS/6xlulOWdwc1rPTsN9e9PSqJRE5QgFe4ODzisHSaiTnPi+TV1OnShBX6EvjL+0foXhjJHHqEtze30wzDpemoHnkGfzMScIvbv7j3Gcbtv2v7HXdVjt5tD1TpppmVLe61AI8LFuFVyhwMn1OB86yn9pHpbVOmtTmvmZ7p7x0P4mfJZWjLELnIwPizj5D2rCfx1/bWM0+rqkoeCOGCINzIQuxcAc+mffP1pt5XJNTu/QKwLG1tpr2fqr4cdTy31kjTH1xsJzgn0rS7Cc3CFhg8nk/wBP6f5V5z8ILy6v9L01mziUBXLH24J/XHf616J0y1Nuo/mBHA9+9X4E1aYjqoqMuDtf/wB2xKDcpBz7VywTfJtcnap9O2aJutkkI55YDH3zXy0BduFAOTn+v/ina4EUJNUlFvJMznaAcfKvJ/jj4t6l0FrlmNEsBqurXG8QxTS7IoEAZmkdj6YXt67flXrfrLTXksmWIbpXICjsCc8g1+e/7WsGoaN1bZX7RTRaaVlsri8WLcI9wUDn053g/wDmkMkFe6StI1NL/a9vY+6I/bS8QIUlutS6f0jWdKtmUXR0qR454VJ/MCSVb5ZHNe0/DHxV0fxF6et73TbkTJMgfB4ZcjOGGeDX5L9DaXe32sW+l6dIt+8spCpDHvMxOB2OQQAM5xx3r9LvAHwuj6N0i2ZT5UoiCyAZwzbRk/0oFklJrYuP2XTwwUG5vn1QF48agtvYvGWOWyBxkU//AGZ71l6NksHcsY5WZdx9Ccn/ADqieM1lNJrjxO/mJG3AxwKtPgdJ+7r6KHOFmVlHpzgH/SsvFlf8x3/gYlBLRUv8mvXsPmo204I5U/Oq/d4QSOq7fQj2Oex+9WVyFOw4/wB5pLrEIEcjg9xzj1r0D64MaBWLuc3EYQE7oHyo9cfzD/f+lW/pqz89jeSLwvC/M1WNJ0WbUb6OJfiO7lvYZ/39q1RdLW0skiVdu1e1ed1+sljg4x7NGEE3ZWNelKozKTVKm1CQysudoHrV91e2LxsoFU270hhIxIr5Lqa3tssyWC2886SFt+V+tWHStaypVjtI9KrwtnTK8gV2BMIOM4pKLV2Uxk4l1g1BJFIDZqRLtcEZBqlW2riBjucD61OvUaA4yB86fhCxiOZsvMV22PhPFMLSYuTuPaqPZ9RqvAIYe1NrTqSL+YgH5VqwyRgqkw1NMuAY4OOKHnuAo5Iqvt1XEON9AXnUcLA4k3HtxSOfXcOMEEq9sM1K93FsN9KTNqJydzfpSO/6g2Mx3ZJ7Uhm6hLuTkZrz04yyO2VPJ9FvuL07Sc0DM7Pzu+1Vk9Qs/wADGjE1mPysbgfrXLSJ8gbmwyeUopG6q1rEh3ls+lHS6msjd6Q63cq4IBq+Gl5CQJJejd+YmuUmebDH1rlN+BBcFWFtEqnGM1JFpsbp2H2pKdSPOaIstacNtGCPnWooSsX5H0ekx7R8OAKnawjjiPwih01RinAFSxXm5fiIxVqjwSBtDhuB2o61ulhzQN7cqG+Ag/SlM1+yvgVyVANF8tpo5k3EgfKoL+4BjIjIPFVu21JkjADEt7URJeyMnbA96TyZa6KxNq0rg4zS2CVllGaYahMP5vWggqkg1fgbkVuI7sG3+5phzilFlIYx8h60ab34eCKd6B2k0smwYOTS2e5wTiizOXQgmgzbb8kfeo3Xwg0QCXJ570bZze2OKDe1ZSaJt42j7jmrVBJWwr4HMNwM8+lFR3KEHsDSiN9ueK6lyDnJFRHa2cmWS3uwQeaJS5X6VWLe8KZAOaM/HhfmflTMYpoNMetebezVJDqrLwScVWZL4t2yM1JDejABPIqvJjtcE2Wk6qD/ADCvqXwbseM80s0XQdU1+XbZWzzA+oHFan0z4E6jfWoe+k/DP/h70vi+PzZ3+EStlYsrpSnBoszqRmr1H4BTx52agAPTjtRFn4H3SSET3yMn/wARWpj+K1UVWwhKjPhPlMKMk+lfLW1v5JsQW8jP7be9bHpPhLpumyiSeZpyOwNW6GysbZVCQICowDitPD8JmnzldB3RlnT2l6jf6L+FvraRWXIVmHt2/wA8fpSmO2eK4EZQjDY2+2PetyE8IU8KP0qhdUaSi6h+JgwA5yyj/OvS6fTPSpRu0dutAVpEqJnjOMZ9qWdW3n4Xpi7YNlpAY1x7HP8ApRwjYQgO2FPB+Y7VX+rZReReQuPKhUE/9R/8f509qMm3EynFG8iMZ07SvxGsu7LlVNaz0+fwCLxujIAbI4qg2MJs9QlydxY9jV/0/M0ICnkDtiszRxio/sf1km2voU9eeH+k9ZWMlvqNpFeW83dJF3Z9uPf5/wBaz7p39k/ovSLxNQttBthcI29JLpnmMeOxHmFsHt2rZI7e5fIRizD3P5ab2FpI/DjPPOOBmtnGt3aM95ZQVJi7ovo2CwtnTkyFwd2OOPlWhQRBAAy4AHpS22AgAUAAduPWjkuCP5ce1MpJcIVlJzdskMCowP5ue3z55rrBGI5CT2Bz8q55wJyOPTH+/wBakU5GRye1G+iKRJNGk8WCvP0qhav4f2l7e3TTonlTEs25c8+/tV93Hbg0LOglB7Ej3qi2GpOPRl2k+Fej6FNJc21lY28rd2SFYi/yYge/fvVzsNRtzCltbGJyo+NogcA+wyBX280ZbzcrbhGe4U4zX2006HTIvKt02qO2WzS+Te3+g9+7tmX+J+mb7+WRwBuXIbjNdOiLaa108XkQJa0cTkAfyj83P0Jp14lhl8lv5W4IIxT/AMK9DgktLkXMeYHiMZ//ALDB9a87qGsWZz+jZwy3YNrLdGYrjEqncHQFWpRrEWUZT9M1BoF4beC406WTdPYyfh298fyt9COacxWH47UoQeI85Ye+K25Z4+HyrqrMqMHu2jjoPpv8JbNdzp8Tj8pp9egNnA5NfReLbwLEvwgDAoa4vFUbiRXh9TnWS22asUoqkLrqzA3Fhk1XNQt0DHint7qIKnmqlrOpKoY7sYFeL18oJfgE2kuQO8t1XJFJ7plVTmhrrqZB8BbJ96W3GsxyAneCPr3rIwJzkJyaIdSfy1LBuKRSaoUcjJwKI1TVVdMKKrNzPlic4rfi6VAxdFog13avDEfrRsGulBnefvVGS9APLcV9l1IbeHwKGUHIs3F1ueoWbJDZpdL1I7E/EcVUn1lVUjdmhJdTDIdpqlYqOssd3r8zscNwPUmgpNcJYHdVe/eJcFSaDub0oCQaPwk3ZbpNYJQkHJrouutk7myBxVUi1HcnJ5xQ8uokM2G4oo464OSLVP1GsbH4zS+56qSUFd39apWp6uST8fFJDq5Vjl654mmTdGjjXkPdxXKzxdUVhnca5ReFnWz7BdsxBYfeiI70oxwPoaXQyIF55oiMq57itCCssod22qlhjNTJq7DIB49qSIm0llNTWxLyDcOc0UlSIcR4vm3B3AAV0e0d8tnBFE2Um1MdhROwHJ96WfPByjYrileNvpTBb3MZG3JoW42RsRkVA06quAfT0pZ4tzOeNHLhWnY8jNC7WEmB6d6mVj6V9Re5J70xjioFbikT2rkrg0asPANBRssY74zRMM28YBqyrKqoMjtg4zRMVqFB44965asqrjvRodcVdCCXLAoAmtO3GRXwxkLgLR8gwK64Vl4HpXTTrgGgSO3Y53c5r5LbE8YohJRGxD12edW7UutyJXAALYg1OsYU8jmpt+fmalXBUnFM45Ow/QBLHyccfSrZ4deHWodWa3DmFlswctIRwRQXTXTknUmrRWkasQzDOB6V6w6X0O26S0SG0gHKryx75r0mh0n8p89Ij1bDtA0HTulrBLe3gRdo5OOaNk1PH5cYpRPf7mOT3oU3IB4r2+PAoKooXlm9IefvQj3ri6ngnk0lWcHP+tfBMQTV+wp8rGs+oBuzc0Kb3APxZpbPcZ9cGuWxLN7ipUOAHlbYd+MkkBCg5+dQxWctwJGnHwgYphZ2hlPxDavvUOr3Kx5jQgKO+KXyU1QzjtcsousXFzBMYkTcFOFx61V9ZuFtYGVn3MTlz2BPvVp1V/4jNnI9DWe9Xz7oHReTjOKxc8pOLscxRSdoX39p/wAwJB6H1q46Bas9sh7dqqrzefGsqHO5QeatfTd2JLNV9VOCKU0GeOWKkMZfyjaLLa2ysFAUkD17im1ughUAD/zSuDUVRADy/wBBTO1dnRnOe3evUY5JrgxJxdkgYj1xUkMrKpyufmTUcUyQMN/qcVFq+vWlgcO6Jxnk1fHnkGq4GkLNMp+HBx3zUhVkztU1SV8X+n9OndLm52sBg4GR/SirXxS0G9WOWG9TZNymWHNWVxwdRb42OOcmuNHySPWo7PVrO6svNgdWB9RUiltoJGKVaoLiiPaEUlRlT6YoaZAVJGOPWpbmU25PGUIpXNeLg/y/Qd6CTSQMU7oo3iDGLu8tI8nAOTVj0a6j6e6bWRs+ZM3b1xVa1hmvteZV5CkIoq76j0/Jc6faRKD/AA0HYeteS+QTyRlt9m7iTUEitXOpJPfJfWwxcMBFKv8A7i54z8x6fU1a49VbTII/MyJGHfHpSdei3xllJPqadW+m3S2ot5D50S/lEi7iv0NZMP5C0707fHoLZzuOr9V5yCTn3NQTdRqUJMma6y9MyOxyDQlz0jMyHaDmsjJos8uw2nXAr1XrARKw3VnnUnXn5kWT4jxxVu1roy8dWCqxzVFvvD6/EhJhJFZ0/jsjdMUlGTYgXXnlONxNFQ3+9fiJNP8ATuiHGBNAR8wKf2/QsMy4AprB8c4LglQZnN5dNGrMmW+tI7zV5MflJPyFbJP4aBh8C0F/wvY5Jizz7U6tDL0D4mzE5dWuOQI3wflQUmoXvYRPz7VureGHp5Q+1d7fwr3d4v6VatE0glhkYItzet/+Nq7ia7zxE2a9BDwnTHMVd4fCqNST5X9Kqejl9B+JmCwWd7OPhjIzU50DUJP5RXoK18NYkbPl9vlTWLw+t9vMY+1GtHKiyGH7PMsvTepqPhUYoNuldWlJwpGflXqj/h/AT+X+lMbToCzQfFED+lAtFKxhYlR49l8MtZvCcNx9Kh/4L6uRkyH/AOte4Lbomwj7QL9qNj6TsV7QL9qvXx82R4YHhRfBjWMcSN/9a5XvROmLML/6dPtXKtXx0wvFA/Pqx8PtXmX8oWm9t4XauzAbv6V63sPDOKLG5F+1OrboO0jA/hDj2FWLQyZO2J5MsfB7UpeWmI+i0w/4T39sN212I9dtevLLpi1hXHkr9qKn0K3KY8oY+lG/jJNWDUTx1F4faisoHltj2Ap3beFuo3MRIikJ+lepIOnLQNnyVz74p3p2kQr2iUD6VGP4pvtnUkeOH8DNaupCVhl/Wjbb9nzWGGTAw+pr2emlxgcIPtUi6cg7IPtTcfiYe2Q2jyDb/s9apjmICjIf2eL4/mUD9K9arp6n+Ufavv7tX/DVn9JxFbjE8n//AMd7psZA4+VHWn7PUsXcA/pXqL93KPSvn4BPajj8XiQOyJ55sfAZFH8QfpU114IQIpx6V6BWxjB7UJfWCBSe1W/0/FVA+OJ5svPCpbRuIyy/0o+x8Kopo8m3X61r9/axpnsaI0i0DxgBaVWijuosWKKRjM3g/AzH+ABQ0nhJGmcQivQR0nP8tdToqkfkFWP4+JGxHn+Hwpj3Y8v+lPLDwftGXLjk+1a+2iYPCUZbaCWPY4oI/HqLO8cShdJ9DWPSxknRCJT2ajb2/wAuSTxTPqq4WzbyYyNw4OKqhLyk7jx7V6vQYVjx0jL1L52oKN4rHGa7LIp7nn3oHzo4uBgV2WZJATmtlJGfQf5mRwc4qN7gqCfShTOFBINRCfecDNC+CAhWaaQAHJNWLTbERR7nxQOkaeE/isM5o64usAqOMUvKV8IuxxS/KQXJdBVIXgCq5qk4fec0xMuIzuNV+/fcT7UvIYTsRalPwcVSuooQIJGOCzD1q33zLkgcmqnrhWRSAcnHc1kZVaHMZVNF1LzII4nBBjJjOD7Hj+mKuugXQAfHI78is0Jey1ogDEU4wT2CsO3+/pVl0nUTY3ioxDBuCT2+grx+mzS0Wrlgn/bLlf8AYx+jStOlWa4UBuCe2eKtrELDwQoAxVG0Zmh1GCMkBXNW+6lX4UZSR/iH8te+0z3KhDNFRdnTU78WOmyTMqlVUsc+w71+f3jH466n1H1BdHTJDHaiQxbZsnAUkEY9DkGvcvWSC56eubWKURtJCdj5z6cE1+TPX2p3OkTXNvIk6zQXEm7YpYsxYnlsHB9f1prNOUEnEjTwjK9xoA6x1ia2Z55miTOd0Hb1zweQDn0IrvY9X6vAkaacvxbiGeVQZAfkRyM/L+lZDoXUt/dxBsuiBxGwkyxwR3BA5/04ojW9b1mxt2ayjkdMgAxISee/OD8v9iqv5XNUNPCqPXfhP49dQdOzQWTyfinvW8iNSxIWT357HkZxwfr394aDey3Gi2c10FWaSNWcKcgEjnBr8pf2atf1z+3GgW8lu48+9j8xLlcuyNhWwD6Y5yfUDFfqpp93ElmAeccKBjv9KsxuU43ITzxUGtoxuQJYHIJ49aqd8xtomkc/CPXORVnjkaSGUkfDjgVmnXXUv7h0RbjYW8yTYo3gD14JxS2omoRdnYo27Fg1+3suptKgnbbJe3aRJnHJJ7V6St9OR7RG2g8e9fn5Yzt1D+2H0fpTrcE29jHqhXYPLUKHbk5POVA7L37nOK/QKy1AJYqCeR71l4qyR3rp9GlA6Np4/wDbrodPUdk/pXf96gV2XUlYVbRcQDTQQSU+9RNaqPQGibjUP4RxS06goBJaoqK7OJhp0coOVFDzdPQuD8Cn9Kms9RSR+4NGm6jf+ah8cJc0SkV2TpqIZwgH6UE/Tscb5UBT8qsss3fDZpfczHnFUywwXokWxadtOCA1HRabEV5Ufah/xRTNdlvzQxUF2TQSuiwd9oqRdKhXsooP94MD3qSPUCAcirE8b9EUwo6bFjsKiOnRDPAoeXWUhGW4qBNZW4bEZrm8SO2thn4GJfavhhiXniug3um49qg3ljtHJoaivRyTJT5PPauyTRL611TS3lHYiuHQ5OcZqNnugkEi8gUd64NShH81BjRXPBHNSLoLEdjU/n6QSSCxqkGO9coX+z5+dcqN2T6DpDaCCMDnFTi2jPY0lttYicZ3DNHRakh7MDV8ZxfQDVDBLdAe/wDSuXUSbcZoNbwls54+VQXN2ST8WPlmibpEJE8ZVDzTOxlTaTmqnLdE5+Kp7W5YLgtyarjkV0RTouS3CD1FSrfRgelVIXLH+Y1984/4jV6kBRbf3nGO+K6nVI/TH3qsBiRnJNdo35IwancwlEsJ1FG9RUf4wEcGl8EW7nbR8MHoFrk7AaSPguTntml2r37RxMSCAoyafxWRweBS7VLBpImXbn9KiV0TGrMi/tmL3WjaqcEHBBrU+molMIJwaxvqjoi5s+olv4Mxgtzj1rVuirwC3jSRviwBzWPhySWZxmaGSEdicS7Q2CvjiiV0qPPp9q7280ZUEEUdDcRe9bKozwD9yofSpJrMWVhLIB+VfWm8U8Rzgik/W2ox2XT1024glfSipUBZgWtag11qlwxYEbyBil11ebVIU4HvQss/mTsSeMk80NcXS7zxwK1cMklRkTVtthcGMlnYljU0lwqKRn+tLReh/wAp57Cviy4J/n+lN7xdoYly8fwtTTSrF52Vs8Clenxi44C7frVltMQRgCofRUMXnEUe0HHHpQHmeZIa+GYEnPeuKcDIAFV1RZdny4lK/CDSe6I+LJplcPnNKrlxtY7c0uWiK/4zjAHvVXv0LBhg47nNWa7IJbJxj+lV7VH4Y4wPSkMsRnHLkpetWHmwSE5B/lxwc+9K7K8luYWR28ueM4Y+/pkf0qy6kFEPJO4jvjtVC6tvbi1tYzZApOh+FsffNed1+hWph+PEl0xtXI1rprVxcx2bEfxYmAf5CtAkuSZV2EuDz5ePzCvPXQHX9tqUohkP4O+xuntWbkDPBHuOc/bNbFp2u2+oQEJOpKDZlGGc/wDen/jdS5Q2ZOJLsqnFyO2u3YuBLHA7xFeXjUfG3y+Q4rxF+0n4U31xrq630/b+XIIz58asdrc9/bP/AO+O1exeoNRiiSQvMkkUeXMn5TgA4Hz5Hf8A7Vl/UOp6WIJ0ubhAjAbiW3ck7fXv/wDv9dvJlUlVnYMe08HzWepabZST6vbXCFoyEdx8Cnn7HjFfdIg1/UbO2fQ5bqGcgRtLGxVZOPyk5Gex+xrfus7XpzT9L1EvrENz5gz+GZN28M2Tx9GGfoaXdJ3nTt1bQWiX0UMUaqPIICqg/l+pzuP65zkUn+K9j9Wi2fsqeHDaHfPresT/AIvVmA+FiR5I9h6f7+3tnQbxhsVx5owP4hGFA/yrzP0Y9jp8ETwXkNxPvBDEnlD8QOfc8n9K3LpTWIbuNUEyuqgERx8ZHpz/AKU5jyRS2mfqMbfJpL3a21lPIDkbC2SeMisJ6gvZepdSgtVldLKGT+IqkES++OPn3q89Z9c2mmwQ6THKg1C8YIsCN8QHqf0FVDpaze81pnnVjGnYEkjucf7+9eX+W1E82WOjwdy7/SAxrZG2XToXw10PTuqn6uOno3Us9oLNr5mYsIN24RgZwBkA5xn51sUal7cHntVU0hUaIKnBUgVebKJfww34zWzDFHBjjjj0i7Bcm2K2jYZxmoG3x5OSMVYRZRv618bS4nBHeq2h2ioXutPEdmCc1HZSi8bGTmn9zoERbtmiLHRbdGyRgj2pFwyOXfBcoqgGLSXhTeDXeKznf8oJp8sCkgZyo9KZWkcWQCBTUY+gOEVmPR7l/Qiph01cOORxV6gjiAHAo2IRewq1QBM4/sdM+eMfpXP7C3BHFagnkntipQY/TFF4osjcZT/YS5+efpX0dD3XI5+1atvQDuAK6eZHz2P6VHhgdvZklx4fXMoPJ+1fLPw6mhOctn6VrZMTA9vtUJeNe2MUH8eF2EsjqjMbzpa7iiKqfT1FI7bQr63lJkAIz3rWtSmTyz9Kq9xJ8R4GBVcsUbssjIG0+xYR/EOcVN5KjIxQ1xqyWy43Yrrb6nHK3BFGpx6s7bJhiWeedua7rbAfy19N6oTOaHfVFXILAUdoCmyYwYJwtcoBtWQE/HXKjdH7JplGh6fmn/u3K0wt9BngHxOSa69Oa7DqKqYXVs+xq2EAKDkVnYYRmrG5N9MRR2cqg96FOnXU0hznb71ZXeMR5yKiW4j2HsKvlBPiwEkAWnTry4yaZQ9NhD9KYaZMhTORRhu0UnkUxCEUihtitdDAPIqZdAUjtRX4+PJ+MV3XUFH84qykBbBk0TaO1d10pUPIFSNqkYBy4oZ9Xi5/iD71PCOVh8Fkg74oyONF9RVfOtQjP8Qfeug1+H/3R965SSB2stcbxL611nSGYcEVVW6jhA/vR96jXqi3Bx5mf1qd6OSZ36h0lJlbKg4qhX+upoMqgttwfernqXU0H4d2LDGK8v8AjB4gM2qC2tSWcvgBffNYuuaSuHZpaWO/iR6T0vrKGa3BEwOR70fF1pAnBmH3qh+EHhncaho9vdanI5kkUN5eeFrW4PCrTSvMKn5kVfp/5E4JsWybItoWW3WUW7PnVD1p1Glx0zcbSHJGAc0+Xwr05eyAYqv+IPSMOkdNztADwOeafisi/uFm01wYYs++5MZPzNRXMgkmKjsO9Axy7LuYk80LcTnc7EkA03hy06Znzx2uAkXQ80op4HrT3SU8xBu/pVMtbgvc4XtnnPrV90aJvJBwF4rTxO2I5I7RzaRBFAFHFsJS9HKtRDSALTIscLDOe9SLJuOKEMnJweKmtm8x8UEuEGkdrg8cUqvCxBC4HzpndYUHHJ9BSq4yFJ9fc0t6LRLeRMoYn4jVZ1LO0mRsk9selWO9JkLf4e3Paq5fxhmYlgcdgKUyF2J8leu/ic7zx7VVdbtTckgHYg4q1XcW0Mfl2HekF5/EhfGN27OKQkPwMi1OwY6p+MgkaCZG3I6Dlfbt8qqnhr4ja7Y/tHXVhJfytazozNATiN2Ee4Er6ds8Vp2rWRs3YbNwJyCeKpVv0FFF4h2PWNhJsvogYp4GG6KdCpUkHOVYA8HkcDj1pOUWoycF+VOi9q1Z6TuNS0zqcQxRXPkzuu54WPDHAPGfqKp3UnhYl4rja8kY+LLNnnOcis+6x1i20HSLq+uLxdOihiYpPJJ5YB2AAA++R2HJ9Kxfp/8AbP6o0xZbGB49WtlbZC8yldy7+Bzz+UBcnHftxytosuXUqSyRao6M3F8GkdU+D8016Li3tfNDP/FzGNyrkj19hjt7etFdJeGct1fBrmJBbsQjRJHjblRknA+YGTxVjuPHzUtKhlHUPQGqQskRczWcYuoWP/VGSAPXmq5e/tldP6PbRva9OXBeUNiNsIQQSCD7EcH9adWMv88jYelPB+w0pXu72QLAhDb5DhRtUjOT9a66744aZ0r5mj9J2I1bVVXbHcyNi2znlRIM/FyewPY5FeS+uv2iusPEvpTVYIrw2IDMRZwHBeMhsKp9SMAEdz6ZzirX+z7EsvhxYyyEmSTIYseQwY5/XmkfkNS9DhWWKu3Qs25v8iy/s9dQ6pf+PfUMGuebs1ONb+ESuWBYN5ZZS2D3JA+RNeyNF0wQorrwGGc+uK8jdU6jadDax0h1OpSOWJ7m2k5wSjqfbuBgn5HBr2fo9v51sjIQV7jHqKY+O2an/wBpr8mq/wDjYnqPT9Fq6eT4FBxxVma4lRdoHAHvSrpy2QKrMMFRTWVRuPNaWV80i/Tqo2fYbyVe/B+tFR6my9yKVtHknmhZRjPxf1pVyaGkyx/j0lX4iAfrUT3JUEo6/TNVrcefjrmcg4fmg8n6D3UN5tZkiOCf1qWHqgWiFpG349BVfaQDu2frUTCJwdxFUOcu0wlL7GN54uw2LkFH49hXS18dLeR9ojk+uKrl/o9rc5OVzSSTQY4CSmP0qh5cq9li2P0apB4vRSDO1hUx8WFA4BrKY08peaFvL9E+ENRrPk9s7bE1s+LY/wADUM/i+yZxEx/Ssmj1pUYjcDiuz61E3fFT55/YO1Gov40YBHkuDQkvja65/gOay+XU4iDyKh/EJKMg5oPPk+yaX0aRL43Ocj8OSPmaX3PjC0o4tiP1rOZzgtkYoRpBzih8032wkkui46r4jz3SnEZT9an6e8Q44j/zMpVh6Gs1vLlos5PFCR3wLc0KSbsJSaVG2aj4v2lvHhFaT6VXZ/GmHcf4Dj6ms4nvUwf+1LppkfPAo3b9kKS+jQ7rxpjEpxC+Me9crKpYonckmuVXsYW4f+E151P03bIt0k07Acs571q0viFq5jx+GYADvitKtekbCMALGv2pi3RtlLAf4S8j2q5aea6C3q+TBLzxiubSbyZN+8/ykd6Z6R17q2q/+ntXbPqasHVHhdpwu/xDoD8Xar30VoWn2logjgQYA5xSsMeTJk2t0MSlGEL7KQuu9SRRALbEDv2Nff391LMNot8GtjNhbkf3akfSu9vp9qH/ALtB+laa08l/uM/evoxqJOrJ23BAv6Ufb2PVbjkj7VtltaW4H5FH6UWkNuOwWro6av8AcwPJ+jEo9A6pmBy4H6VNH0R1FMTvnx9BW4xLAo7CpFkt0PpVn8ePtg+R/Ri1v4YaxN+e7cUfB4R3zZ3XUpP1rXo7uBc8qKkGo24HMi/eiWnxgvJIyhPBuVvz3EpH/VTXT/B+2tzulYtj3NaD+97VR/ern61BP1DZpGxMy/ejWHEuQd82Z71N0vZadp8oSJVAB5PNeR9eSyl6uM8YR2inGeM9jW9/tD+LsGi6BdWWkf8AOarOpRFTsnf4mNeQumLjVrCSS4vszSSHcxYY5+VZGsW7iJo6eWzln6A9Fa/Zy6TbPHIoXYKtMnWOm2qgPcJn614Ei8brrRSlrHKbfdxjdmr50r1c+vKJbidpHPqTQ4dXkhHa4g5sMe0z1+vW2muOLhPvVS8Tddt9U6cmhtZVYkZODWVWSCZQFJz9aZ3UaW2nSxs5LOPetPFknm6RnTcYLkx+7kMN47MeM4rreHzFAXsa69VR+SZGBwAc0q0rVRd2hQth0OMetFHhkVasnWVbWReeSe1aRoFwHslx7CsluJs3qrznNab0/P8A8hGOMYxWvppXZnZ4joSAyHBrs85/SgWmCtxXDPmtAToMSX1PFMtPAMTyfoKTJKMHFO1Bt7NFUZJGTVc/olHSVhk54+dLbt1Ctnv7d6JlkYE7l/Sld5cBNwI2k/KqW6Rwl1AFy2DtHrkGq9cI3xA8L74p3qF2iK2O/wBO9Vq81F8kEgD50hkasYxJkF1HFIpRM8DGfaqzeWzRSNuPwc+nfvT5tRTYA3wL9QKXXxWYsBx8PGPSlnyORdCG4gW7tJAVDY4IzyKRWlhFBM6yFFVT8JOMn9KsVzGu4x/zYB47/wDmprfRIAyGQqz4oNvsvT4EFzp0GqRPEbY3COu1hIoKkexFULU/2aekdQLu2hxWxdi+LaV05PfCqQB9q3eC3hjXaqbQPlX2S3UITnCn71zhRymedrb9mPSdOuY5LPUNYs9pB8u3v3UfQ45/rT+48Iba7sXt7i71C4jPKefeyy7DzyNzHAP++1a7OsaqQBucnHHpXRIlfKonI4Az3qlr9h7jy7P+yYj3UqQazPDpky7ZIWiDyDnsHyB/Q/rWq9B+Elv0lpcWl20lxLb797PNJukLHGSTj5VqkWltLIAcDd7e3pTvTtF2SAnBOMfpQTxRzR2ZFa/ZW5qJ5W/ag8J76x1Kx6osvPlsTpj2TQLltkwclcDPG4SN2H8te5/DaCa36V0aK5DR3IsYPNR+Cr+Wu4H9c0Ppumhrddn5hggGrRpcG7yyVw47getaeHEsa/FcCE8m9bRjrmtL0/p1u5O3zX2k11stfF5GGWXIPzqt+MNvM+naf5AOEDE1lNr1XfaV8O5tvsay89vIzUwxTgehBds+cSmoZWds5c1hJ8YBaSKskpjb1ya0HpLr+HW1Cs6ksODVCdhuDRa3DDs7feoHd8H4j96nimWTIyKjuMDParNpXYHK7gn4jXQM3OCa+yyARkjk1Ak/t3rqXRNnd5DyM0HNcFCeanLjcaX3bZfAFVuKCTO4vMjnkUPNFFMDxg1FgqDXxZhzzQ7UFYPJpyjJWhmstueaOmudgyMGoI7hpc5Wh2ILcxFqEUitwTiuttdyWsTu3IUZ5p3LCrk7hzUFzp8c1q6Dgmh2BKfBVP7VCa52k4yexp6oWWMOMcj0qp6l001vcmRlO0cg10TWJ7dtgYlRxiuUKCu+iw3UJbI7ilj2oUnAqSHVw65YkH512a6UgncMV20gXTKQDzS25ZkBJ/pRl5q9rGSGljHyzS2SaK9VvKYN/wBJqKZKBjqABOa5UR02TJ+E1ypph2j0jH49aSnPnDApnpP7RXTt0rxG9jWRe6k4NeThGFiY59KxnrO7uotbLWkjRtnAIOKhSnXEi2Ci+0foF1T4vaXeQ4guFfnuDQdh45R6fGI4bZ5CP5s4FeTOgHu/wKS3cjyNxjJrR9OuGmGFFV41JS3N8kZZpralwb3F+0BNITutGUfWiE8f2TtaMfq4rEVgkI7nFQXFwLcHcxprfNexXs3sftDzAYSx+70LP+0Fq7f3NnGB82JrBodbGSFGcUbHrEm3OMVO+bXZFGuT/tBdRAfDBCPqTX228aepr4/miX6A/wDeskj1MyNyKPttVaFcrxXJt+2R0au3iP1JMv8A6oL/ANIodutOonyTqD/pWdJ1QyHDPRMfVq45cGh/7Itl3HVWuSH+JqExHyOK7/v2+kB8y6lfPu5qmQ9VRyHAfNNbPU1uP5hRRddMHkIvLG3viWkjBY9ye5pRqvT1stm7RoMge1P1CuO9cltwYXBOcj3qy+Dk6PJXiqkmm3wmXOUfP0q+eDnUUt60CqS7NgBQaT+NXSt3q8xtbJXa4kbCKoya1r9nfwWbobRYtQ1h/MuSNwVvSgw6aWafHQ5nzxhiV9my6HbHT7ETXB+MjODSDqPqLfNtVsKDzXfqLqZWDKjYUD0rLdb6jMkkgDcV6GMIaeG1GBcs0rH/AFC631szJ8QxWfRrNZXxkTsTgim2i6+1zMbdiSnzo7UdL2rlR8wayXy+DSj+Kpi17gSuGix5vrmtA6buGbT0ywZh3rKbljZXgkBOR6e9X3pa+8+2IHAFPaWdSpiepjcbRbxPn61JFKpJyCPpSfz8E81PDdAE5NbMZJmW+B9p8X4u7RAMjOTVhuGHPsOBSzpa3LwSXDcKeAT601lCnPtUdsBukLppHUEgAf8AVSLVbi5WMlUDe+B2qwSBWJ9BUMlqJByB8s0EobiFKjL9a1q4gDb0AA4O4dxVdOsQSMwbAkxkZORWn9Q9PC6tZUVdwZcMMdxWLdT9OyWRO2dl2cBccj9RSM9POPK5HcU4S4fAxupPOZS5CoihsKec0judXe0DHB2jPPrQFvqUtvH8WXwNtC6nJHf6eYmOFbOVHBpRxY5GlwSy9TQS3MPxiNjxvPfvTkXMUSLKJJJXbHcHFUCPTI5biIPcFIBnk43fSrHBcrHtVCfLHCr64HzoVGT7LVXovNtdAIGJyAM4oHUNdBkEccbSvn8o4/r6UslvDDaQQgklxnPy+lEWllEXDs2R8+P9aJxlLhAJpcsaWKpeKGkjwBzgngHnvTW1t49qhxy3PHelluLi4dltLZ5wvJESkge2T6U60HozVrvdJPdQwNI+/tuKj2GOKhYZPhIB5ElbYZaWsW84bJ98U9s4UxuIzjiiIOivIgIeaRiOC6kAf5URF0tNEmIbkkj0dc1asMo+hOWRS9hmlzpCQrEYJ4zxirfpqxygFeGPcYqpW2lTKds3PzU4q09N2ksMm0sTGORmmo2o8lS5kqJ+qrBL23iR+QOO1Z5rHQtvcgmKMKfpWka3dqgUE/pSc3sYBzisnLW5mvjdR4MH6u8PHEMiG3BJ7MBSXo9LzpucLJnYh9a9A3scd6CCMj2xVO6k6OFzA5txsc/LvS1JcjKm+mcsvESzgQb5Rv8AbNWbTOpIdXQOjqc+grzJ170B1DFumtpZIwpz8PrS/oDxQ1LpzUVsdSikVhgb27GqlN7v0XPEnG0+T106K44PFDGHZnnJ96reh9ZwX9tG4kUkgcZpzNfl490Z4NW74iu1olLYJ5qF0BOTUEV6z5yM/Sufi8vtxih3ommfZ0UxnHelbo6N8qZyqyk57e9RKFdTxzUOSZyQrkbcSDkCu0DJH6k0cbdSDx+tKr2WK2PxNgig3IkNdg65HegpJtpIP3oCfVvLiOw5pFNrkpcjuPpUqUUEkx/cTK6kNhxSaewtpHyFGaE/ejtkkH9ahe/bnnNdviFTPt3YbAdnIrPuvtYv9H02Z7XfuxwBzVzkv5HJALH5UvvbFNSjZLiIupodyLI37PG2oeKfVd11C1s8MyJu4Pp3r0z4V3hOkxT3j7XKgkNQ2p+FlpcXRlggUODnkc1XNd0XW9LcJarIqD0FTug+ixK1RtQvo3yVKkVysYtuqtVsoVikhcsB3IrlDaI8TLvr2s2+n6fIdwRsVkunQv1DruACy7sk0o8WOs2bVFsbeUklsEA1oHhPpv4WwSeWP+I3q1UxTasuf4qjTenunY0to1IwoHrVkt47bTwckZFVubqBLOPDyCMD2pZ/azT3kPm3oAoo/j6FWmy6XeupjbHQf4SbUDkqdppbadSaEgB/ECQ04j6z0xI8RycfSitt8g1XQbYaDDCN0hA+tNEsrILgsD+lIYtdt78ny3Y/pTK0aJhySaNP9A0w6O1tFOQuaJEVsq/kxXLCGGSmDafE6nHFEmyBJNZQy52AGhG0XeCFUfarZZafCgO4AmjUsIudqihaTOsosGgTRPu28Zp3Zq8AxsOferGLby/5OKktrdLp9gQbu3AqIpdIixPbyTs3B4o5Le9ucImSTx2p8vTE6ruRP0xRcLrpduzSKFkHoavx4nOW1lcpqKsB0XovT9Pk/H6gqy3XcbvSheq+rkXMEBCgcYFJep+tVtoZHaXnsOay686ra6LuG5PrW4pQwR2xElGeV3IsOt9RFI3G/LNVS817yUquSTQSSTapd7RlsVfejumWdxI0Zc1lZtRb5NDHiUUEdIdJMWWeYbVGD9asPUNqkVv8I7CnC208KhRHsXFD3lmbqB0fvjikoZqlz0TKLZjesQPNej4iBmnvTmqfhZVjMhCnjA9a+a3pbafcsZASPevmnWcSkSL+dq1sNv8AKItkaqmW6eY7fhI5qe2yyhdxJbikpmMSDNH6NP595AvONw5J7VpwmjPlHg1vTlWz0+GFeyqP1NSMwf3JNCtIeADgCpo1Z+M8+ppuHQlJHXaozgZ+VdMscgD71PIFhXLHmpLaIAbm7+nyorBriwcQdwwJzVf6m6MsNcgk8yMwzgYWRO+fp61aHGWO1QSOx+9CXQkAKjLe+BU8EJuzyr1pot30hqxt7pR5MuTFKv5XHrj2I9RVF1TqUWkMreYuADnnt869edVdJ2vVWiXFlfJ5kEoyrISCjjsRg5GDj61+cfjBJqfSnXt901PNmeBwylMjepyVIHsRSOeGyO40dPLyOjU+n9XOoC5uBJujQZPvnOB/nVk0y7FxKsCnDscknPA5zmst0+/i0TR7WzXas0qh5CW5xxjj9Kslv1EumaO9y8vly3L+VCGPIUfmP0z/AJ1RBKhuXC4NKbVVln7nA4Cn0HoKtPR2nJrWpbZ0cwRjc3Pf5cdqzLpCUXozHlmYAl2NegvDnQ10+0yeXbDsSOSfQUzDHyKTlSLbbWq2NnFHFEIIj8OxBge5yM+w/qan0qEWwYIAcEEbu5zkH/I80QdNkkiVArdj68ff7UxtdJkMrPwV9F44GaYqmJ3wdnMcSFydvw4we2P94qCwuYbsMbdxIgYr3/KR3FT6npct3ZOseBKvI9eR/wCKRdLWF7pV3dQXMKrDIfNDp/izzSc8jU9tcFkYXFss8ERkHIwadWMXkWcrY5HGRSuPEblex700M3l6fKcjLAYz70UuicS/IrfUbs86ImcgUtjtJiM8kUYuprqtncSyKFurVyrr8qEbqBEi2gc4rzmdPe7Zs4/7eD6EeMfOiol3rgjNV241WTeW3/pUS9WGyIEi5FLp0Wjy90uG8VldFYHuCKz/AKn8INM1QtLFGI5u/wCtW2LqiC4JIIBrvFrtvISC2T270Lugk2jD9X6e1fpNWe2VyqdgPap9D8YvIZbW/QxOCFyw4JrZrme1u42R1V19mFZv1p4aaVroZoQIJu4IqE/ss3Jrk0DQtasNVijaKRHJHoaYXdkiy71A5ryf1Fa9b+GYE+js9/bqf7sn0+taR0d42T3mlQHU0NvdH8yP6Gu/wQ4cWjY7qYJEcgVhfi94r6r0RKGsbKW6GeVjHpWoWXWNjq8B3TIGxzzSjVtLstb+Ly0uEHYkZokk3ywVw+SjeFnjdfdYOUu7GW2xwRIKu2r6rFcscGgoOmo9PDm1tkjY/wCEYqJdJudx3IaiUPoPj6JI9RiSM7gDS+41K1LnO0ZrvfaXMEPGB9KrN/p8xcfxCFB5xihWNeyVTHd1rVnaxjnJ+VRLqMc4BVeKSSSWkYHmqX2+5qKTqGGEYhjJovGkgkiwLOrOSO49qkF6gDbhVLl6kmRyUjPzqb9/yNB/d5c+hodqJos/44csBkDscUPcajFKh3Rhj7MKr1r1IyIY5FAb2NDvrcURbzWAz2BodiOoaSRWUzFmtlz9K5SYdSIOxBFcqKRZTP/Z'; +export const portrait = + 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAEsAMgDASIAAhEBAxEB/8QAHQAAAAYDAQAAAAAAAAAAAAAAAgMEBQYHAAEICf/EAD0QAAIBAwMCBAMGBQMDBAMAAAECAwAEEQUSIQYxBxNBUSJhcQgUMoGRoRUjscHRQlLwFjPhJGJygpOi8f/EABsBAAIDAQEBAAAAAAAAAAAAAAIDAQQFAAYH/8QALREAAgIBBAEDAwMEAwAAAAAAAAECEQMEEiExQQUTURQiYTJxkQYjQqFDgeH/2gAMAwEAAhEDEQA/APUH3oSYOc1srxWlFVUqY2+AZIxig7aGo5ya2Rk0dAgAue1YE4OK2PhJoasCTXUjgojisB9DQyvPFaKkULiTYWO5oaHms2fI0JE9amKZzBHOOKKNHBeDQWTI470VEBVbAyDWbcUJV4oKJs0B7VrGM0aq4rTDIyKnaRYXzWhQsd60KFKgrMH1rdZtBrAMcUQIEpkH3ooxkZo/FYB39aXtCsKRcDmtkUPFaxXUSmAVM5rKGuBmsqVFEWGDgHjvQCMVjPkk0DfnvRNkJWGK351vOKLHOaF61FnUCB96FGAc0WvrWwfaiT+SA5FAzQu9AVxjFGAAj501HGuRWu+aEc4xQC2K58HGDOa2TxQPMrW/GfWhtHGZBIyKMH70TuBPNCBLDg9q5M4NxRbdiPWgbivGa1knNRZxvGCa1Ws1maCyaN1mawYOayus6jdYFzmtDihBuea5EGgpNBPrRm/g0CpZKC8VlBY4JrKVuoLgSSXuMj2rEuN/bPNbksxuJHFCitQpzS/uZAohJZee9Gdga0gABxQsd+KclwcBHNbH1rezb8jWsYrqO4N54oayH15oFYBgmpVogO80c4FAJ3Gg981taO2yDPetYoeMDIoFRRxqs5HrW8d6wCoJs0O1bHbNb7VlccAJoDMaHxzQdmW7ZFLYQJO1CoAHt6ULdxUp0iDeKDnB54oDS4oiS4wDk0LmjkhUH571vPzpBHc5Jyc0oEgx3oYzsmgTYJOO1ZQdw296yuIFRh7nvRYXv6UczjacUXnPNWGkQmBxihx4z+VAPA71oMKi6Jqw4ASZ5wRWEqAQB+dFjkVvPzqbVA0ZWVrOa0OaGyaNoBmlCoMUQhwTxRyvmmQryQAZMH60GjH5ookA8kCodI4yhBDSVtVs4pxC86LIewY0XfdRWFgGE11GjAZ255NQmvk4XH1oPb86rbU/E66MpS1hTYCRv/3D5Uznr7WyV/nJ8Ix+HvRLHOXSFPNCPkt8kD1rDwKqaDxH1mJgXWKQYAwVxR8PilqSM++2idT2AyMVHsZfgj6jH8lmkkEmk0s+DgGqsvuvtZvS2xkt1Pog7fmaJterNRWSMTzExjuQOTQS02WuEQtTjui0ZroomS1InvxjvUVTrWG6O0oYlHA3dzSFupxJMUTOCcZ96oSxZuftHLJB+SaRX4B70rjvg3GRioONTxIV3bj60oj1fyx+Ks/6j2/1KhqV9E1e+G3GRisqDtrrEnB4rK5a3G/JNMsdL+Ns/EKNE6n/AFVXqa2FfG6nK31sY5fv860I6uL8g0S9rhR6ikj3eGPPamA6/Gob4waJOurJ2PeglqYvizkSuC5BU5o3zvpUYt9WBGN1LDqY2bd2fzpsMqaOHvzOO9aWXaDUek1cx8k9vnSN+rrcEo0hUj0o1O+jiXpcKTjIzWp72O1jZ3faoqCXfWVvEp8uQk/MVHtV6ue9UjeR9DVjGssukLlOEe2S7qDr5IVaO0JDg/jqJaj1xf6jFtZxG49U4zUYnvyxJ70RHMZH5baK0YaXi58mfPUtuoi+7vZ55S8kjEk98+takka5+JnLsBj4jQXRWTAk3fWkctwlmmWcfrVmMIrorSnLmxYrMOM80PPHzpttbsysTzg0qEpzjsaNKhO/5FIU7TznNFIT8Wa0sxKtzjFADhmcg/KjTIcg9CcGhK+44xRSSYU5oLsQpb1pfkNS44DnUJ3rUUg3ZGBikcN4lwWTcNw9M0asMu07SKivkYn8CtbkqThsH1NLrW9yMOMio9ILhGyWX9KOhumC/ERVfNpIZo1JWNhmlBknjt45iNjflWUxw6m8P4Tj51leYn6Etz2Pg0I6uNcgG1YopLPimuXqwxsQJMj3zUH1DqUSKQrkU1fxQyqOSTXzzJLLNVdDXNros+Hq8OPx96X2/UwB5kGPrVNT6pJETtYg0kPUd1krvOPrUY8k4eQVmZ0BF1RGBxICfrSqLqre34s/Q1zrB1RdQOR5jY+dOVn1hNCwYyH65q/HWZo9He6vKOiY9SNzEWOcfI0yarfWq5IJV/YHNMvT+vHWOmTPDlCG2szHn+1NGqRm6BkaZo7ePvj/AFH519G9JxxzYo5Wyvly1whwm1YyEqpyaRtNLK3D8DvxSC0l85mVBsjX8R7Y+VanuJHby0OxPcccV6iMYx6M+XY5hwq8kk0dFIFUuxOB70hgG0qvr86BqEreU6Ix3Y4x71LaSFxXJWfX/itqsOu/w/TEC2cfdywDOfXGSOKd+kNUuOppIzLLIqr3X8Qz7Eg4qiOr3vbnrSLT4Z3jmlfzJACAxXPqSDjNdG9EaUNF0aJeI2K8nhif0FY2klPJOUpPg1NVCGOEUlyTWECFNoGVo9ckA98d6aYbiWRTghh6EAillleOMRyHPzNaRjuI4eVuQlT6UTbcKynnHNCWUgkfLJFExynkfUUHRCVikcA1piSMHPPHFaUHuQeaCQ2ST+VCGlXBGurjcabAbqB1ijQZdSeSPTHNNPRPijHqt6thM6Mx4yDg/oeaml8iX1pLDiNiykcjIrm/qq61Tw762tnmtop7B3G2WMAmPn3I7fnVTNOUKmnwaGmjHInB9+DpycbgcCm6TcobGfpQtO1D+J6TaXsWGEsYbj1HrWpWLAkHOf1rQxytFOS5G7z5Q5O/4M4Knuv/AIrKOE2ZSrL8YHDY7j2NZTuCVIpWHUWmXHrSyCcjsSTUftJAGp9tWwo9/nXw6ceDXa4DmDSnvQGtcc0rj5Q4AzRixsEJxke9Z7XPInoZ5YcZ9aRTBge/FO9wMZ9KRGEO2D3p6lXQLJ14V9QR2sj6Y7FYp+8kh/EfYD9amOroBA0C4Gw9v+frVO2LPYXkNxH3jYMAPXBq3L26TUrEXUTDY4KMR6H1/pXt/wCn9ZtTwy/6Ba3r9htsLlPJxu+Ae3djSiMmMyzS43dlT/bTFpt15bswHfIQewHGf8fnTrHK0ka4PL/FuP8ApX3r3ccliZwaB/eXTdIeCeATThYonlzXMg/lohYlvkKaIsXTsRnbnCj5D/NA8RtWPT/h3qUsQ2yyRCJOfVjiuyz2wcmBGFyUfkpjw20qfqjrjWuopFXyp7llhy2AI1OF9fXGfzq9IT5eIlHmv9CaiHhLp62eiwRKhHwgfWrINzZ6ShLFI3b3qvp4qONB6ibnkaXjg1aWjgbnyD7Glz2QZMj/ALi8j51D77rSGO6KNKFUc47Ej3HvUottUjvI98bZGODnvTvci+EV9kkrZksm1lY8qQR/mh22JCpx+MZ59K1PC0ts3w/GORj1PI/vRFlPjHmDbtH9sVIKHG3lDlxjAVtvNGsI5Moe9M8109rOScc/Fj+v96id54h2660LVG2yAZZm4Cj3P15pEskY9joY5T/Sidy28sJzGm5T61W/i90nBrmiSyyKqFV5LEL/APsRVh6Xr0FzHGA+S3YnsfpSbq5TJpsysMoy474zQTinFkwbhJNEP8BupE6g6F+7ecs8+nSG2kIbJyOx/Pg/nUvmkxuUkqx7H51Tvgnqlno3iXq+kQu4+/Q+aVOMB1Ppz6g/tV0apEFZ3OMY5rtLk3Y/9D9Tj25H+ef5EkjiQB8gMMZ4/espva5eIsHT4l/ce1ZVveiuoMpGygJAOKdYHKNjOR8qZkuuBhsUdHemMZzn618ep0adkmhkG3NGG+AUrUfg1lSNpox79STg81mZbTsWxVPLvkyK3DG0rE44pJbzJLLjP/mnmEqE4ocMXJ8irtmltWVckDipP0TeK63mnTNhJkyhPoRn/NR1ZcggngUXa6j9yuhIp5B9K1sE/YmpIbHh2Pl6rabdzI6/FnYBS2GeW5XAB2YGfoP7f4o15E6n0hLtF23MQ2uPcD1/570HShukWIdu/wAz6V9G0WZZopphTqh5sLUKU/05Hr6VBPtB3/l9MWVsj/jkViPkOR/SrJgQxgE8kkCqX8a7ptR1kWq4KRAJj5+v9as+oT24Gl2wdHHfnTfgevDHqOL+GoSfjVRlR3zXPn2lPtF9RaffSWWg3cnT1vFjz9Q8tTcSZJ4i38KAAST37e/F+eHdgumW6eYgIYbSSM1A/tBeAEXiRYk2kq212hLRysu5TnuCPb+nzpOL3ZY0rHf2VllZzJ4b+NGv6h1bZw3fUt31Bpk9wsUr35XfE7AbXRhg/iPIOQRkiu+egdYN1YxRISdoG75dv+frXHHRH2Odbsdcsb/U7+3itbOQTJa6dE2ZHAwGZ29B34FdueHvSsmjwRvIADJEu71GRVmGKTnvar9hWaUVi23ZM4k8yHIBU4pJBBidmJHDE4/59KcxblUypyMGiVttjqc7iRzn61oKPBkjR1Pvt4JbhewUfl8/6V59/az6kabqdrCe6u4bWOze5+62srR/eZCwA3kclVGTjPevSLU9Oj1Cy8pj8PHw471y/wCMn2VrLxK1yS/NzeabqFs7tFcWhX4kbgqysCCMAe3aqk8bbuNX+TQ084pNS4OQfA3rvVuntd0p+lby8hv3kH3qwNwz2tzGTwpQ5G4AE54IJH5+jh6qub3oQX1/EYJ9pDKOdp5qkvBX7Jem+HmtpqV1eXOo3e7bE0sQVUJ74UepHck/QCugurIom6Xu7SEgoqBc47YqrOM0m2+a6XQ+c8b2wXPPZz34bXssXiMNUY4/mEcD0NdU3BEhOcY+dc1dM6OY9eeFVOXPGK6G0e6OqaVZTg4ZowHz/uHBH61U9Nk1GUX8jtek5RkvgatUgMCSd8ADafz7ftWUr1sEQstZWlNpPsowao5jh1DKkk4x61uTUxj4WJpvityqnOSK3LH8PAxXzKDU1Q0Xw3+QCW5py0yy1HV5dlpbSz5P+hSRSzw38NtR6y1iAiJl09TmSU9se1dWaHoWl9K2EdtaW8abQBuA5NaGm9Jlq3b4RDKP0zwY6iuLZJgqREjIRjg/nTmnhH1NEF/lxMD7N2q6W1bBOMY+VB/i5Oe9b8fQNOl5FboorCw8GdTkZTc3EcSk/EByamen+Geh2KRmWITTL3Y+tPUuqZQ8kUia/PPxZq9g9J02LlRv9znlSHCLQtKt4Gjito41YEHaMVX13pDaVqMqoAyd1Py/5/WpabyaRCEH60ivbOT7k80mPOzlQTV5444qcVRMZb00hie4+7K0spwkSk7ffj/xVQdW2zyaqszgEs+58+5qw7+5mmaTzsLGpBOPUgkgVCtW26h53PKtg/WszV5lNpeC5pVsbY7dPlXtQFAz7GnkedIoQx+aqngcn9aYukrZniI4BXjNTeytAQByfc+hq/ge9FTKtjZrT7MzKFKbFHcAVJLEpAmxVwB7CkkKCJCoXGKGGYfh5OewrTXCooXY6C4BU445BHz5rEKt8sUkimJYAoBn50qEZXkDn2FMrgmw9GAU8YpFeReaGPb3xSiNmIOe47gVp4xye4Peq74ZPi0Re+0q6viE+9PFCDyFHLAHtmh3VukOmywoONhGWNSF1VFwQNvuaaNWZYbSZuANp/DSJxSuQUHboqjpHTje9TjapGZApGM+tWlGq6Jrmo6eXBidvvcPp8LH4sD5Nn9qhvh7Zi3vp7yUnEe6Vj7n0py1XXE1GWO4CmO6gJaJm9QeGU/I/wBQDXkfrVo88b6fZtZo+5GiW/cW1K9giONjYLH6VlJ7TVn0+zgmdTukHwkcjFZStd6lWZqD4QrFjUY8nL8Vjck/9l/0px0TpO91zVILRLdhvYAntxXSFh0BZQNlrdX/ACp9ten7TR1NykCRnGM7aqab0+TkkyXipW2JumdGtOjtChsbZRGwXLkep9aHNflic0gvdR3yMVOT7UlSaRvxAAexr6LgwxhFRRlZJtscluiSRQ/vAI74puFx3GKxphirO1Iriya6AU5ORWrTdK/w803Jvnk2qM5PepLYW0dlDub8VLbUUFGG9im0tQo3y9u4FMeuXwdnHIHYCnOe7LxsQew4qK6rcFt2O9UsjtOy6qXCIxrU4jic96gNtc4vLyKT4S22QfuP8VN9S+IsX/Sqy12ZrLVVnBKo/wDKYfU8fuBXlfUlJYXKHa5/gv4+ic9L3TRyyIT8JGQfepna6iyjy1+Js9yef0qstA1NRcorEZIxkDFTfRbnzbxA2O+PrV307Vxz44zg+GBmhuTZMIgywfGeTWSatFpEEstziKFVLeY3ag3Mu0D4Sxz6elUV9rbrm96S6GSOxmMc15PHb8eqsefXg45/KvSKVJyZnRhukoolWs/aL6c0qVgl2k75xtAIH64x6UjtftZdN388kJV1lRQQkYLls/Tt+decB6lt21KVpr6Uvv5bcSCfz4pQ2uwbJFa7EUDD8cfB/X8z+9THUQauyw9M0ernRvizoXVsMiWN3G9woyY9wDD/AMVLYyXQNkMD6ivLHwl6se46gtbLRtXa3eS4SJpZ3ZVZWyGA+ZwFH/yGa9Oumo3stCsICxlaKJUZ3bcSQMEk+tBvWS3ETPG8dWw6+me3zz8PoajHUd8W02dU/E2FBzUo1Yq1mGPIBxkcVWPiF1Db9P6beXU7Ew2kTTOqDLcAnt68CqWoyNRoPBBXZLegtBe60i6ZQf5nwcU4L4f4ByvrSb7LPUp608NrbV5ImiW6mnMYcYbashUEj0Pw1bT28ZJw1YktLDL90jWjyuSvbPpqa1gMKMyxHumePrisqfG1Q9mH6VlD9Fi8hjpadOfHhkxUM8Q9QSynWxiPpzirnWGNFLcYA9a5x8QtS+9dT3ZUghW2jHOK18UUplfLJ7GkNz3CwLuIySKIjvJJ8kDav9aQXE4ztLn54oIugPwHJ9K3IyVGO4jt97ZcLwaLFy0khUZzTak+XGXKt7U96Xb7pBI3K0V2KY86JbKkPmSA59jSi5ud77R2ot5/h2g4HyohQN27JNJq3YadKkDnn2Rke9R6+LEMR+9O904JJzTLfOAh55qs1aY5OiMam5CsAefeoD1HYLeRvG2SD7dzVgX6gqxbn2xUUv1DM4GBgYzWVmx3aZdxSIpZ6gTF5Z+GeA4YD1Po351ZPTGqLdNp9yuBlgjAn1qqdblTS457xADMgwFz3HsfrTv4edXWmpqHgkwdwDROcNE/rkfX17GvM6fHL07U1/xy6/DHeC+JLnM5wSrgev4cZqkftK9MN1/0Rd6cm2K4ikE8cjcKrLk4BHerTW9F1EXTa+QAQx/p7fWoR1PP5lu0YPA+EeYNxB5zg/LivcxypwKccb3nlnc6REutubqe8W9ik2NbsF25BxjPHH1FOMllaCCe2uVlkigwCLcqGwRn4eDzz611l4ieFematqCXdrY2MjNxKXZQQD9T9Of0xVSaN4X6Tb69qaMVnbzNiwSzhliIAXA/3HPI79j3xmqLXPZqJKhq+zL4f23UfXdn/DIbwaXaTLNLc3p5JDAhFwMA+5+vNep2jakbq2Vd5Qeoxgk+1ci+F2gHphTJFGkUYCgpEow+fXA9eDmulOmNRWVEbIUrhWlPLH6AfLHp2q5jmqoz9RB9kw1+5S20Ul8KQ44z8655660rUvEi26ws9Gd47m9spbC0aWUoiyMmA24Zwo4OQMirQ8SOoYfuK6cj7pWXzZFXvt7enbvSbwx01fJFw+F3DCqP9IzXmdZnlqdXHSYvFOT+F/6RH7IE58Bekp/Djwx6d6emmSe60+xjinkj5V5cZkI4HBYtjjtipxJeybj3pP09DuDKR8s06tpu7OMVry4LuK3GxAupuhwSSKylUuisynBGayq7cl0OSsktp1fDcQuvmhvh7Zqgepb/AM3XLphxvlIAroqTw9020glaKPDBTjFcxdVYtepJ1z8KyMBg/Ompyj+oVNKXQG7cGTYD6cmkUV3mUqh4HH1pHeXB3O5Jx2pPpExlugOApPGfWtHHk3Izp46tk30y2WVVZh+WKkVqqouAABTVYoY4ASR2pdby/Ca0l0Z4fI+ScmtrLkBc0lebJ4OKHbMXkAxUPhEpA7g8e9Mt/vbIUDHzp5uxnIUZP9KZb3KIeKq+BxHNSDoCBjP+41Er9vxhW4J5JqU6gQVOXGT+ZqL38KkkKcgVQydlrC+CJa9bCWFkQA57sRVWajHc6brxvbCY280XwZAOGHqCPUZyaty+HxSKRjIwKg2uaXJCXlWPerfETjOPes7JFSVNWjQh8DB4B+NGtan4jdX6JrNx5+m20zPDERzEGkIOD3wM8A1dOraXF1PvlsdQ82OPG3Zww5B5H6VRfS/Rdto/V97r9iHSXUIxHdwEZSTBBDqO6tkc+hz781FvGfxC1Tw3s7O70v7/AA33nL/Nt4maIAYGHf8ACMjI9Tz2qjLJnjnWOMLg65+P3O/TZP8ArTwnvZYpR59wHlwcBm7DsODxyo/Sq70fwju1vI1ksNk4YtIXDFj34HJ/zzRPh19q7q3WobxtVm6fmaBEC2+qXgs5ZWIOSjEFTjHIJHepbc/aa1a3N1LZ9ERXckSqyPaXUdzvHrzEW7cH6Z9qvPG77LCytLosvo7wge0kE8t/JHYxqGwXKqvxbu/5U5634y6P0Ta3Om9OQSa3q8aENOpAiQc5ZW7My4/CP7HHJfWn2kuseubTW9OuLlunIfLylpFldhHBVieRnJOcf5Et8AI0Phvp/mkNNkq+Wzlgznv+ff1zVDX6mWhwrJFXbSK8m5vkt37K2v6n1tp3Ub9QzTz67b37QvLdf91o8qybvyfj/wAV1J05Y/czHGAAq4G2uUPC3qvStI8fJNGsriKT+K28YuhGc+XcRxykIccA7FBx9M12Po1mfORvxA+lX/T8cJReoqpTpv8Ago5r3ImOmyNbW+UGc0qi1GUNyCKLXykgVFIGB2pPJtOfi/emylyaEPtikO0WqkfixWVHZmVc/H+9ZSfcGJkzPivFfRvCIHVnBAJFc6ddYi1i4lGdu4nJqyDPHploZZMB8fpVcdXyrfxyTr61Y2TUFOfkr71KW1DC063lsrhvh7GklpdiPUYkQZ5GaYNN1U2l3JbSn4GOQ3saWwS+TqSvI2FJG2mYZ0yMkOGXDbzH7qoPfFDSb4OCaa7S7BgXnuBRglPbOa9AuTFoXrISe+ce9OWmcrJJjgcUxpIyCn+3iKaeinhm+I0E+qJQCaTk85pm1CY7CAB+ZpxmRVz/ADNo+dMGpXCxE/8AqE/xVebpHIY9RiDE/Fg+5NMkxwWVQrZ7saP1a7SRiomEh7YH/mmC4naFXcuFIH4QfWs6Ur6LmNUhNqtmpbzQOc/qef8ANMUyhoJBIPhbsQMg07S6luwJjsbjg013NxH5qfENjDHHfv7Umky3FvyNVjaMrskUDSEn4Sew7/8AOacT0u92jLcKgRhgqqjBFOlpdIHGIfLXsrMOad4mDKcnj+tQoJoPc0VzqHhF07qBY3Wj2VwT6vbIxJ+ZxRVp4VaDYRCK30q0hiQYCJAoXnORjFWBJchnITHBoMFnNIcN8LYJIJz3pLig9zKi1L7PXSOp3q3M2kxRuM5WEmJXB9GCkA/nU46Q8NdN0NYbawsoLa1jIYQxRhVB98Ad6m1rpOXGUPHfNSPTtKCMGVBxUrHu4aEzyqJT+n/ZxubPx+0vrTS2t4tMe5a9vkdiH8z7uYsKvruJDH6n8+tunV7ZGDGOajmmWizomMAjsRUv0i3KJLuyGKEZrSUNsW0UlNzkk/BBLDxCjkvp4p5NvxnBPtmpDF1JZSAEzLj3qreo+iLpbmeW2B25JqD6udd0yJzBLjbyVYmsBxaNpKMlwdKrLFcpujYOPkayqJ8MfEW6mlEV2Sj/AIWVjWUS/IDi1wT3q3qoEMN3w+1QqHqdLiR4JDkNwoz2qN69r5vJ2AbIFD6a0C41S8STBABzmtTUZ01tRWw4dv3MW6jpOyQyhc85FN9peGO+Ec2MD8J9anutactrZLjkqOTVYXplbU88BBzVWDTVodd8Fv6fe+ZZxkcjA5pUl1k8+lRDpvVvvFr5O5QVHYd6c47qR5SuQF+db+LJaRjzxtNkw0tfvd5HF35yefSpZOmBjgf2qM9Dx4juLpyCSdi/L3qRPJvBw3NPT3Mqy4QimjDZUYI9aZtT0KO8Ukgn9qfigHck0EZfgDPzrnBPsFSa6KU6v0K4sZt0Cu64IYcZz6EVC4tduY5Hiuo9pGOW74BrpPUtBttTt3jnUjPG4DBFUX4l9DXPS+69iH3mzB+ORRymf9w/vVSenXcS7izf4yIxqV0t1HNJG25sfCT71EY5dTa6gjjJ83JPwn4f39KNvdbjtAxGNpGSAaZ9K1/+IyzujjykG47TwPT0qjLHyXoS4LBh1CRpYyzFmTAHPBPyp2u76SQmCIndjnmodo96kkyndu8sFm+QHYfmSB+dPFvexvNJIMbye45ovabJlNIetNsRbjz5fx55JyS31p2tb2W4uhBa28s525Yom7b7D60+9FdKQahapdXu+4ZxuSJuEHtuHr9O1TKx0+KG4BhjSKI8CONdijHOaatL+StLP2R3T9L1J49727RHHCStg0629teQIPMtXGTyUw1TJEQwA5wpH4W/56UG0ZJAfLYSqOMj+lE8EY9MqvI5eBp043CMGQEgd1bg1PtJk3WJkbIJHrTLb2gZgyrg+1PF433Sz2g4AQt2qZLZEPFzKxlnSGV3DHIzUf13pyy1CJlMYLe4o0STys2MkZoaiRc7h+tefeWJsJMq3XOiW0XzLi1i3Hv8NZVr/d47lMOgOayo3/AxP5Oe+m+npr+WMyKfiOcH1q3tO0eXTrRFjhCDHJrn7pHxHu9c0SxuoWEGYwd1WTYdS6pe6duN35i+6tWfPNJ9rgsOCSJvfWRu4Hjk744qs9Y0ptPu2WVThjgNTmuuXlvMA87fEM5JpJqepJcNi4ul2jk7qZg1ag/u6EShaDtJtkts+V+Z96cI73ZKRk/rTTp2uafHOII7mN3fthhRutXP3SLzQowTz8q9JizRlFSh0Z8sbtp9ludJybdDjIOCxJPNPsO6T1yagXh7q8F5okYjbOGIxnmp3BcAHYnLHgAVp4ppozckWm0GSKsYA7seABR8UapHzy3vTfqmpW+h7JbjdLKxCJEndmPAxTg85Ee4bIiMMScH+vv2pm5WBsaQWynYcAJ+Wc0z31n99DwzKrhgQY5ACGXsR+npSC08RbDUOpr3RY5F++Wqq0ijBYbslRj6K36VJ5LkOAsyEAepqVJS5QLhKHZ59/az0K48L9esxYyNHpeplhB3zG47pn8wR8uPTNRHp7VF0XQ7aJzi7ugJJCW5xngY+tdEfbx6bd/D/TdQaFpYINSjYyL2TKuMH2ycfniuMdL1531IGaRgQw284wPX+9Z+eoZeDX0334k2XovUwsbS1t/NK3F6d7AfiCDgD696sroTTf4z5CjKwnknOSwrmfUNZkuep4ot4AVEjbaflkj5An+tdb+C5juAm3kRw5JHuasYlvTE5ft5Lx0PTitskcKnhcYT6U6WuiyKV3YjIIJB/pTEerLLp9Y0cGSU4J9gMgE/kM1CLvxQu9Y8Yj01bbzb28BkmZfwBsjGf3opZYxaQmGDJNOXgt65083NrJDHKgmAGMMCc/T9aaumNMvdLmure6jVY3fzUZf9xJ3cfpRMnUkGnW8k+8RwQY3Hbk/jXn+/51rWvE+00vq+y0ieNPIurVLlZT7FmAIwf/bn86RkS3qVkwg3FpImFoQkgQ8YOCDRXUuuJpzQbtrxErHNk8qDnmjb+4ggtE1ESqYNm5jnsMZz9K5X1rxC17qzq/UI5LW4tNMmcLFLjHwen596TnyKKobpsTk2joe41GPTbmSNRvUcgjng00XutvIxKttHtUU0XVWtbBopb03DA8SsMnHzocWpxpM29xcBj3Udq83KXLo1VEfh1a1iQHTeDWU3Lai6yy26uPT4qyhUjqRxv4A6ymv+FsFwW8sRkxNuPII9KsfQri4tIX2TOUZsKo9TXNv2e+pXs9W1PpQSeWXuXn8tsr5QU/FnPYYwa6N0eZpne8EmYiPKhWJMhT7jOef80UsaeRxZat7eRdfalLBIc3DFgNuCpx+tMt1qVxFC26RZC2VABIwKkMejQRx+dcSyNnLfzAAfl3FJW0ixuJD5lwys3HMijb9O3NNjpY+UIsrqYSrdmaJ5RcqePLOdv+KkDXOudU6elncXsq254Z41zIfTvnipKNBsrZHjti7O3Jw2QfmSO9ChtrjRD5gSLYDkJImV/TNXoRUeAG75JV4JaPrPTDyJfTGWxUZV3k3Mw9OAABV52fUMGi9P3OsXTBUJOD7KDgAfMmudIfFi6x91S2tFUHaWjJB/QvTV49dRdU3vhZZDS0ebTkDi9S1yZQpPwtjvjkjinrN7SbXJXjg97IlPiy3bHrJvEDrWxu4ZlGmadGJrkElg0zL8EYI4OCcn6fMU/wBz4r6J/wBS2fTE94P4ncrJdeWM58tUfGf/ALD9q4/6G8ZIumfCa9m0gGbVUl+KLJaSLJ5OD3OAM1E+hPHF7nrqG+eVbi4uIzay72wQhPox5GCP3NC9VSS8vsurQxnuafC6/J0R9nvqaPXPFXrXVL6aOLEp3zydsKOAPpg/rXQs2vWw6burlndLXyJZN7DBRAW5PqCAK4s6b6qsujenNYvb9RHLfXNy3wH/ALgBZcfTg/rU18AfHXTOotMg6burg3HkW8kZN3KWedW3FsknJ4OPkM+1HgzriNiNTpnJPKvFHQN7pEPiX4P6npN5F5pvrJo9rnu+3KsPmGCn6ivJ666gi0692TDZMhCsh7qc85r0p8OvEaG/1jXLGSdwdMHlRx5Hl+SAoVxzySd2foPlXm5qvTCX/UOp30sjBpbmSQlZFwNzk8evrVnK1OMZFXFB45yj+zH201uC663hxMhDqCQT/r24H9q7H8BurYNN6XaTCv8A9xnOfiO0gAfpn9TXEWldGWC3MU9ukxu435csWLD6d8/r9KtLpTq+56XsTbRmQqd2XZSAoPcn9v7d6XHLsi0h7xb39xYkfjRqHiR1JdGKS6t7eKRhEkD7VC5BCuM/F+EcGpTpviFYeEug3OqXxF1rWqyebOxYB3A7DPy4+pP6c76D1lo/TPUeoX/35bOe5yTGV+CT54xwe/r602dT9faT1YTaXt0Ykz/IuVYEJ34Py/SsrdljPeuWbN4pxWNqoove++0HqHWaxWYmNrbTyqhW2+BzHkcbs8EEDNT7T9dbqHxZhma6aawsbWC2CEk7FHxEfXLMc1yR0FpU8evxTSzRvY25EjSpJv3KO4A/z7099T+MunW0E9hpF0H1HeZLiZRgSyHk7G+XbHr86GOXK8lvkbOGHaowVHo/4VeLEHUPSmvXEloSumzyRS2wjG0IpGUX0YAevrzUL6z0ZNK6plEf8vT72Jb2zjlG0rG/Ow49VOR+QrmP7P8A4u6p094bda6tqEskdvcQ+VZhzhnkZWDsCe/cH64q4NU1+7638J/D7UZdd/h986XAZ7NfMYplNo7gjaS/bPBHtVqWRzhz2ZUsKxzcodXX+iY2up2NujYuHUEY3ICce+eKVJewRoxSW48zGeBgEe9RLp3V7ez06aCfWJtUCMU8+W3cOSO/x4AYe2R6d6kNp1Np8gWHzmaNFGAFGcc4yucjj1rMlHkjoPh1cXUTtaXExlH4lMwU1lCt9R0K5O522hcZlT+Wyn5uMfpisoNkjrRwl4labF0N4yaXraRqlpqYNtOinaGLcc98Z/PtXROldTCXS7SC3KGKKIyCKJcYY9s4B28AY5PHr3qR6lN0b1BGJdT6Utr5EbzF+8W4ba3uAaeNE13RLZjDYdOwWy9zsQKCa1vpZSad8oh5Y88Edh1G8uZB5E1xIARkCPsABjJ59x39qR6xaskcks0N47qcBTBy3rlc9s1PbPqOaeacpYwxxgAHIUZrP+o7mVXQLbRy/wDvOcD/AIKsLBJoV7iT6KqtWvo8yeSdobHlvCMtn6CjVsdb1GUl7qWxzhtkdsCMH05U1bkPUEiwfzbi2ViBnYmaJutXjkjZfvLyD1EUeMUX07Xkj3E/BUsvSevx3KmK/u1J53Jajdx/9Bj9KI1K08TTBLDZao4iAwUnXcG9ORtwPpirDuL2W2kLW7Xcu7/TJJgD9aLkvrtApliH4if5r5/pS3iryFuvwc8P0b4h208kw0uwvJX+FpIMxl+eARj057VDdZ8GfEnVepYtWTpyC0kjkV9quy7sH3A7115pmu3sLp8VjHFnAYgZBzTw3V9+X2pJp8mBtzgZz+tRDDBchPLJdHHHW/gh4odZXFvLDpZtreJdohNz8PfOcbe/zrOhPs++KfSmrffINJgEqgrueZskHvg7fWuwBr11MGeWS0QHjJwP70TH1HMhf/1tiFU9iAf70SxQSpEe9JnN2keF3i1p8urzvMttJqSGFlhk/Am7JA/pn0pBpv2dOpIUH/olk2fjWWRQR37AGumk6qukuDI95btCcgBIx+Rrd110+Nsd1H5h5P8AL4x6+lFtSXZG9t3RzRb+BHUrSP5enBk3AMokUfsaex9nDq6/I36PCVHY+apOOfc/P/8AlX9/1YbqAMJ5cqdpHl4/OjB1BGG8wXd27beY1k2iuqPlk75LpFAR/Y8v9W8sX2lwo/8A7ZMqP8jv6ZHpmlkf2DrS8haOS3ELEZV0nfMZ9cj/AFKfyI+dXmnWSozIskxGO8k3b96Mg62gljK/eFMqk5zOeK5LH4kQ5zfhHPmmfY3666LluoOnbywvbC5GTHqE2x4W5HDBfiB+g+la0z7F/W12x/iepaJp4DZIsl3MM+uWHP8AzmuiLbqy0k3hriJCDg7pSc/SlMXWFioCP93cE4LbyT9acseJ8uQn3ckekUvefYy1TWbS1ttU60eSC2GEhhZIowOPQL6/tVs6H4YPomk6fpSanYvBZRCOKJyCqAeg+EfXPelh6vtEQ7ZYdo5B2k02TdaWksgJnXHqBGQaCWHC+2FHLlfFDxN0rkIi6zpludu1sRh2x9eP3yOaRjoRoppAmvaUwfnabdCfX5cflimqTq3SmY7rgKW9Bbk/vRQ6w06BtsZZsdmEP+ar+1hTGKWRqx7foUugkbqLTkl94YthGPmMH9SayodrHWdugeVZHCKO/lYJ+VZXOGAle4QMdU6iibbi859QoVaU2fVsmNxkZ/XIf/FQ5royFSEwPdjWCSUvnzFCkei+tB7j7sbs/BPYOqdzuVWQrjJwxIFKIOq5FXdHCO3+o81BLeRolOZmGR/pOBSuBgybjKz4HbPNR7j+SPbomMnVN4eACo7/AI61J1hdgbjJGmPduajNtNbTA5Yk+mTzR1xdWdvDj8Ujdhjn51PuNeTljTFz9Sz3czM88pHpszihfxm/ZXKktj8JkNImv4Y0VYrbAOAC3P51GupetodMvXtt5IHdcYwaVzLmxiSXFEvjn1BkzKFlDHtG1DS9AiO+N4nHGMA1CdA64up5AmRNAw3AnA21JTq1oQZZGZc+gPFKaa4sJR80LX1xWG3bJj5p3pGs24EiNkYn1IBpJJqdpJkIpOPVmoCTm5VmD7W5C+hFDZKiPUVxNEvw5GfUueKUJd3DDLzDB7ADJqMzR3UdoWkvEmCkHBIDftRtlqMYkEDyKJh2Utyc1Nk7ESGW5eHaxunYYxtBwP0pL55CsWuJmJ5whpqvbibIKbNw4wx70b5ojiQ42gDBC9qGVsOEUKnnjLndvIAHBkIP6UWJPurOot/hf/WXzSMz+ZvIA2kdjTTe3t8JwtvcIkSjnI5zS7rkYop8EqtLpUJ2Ab85+dO1pcMQecMPb0qEaLFeteM8127xH0Cng1JI7Bd7MoLMB3Pc0+ErFSgkOB1cRjElxEBnHPGKSPq8Llj96jC+4NNV5vgBCWyFmOOaSx283wHyRtGdyn1onIiOMX3et28fAuUf5DvSU6vFMzlZnXcMYOaTXMKOwIhVGXt71jyhI8SBzgZG1KCw9tCfWtWEbQRostzkjIHoKygvfrKrNJAy4GMhMHvWVB1DdDrS/dgkLxFwDklMf1rU1zPcKA10sYx3TApqtXDgEonA9qV2saSRbii5GfSmOQKikH2YtSSjXzFgc7Sw5/OnGCW27C5Gf/lxSGK0hSZSIlyygk4pQkUapgRJ3x2oV0FSTFaJH6TYOM5zxSSC2nkmMpnRgBhMN6Vk6Jt27FxigwsFO0KoGPQV34OoPklmZwrs7Njjn+lR3qjoS36guFufvk9jcoQTt+IMR7in0cgt2I7YNalZpXO5ie3rUxk0DQl0TRY9Ih2IzSErtZ3XAHfsKXB4YwI44nlPox7E0XcztbRbl+Ijtv59DSYXc0wUmVlDEZVeBUPl2HEWpbzSIcwogJwcnmhacohmaKTy0EYwu5s5pIkQd2JLEqeMnNLIItztliaXQQfNdQ43OYlQHJJFFP5LI0kRC3CcrIU9R2pROwtLbKor7f8AeM0yXmu3TzmH4FQuM7VriUONv1FFqgiQALPglx5ZO1hW36ge2huI7lXyEJDCA4OKiouni1FZY8RvuydoxnmpNc3kptpdzBwV7MoIqU+CHHkV6V1FZahp6Lb+duAG4OoBX5UOe9E6ujRy/AMjGBUQ05GdG/muh3d1IBpVGZVwouJueM7uaUwoofINUu5XYwhxCDhlLAEVI7G9uJY+NynOCrSDkVXUqusUrCaXepxu3cn60kiu5sKxldjvI5Y0Kk4h7Uy0JUnmkzsLD38wUWzSodhU/wD5BURs7mR05Y9wO5+dGwSMb8xk5XHqaJTt0DtpWPU8bKdxjPGc/wAwHNJwZJshY2x7hhQmhRouVHai4kCICB+9MXAu7BKssW5GRmjx6uKykeoxL5R754Oc1lCmyej/2Q=='; diff --git a/1st-gen/packages/dialog/stories/index.ts b/1st-gen/packages/dialog/stories/index.ts new file mode 100644 index 00000000000..a4da110679e --- /dev/null +++ b/1st-gen/packages/dialog/stories/index.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; + +class CountdownWatcher extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + connectedCallback(): void { + (this.previousElementSibling as HTMLElement).addEventListener( + 'countdown-complete', + () => { + this.ready(true); + } + ); + this.readyPromise = new Promise((res) => { + this.ready = res; + }); + } + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } +} + +customElements.define('countdown-complete-watcher', CountdownWatcher); + +export const disabledButtonDecorator = ( + story: () => TemplateResult +): TemplateResult => { + return html` + ${story()} + + `; +}; + +export const withOverlayDecorator = ( + story: () => TemplateResult +): TemplateResult => { + return html` + Toggle Dialog + + ${story()} + + `; +}; + +export const disabledButtonWithOverlayDecorator = ( + story: () => TemplateResult +): TemplateResult => withOverlayDecorator(() => disabledButtonDecorator(story)); diff --git a/1st-gen/packages/dialog/test/benchmark/basic-test.ts b/1st-gen/packages/dialog/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..81a46819627 --- /dev/null +++ b/1st-gen/packages/dialog/test/benchmark/basic-test.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/dialog/sp-dialog.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +

Disclaimer

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Auctor augue mauris + augue neque gravida. Libero volutpat sed ornare arcu. Quisque egestas + diam in arcu cursus euismod quis viverra. Posuere ac ut consequat semper + viverra nam libero justo laoreet. Enim ut tellus elementum sagittis + vitae et leo duis ut. Neque laoreet suspendisse interdum consectetur + libero id faucibus nisl. Diam volutpat commodo sed egestas egestas. + Dolor magna eget est lorem ipsum dolor. Vitae suscipit tellus mauris a + diam maecenas sed. Turpis in eu mi bibendum neque egestas congue. + Rhoncus est pellentesque elit ullamcorper dignissim cras lobortis. +
+`); diff --git a/1st-gen/packages/dialog/test/dialog-base.test.ts b/1st-gen/packages/dialog/test/dialog-base.test.ts new file mode 100644 index 00000000000..44f6fa7f7da --- /dev/null +++ b/1st-gen/packages/dialog/test/dialog-base.test.ts @@ -0,0 +1,149 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + aTimeout, + elementUpdated, + expect, + fixture, + html, + oneEvent, +} from '@open-wc/testing'; +import { TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/dialog/sp-dialog-base.js'; +import { Theme } from '@spectrum-web-components/theme'; +import { OverlayTrigger } from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; +import { alertDestructive } from '../stories/dialog.stories.js'; +import { Button } from '@spectrum-web-components/button/src/Button.js'; +import { DialogBase } from '@spectrum-web-components/dialog'; + +async function styledFixture( + story: TemplateResult +): Promise { + const test = await fixture(html` + + ${story} + + `); + return test.children[0] as T; +} + +const overlayTrigger = (story: () => TemplateResult): TemplateResult => html` + + Toggle Dialog + ${story()} + +`; + +describe('dialog base', () => { + it('does not close by default when interacting with buttons', async () => { + const el = await styledFixture( + overlayTrigger( + () => html` + + ${alertDestructive()} + + ` + ) + ); + await elementUpdated(el); + + const dialog = el.querySelector('sp-dialog-base') as DialogBase; + await elementUpdated(dialog); + const secondaryButton = el.querySelector( + '[variant="secondary"]' + ) as Button; + const negativeButton = el.querySelector( + '[variant="negative"]' + ) as Button; + + expect(el.open).to.be.undefined; + expect(dialog.open).to.be.false; + const opened = oneEvent(el, 'sp-opened'); + el.open = 'click'; + await opened; + + expect(dialog.open).to.be.true; + expect(el.open).to.be.equal('click'); + + secondaryButton.click(); + // Give time to ensure reactions DO NOT close the dialog. + await aTimeout(100); + + expect(el.open).to.be.equal('click'); + + negativeButton.click(); + // Give time to ensure reactions DO NOT close the dialog. + await aTimeout(100); + + expect(el.open).to.be.equal('click'); + + const closed = oneEvent(el, 'sp-closed'); + dialog.open = false; + await closed; + + expect(dialog.open).to.be.false; + }); + it('does not close by default when interacting with buttons when recycled', async () => { + const el = await styledFixture( + overlayTrigger( + () => html` + + ${alertDestructive()} + + ` + ) + ); + await elementUpdated(el); + + const dialog = el.querySelector('sp-dialog-base') as DialogBase; + await elementUpdated(dialog); + const secondaryButton = el.querySelector( + '[variant="secondary"]' + ) as Button; + const negativeButton = el.querySelector( + '[variant="negative"]' + ) as Button; + + expect(el.open).to.be.undefined; + expect(dialog.open).to.be.false; + const opened = oneEvent(el, 'sp-opened'); + el.open = 'click'; + await opened; + + expect(dialog.open).to.be.true; + expect(el.open).to.be.equal('click'); + + secondaryButton.click(); + // Give time to ensure reactions DO NOT close the dialog. + await aTimeout(100); + + expect(el.open).to.be.equal('click'); + + negativeButton.click(); + // Give time to ensure reactions DO NOT close the dialog. + await aTimeout(100); + + expect(el.open).to.be.equal('click'); + + const closed = oneEvent(el, 'sp-closed'); + dialog.open = false; + await closed; + await elementUpdated(el); + + expect(dialog.open).to.be.false; + }); +}); diff --git a/1st-gen/packages/dialog/test/dialog-memory.test.ts b/1st-gen/packages/dialog/test/dialog-memory.test.ts new file mode 100644 index 00000000000..f927863336e --- /dev/null +++ b/1st-gen/packages/dialog/test/dialog-memory.test.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { small } from '../stories/dialog.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(small()); diff --git a/1st-gen/packages/dialog/test/dialog-wrapper.test.ts b/1st-gen/packages/dialog/test/dialog-wrapper.test.ts new file mode 100644 index 00000000000..a228700f174 --- /dev/null +++ b/1st-gen/packages/dialog/test/dialog-wrapper.test.ts @@ -0,0 +1,376 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + elementUpdated, + expect, + fixture, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { SinonStub, spy, stub } from 'sinon'; + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { Button } from '@spectrum-web-components/button'; +import { Dialog, DialogWrapper } from '@spectrum-web-components/dialog'; +import '@spectrum-web-components/dialog/sp-dialog-wrapper.js'; +import { Divider } from '@spectrum-web-components/divider/src/Divider.js'; +import { OverlayTrigger } from '@spectrum-web-components/overlay'; +import { nextFrame } from '@spectrum-web-components/overlay/src/AbstractOverlay.js'; +import { Theme } from '@spectrum-web-components/theme'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import { Underlay } from '@spectrum-web-components/underlay'; +import { + mouseClickOn, + testForLitDevWarnings, +} from '../../../test/testing-helpers.js'; +import { + lazyHero, + longContent, + wrapperButtons, + wrapperButtonsUnderlay, + wrapperDismissable, + wrapperDismissableUnderlayError, + wrapperFullscreen, + wrapperHeadlineVisibilityNone, + wrapperLabeledHero, + wrapperWithHeadline, + wrapperWithHeadlineNoDivider, +} from '../stories/dialog-wrapper.stories.js'; + +async function styledFixture( + story: TemplateResult +): Promise { + const test = await fixture(html` + + ${story} + + `); + return test.children[0] as T; +} + +describe('Dialog Wrapper', () => { + testForLitDevWarnings( + async () => await styledFixture(wrapperDismissable()) + ); + it('loads wrapped dialog accessibly', async () => { + const el = await styledFixture(wrapperDismissable()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads labeled hero dialog accessibly', async () => { + const el = await styledFixture(wrapperLabeledHero()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads fullscreen wrapped dialog accessibly', async () => { + const el = await styledFixture(wrapperFullscreen()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + xit('loads with underlay and no headline accessibly', async () => { + const el = await styledFixture(wrapperButtonsUnderlay()); + await elementUpdated(el); + el.headline = ''; + await elementUpdated(el); + await expect(el).to.be.accessible(); + }); + it('opens and closes', async () => { + const closeSpy = spy(); + const openedSpy = spy(); + const test = await styledFixture(html` +
openedSpy()}>${longContent()}
+ `); + const overlayTrigger = test.querySelector( + 'overlay-trigger' + ) as OverlayTrigger; + const el = test.querySelector('sp-dialog-wrapper') as DialogWrapper; + el.addEventListener('close', () => closeSpy()); + await waitUntil( + () => openedSpy.calledOnce, + 'click content projected to overlay', + { timeout: 2000 } + ); + + expect(el.open).to.be.true; + const closed = oneEvent(overlayTrigger, 'sp-closed'); + overlayTrigger.open = undefined; + await closed; + + expect(el.open).to.be.false; + expect(closeSpy.callCount).to.equal(1); + }); + it('opens and closes when element is recycled', async () => { + const closeSpy = spy(); + const openedSpy = spy(); + const test = await styledFixture(html` +
openedSpy()}>${longContent()}
+ `); + const overlayTrigger = test.querySelector( + 'overlay-trigger' + ) as OverlayTrigger; + const el = test.querySelector('sp-dialog-wrapper') as DialogWrapper; + el.addEventListener('close', () => closeSpy()); + + await waitUntil( + () => openedSpy.calledOnce, + 'click content projected to overlay', + { timeout: 2000 } + ); + + expect(el.open).to.be.true; + const closed = oneEvent(overlayTrigger, 'sp-closed'); + overlayTrigger.open = undefined; + await closed; + + expect(el.open).to.be.false; + expect(closeSpy.callCount).to.equal(1); + }); + it("shows header divider when there's a header", async () => { + const wrapper = await styledFixture( + wrapperWithHeadline() + ); + await elementUpdated(wrapper); + + const dialog = wrapper.shadowRoot.querySelector('sp-dialog') as Dialog; + const divider = dialog.shadowRoot.querySelector( + 'sp-divider.divider' + ) as Divider; + + expect(divider).to.be.not.null; + }); + it('hides header divider when there\'s a header but "no-divider"', async () => { + const wrapper = await styledFixture( + wrapperWithHeadlineNoDivider() + ); + await elementUpdated(wrapper); + + await expect(wrapper).to.be.accessible(); + + const dialog = wrapper.shadowRoot.querySelector('sp-dialog') as Dialog; + const divider = dialog.shadowRoot.querySelector( + 'sp-divider.divider' + ) as Divider; + + expect(divider).to.be.null; + }); + it("hides header divider when there's no header", async () => { + const wrapper = await styledFixture( + wrapperHeadlineVisibilityNone() + ); + await elementUpdated(wrapper); + + await expect(wrapper).to.be.accessible(); + + const dialog = wrapper.shadowRoot.querySelector('sp-dialog') as Dialog; + const divider = dialog.shadowRoot.querySelector( + 'sp-divider.divider' + ) as Divider; + + expect(divider).to.be.null; + }); + it('dismisses via clicking the underlay when [dismissable]', async () => { + const test = await styledFixture( + wrapperDismissableUnderlayError() + ); + const el = test.querySelector('sp-dialog-wrapper') as DialogWrapper; + await elementUpdated(el); + expect(el.open).to.be.true; + el.dismissable = true; + const underlay = el.shadowRoot.querySelector('sp-underlay') as Underlay; + underlay.click(); + await elementUpdated(el); + expect(el.open).to.be.false; + }); + it('does not dismiss via clicking the underlay :not([dismissable])', async () => { + const el = await styledFixture(wrapperButtonsUnderlay()); + await elementUpdated(el); + expect(el.open).to.be.true; + const underlay = el.shadowRoot.querySelector('sp-underlay') as Underlay; + underlay.click(); + await elementUpdated(el); + expect(el.open).to.be.true; + }); + it('dismisses', async () => { + const el = await styledFixture(wrapperDismissable()); + + await elementUpdated(el); + expect(el.open).to.be.true; + + const root = el.shadowRoot ? el.shadowRoot : el; + const dialog = root.querySelector('sp-dialog') as Dialog; + const dialogRoot = dialog.shadowRoot ? dialog.shadowRoot : dialog; + const dismissButton = dialogRoot.querySelector( + '.close-button' + ) as HTMLButtonElement; + expect(dismissButton.ariaLabel).to.be.equals('Close'); + dismissButton.click(); + + await elementUpdated(el); + expect(el.open).to.be.false; + }); + it('manages entry focus - buttons', async () => { + const el = await styledFixture(wrapperButtons()); + + await elementUpdated(el); + expect(el.open).to.be.true; + expect(document.activeElement !== el, 'no focused').to.be.true; + + const button = el.shadowRoot.querySelector('sp-button') as Button; + + el.focus(); + await elementUpdated(el); + expect( + document.activeElement === el, + `focused generally, ${document.activeElement}` + ).to.be.true; + expect( + (button.getRootNode() as Document).activeElement === button, + `focused specifically, ${ + (button.getRootNode() as Document).activeElement?.outerHTML + }` + ).to.be.true; + }); + it('dispatches `confirm`, `cancel` and `secondary`', async () => { + const confirmSpy = spy(); + const cancelSpy = spy(); + const secondarySpy = spy(); + const handleConfirm = (): void => confirmSpy(); + const handleCancel = (): void => cancelSpy(); + const handleSecondary = (): void => secondarySpy(); + const el = await styledFixture(wrapperButtons()); + el.addEventListener('confirm', handleConfirm); + el.addEventListener('cancel', handleCancel); + el.addEventListener('secondary', handleSecondary); + + await elementUpdated(el); + expect(confirmSpy.called).to.be.false; + expect(cancelSpy.called).to.be.false; + expect(secondarySpy.called).to.be.false; + + const accentButton = el.shadowRoot.querySelector( + '[variant="accent"]' + ) as Button; + const primaryButton = el.shadowRoot.querySelector( + '[variant="primary"]' + ) as Button; + const secondaryButton = el.shadowRoot.querySelector( + '[variant="secondary"]' + ) as Button; + + accentButton.click(); + + await elementUpdated(el); + expect(confirmSpy.called, 'dispatched `confirm`').to.be.true; + expect(secondarySpy.called).to.be.false; + expect(cancelSpy.called).to.be.false; + + primaryButton.click(); + + await elementUpdated(el); + expect(confirmSpy.callCount).to.equal(1); + expect(secondarySpy.called, 'dispatched `cancel`').to.be.true; + expect(cancelSpy.called).to.be.false; + + secondaryButton.click(); + + await elementUpdated(el); + expect(confirmSpy.callCount).to.equal(1); + expect(secondarySpy.callCount).to.equal(1); + expect(cancelSpy.called, 'dispatched `secondary`').to.be.true; + }); + + describe('dev mode', () => { + let consoleWarnStub!: SinonStub; + before(() => { + consoleWarnStub = stub(console, 'warn'); + }); + afterEach(() => { + consoleWarnStub.resetHistory(); + }); + after(() => { + consoleWarnStub.restore(); + }); + it('warns in Dev Mode when accessible attributes are not leveraged', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(consoleWarnStub.called, 'console.warn called').to.be.true; + const spyCall = consoleWarnStub.getCall(0); + expect( + spyCall.args.at(0).includes('accessible'), + 'confirm accessibility-centric message' + ).to.be.true; + expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({ + data: { + localName: 'sp-dialog-wrapper', + type: 'accessibility', + level: 'default', + }, + }); + }); + }); + + it('manages content element tabindex on resize observer time', async () => { + const imgReadyPromise = new Promise((res) => { + const img = document.createElement('img'); + img.onload = res; + img.src = lazyHero.args.src; + }); + const test = await styledFixture(lazyHero(lazyHero.args)); + const dialog = document.querySelector( + 'sp-dialog-wrapper' + ) as DialogWrapper; + const button = document.querySelector('sp-button') as Button; + const contentElement = ( + (dialog as unknown as { dialog: Dialog }).dialog as unknown as { + contentElement: HTMLElement; + } + ).contentElement; + expect(contentElement.hasAttribute('tabindex')).to.be.false; + await elementUpdated(dialog); + const opened = oneEvent(test, 'sp-opened'); + await mouseClickOn(button); + await opened; + await elementUpdated(dialog); + await imgReadyPromise; + // Resize observer timing. + await nextFrame(); + await nextFrame(); + expect(contentElement.hasAttribute('tabindex')).to.be.true; + }); +}); + +describe('dev mode', () => { + let consoleWarnStub!: ReturnType; + before(() => { + window.__swc.verbose = true; + consoleWarnStub = stub(console, 'warn'); + }); + afterEach(() => { + consoleWarnStub.resetHistory(); + }); + after(() => { + window.__swc.verbose = false; + consoleWarnStub.restore(); + }); +}); diff --git a/1st-gen/packages/dialog/test/dialog.test.ts b/1st-gen/packages/dialog/test/dialog.test.ts new file mode 100644 index 00000000000..6efb18722ad --- /dev/null +++ b/1st-gen/packages/dialog/test/dialog.test.ts @@ -0,0 +1,262 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + elementUpdated, + expect, + fixture, + html, + nextFrame, +} from '@open-wc/testing'; +import { TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/dialog/sp-dialog.js'; +import { Dialog } from '@spectrum-web-components/dialog'; +import { + alertError, + dismissable, + fullscreen, + small, +} from '../stories/dialog.stories.js'; +import { spy } from 'sinon'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('Dialog', () => { + testForLitDevWarnings(async () => await fixture(small())); + it('loads `[size=small]` dialog accessibly', async () => { + const el = await fixture(small()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads `[size=alert]` dialog accessibly', async () => { + const el = await fixture(alertError()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads `[dismissable]` dialog accessibly', async () => { + const el = await fixture(dismissable()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads `[mode=fullscreen]` dialog accessibly', async () => { + const el = await fixture(fullscreen()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads dialog without footer accessibly', async () => { + const el = await fixture(small()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('does not recycle applied content ids', async () => { + const el = await fixture(html` + +

Disclaimer

+
+ `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + const paragraph = document.createElement('p'); + paragraph.textContent = 'Added paragraph.'; + + el.querySelector('p')?.remove(); + el.insertAdjacentElement('beforeend', paragraph); + + // Slotchange time exists outside of the standard update lifecycle + await nextFrame(); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + paragraph.querySelector('p')?.remove(); + + // Slotchange time exists outside of the standard update lifecycle + await nextFrame(); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + el.insertAdjacentElement('beforeend', paragraph); + + // Slotchange time exists outside of the standard update lifecycle + await nextFrame(); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + const heading = document.createElement('h2'); + heading.slot = 'heading'; + heading.textContent = 'New heading'; + + el.querySelector('h2')?.remove(); + el.insertAdjacentElement('afterbegin', heading); + + // Slotchange time exists outside of the standard update lifecycle + await nextFrame(); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('closes', async () => { + const closeSpy = spy(); + const el = await fixture(dismissable()); + el.addEventListener('close', () => closeSpy()); + await elementUpdated(el); + + const closeButton = ( + el.shadowRoot + ? el.shadowRoot.querySelector('.close-button') + : el.querySelector('.close-button ') + ) as HTMLElement; + + expect(closeButton.ariaLabel).to.be.equals('Close'); + + closeButton.click(); + + await elementUpdated(el); + expect(closeSpy.calledOnce).to.be.true; + }); + it('allows hero override', async () => { + class Override extends Dialog { + protected override get hasHero(): boolean { + return true; + } + protected override renderHero(): TemplateResult { + return html` +
+ `; + } + } + + customElements.define('hero-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#hero-container'); + expect(container).to.not.be.null; + }); + it('allows heading override', async () => { + class Override extends Dialog { + protected override renderHeading(): TemplateResult { + return html` +

Test

+ `; + } + } + + customElements.define('heading-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#heading-container'); + expect(container).to.not.be.null; + }); + it('allows content override', async () => { + class Override extends Dialog { + protected override renderContent(): TemplateResult { + return html` +

Test

+ `; + } + } + + customElements.define('content-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#content-container'); + expect(container).to.not.be.null; + }); + it('allows footer override', async () => { + class Override extends Dialog { + protected override get hasFooter(): boolean { + return true; + } + protected override renderFooter(): TemplateResult { + return html` + + `; + } + } + + customElements.define('footer-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#footer-container'); + expect(container).to.not.be.null; + }); + it('allows button override', async () => { + class Override extends Dialog { + protected override get hasButtons(): boolean { + return true; + } + protected override renderButtons(): TemplateResult { + return html` +

Test

+ `; + } + } + + customElements.define('button-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#button-container'); + expect(container).to.not.be.null; + }); + it('allows dismiss override', async () => { + class Override extends Dialog { + protected override renderDismiss(): TemplateResult { + return html` +

Test

+ `; + } + } + + customElements.define('dismiss-dialog', Override); + + const el = await fixture(html` + + `); + + const container = el.shadowRoot.querySelector('#dismiss-container'); + expect(container).to.not.be.null; + }); +}); diff --git a/1st-gen/packages/dialog/tsconfig.json b/1st-gen/packages/dialog/tsconfig.json new file mode 100644 index 00000000000..3d15c25d50e --- /dev/null +++ b/1st-gen/packages/dialog/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../action-button" }, + { "path": "../icons-ui" }, + { "path": "../icons-workflow" }, + { "path": "../../tools/shared" }, + { "path": "../underlay" } + ] +} diff --git a/1st-gen/packages/divider/.npmrc b/1st-gen/packages/divider/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/divider/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/divider/CHANGELOG.md b/1st-gen/packages/divider/CHANGELOG.md new file mode 100644 index 00000000000..7dd03fa4172 --- /dev/null +++ b/1st-gen/packages/divider/CHANGELOG.md @@ -0,0 +1,427 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- [#5629](https://github.com/adobe/spectrum-web-components/pull/5629) [`826a2d5`](https://github.com/adobe/spectrum-web-components/commit/826a2d533e46a6f945daefa8999fadca78bd8688) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! - **Added**: `staticColor` property to the Divider component, enabling programmatic control of the existing static color functionality. + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Features + +- add `static-color` to replace `static` ([#4808](https://github.com/adobe/spectrum-web-components/issues/4808)) ([43cf086](https://github.com/adobe/spectrum-web-components/commit/43cf0865d902346568c755650f53410c7788f2a1)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- **divider:** update a11y semantics ([46e6a12](https://github.com/adobe/spectrum-web-components/commit/46e6a1257135389e72a09f376f6b9149573873e6)) +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **divider:** create sp-divider from sp-rule ([ec26d81](https://github.com/adobe/spectrum-web-components/commit/ec26d81bf92742a42913b8cb7f87beaba035743a)) +- **divider:** use core tokens ([e30c969](https://github.com/adobe/spectrum-web-components/commit/e30c969c8688ca37b5b750cd8333844d383927fb)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.8...@spectrum-web-components/divider@0.6.9) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.7...@spectrum-web-components/divider@0.6.8) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.6...@spectrum-web-components/divider@0.6.7) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.5...@spectrum-web-components/divider@0.6.6) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.4...@spectrum-web-components/divider@0.6.5) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.3...@spectrum-web-components/divider@0.6.4) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.2...@spectrum-web-components/divider@0.6.3) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.1...@spectrum-web-components/divider@0.6.2) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.6.0...@spectrum-web-components/divider@0.6.1) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.5.1...@spectrum-web-components/divider@0.6.0) (2022-10-28) + +### Features + +- **divider:** use core tokens ([e30c969](https://github.com/adobe/spectrum-web-components/commit/e30c969c8688ca37b5b750cd8333844d383927fb)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.5.0...@spectrum-web-components/divider@0.5.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.12...@spectrum-web-components/divider@0.5.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.4.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.11...@spectrum-web-components/divider@0.4.12) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.10...@spectrum-web-components/divider@0.4.11) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.9...@spectrum-web-components/divider@0.4.10) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.8...@spectrum-web-components/divider@0.4.9) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.7...@spectrum-web-components/divider@0.4.8) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.6...@spectrum-web-components/divider@0.4.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.5...@spectrum-web-components/divider@0.4.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.4...@spectrum-web-components/divider@0.4.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.3...@spectrum-web-components/divider@0.4.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.2...@spectrum-web-components/divider@0.4.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.1...@spectrum-web-components/divider@0.4.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.4.0...@spectrum-web-components/divider@0.4.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.3.1...@spectrum-web-components/divider@0.4.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.3.0...@spectrum-web-components/divider@0.3.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.8...@spectrum-web-components/divider@0.3.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.2.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.7...@spectrum-web-components/divider@0.2.8) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.6...@spectrum-web-components/divider@0.2.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.5...@spectrum-web-components/divider@0.2.6) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.4...@spectrum-web-components/divider@0.2.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.3...@spectrum-web-components/divider@0.2.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.2...@spectrum-web-components/divider@0.2.3) (2021-03-29) + +### Bug Fixes + +- **divider:** update a11y semantics ([46e6a12](https://github.com/adobe/spectrum-web-components/commit/46e6a1257135389e72a09f376f6b9149573873e6)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.1...@spectrum-web-components/divider@0.2.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/divider + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.2.0...@spectrum-web-components/divider@0.2.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/divider + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.1.1...@spectrum-web-components/divider@0.2.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/divider@0.1.0...@spectrum-web-components/divider@0.1.1) (2021-02-11) + +### Bug Fixes + +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# 0.1.0 (2021-02-02) + +### Features + +- **divider:** create sp-divider from sp-rule ([ec26d81](https://github.com/adobe/spectrum-web-components/commit/ec26d81bf92742a42913b8cb7f87beaba035743a)) diff --git a/1st-gen/packages/divider/README.md b/1st-gen/packages/divider/README.md new file mode 100644 index 00000000000..988a39da68c --- /dev/null +++ b/1st-gen/packages/divider/README.md @@ -0,0 +1,198 @@ +## Overview + +`sp-divider` brings clarity to a layout by grouping and dividing content that exists in close proximity. It can also be used to establish rhythm and hierarchy. + +[View the design documentation for this component.](https://spectrum.adobe.com/page/divider/) + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/divider?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/divider) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/divider?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/divider) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-rqfjtpgz) + +```zsh +yarn add @spectrum-web-components/divider +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/divider/sp-divider.js'; +``` + +When looking to leverage the `Divider` base class as a type and/or for extension purposes, do so via: + +```js +import { Divider } from '@spectrum-web-components/divider'; +``` + +### Options + +Horizontal dividers are used to separate content stacked vertically. + + +Small + + +```html +

Small

+ +

+ The small divider is used to divide similar components such as table rows, + action button groups, and components within a panel. +

+``` + +
+Medium + + +```html +

Medium

+ +

+ The medium divider is used to divide subsections on a page, or to separate + different groups of components such as panels, rails, etc. +

+``` + +
+Large + + +```html +

Large

+ +

+ The large divider should be used only for page titles or section titles. +

+``` + +
+
+ +#### Vertical + +Vertical dividers are used to separate content horizontally. + +When a vertical divider is used inside of a flex container, use `align-self: stretch; height: auto;` on the divider. + + +Small + + +```html +
+ + + + + + + +
+``` + +
+Medium + + +```html +
+ + + + + + + +
+``` + +
+Large + + +```html +
+ + + + + + + +
+``` + +
+
+ +#### Static color + +Use the static color option when a divider needs to be placed on top of a color background or visual. Static color dividers are available in black or white regardless of color theme. + + +Static black + + +```html +
+

+ Static black on light background +

+ +

+ Use static black on light color or image backgrounds. +

+
+``` + +
+Static white + + +```html +
+

+ Static white on dark background +

+ +

+ Use static white on dark color or image backgrounds. +

+
+``` + +
+
+ +### Accessibility + +The `` element implements the following accessibility features: + +- **ARIA role**: Automatically sets `role="separator"` to ensure proper semantic meaning for assistive technologies +- **Orientation support**: When `vertical` is true, automatically sets `aria-orientation="vertical"` to indicate the divider's orientation + +#### Best practices + +- Medium or large dividers can be used with header text to visually create a section or page title. Place the divider below the header for best results. +- Ensure sufficient color contrast when using `static-color` variants on colored backgrounds. +- Use dividers to create meaningful visual separation, not just decorative lines. +- Use dividers sparingly; excessive use can diminish their visual impact. diff --git a/1st-gen/packages/divider/package.json b/1st-gen/packages/divider/package.json new file mode 100644 index 00000000000..408d1ae9af6 --- /dev/null +++ b/1st-gen/packages/divider/package.json @@ -0,0 +1,77 @@ +{ + "name": "@spectrum-web-components/divider", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/divider", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/divider" + }, + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "type": "module", + "exports": { + ".": { + "default": "./src/index.js", + "development": "./src/index.dev.js" + }, + "./package.json": "./package.json", + "./sp-divider.js": { + "default": "./sp-divider.js", + "development": "./sp-divider.dev.js" + }, + "./src/Divider.js": { + "default": "./src/Divider.js", + "development": "./src/Divider.dev.js" + }, + "./src/divider-overrides.css.js": "./src/divider-overrides.css.js", + "./src/divider.css.js": "./src/divider.css.js", + "./src/index.js": { + "default": "./src/index.js", + "development": "./src/index.dev.js" + } + }, + "main": "./src/index.js", + "module": "./src/index.js", + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js", + "./stories/typography-decorator.js" + ], + "types": "./src/index.d.ts", + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/core": "0.0.1" + }, + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "customElements": "custom-elements.json" +} diff --git a/1st-gen/packages/divider/sp-divider.ts b/1st-gen/packages/divider/sp-divider.ts new file mode 100644 index 00000000000..85554a65b3c --- /dev/null +++ b/1st-gen/packages/divider/sp-divider.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Divider } from './src/Divider.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-divider', Divider); + +declare global { + interface HTMLElementTagNameMap { + 'sp-divider': Divider; + } +} diff --git a/1st-gen/packages/divider/src/Divider.ts b/1st-gen/packages/divider/src/Divider.ts new file mode 100644 index 00000000000..c0df5648376 --- /dev/null +++ b/1st-gen/packages/divider/src/Divider.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + TemplateResult, +} from '@spectrum-web-components/base'; + +import { DividerBase } from '@spectrum-web-components/core/components/divider'; +import styles from './divider.css.js'; + +/** + * @element sp-divider + */ +export class Divider extends DividerBase { + public static override styles: CSSResultArray = [styles]; + + protected override render(): TemplateResult { + return html``; + } +} diff --git a/1st-gen/packages/divider/src/divider-overrides.css b/1st-gen/packages/divider/src/divider-overrides.css new file mode 100644 index 00000000000..55170027adb --- /dev/null +++ b/1st-gen/packages/divider/src/divider-overrides.css @@ -0,0 +1,17 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-divider-background-color: var(--system-divider-background-color); + --spectrum-divider-background-color-static-white: var(--system-divider-background-color-static-white); + --spectrum-divider-background-color-static-black: var(--system-divider-background-color-static-black); +} diff --git a/1st-gen/packages/divider/src/divider.css b/1st-gen/packages/divider/src/divider.css new file mode 100644 index 00000000000..27ab0099bc4 --- /dev/null +++ b/1st-gen/packages/divider/src/divider.css @@ -0,0 +1,23 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-divider.css"); +@import url("./divider-overrides.css"); + +:host { + display: block; +} + +hr { + border: none; + margin: 0; +} diff --git a/1st-gen/packages/divider/src/index.ts b/1st-gen/packages/divider/src/index.ts new file mode 100644 index 00000000000..c050a02046e --- /dev/null +++ b/1st-gen/packages/divider/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './Divider.js'; diff --git a/1st-gen/packages/divider/src/spectrum-divider.css b/1st-gen/packages/divider/src/spectrum-divider.css new file mode 100644 index 00000000000..3cb844a9e29 --- /dev/null +++ b/1st-gen/packages/divider/src/spectrum-divider.css @@ -0,0 +1,72 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-divider-background-color: CanvasText; + } +} + +:host { + --spectrum-divider-thickness: var(--spectrum-divider-thickness-medium); +} + +:host([size="s"]) { + --spectrum-divider-thickness: var(--spectrum-divider-thickness-small); +} + +:host([size="l"]) { + --spectrum-divider-thickness: var(--spectrum-divider-thickness-large); + --spectrum-divider-background-color: var(--spectrum-gray-800); +} + +:host([static-color="white"]) { + --mod-divider-background-color: var(--mod-divider-background-color-medium-static-white, var(--spectrum-divider-background-color-static-white)); +} + +:host([static-color="white"][size="s"]) { + --mod-divider-background-color: var(--mod-divider-background-color-small-static-white, var(--spectrum-divider-background-color-static-white)); +} + +:host([static-color="white"][size="l"]) { + --mod-divider-background-color: var(--mod-divider-background-color-large-static-white, var(--spectrum-transparent-white-800)); +} + +:host([static-color="black"]) { + --mod-divider-background-color: var(--mod-divider-background-color-medium-static-black, var(--spectrum-divider-background-color-static-black)); +} + +:host([static-color="black"][size="s"]) { + --mod-divider-background-color: var(--mod-divider-background-color-small-static-black, var(--spectrum-divider-background-color-static-black)); +} + +:host([static-color="black"][size="l"]) { + --mod-divider-background-color: var(--mod-divider-background-color-large-static-black, var(--spectrum-transparent-black-800)); +} + +:host { + block-size: var(--mod-divider-thickness, var(--spectrum-divider-thickness)); + inline-size: 100%; + border: none; + border-width: var(--mod-divider-thickness, var(--spectrum-divider-thickness)); + border-radius: var(--mod-divider-thickness, var(--spectrum-divider-thickness)); + background-color: var(--highcontrast-divider-background-color, var(--mod-divider-background-color, var(--spectrum-divider-background-color))); + overflow: visible; +} + +:host([vertical]) { + inline-size: var(--mod-divider-thickness, var(--spectrum-divider-thickness)); + block-size: 100%; + block-size: var(--mod-divider-vertical-height, 100%); + margin-block: var(--mod-divider-vertical-margin); + align-self: var(--mod-divider-vertical-align); +} diff --git a/1st-gen/packages/divider/stories/divider.stories.ts b/1st-gen/packages/divider/stories/divider.stories.ts new file mode 100644 index 00000000000..06158c2149e --- /dev/null +++ b/1st-gen/packages/divider/stories/divider.stories.ts @@ -0,0 +1,150 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/divider/sp-divider.js'; +import './typography-decorator.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-left.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-right.js'; + +export default { + title: 'Divider', + decorators: [ + (story: () => TemplateResult): TemplateResult => html` + + `, + ], +}; + +export const large = (): TemplateResult => { + return html` +

Large

+ +

Page or Section Titles.

+ `; +}; + +export const medium = (): TemplateResult => { + return html` +

Medium

+ +

+ Divide subsections, or divide different groups of elements (between + panels, rails, etc.) +

+ `; +}; + +export const small = (): TemplateResult => { + return html` +

Small

+ +

+ Divide like-elements (tables, tool groups, elements within a panel, + etc.) +

+ `; +}; + +export const verticalSmall = (): TemplateResult => { + return html` +
+ + + + + + + +
+ `; +}; + +export const verticalMedium = (): TemplateResult => { + return html` +
+ + + + + + + +
+ `; +}; + +export const verticalLarge = (): TemplateResult => { + return html` +
+ + + + + + + +
+ `; +}; + +export const staticBlack = (): TemplateResult => { + return html` +
+

+ Static black on light background +

+ +

+ Use static black on light color or image backgrounds. +

+
+ `; +}; + +export const staticWhite = (): TemplateResult => { + return html` +
+

+ Static white on dark background +

+ +

+ Use static white on dark color or image backgrounds. +

+
+ `; +}; diff --git a/1st-gen/packages/divider/stories/typography-decorator.ts b/1st-gen/packages/divider/stories/typography-decorator.ts new file mode 100644 index 00000000000..6c7db01aab5 --- /dev/null +++ b/1st-gen/packages/divider/stories/typography-decorator.ts @@ -0,0 +1,42 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + customElement, + property, +} from '@spectrum-web-components/base/src/decorators.js'; + +import styles from '@spectrum-web-components/theme/src/typography.css.js'; + +/** + * @element typography-decorator + */ +@customElement('typography-decorator') +export class Typography extends LitElement { + static override styles: CSSResultArray = [styles]; + + @property({ attribute: false }) + public story?: TemplateResult; + + protected override render(): TemplateResult { + if (!this.story) return html``; + return html` +
${this.story}
+ `; + } +} diff --git a/1st-gen/packages/divider/test/benchmark/basic-test.ts b/1st-gen/packages/divider/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..33063cd787b --- /dev/null +++ b/1st-gen/packages/divider/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/divider/sp-divider.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/divider/test/divider-memory.test.ts b/1st-gen/packages/divider/test/divider-memory.test.ts new file mode 100644 index 00000000000..5cd727bd98f --- /dev/null +++ b/1st-gen/packages/divider/test/divider-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/divider/sp-divider.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/divider/test/divider.test.ts b/1st-gen/packages/divider/test/divider.test.ts new file mode 100644 index 00000000000..1d6018b6233 --- /dev/null +++ b/1st-gen/packages/divider/test/divider.test.ts @@ -0,0 +1,57 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +import '@spectrum-web-components/divider/sp-divider.js'; +import { Divider } from '@spectrum-web-components/divider'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('Divider', () => { + testForLitDevWarnings( + async () => + await fixture(html` + + `) + ); + it('loads default divider accessibly', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads [vertical] divider accessibly', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('manages a `static-color` attribute', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + expect(el.staticColor).to.equal('black'); + expect(el.getAttribute('static-color')).to.equal('black'); + el.removeAttribute('static-color'); + await elementUpdated(el); + expect(el.staticColor).to.be.null; + expect(el.hasAttribute('static-color')).to.be.false; + }); +}); diff --git a/1st-gen/packages/divider/tsconfig.json b/1st-gen/packages/divider/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/divider/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/dropzone/.npmrc b/1st-gen/packages/dropzone/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/dropzone/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/dropzone/CHANGELOG.md b/1st-gen/packages/dropzone/CHANGELOG.md new file mode 100644 index 00000000000..d40014386ce --- /dev/null +++ b/1st-gen/packages/dropzone/CHANGELOG.md @@ -0,0 +1,564 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5349](https://github.com/adobe/spectrum-web-components/pull/5349) [`a9727d2`](https://github.com/adobe/spectrum-web-components/commit/a9727d2975b01f440c09789c9e7e0122063b6f7e) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +### Features + +- add filled state to dropzone component ([#4617](https://github.com/adobe/spectrum-web-components/issues/4617)) ([f6b7144](https://github.com/adobe/spectrum-web-components/commit/f6b7144efde6507b2690f011af00b9529112c373)) + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Features + +- **dropzone:** use core tokens ([11f7560](https://github.com/adobe/spectrum-web-components/commit/11f7560fcc83c28e84d05bf23699dd6e9cc90fa1)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- **dropzone:** show dragged color in new illustratedmessage version ([0591acf](https://github.com/adobe/spectrum-web-components/commit/0591acf92e5f458ac90ab2f8938142c06683c80a)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- move hover/focus hoisting into conditioning ([15ac2f7](https://github.com/adobe/spectrum-web-components/commit/15ac2f7f561b3cb5b865d1539fbd753999f25119)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843a049a6a37bbeee7bbfb50b4d5eb24f3fd)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-group:** add action-group pattern ([d2de766](https://github.com/adobe/spectrum-web-components/commit/d2de766efde6dfbaa1cd604f99ae3128b4fc81b5)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **dropzone:** update spectrum css input ([0f5a667](https://github.com/adobe/spectrum-web-components/commit/0f5a6679f4e0fb7ae4561a0e13e1db9ad89b21d8)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc77960de8e57dd9c49bb7669df689f0ebaa)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.10.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.8...@spectrum-web-components/dropzone@0.10.9) (2023-04-24) + +### Bug Fixes + +- **dropzone:** show dragged color in new illustratedmessage version ([0591acf](https://github.com/adobe/spectrum-web-components/commit/0591acf92e5f458ac90ab2f8938142c06683c80a)) + +## [0.10.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.7...@spectrum-web-components/dropzone@0.10.8) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.6...@spectrum-web-components/dropzone@0.10.7) (2023-03-22) + +### Bug Fixes + +- move hover/focus hoisting into conditioning ([15ac2f7](https://github.com/adobe/spectrum-web-components/commit/15ac2f7f561b3cb5b865d1539fbd753999f25119)) + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.5...@spectrum-web-components/dropzone@0.10.6) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.4...@spectrum-web-components/dropzone@0.10.5) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.3...@spectrum-web-components/dropzone@0.10.4) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.2...@spectrum-web-components/dropzone@0.10.3) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.1...@spectrum-web-components/dropzone@0.10.2) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.10.0...@spectrum-web-components/dropzone@0.10.1) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.11...@spectrum-web-components/dropzone@0.10.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.9.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.10...@spectrum-web-components/dropzone@0.9.11) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.9...@spectrum-web-components/dropzone@0.9.10) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.8...@spectrum-web-components/dropzone@0.9.9) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.7...@spectrum-web-components/dropzone@0.9.8) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.6...@spectrum-web-components/dropzone@0.9.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.5...@spectrum-web-components/dropzone@0.9.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.4...@spectrum-web-components/dropzone@0.9.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.3...@spectrum-web-components/dropzone@0.9.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.2...@spectrum-web-components/dropzone@0.9.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.1...@spectrum-web-components/dropzone@0.9.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.9.0...@spectrum-web-components/dropzone@0.9.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.8.1...@spectrum-web-components/dropzone@0.9.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.8.0...@spectrum-web-components/dropzone@0.8.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.10...@spectrum-web-components/dropzone@0.8.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.7.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.9...@spectrum-web-components/dropzone@0.7.10) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.8...@spectrum-web-components/dropzone@0.7.9) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.7...@spectrum-web-components/dropzone@0.7.8) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.6...@spectrum-web-components/dropzone@0.7.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.5...@spectrum-web-components/dropzone@0.7.6) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.4...@spectrum-web-components/dropzone@0.7.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.3...@spectrum-web-components/dropzone@0.7.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.2...@spectrum-web-components/dropzone@0.7.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.1...@spectrum-web-components/dropzone@0.7.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.7.0...@spectrum-web-components/dropzone@0.7.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.6.1...@spectrum-web-components/dropzone@0.7.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.6.0...@spectrum-web-components/dropzone@0.6.1) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.4...@spectrum-web-components/dropzone@0.6.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **dropzone:** update spectrum css input ([0f5a667](https://github.com/adobe/spectrum-web-components/commit/0f5a6679f4e0fb7ae4561a0e13e1db9ad89b21d8)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.4...@spectrum-web-components/dropzone@0.5.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **dropzone:** update spectrum css input ([0f5a667](https://github.com/adobe/spectrum-web-components/commit/0f5a6679f4e0fb7ae4561a0e13e1db9ad89b21d8)) + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.3...@spectrum-web-components/dropzone@0.4.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.2...@spectrum-web-components/dropzone@0.4.3) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.1...@spectrum-web-components/dropzone@0.4.2) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.4.0...@spectrum-web-components/dropzone@0.4.1) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.3.1...@spectrum-web-components/dropzone@0.4.0) (2020-08-31) + +### Features + +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- **action-group:** add action-group pattern ([d2de766](https://github.com/adobe/spectrum-web-components/commit/d2de766efde6dfbaa1cd604f99ae3128b4fc81b5)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.3.0...@spectrum-web-components/dropzone@0.3.1) (2020-08-19) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.7...@spectrum-web-components/dropzone@0.3.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.6...@spectrum-web-components/dropzone@0.2.7) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.5...@spectrum-web-components/dropzone@0.2.6) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.4...@spectrum-web-components/dropzone@0.2.5) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.3...@spectrum-web-components/dropzone@0.2.4) (2020-03-11) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.2...@spectrum-web-components/dropzone@0.2.3) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/dropzone + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.1...@spectrum-web-components/dropzone@0.2.2) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.2.0...@spectrum-web-components/dropzone@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.1.5...@spectrum-web-components/dropzone@0.2.0) (2019-11-19) + +### Features + +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc7)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.1.4...@spectrum-web-components/dropzone@0.1.5) (2019-11-01) + +### Bug Fixes + +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/dropzone@0.1.3...@spectrum-web-components/dropzone@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/dropzone diff --git a/1st-gen/packages/dropzone/README.md b/1st-gen/packages/dropzone/README.md new file mode 100644 index 00000000000..cbaa221425f --- /dev/null +++ b/1st-gen/packages/dropzone/README.md @@ -0,0 +1,294 @@ +## Overview + +A `` is an area on the screen into which an object can be dragged and dropped to accomplish a task. For example, a drop zone might be used in an upload workflow to enable the user to drop a file from their operating system into the drop zone, which is a more efficient and intuitive action than utilizing the standard "Choose File" dialog. + +Drop zones should be used with an [illustrated message](/components/illustrated-message) component as a child if the drop zone is empty, otherwise the existing content should be passed as a child. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/dropzone?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/dropzone) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/dropzone?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/dropzone) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-q5adfsfk) + +```zsh +yarn add @spectrum-web-components/dropzone +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/dropzone/sp-dropzone.js'; +``` + +When looking to leverage the `Dropzone` base class as a type and/or for extension purposes, do so via: + +```js +import { Dropzone } from '@spectrum-web-components/dropzone'; +``` + +### Anatomy + +The `` element consists of several key parts: + +- An [illustrated message](/components/illustrated-message) child component that includes a heading, illustration and an optional body area. +- An optional action area that can be used to provide additional context to the heading, including a single button or links to prompt the user to take action. + +### Examples + + +Call to action with links + + +```html + + + + + + + +
+ + +
+
+ or + + Search Adobe Stock + +
+
+``` + +
+Call to action with button + + +```html + + + + + + + + Browse files + +``` + + +
+ +### States + + +Dragged + + +When a file is dragged over the `` element, it will display with the `dragged` attribute, as follows: + +```html + + + + + + + +
+ + +
+
+ or + + Search Adobe Stock + +
+
+``` + +
+Filled + + +When the `` is in a filled state, set the `filled` attribute, as follows: + +```html-live + + + Drag me + + + + + + + +
+ + +
+
+ or + + Search Adobe Stock + +
+
+ + + +``` + + + +
+
+ +### Accessibility + +When actions, e.g. copy/paste, can be enacted directly on the `` element itself, be sure to supply a `tabindex` so that keyboard users can find this interaction in the tab order. For screen readers, be sure to announce what the actions are, how to complete them, and when they are completed by supplying the appropriate `role` and `aria-label` attributes. + +#### Include a label + +A button is required to have either a visible text label or a `label` attribute on either the `` itself +or on an `` element child. + +#### Keyboard navigation + +- `Tab`: Moves focus into the dropzone only when button or link is present. +- `Enter` or `Space`: Activates the button or link. diff --git a/1st-gen/packages/dropzone/package.json b/1st-gen/packages/dropzone/package.json new file mode 100644 index 00000000000..f904196fba5 --- /dev/null +++ b/1st-gen/packages/dropzone/package.json @@ -0,0 +1,75 @@ +{ + "name": "@spectrum-web-components/dropzone", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/dropzone" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/dropzone", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Dropzone.js": { + "development": "./src/Dropzone.dev.js", + "default": "./src/Dropzone.js" + }, + "./src/dropzone-overrides.css.js": "./src/dropzone-overrides.css.js", + "./src/dropzone.css.js": "./src/dropzone.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-dropzone.js": { + "development": "./sp-dropzone.dev.js", + "default": "./sp-dropzone.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/dropzone/sp-dropzone.ts b/1st-gen/packages/dropzone/sp-dropzone.ts new file mode 100644 index 00000000000..04da9b83e16 --- /dev/null +++ b/1st-gen/packages/dropzone/sp-dropzone.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Dropzone } from './src/Dropzone.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-dropzone', Dropzone); + +declare global { + interface HTMLElementTagNameMap { + 'sp-dropzone': Dropzone; + } +} diff --git a/1st-gen/packages/dropzone/src/Dropzone.ts b/1st-gen/packages/dropzone/src/Dropzone.ts new file mode 100644 index 00000000000..793d0bbd607 --- /dev/null +++ b/1st-gen/packages/dropzone/src/Dropzone.ts @@ -0,0 +1,172 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; + +import dropzoneStyles from './dropzone.css.js'; + +export type DropzoneEventDetail = DragEvent; + +export type DropEffects = 'copy' | 'move' | 'link' | 'none'; + +/** + * @element sp-dropzone + * + * @slot - The default slot on an `sp-dropzone` is a great place to place upload instructions + * built with an `sp-illustrated-message` or other information, possibly even built from data + * provided by the upload, to support users successfully interacting with the drag and drop + * based features of your application + * + * @fires sp-dropzone-should-accept - A cancellable event that confirms whether or not + * a file dropped on the UI should be accepted. + * @fires sp-dropzone-dragover - Announces when files have been dragged over the UI, but not yet dropped. + * @fires sp-dropzone-dragleave - Announces when dragged files have been moved out of the UI without having been dropped. + * @fires sp-dropzone-drop - Announces when dragged files have been dropped on the UI. + */ +export class Dropzone extends SpectrumElement { + public static override get styles(): CSSResultArray { + return [dropzoneStyles]; + } + + /** + * Controls the feedback (typically visual) the user is given during a drag and drop operation + * @attr + * @type {'copy' | 'move' | 'link' | 'none'} + */ + public get dropEffect(): DropEffects { + return this._dropEffect; + } + public set dropEffect(value: DropEffects) { + if (['copy', 'move', 'link', 'none'].includes(value)) { + this._dropEffect = value; + } + } + private _dropEffect: DropEffects = 'copy'; + + /** + * Indicates that files are currently being dragged over the dropzone. + */ + @property({ type: Boolean, reflect: true, attribute: 'dragged' }) + public isDragged = false; + + /** + * Set this property to indicate that the component is in a filled state. + */ + @property({ type: Boolean, attribute: 'filled' }) + public isFilled = false; + + private debouncedDragLeave: number | null = null; + + public override connectedCallback(): void { + super.connectedCallback(); + + this.addEventListener('drop', this.onDrop); + this.addEventListener('dragover', this.onDragOver); + this.addEventListener('dragleave', this.onDragLeave); + } + + public override disconnectedCallback(): void { + super.disconnectedCallback(); + + this.removeEventListener('drop', this.onDrop); + this.removeEventListener('dragover', this.onDragOver); + this.removeEventListener('dragleave', this.onDragLeave); + } + + public onDragOver(event: DragEvent): void { + const shouldAcceptEvent = new CustomEvent('sp-dropzone-should-accept', { + bubbles: true, + cancelable: true, + composed: true, + detail: event, + }); + const shouldAccept = this.dispatchEvent(shouldAcceptEvent); + if (!event.dataTransfer) { + return; + } + if (!shouldAccept) { + event.dataTransfer.dropEffect = 'none'; + return; + } + + event.preventDefault(); + + this.clearDebouncedDragLeave(); + + this.isDragged = true; + + event.dataTransfer.dropEffect = this.dropEffect; + const dragOverEvent = new CustomEvent('sp-dropzone-dragover', { + bubbles: true, + composed: true, + detail: event, + }); + this.dispatchEvent(dragOverEvent); + } + + public onDragLeave(event: DragEvent): void { + this.clearDebouncedDragLeave(); + + this.debouncedDragLeave = window.setTimeout(() => { + this.isDragged = false; + + const dragLeave = new CustomEvent('sp-dropzone-dragleave', { + bubbles: true, + composed: true, + detail: event, + }); + this.dispatchEvent(dragLeave); + }, 100); + } + + public onDrop(event: DragEvent): void { + event.preventDefault(); + + this.clearDebouncedDragLeave(); + + this.isDragged = false; + const dropEvent = new CustomEvent('sp-dropzone-drop', { + bubbles: true, + composed: true, + detail: event, + }); + this.dispatchEvent(dropEvent); + } + + protected override render(): TemplateResult { + return html` + + `; + } + + protected clearDebouncedDragLeave(): void { + if (this.debouncedDragLeave) { + clearTimeout(this.debouncedDragLeave); + this.debouncedDragLeave = null; + } + } +} + +declare global { + interface GlobalEventHandlersEventMap { + 'sp-dropzone:should-accept': CustomEvent; + 'sp-dropzone:dragover': CustomEvent; + 'sp-dropzone:dragleave': CustomEvent; + 'sp-dropzone:drop': CustomEvent; + } +} diff --git a/1st-gen/packages/dropzone/src/dropzone-overrides.css b/1st-gen/packages/dropzone/src/dropzone-overrides.css new file mode 100644 index 00000000000..e780fc00d25 --- /dev/null +++ b/1st-gen/packages/dropzone/src/dropzone-overrides.css @@ -0,0 +1,15 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-drop-zone-border-color: var(--system-drop-zone-border-color); +} diff --git a/1st-gen/packages/dropzone/src/dropzone.css b/1st-gen/packages/dropzone/src/dropzone.css new file mode 100644 index 00000000000..7c3ea7115c1 --- /dev/null +++ b/1st-gen/packages/dropzone/src/dropzone.css @@ -0,0 +1,31 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-dropzone.css"); +@import url("./dropzone-overrides.css"); + +/* + * Host is inline-block by default which caused all the computed styling to be wrong. + * We need it as a block + */ +:host { + display: block; +} + +::slotted(*) { + font-family: var(--mod-drop-zone-body-font-family, var(--spectrum-sans-font-family-stack)); + font-size: var(--mod-drop-zone-body-font-size, var(--spectrum-drop-zone-body-size)); + font-weight: var(--mod-drop-zone-body-font-weight, var(--spectrum-body-sans-serif-font-weight)); + line-height: var(--mod-drop-zone-body-line-height, var(--spectrum-body-line-height)); + font-style: var(--mod-drop-zone-body-font-style, var(--spectrum-body-sans-serif-font-style)); + margin-block: 0; +} diff --git a/1st-gen/packages/dropzone/src/index.ts b/1st-gen/packages/dropzone/src/index.ts new file mode 100644 index 00000000000..c39b5c98a51 --- /dev/null +++ b/1st-gen/packages/dropzone/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Dropzone.js'; diff --git a/1st-gen/packages/dropzone/src/spectrum-dropzone.css b/1st-gen/packages/dropzone/src/spectrum-dropzone.css new file mode 100644 index 00000000000..32e9d1e6d45 --- /dev/null +++ b/1st-gen/packages/dropzone/src/spectrum-dropzone.css @@ -0,0 +1,122 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-drop-zone-border-width: var(--spectrum-border-width-200); + --spectrum-drop-zone-background-color: var(--spectrum-drop-zone-background-color-rgb); + --spectrum-drop-zone-border-color-hover: var(--spectrum-accent-visual-color); + --spectrum-drop-zone-illustration-color: var(--spectrum-neutral-visual-color); + --spectrum-drop-zone-content-background-color: var(--spectrum-accent-visual-color); + --mod-illustrated-message-content-maximum-width: var(--mod-drop-zone-content-maximum-width, var(--spectrum-drop-zone-content-maximum-width)); + --mod-illustrated-message-illustration-color: var(--mod-drop-zone-illustration-color, var(--spectrum-drop-zone-illustration-color)); + --mod-illustrated-message-title-to-heading: var(--mod-drop-zone-illustration-to-heading, var(--spectrum-spacing-400)); + --mod-illustrated-message-heading-to-body: var(--mod-drop-zone-heading-to-body, var(--spectrum-spacing-75)); + --mod-illustrated-message-title-font-family: var(--mod-drop-zone-heading-font-family, var(--spectrum-sans-font-family-stack)); + --mod-illustrated-message-title-font-weight: var(--mod-drop-zone-heading-font-weight, var(--spectrum-heading-sans-serif-font-weight)); + --mod-illustrated-message-title-font-style: var(--mod-drop-zone-heading-font-style, var(--spectrum-heading-sans-serif-font-style)); + --mod-illustrated-message-title-font-size: var(--mod-drop-zone-heading-font-size, var(--spectrum-drop-zone-title-size)); + --mod-illustrated-message-title-line-height: var(--mod-drop-zone-heading-line-height, var(--spectrum-heading-line-height)); + --mod-illustrated-message-title-color: var(--mod-drop-zone-heading-color, var(--spectrum-heading-color)); + --mod-illustrated-message-description-position: relative; + --mod-illustrated-message-description-z-index: 1; + --mod-illustrated-message-heading-to-description: 0; + --mod-illustrated-message-description-font-family: var(--mod-drop-zone-body-font-family, var(--spectrum-sans-font-family-stack)); + --mod-illustrated-message-description-font-weight: var(--mod-drop-zone-body-font-weight, var(--spectrum-body-sans-serif-font-weight)); + --mod-illustrated-message-description-font-style: var(--mod-drop-zone-body-font-style, var(--spectrum-body-sans-serif-font-style)); + --mod-illustrated-message-description-font-size: var(--mod-drop-zone-body-font-size, var(--spectrum-drop-zone-body-size)); + --mod-illustrated-message-description-line-height: var(--mod-drop-zone-body-line-height, var(--spectrum-body-line-height)); + --mod-illustrated-message-description-color: var(--mod-drop-zone-body-color, var(--spectrum-body-color)); + --mod-actionbutton-font-size: var(--mod-drop-zone-content-font-size, var(--spectrum-font-size-300)); + --mod-actionbutton-label-color: var(--mod-drop-zone-content-color, var(--spectrum-white)); + --mod-actionbutton-edge-to-text: var(--mod-drop-zone-content-edge-to-text, var(--spectrum-component-edge-to-text-300)); + box-sizing: border-box; + inline-size: var(--mod-drop-zone-width, var(--spectrum-drop-zone-width)); + padding: calc(var(--mod-drop-zone-padding, var(--spectrum-spacing-400)) - var(--mod-drop-zone-border-width, var(--spectrum-drop-zone-border-width))); + text-align: center; + border-color: var(--mod-drop-zone-border-color, var(--spectrum-drop-zone-border-color)); + border-width: var(--mod-drop-zone-border-width, var(--spectrum-drop-zone-border-width)); + border-radius: var(--mod-drop-zone-corner-radius, var(--spectrum-corner-radius-100)); + border-style: dashed; + border-style: var(--mod-drop-zone-border-style, dashed); + background-color: var(--mod-drop-zone-background-color, var(--spectrum-drop-zone-background-color)); + background-size: cover; +} + +:host:lang(ja), +:host:lang(ko), +:host:lang(zh) { + --mod-illustrated-message-title-font-size: var(--spectrum-drop-zone-cjk-title-size); +} + +:host([dragged]) { + --mod-drop-zone-border-style: var(--mod-drop-zone-border-style-dragged, solid); + --mod-drop-zone-background-color: rgba(var(--spectrum-drop-zone-background-color), var(--mod-drop-zone-background-color-opacity, var(--spectrum-drop-zone-background-color-opacity))); + --mod-drop-zone-border-color: var(--highcontrast-drop-zone-border-color-hover, var(--mod-drop-zone-border-color-hover, var(--spectrum-drop-zone-border-color-hover))); + --mod-illustrated-message-illustration-color: var(--mod-drop-zone-illustration-color-hover, var(--spectrum-accent-visual-color)); +} + +:host([filled]) { + --mod-drop-zone-background-color: rgba(var(--spectrum-drop-zone-background-color), var(--mod-drop-zone-background-color-opacity-filled, var(--spectrum-drop-zone-background-color-opacity-filled))); + --mod-illustrated-message-display: none; +} + +:host([filled][dragged]) { + --mod-drop-zone-content-display: flex; +} + +:host(:focus-visible) { + --mod-drop-zone-border-style: solid; + --mod-drop-zone-border-color: var(--highcontrast-drop-zone-border-color-hover, var(--mod-drop-zone-border-color-hover, var(--spectrum-drop-zone-border-color-hover))); + outline: 0; +} + +.spectrum-DropZone-content { + display: none; + display: var(--mod-drop-zone-content-display, none); + block-size: 100%; + z-index: 1; + justify-content: center; + align-items: center; + position: relative; +} + +.spectrum-DropZone-button { + box-sizing: border-box; + block-size: var(--mod-drop-zone-content-height, var(--spectrum-component-height-300)); + max-inline-size: var(--mod-drop-zone-content-max-width, var(--spectrum-drop-zone-content-maximum-width)); + font-family: var(--mod-drop-zone-content-font-family, var(--spectrum-sans-font-family-stack)); + font-weight: var(--mod-drop-zone-content-font-weight, var(--spectrum-bold-font-weight)); + font-style: var(--mod-drop-zone-content-font-style, var(--spectrum-default-font-style)); + line-height: var(--mod-drop-zone-content-line-height, var(--spectrum-line-height-100)); + border: none; + padding-block-start: var(--mod-drop-zone-content-top-to-text, var(--spectrum-component-top-to-text-300)); + padding-block-end: var(--mod-drop-zone-content-bottom-to-text, var(--spectrum-component-bottom-to-text-300)); +} + +.spectrum-DropZone-button, +.spectrum-DropZone-button:focus { + background-color: var(--mod-drop-zone-content-background-color, var(--spectrum-drop-zone-content-background-color)); +} + +@media (hover: hover) { + .spectrum-DropZone-button:hover { + background-color: var(--mod-drop-zone-content-background-color, var(--spectrum-drop-zone-content-background-color)); + } +} + +@media (forced-colors: active) { + :host { + --highcontrast-drop-zone-illustration-color: CanvasText; + --highcontrast-drop-zone-border-color-hover: Highlight; + --highcontrast-illustrated-message-illustration-color: var(--highcontrast-drop-zone-illustration-color); + } +} diff --git a/1st-gen/packages/dropzone/stories/dropzone.stories.ts b/1st-gen/packages/dropzone/stories/dropzone.stories.ts new file mode 100644 index 00000000000..ed50f35006c --- /dev/null +++ b/1st-gen/packages/dropzone/stories/dropzone.stories.ts @@ -0,0 +1,210 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; +import { state } from '@spectrum-web-components/base/src/decorators.js'; + +import '@spectrum-web-components/dropzone/sp-dropzone.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import { illustration } from '../test/test-svg'; +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +import '@spectrum-web-components/link/sp-link.js'; + +export default { + component: 'sp-dropzone', + title: 'Dropzone', + args: { + isDragged: false, + isFilled: false, + }, + argTypes: { + isDragged: { + name: 'isDragged', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + isFilled: { + name: 'isFilled', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + }, +}; + +type StoryArgs = { + isDragged?: boolean; + isFilled?: boolean; +}; + +export const Default = (args: StoryArgs): TemplateResult => { + return html` + + + ${illustration} + +
+ + +
+
+ or + + Search Adobe Stock + +
+
+ `; +}; + +export const Dragged = (args: StoryArgs): TemplateResult => { + return html` + + + ${illustration} + +
+ + +
+
+ or + + Search Adobe Stock + +
+
+ `; +}; +Dragged.args = { + isDragged: true, +}; + +export const Filled = (args: StoryArgs): TemplateResult => { + return html` + + Filled dropzone + + `; +}; +Filled.args = { + isFilled: true, +}; + +class ControlledDropzone extends LitElement { + @state() + private beingDraggedOver: boolean = false; + + @state() + private input?: string = undefined; + + override render(): TemplateResult { + return html` + + + Drag me + + + + ${illustration} + +
+ + +
+
+
+ `; + } + + private onChange(): void { + this.input = 'mock-file'; + this.beingDraggedOver = false; + } + + private onDragOver(): void { + this.beingDraggedOver = true; + } + + private onDragLeave(): void { + this.beingDraggedOver = false; + } +} +defineElement('controlled-dropzone', ControlledDropzone); + +export const Controlled = (): TemplateResult => { + return html` + + `; +}; diff --git a/1st-gen/packages/dropzone/test/benchmark/test-basic.ts b/1st-gen/packages/dropzone/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..7426b7f3f8e --- /dev/null +++ b/1st-gen/packages/dropzone/test/benchmark/test-basic.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/dropzone/sp-dropzone.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + + + +
+
+ + +
+
+ or + + Search Adobe Stock + +
+
+
+`); diff --git a/1st-gen/packages/dropzone/test/dropzone-memory.test.ts b/1st-gen/packages/dropzone/test/dropzone-memory.test.ts new file mode 100644 index 00000000000..caddc2341e6 --- /dev/null +++ b/1st-gen/packages/dropzone/test/dropzone-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/dropzone/sp-dropzone.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/dropzone/test/dropzone.test.ts b/1st-gen/packages/dropzone/test/dropzone.test.ts new file mode 100644 index 00000000000..c2cb23a8c56 --- /dev/null +++ b/1st-gen/packages/dropzone/test/dropzone.test.ts @@ -0,0 +1,186 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/dropzone/sp-dropzone.js'; +import { Dropzone } from '@spectrum-web-components/dropzone'; +import { illustration } from './test-svg.js'; +import { waitForPredicate } from '../../../test/testing-helpers.js'; +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +describe('Dropzone', () => { + it('loads', async () => { + const el = await fixture(html` + + + ${illustration} + + +
+
+ + +
+
+ or + + Search Adobe Stock + +
+
+
+ `); + expect(el).to.not.equal(undefined); + if (!el.shadowRoot) throw new Error('No shadowRoot'); + const slot = el.shadowRoot.querySelector('slot') as HTMLSlotElement; + expect(slot).to.not.equal(undefined); + return true; + }); + it('manages `dropEffects`', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el.dropEffect).to.equal('copy'); + + el.dropEffect = 'move'; + + await elementUpdated(el); + + expect(el.dropEffect).to.equal('move'); + }); + it('manages `dragover` events', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el.isDragged).to.be.false; + + el.dispatchEvent(new DragEvent('dragover')); + + expect(el.isDragged).to.be.false; + + let dataTransfer: DataTransfer | boolean = false; + try { + // Safari doesn't like this... + dataTransfer = new DataTransfer(); + } catch (error) {} + if (dataTransfer) { + const dragOverEvent = new DragEvent('dragover', { + dataTransfer, + }); + + el.dispatchEvent(dragOverEvent); + + expect(el.isDragged).to.be.true; + // We should be able to make the following test here: + // expect(dataTransfer.dropEffect).to.equal(el.dropEffect); + // However, Chrome doesn't like it in the context of a test... + } + }); + it('allows `dragover` events to be canceled', async () => { + const canceledDrag = (event: DragEvent): void => { + event.preventDefault(); + }; + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el.isDragged).to.be.false; + + let dataTransfer: DataTransfer | boolean = false; + try { + // Safari doesn't like this... + dataTransfer = new DataTransfer(); + } catch (error) {} + if (dataTransfer) { + const dragOverEvent = new DragEvent('dragover', { + dataTransfer, + }); + + el.dispatchEvent(dragOverEvent); + + expect(el.isDragged).to.be.false; + expect(dataTransfer.dropEffect).to.not.equal(el.dropEffect); + expect(dataTransfer.dropEffect).to.equal('none'); + } + }); + it('manages `dragleave` events via debounce', async () => { + let dragLeftCount = 0; + const onDragLeave = (): void => { + dragLeftCount += 1; + }; + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(dragLeftCount).to.equal(0); + + el.dispatchEvent(new DragEvent('dragleave')); + el.dispatchEvent(new DragEvent('dragleave')); + + await waitForPredicate(() => dragLeftCount === 1); + + expect(dragLeftCount).to.equal(1); + }); + + it('manages `dragleave` events', async () => { + let dropped = false; + const onDrop = (): void => { + dropped = true; + }; + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(dropped).to.be.false; + + el.dispatchEvent(new DragEvent('drop')); + + expect(dropped).to.be.true; + }); + + it('sets `filled` attribute', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el.isFilled).to.be.true; + expect(el.hasAttribute('filled')).to.be.true; + }); +}); diff --git a/1st-gen/packages/dropzone/test/test-svg.ts b/1st-gen/packages/dropzone/test/test-svg.ts new file mode 100644 index 00000000000..b96792063f6 --- /dev/null +++ b/1st-gen/packages/dropzone/test/test-svg.ts @@ -0,0 +1,74 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html } from '@spectrum-web-components/base'; + +export const illustration = html` + + + + + + + + + + + + + + + +`; diff --git a/1st-gen/packages/dropzone/tsconfig.json b/1st-gen/packages/dropzone/tsconfig.json new file mode 100644 index 00000000000..b10d59338e5 --- /dev/null +++ b/1st-gen/packages/dropzone/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"] +} diff --git a/1st-gen/packages/field-group/.npmrc b/1st-gen/packages/field-group/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/field-group/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/field-group/CHANGELOG.md b/1st-gen/packages/field-group/CHANGELOG.md new file mode 100644 index 00000000000..d9fbaee18be --- /dev/null +++ b/1st-gen/packages/field-group/CHANGELOG.md @@ -0,0 +1,489 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c)]: + - @spectrum-web-components/help-text@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/help-text@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/help-text@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/help-text@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies [[`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0)]: + - @spectrum-web-components/help-text@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/help-text@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/help-text@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +### Bug Fixes + +- **field-group:** apply role when none present ([3616199](https://github.com/adobe/spectrum-web-components/commit/36161997825b77b3a31a4090e273c12329be9d8c)) + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- reduce cycles ([66a4efb](https://github.com/adobe/spectrum-web-components/commit/66a4efbc55c108e886699ce9dd0eb1c7e57e5a7d)) +- update file path access ([8898bf7](https://github.com/adobe/spectrum-web-components/commit/8898bf707e6e28abb78c92a0a0858d459e65347b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- add t-shirt sizing to the Radio pattern ([fc49343](https://github.com/adobe/spectrum-web-components/commit/fc49343311d4ff95699b455c451514cb7fc62a45)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- **field-group:** update spectrum css input ([b2160a9](https://github.com/adobe/spectrum-web-components/commit/b2160a9c2a3ed95f20979cf3a5836bb9fca48c0c)) +- **field-group:** use core tokens ([7433e59](https://github.com/adobe/spectrum-web-components/commit/7433e598634adc74eb8d2d6c7794eaa5a2ec27e7)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.6...@spectrum-web-components/field-group@0.8.7) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.5...@spectrum-web-components/field-group@0.8.6) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.4...@spectrum-web-components/field-group@0.8.5) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.3...@spectrum-web-components/field-group@0.8.4) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.2...@spectrum-web-components/field-group@0.8.3) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.1...@spectrum-web-components/field-group@0.8.2) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.8.0...@spectrum-web-components/field-group@0.8.1) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.5...@spectrum-web-components/field-group@0.8.0) (2022-12-08) + +### Features + +- **field-group:** use core tokens ([7433e59](https://github.com/adobe/spectrum-web-components/commit/7433e598634adc74eb8d2d6c7794eaa5a2ec27e7)) + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.4...@spectrum-web-components/field-group@0.7.5) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.3...@spectrum-web-components/field-group@0.7.4) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.2...@spectrum-web-components/field-group@0.7.3) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.1...@spectrum-web-components/field-group@0.7.2) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.7.0...@spectrum-web-components/field-group@0.7.1) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.6.0...@spectrum-web-components/field-group@0.7.0) (2022-08-24) + +### Features + +- add t-shirt sizing to the Radio pattern ([fc49343](https://github.com/adobe/spectrum-web-components/commit/fc49343311d4ff95699b455c451514cb7fc62a45)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.12...@spectrum-web-components/field-group@0.6.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.5.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.11...@spectrum-web-components/field-group@0.5.12) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.10...@spectrum-web-components/field-group@0.5.11) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.9...@spectrum-web-components/field-group@0.5.10) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.8...@spectrum-web-components/field-group@0.5.9) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.7...@spectrum-web-components/field-group@0.5.8) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.6...@spectrum-web-components/field-group@0.5.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.5...@spectrum-web-components/field-group@0.5.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.4...@spectrum-web-components/field-group@0.5.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.3...@spectrum-web-components/field-group@0.5.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.2...@spectrum-web-components/field-group@0.5.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.1...@spectrum-web-components/field-group@0.5.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.5.0...@spectrum-web-components/field-group@0.5.1) (2021-12-13) + +### Bug Fixes + +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.4.1...@spectrum-web-components/field-group@0.5.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.4.0...@spectrum-web-components/field-group@0.4.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.9...@spectrum-web-components/field-group@0.4.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.3.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.8...@spectrum-web-components/field-group@0.3.9) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.7...@spectrum-web-components/field-group@0.3.8) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.6...@spectrum-web-components/field-group@0.3.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.5...@spectrum-web-components/field-group@0.3.6) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.4...@spectrum-web-components/field-group@0.3.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.3...@spectrum-web-components/field-group@0.3.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.2...@spectrum-web-components/field-group@0.3.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.1...@spectrum-web-components/field-group@0.3.2) (2021-03-22) + +### Bug Fixes + +- reduce cycles ([66a4efb](https://github.com/adobe/spectrum-web-components/commit/66a4efbc55c108e886699ce9dd0eb1c7e57e5a7d)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.3.0...@spectrum-web-components/field-group@0.3.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.2.3...@spectrum-web-components/field-group@0.3.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.2.2...@spectrum-web-components/field-group@0.2.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.2.1...@spectrum-web-components/field-group@0.2.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-group@0.2.0...@spectrum-web-components/field-group@0.2.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/field-group + +# 0.2.0 (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update file path access ([8898bf7](https://github.com/adobe/spectrum-web-components/commit/8898bf707e6e28abb78c92a0a0858d459e65347b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- **field-group:** update spectrum css input ([b2160a9](https://github.com/adobe/spectrum-web-components/commit/b2160a9c2a3ed95f20979cf3a5836bb9fca48c0c)) + +# 0.1.0 (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update file path access ([8898bf7](https://github.com/adobe/spectrum-web-components/commit/8898bf707e6e28abb78c92a0a0858d459e65347b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- **field-group:** update spectrum css input ([b2160a9](https://github.com/adobe/spectrum-web-components/commit/b2160a9c2a3ed95f20979cf3a5836bb9fca48c0c)) diff --git a/1st-gen/packages/field-group/README.md b/1st-gen/packages/field-group/README.md new file mode 100644 index 00000000000..59ccdc095a0 --- /dev/null +++ b/1st-gen/packages/field-group/README.md @@ -0,0 +1,150 @@ +## Overview + +An `` element is used to layout a group of fields, usually `` elements. It can be leveraged for `vertical` or `horizontal` organization of the fields that are supplied as its children. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/field-group?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/field-group) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/field-group?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/field-group) + +```zsh +yarn add @spectrum-web-components/field-group +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/field-group/sp-field-group.js'; +``` + +When looking to leverage the `FieldGroup` base class as a type and/or for extension purposes, do so via: + +```js +import { FieldGroup } from '@spectrum-web-components/field-group'; +``` + +### Anatomy + +```html + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + +``` + +#### Label + +A field group must have a label in order to be accessible. A label can be provided either via the `label` attribute, like the previous example or with an `` element. + +```html + + Choose from horizontally placed options + + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + +``` + +#### Help text + +Help text can be accessibly associated with an `` element by using the `help-text` or `negative-help-text` slots. When using the `negative-help-text` slot, `` will self manage the presence of this content based on the value of the `invalid` property on your `` element. Content within the `help-text` slot will be show by default. When your `` should receive help text based on state outside of the complexity of `invalid` or not, manage the content addressed to the `help-text` from above to ensure that it displays the right messaging and possesses the right `variant`. + + +Self managed + + +```html + + Apple + + Lettuce + + Strawberry + One of these is not a fruit. + + Choose actual fruit(s). + + +``` + + +Managed from above + + +```html +What are your favorite fruits? + + Apple + + Lettuce + + Strawberry + One of these is not a fruit. + +``` + + + + +### Options + +#### Vertical + +```html + + Choose from vertically placed options + + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + +``` + +### Accessibility + +#### Include a label + +Every field group should have a label. A field without a label is ambiguous and not accessible. + +#### Include help text + +The description in the help text is flexible and encompasses a range of guidance. Sometimes this guidance is about what to input, and sometime it’s about how to input. This includes information such as: + +- An overall description of the input field +- Hints for what kind of information needs to be input +- Specific formatting examples or requirements + +Learn more about [using help text](https://spectrum.adobe.com/page/text-field/#Use-help-text-to-show-hints,-formatting,-and-requirements). + +#### Include negative help text + +Write error messaging in a human-centered way by guiding a user and showing them a solution — don’t simply state what’s wrong and then leave them guessing as to how to resolve it. Ambiguous error messages can be frustrating and even shame-inducing for users. Also, keep in mind that something that a system may deem an error may not actually be perceived as an error to a user. + +Learn more about [writing error messages](https://spectrum.adobe.com/page/text-field/#Write-error-text-that-shows-a-solution). + +#### Do not us a placeholder as a replacement for a label or help-text + +Putting instructions for how to complete an input, requirements, or any other essential information into placeholder text is not accessible. Once a value is entered, placeholder text is no longer viewable; if someone is using an automatic form filler, they will never get the information in the placeholder text. + +Instead, use the help text description to convey requirements or to show any formatting examples that would help user comprehension. If there's placeholder text and help text at the same time, it becomes redundant and distracting, especially if they're communicating the same thing. diff --git a/1st-gen/packages/field-group/package.json b/1st-gen/packages/field-group/package.json new file mode 100644 index 00000000000..efdbce66848 --- /dev/null +++ b/1st-gen/packages/field-group/package.json @@ -0,0 +1,76 @@ +{ + "name": "@spectrum-web-components/field-group", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/field-group" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/field-group", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/FieldGroup.js": { + "development": "./src/FieldGroup.dev.js", + "default": "./src/FieldGroup.js" + }, + "./src/field-group-overrides.css.js": "./src/field-group-overrides.css.js", + "./src/field-group.css.js": "./src/field-group.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-field-group.js": { + "development": "./sp-field-group.dev.js", + "default": "./sp-field-group.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/help-text": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/field-group/sp-field-group.ts b/1st-gen/packages/field-group/sp-field-group.ts new file mode 100644 index 00000000000..578e524d7b1 --- /dev/null +++ b/1st-gen/packages/field-group/sp-field-group.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { FieldGroup } from './src/FieldGroup.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-field-group', FieldGroup); + +declare global { + interface HTMLElementTagNameMap { + 'sp-field-group': FieldGroup; + } +} diff --git a/1st-gen/packages/field-group/src/FieldGroup.ts b/1st-gen/packages/field-group/src/FieldGroup.ts new file mode 100644 index 00000000000..6fc07fe54d9 --- /dev/null +++ b/1st-gen/packages/field-group/src/FieldGroup.ts @@ -0,0 +1,81 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { ManageHelpText } from '@spectrum-web-components/help-text/src/manage-help-text.js'; + +import styles from './field-group.css.js'; + +/** + * @element sp-field-group + * @slot - the form controls that make up the group + * @slot help-text - default or non-negative help text to associate to your form element + * @slot negative-help-text - negative help text to associate to your form element when `invalid` + */ +export class FieldGroup extends ManageHelpText(SpectrumElement, { + mode: 'external', +}) { + public static override get styles(): CSSResultArray { + return [styles]; + } + + @property({ type: Boolean, reflect: true }) + public horizontal = false; + + @property({ type: Boolean, reflect: true }) + public invalid = false; + + @property() + public label = ''; + + @property({ type: Boolean, reflect: true }) + public vertical = false; + + protected handleSlotchange(): void { + // Surface this functionality for easy composition in extensions. + return; + } + + protected override render(): TemplateResult { + return html` + + ${this.renderHelpText(this.invalid)} + `; + } + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'group'); + } + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if (changes.has('label')) { + if (this.label) { + this.setAttribute('aria-label', this.label); + } else { + this.removeAttribute('aria-label'); + } + } + } +} diff --git a/1st-gen/packages/field-group/src/field-group-overrides.css b/1st-gen/packages/field-group/src/field-group-overrides.css new file mode 100644 index 00000000000..49f1cf3e2d2 --- /dev/null +++ b/1st-gen/packages/field-group/src/field-group-overrides.css @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-fieldgroup-margin: var(--system-field-group-margin); + --spectrum-fieldgroup-readonly-delimiter: var(--system-field-group-readonly-delimiter); +} diff --git a/1st-gen/packages/field-group/src/field-group.css b/1st-gen/packages/field-group/src/field-group.css new file mode 100644 index 00000000000..c1c4c6f496e --- /dev/null +++ b/1st-gen/packages/field-group/src/field-group.css @@ -0,0 +1,26 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-field-group.css"); +@import url("./field-group-overrides.css"); + +:host([horizontal][dir="rtl"]) slot:not([name])::slotted(*:not(:last-child)), +:host([dir="rtl"]:not([vertical])) slot:not([name])::slotted(*:not(:last-child)) { + /* .spectrum-FieldGroup--horizontal .spectrum-FieldGroup-item+.spectrum-FieldGroup-item */ + margin: 0 0 0 var(--spectrum-fieldgroup-margin); +} + +:host([horizontal][dir="ltr"]) slot:not([name])::slotted(*:not(:last-child)), +:host([dir="ltr"]:not([vertical])) slot:not([name])::slotted(*:not(:last-child)) { + /* .spectrum-FieldGroup--horizontal .spectrum-FieldGroup-item+.spectrum-FieldGroup-item */ + margin: 0 var(--spectrum-fieldgroup-margin) 0 0; +} diff --git a/1st-gen/packages/field-group/src/index.ts b/1st-gen/packages/field-group/src/index.ts new file mode 100644 index 00000000000..57f114c4577 --- /dev/null +++ b/1st-gen/packages/field-group/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './FieldGroup.js'; diff --git a/1st-gen/packages/field-group/src/spectrum-field-group.css b/1st-gen/packages/field-group/src/spectrum-field-group.css new file mode 100644 index 00000000000..f5317cbd74c --- /dev/null +++ b/1st-gen/packages/field-group/src/spectrum-field-group.css @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.group { + flex-flow: column wrap; + display: flex; +} + +.spectrum-FieldGroup--toplabel { + flex-direction: column; +} + +.spectrum-FieldGroup--sidelabel { + flex-direction: row; +} + +.group { + flex-flow: column wrap; + display: flex; +} + +:host([vertical]) .group { + flex-direction: column; +} + +:host([horizontal]) .group { + flex-direction: row; +} + +:host([horizontal]) .group slot:not([name])::slotted(:not(:last-child)) { + margin-inline-end: var(--spectrum-fieldgroup-margin); +} + +:host([horizontal]) .group .spectrum-HelpText { + flex-basis: 100%; +} diff --git a/1st-gen/packages/field-group/stories/field-group.stories.ts b/1st-gen/packages/field-group/stories/field-group.stories.ts new file mode 100644 index 00000000000..31eba5ef704 --- /dev/null +++ b/1st-gen/packages/field-group/stories/field-group.stories.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/field-group/sp-field-group.js'; +import '@spectrum-web-components/checkbox/sp-checkbox.js'; +import '@spectrum-web-components/radio/sp-radio.js'; + +export default { + title: 'Field Group', + component: 'sp-field-group', +}; + +export const horizontal = (): TemplateResult => { + return html` + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + + `; +}; + +export const vertical = (): TemplateResult => { + return html` + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + + `; +}; diff --git a/1st-gen/packages/field-group/test/benchmark/basic-test.ts b/1st-gen/packages/field-group/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..5f12a89a8d2 --- /dev/null +++ b/1st-gen/packages/field-group/test/benchmark/basic-test.ts @@ -0,0 +1,26 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/field-group/sp-field-group.js'; +import '@spectrum-web-components/checkbox/sp-checkbox.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + +`); diff --git a/1st-gen/packages/field-group/test/field-group-memory.test.ts b/1st-gen/packages/field-group/test/field-group-memory.test.ts new file mode 100644 index 00000000000..2d9dcc08289 --- /dev/null +++ b/1st-gen/packages/field-group/test/field-group-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/field-group/sp-field-group.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/field-group/test/field-group.test.ts b/1st-gen/packages/field-group/test/field-group.test.ts new file mode 100644 index 00000000000..9098cfbb5fa --- /dev/null +++ b/1st-gen/packages/field-group/test/field-group.test.ts @@ -0,0 +1,130 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import { findDescribedNode } from '../../../test/testing-helpers-a11y.js'; +import { HelpText } from '@spectrum-web-components/help-text'; +import { FieldGroup } from '@spectrum-web-components/field-group'; +import '@spectrum-web-components/help-text/sp-help-text.js'; +import '@spectrum-web-components/checkbox/sp-checkbox.js'; +import '@spectrum-web-components/field-group/sp-field-group.js'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('FieldGroup', () => { + testForLitDevWarnings( + async () => + await fixture(html` + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + + `) + ); + it('loads default field-group accessibly', async () => { + const el = await fixture(html` + + Checkbox 1 + Checkbox 2 + Checkbox 3 + Checkbox 4 + Checkbox 5 + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + + describe('help text', () => { + const name = 'This is a field group'; + const description = 'This text helps you fill it out'; + const descriptionNegative = 'This text helps you when invalid'; + it('accepts help text in `slot="help-text"`', async () => { + const el = await fixture(html` + + ${description} + + `); + + await elementUpdated(el); + + await findDescribedNode(name, description); + }); + it('accepts help text in `slot="help-text"` w/ own ID', async () => { + const el = await fixture(html` + + + ${description} + + + `); + + await elementUpdated(el); + + await findDescribedNode(name, description); + }); + it('manages neutral/negative help text pairs', async () => { + const el = await fixture(html` + + ${description} + + ${descriptionNegative} + + + `); + const negativeHelpText = el.querySelector( + '[slot="negative-help-text"]' + ) as HelpText; + + await elementUpdated(el); + + expect(negativeHelpText.variant).to.equal('neutral'); + await findDescribedNode(name, description); + + el.invalid = true; + await elementUpdated(el); + + expect(negativeHelpText.variant).to.equal('negative'); + await findDescribedNode(name, descriptionNegative); + }); + it('manages neutral/negative help text pairs w/ own IDs', async () => { + const el = await fixture(html` + + + ${description} + + + ${descriptionNegative} + + + `); + const negativeHelpText = el.querySelector( + '[slot="negative-help-text"]' + ) as HelpText; + + await elementUpdated(el); + + expect(negativeHelpText.variant).to.equal('neutral'); + await findDescribedNode(name, description); + + el.invalid = true; + await elementUpdated(el); + + expect(negativeHelpText.variant).to.equal('negative'); + await findDescribedNode(name, descriptionNegative); + }); + }); +}); diff --git a/1st-gen/packages/field-group/tsconfig.json b/1st-gen/packages/field-group/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/field-group/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/field-label/.npmrc b/1st-gen/packages/field-label/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/field-label/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/field-label/CHANGELOG.md b/1st-gen/packages/field-label/CHANGELOG.md new file mode 100644 index 00000000000..d26116614f3 --- /dev/null +++ b/1st-gen/packages/field-label/CHANGELOG.md @@ -0,0 +1,571 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- [#5721](https://github.com/adobe/spectrum-web-components/pull/5721) [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c) Thanks [@iuliauta](https://github.com/iuliauta)! - - **Fixed**: Update block paddings for S2 and Express themes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +### Bug Fixes + +- **picker:** support inline labeling of quiet Picker ([#3704](https://github.com/adobe/spectrum-web-components/issues/3704)) ([3372286](https://github.com/adobe/spectrum-web-components/commit/337228659bfcd831700ce782254e5cb539c503d2)) + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- support numeric IDs when resolving elements ([f62bf0d](https://github.com/adobe/spectrum-web-components/commit/f62bf0d24191ef47a4d7f9172c40570e052808a2)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **slider:** add t-shirt sizing ([24dac78](https://github.com/adobe/spectrum-web-components/commit/24dac789239bc154e97b3062fa4a91b2174f685e)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **picker:** correct label application for screen readers ([8ce0cb0](https://github.com/adobe/spectrum-web-components/commit/8ce0cb0b76fcb76af34fdd3228ae268509f80ee0)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Features + +- **slider:** use spectrum-tokens ([8b1e72c](https://github.com/adobe/spectrum-web-components/commit/8b1e72c2876a6480421490509eb3b4def00a7a5f)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- add "editable" option to "sp-slider" ([e86d7fa](https://github.com/adobe/spectrum-web-components/commit/e86d7fa84491b41a39dbab9c8d85eec42df320cd)) +- allow sp-dropdown to accept focus visibly from sp-field-label ([134bafc](https://github.com/adobe/spectrum-web-components/commit/134bafc9c2e4d06e48107182f82dd7487066b7f1)) +- **field-label:** do not assume a target is available and surface t-shirt sizing ([c5daead](https://github.com/adobe/spectrum-web-components/commit/c5daead76698733ce52878fc50e01cdb640396cc)) +- move property management into update or willUpdate ([f66069f](https://github.com/adobe/spectrum-web-components/commit/f66069f2e38ea89de67d649b3b0bb84cc726ed73)) +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- add t-shirt sizing to the Radio pattern ([fc49343](https://github.com/adobe/spectrum-web-components/commit/fc49343311d4ff95699b455c451514cb7fc62a45)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **field-label:** add field label pattern ([2fa7c7e](https://github.com/adobe/spectrum-web-components/commit/2fa7c7e0201a6161d6cc769dc171ae37c70ab136)) +- **field-label:** update spectrum css input ([80a993d](https://github.com/adobe/spectrum-web-components/commit/80a993d787af98f41a613f053e4c2497d07f07ee)) +- **field-label:** use core tokens ([8db7ac4](https://github.com/adobe/spectrum-web-components/commit/8db7ac48badbad06dbcc7665e9a3bd19b271bb45)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.10.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.9...@spectrum-web-components/field-label@0.10.10) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.8...@spectrum-web-components/field-label@0.10.9) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.7...@spectrum-web-components/field-label@0.10.8) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.6...@spectrum-web-components/field-label@0.10.7) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.5...@spectrum-web-components/field-label@0.10.6) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.4...@spectrum-web-components/field-label@0.10.5) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.3...@spectrum-web-components/field-label@0.10.4) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.2...@spectrum-web-components/field-label@0.10.3) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.1...@spectrum-web-components/field-label@0.10.2) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.10.0...@spectrum-web-components/field-label@0.10.1) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.9.1...@spectrum-web-components/field-label@0.10.0) (2022-10-28) + +### Features + +- **field-label:** use core tokens ([8db7ac4](https://github.com/adobe/spectrum-web-components/commit/8db7ac48badbad06dbcc7665e9a3bd19b271bb45)) + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.9.0...@spectrum-web-components/field-label@0.9.1) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.8.0...@spectrum-web-components/field-label@0.9.0) (2022-10-10) + +### Features + +- add t-shirt sizing to the Radio pattern ([fc49343](https://github.com/adobe/spectrum-web-components/commit/fc49343311d4ff95699b455c451514cb7fc62a45)) + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.14...@spectrum-web-components/field-label@0.8.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.7.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.13...@spectrum-web-components/field-label@0.7.14) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.12...@spectrum-web-components/field-label@0.7.13) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.11...@spectrum-web-components/field-label@0.7.12) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.10...@spectrum-web-components/field-label@0.7.11) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.9...@spectrum-web-components/field-label@0.7.10) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.8...@spectrum-web-components/field-label@0.7.9) (2022-05-12) + +### Bug Fixes + +- move property management into update or willUpdate ([f66069f](https://github.com/adobe/spectrum-web-components/commit/f66069f2e38ea89de67d649b3b0bb84cc726ed73)) + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.7...@spectrum-web-components/field-label@0.7.8) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.6...@spectrum-web-components/field-label@0.7.7) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.5...@spectrum-web-components/field-label@0.7.6) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.4...@spectrum-web-components/field-label@0.7.5) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.3...@spectrum-web-components/field-label@0.7.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.2...@spectrum-web-components/field-label@0.7.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.1...@spectrum-web-components/field-label@0.7.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.7.0...@spectrum-web-components/field-label@0.7.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.6.1...@spectrum-web-components/field-label@0.7.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.6.0...@spectrum-web-components/field-label@0.6.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.9...@spectrum-web-components/field-label@0.6.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.5.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.8...@spectrum-web-components/field-label@0.5.9) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.7...@spectrum-web-components/field-label@0.5.8) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.6...@spectrum-web-components/field-label@0.5.7) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.5...@spectrum-web-components/field-label@0.5.6) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.4...@spectrum-web-components/field-label@0.5.5) (2021-08-17) + +### Bug Fixes + +- add "editable" option to "sp-slider" ([e86d7fa](https://github.com/adobe/spectrum-web-components/commit/e86d7fa84491b41a39dbab9c8d85eec42df320cd)) + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.3...@spectrum-web-components/field-label@0.5.4) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.2...@spectrum-web-components/field-label@0.5.3) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.1...@spectrum-web-components/field-label@0.5.2) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.5.0...@spectrum-web-components/field-label@0.5.1) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.5...@spectrum-web-components/field-label@0.5.0) (2021-05-24) + +### Features + +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.4...@spectrum-web-components/field-label@0.4.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.3...@spectrum-web-components/field-label@0.4.4) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.2...@spectrum-web-components/field-label@0.4.3) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.1...@spectrum-web-components/field-label@0.4.2) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.4.0...@spectrum-web-components/field-label@0.4.1) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.3.1...@spectrum-web-components/field-label@0.4.0) (2021-03-22) + +### Bug Fixes + +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) + +### Features + +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.3.0...@spectrum-web-components/field-label@0.3.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.2.3...@spectrum-web-components/field-label@0.3.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.2.2...@spectrum-web-components/field-label@0.2.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.2.1...@spectrum-web-components/field-label@0.2.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/field-label@0.2.0...@spectrum-web-components/field-label@0.2.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/field-label + +# 0.2.0 (2021-01-21) + +### Bug Fixes + +- **field-label:** do not assume a target is available and surface t-shirt sizing ([c5daead](https://github.com/adobe/spectrum-web-components/commit/c5daead76698733ce52878fc50e01cdb640396cc)) +- allow sp-dropdown to accept focus visibly from sp-field-label ([134bafc](https://github.com/adobe/spectrum-web-components/commit/134bafc9c2e4d06e48107182f82dd7487066b7f1)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **field-label:** add field label pattern ([2fa7c7e](https://github.com/adobe/spectrum-web-components/commit/2fa7c7e0201a6161d6cc769dc171ae37c70ab136)) +- **field-label:** update spectrum css input ([80a993d](https://github.com/adobe/spectrum-web-components/commit/80a993d787af98f41a613f053e4c2497d07f07ee)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +# 0.1.0 (2021-01-13) + +### Bug Fixes + +- allow sp-dropdown to accept focus visibly from sp-field-label ([134bafc](https://github.com/adobe/spectrum-web-components/commit/134bafc9c2e4d06e48107182f82dd7487066b7f1)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **field-label:** add field label pattern ([2fa7c7e](https://github.com/adobe/spectrum-web-components/commit/2fa7c7e0201a6161d6cc769dc171ae37c70ab136)) +- **field-label:** update spectrum css input ([80a993d](https://github.com/adobe/spectrum-web-components/commit/80a993d787af98f41a613f053e4c2497d07f07ee)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) diff --git a/1st-gen/packages/field-label/README.md b/1st-gen/packages/field-label/README.md new file mode 100644 index 00000000000..38524795b84 --- /dev/null +++ b/1st-gen/packages/field-label/README.md @@ -0,0 +1,290 @@ +## Overview + +An `` provides accessible labelling for form elements. Use the `for` attribute to outline the `id` of an element in the same DOM tree to which it should associate itself. Field labels give context to information that a user needs to input and are commonly used in forms to provide users with clear guidance about what information is required. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/field-label?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/field-label) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/field-label?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/field-label) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-zqj9achu) + +``` +yarn add @spectrum-web-components/field-label +``` + +Import the side effectful registration of `` via: + +```ts +import '@spectrum-web-components/field-label/sp-field-label.js'; +``` + +When looking to leverage the `FieldLabel` base class as a type and/or for extension purposes, do so via: + +```ts +import { FieldLabel } from '@spectrum-web-components/field-label'; +``` + +### Anatomy + +Field labels can be associated with form elements by using the `for` attribute, which should reference the `id` of the related input element. + +```html demo +Email address + +``` + +Field labels can also be used to label a group of related inputs: + +```html demo +Account type + + Admin + Member + Guest + +``` + +### Options + +#### Sizes + + +Small + + +```html demo +Life Story (Small) + +``` + + +Medium + + +```html demo +Life Story (Medium) + +``` + + +Large + + +```html demo +Life Story (Large) + +``` + + +Extra Large + + +```html demo + + Life Story (Extra Large) + + +``` + + + + +#### Label Position + +Field labels can be positioned either on top of an input (default) or to the side of an input. The top position is recommended for most cases as it works better with long text, localization, and responsive layouts. + +Using the `side-aligned` attribute will display the `` element inline with surrounding elements and the `start` and `end` values outline the alignment of the label text in the width specified. + + +Top (Default) + + +```html demo +Country + +``` + + +Side (Start Aligned) + + +Use `side-aligned="start"` to display the `` inline and to align the label text to the "start" of the flow of text: + +```html demo + + Life Story + + +
+
+ + Birthplace + + + Choose a location: + Istanbul + London + Maputo + Melbourne + New York + San Francisco + Santiago + Tokyo + +``` + +
+Side (End Aligned) + + +Use `side-aligned="end"` to display the `` inline and to align the label text to the "end" of the flow of text: + +```html demo + + Life Story + + +
+
+ + Birthplace + + + Choose a location: + Istanbul + London + Maputo + Melbourne + New York + San Francisco + Santiago + Tokyo + +``` + +
+
+ +#### Necessity Indicator + +Field labels can indicate whether an input is required or optional. By default, required fields are marked with an asterisk icon. + + +Required (Icon) + + +```html demo +Full name + +``` + + +Optional (Text) + + +```html demo + + Profile description (optional) + + +``` + + + + +### States + +#### Disabled + +When the associated input field is disabled, the field label should also be disabled. + +```html demo +Country + +``` + +### Behaviors + +#### Text Overflow + +When a field label is too long for the available horizontal space, it wraps to form another line. + +```html demo + + What you're hoping to learn from the seminar and any specific topics you'd + like covered + + +``` + +### Accessibility + +#### Always include a label + +Every input should have a label. An input without a label is ambiguous and not accessible. In rare cases where context is sufficient and an accessibility expert has reviewed the design, the label could be visually hidden but should still include an `aria-label` in HTML. + +#### Ensure proper association + +The `for` attribute of the field label should match the `id` attribute of the associated input element to ensure proper association for screen readers and other assistive technologies. + +#### Keep labels concise + +Use a short, descriptive label (1-3 words) for the information that users need to provide. Supplementary information or requirements should be shown in help text below the field, not in the label. + +#### Use sentence case + +Following Adobe's UX writing style, field labels should be written in sentence case unless they contain words that are branded terms. + +#### Don't add a colon at the end of a field label + +The design of the component already communicates the relationship between the label and the input field, so a colon is unnecessary. + +#### Mark only required or only optional fields, not both + +In a single form, mark only the required fields or only the optional fields, depending on whichever is less frequent in the entire form. This reduces visual noise and makes the form easier to understand. diff --git a/1st-gen/packages/field-label/package.json b/1st-gen/packages/field-label/package.json new file mode 100644 index 00000000000..acaa4a54232 --- /dev/null +++ b/1st-gen/packages/field-label/package.json @@ -0,0 +1,79 @@ +{ + "name": "@spectrum-web-components/field-label", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/field-label" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/field-label", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/FieldLabel.js": { + "development": "./src/FieldLabel.dev.js", + "default": "./src/FieldLabel.js" + }, + "./src/field-label-overrides.css.js": "./src/field-label-overrides.css.js", + "./src/field-label.css.js": "./src/field-label.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-field-label.js": { + "development": "./sp-field-label.dev.js", + "default": "./sp-field-label.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-ui": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/field-label/sp-field-label.ts b/1st-gen/packages/field-label/sp-field-label.ts new file mode 100644 index 00000000000..4841c1dd6fc --- /dev/null +++ b/1st-gen/packages/field-label/sp-field-label.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { FieldLabel } from './src/FieldLabel.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-field-label', FieldLabel); + +declare global { + interface HTMLElementTagNameMap { + 'sp-field-label': FieldLabel; + } +} diff --git a/1st-gen/packages/field-label/src/FieldLabel.ts b/1st-gen/packages/field-label/src/FieldLabel.ts new file mode 100644 index 00000000000..763c272caab --- /dev/null +++ b/1st-gen/packages/field-label/src/FieldLabel.ts @@ -0,0 +1,184 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + nothing, + PropertyValues, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; +import type { Focusable } from '@spectrum-web-components/shared'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-asterisk100.js'; +import asteriskIconStyles from '@spectrum-web-components/icon/src/spectrum-icon-asterisk.css.js'; +import { + conditionAttributeWithId, + conditionAttributeWithoutId, +} from '@spectrum-web-components/base/src/condition-attribute-with-id.js'; +import { + ElementResolutionController, + elementResolverUpdatedSymbol, +} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js'; + +import styles from './field-label.css.js'; + +type AcceptsFocusVisisble = HTMLElement & { forceFocusVisible?(): void }; +type Labelable = Focusable & { + applyFocusElementLabel?: ( + appliedLabel: string, + labelElement?: FieldLabel + ) => void; +}; + +/** + * @element sp-field-label + * + * @slot - text content of the label + */ +export class FieldLabel extends SizedMixin(SpectrumElement, { + noDefaultSize: true, +}) { + public static override get styles(): CSSResultArray { + return [styles, asteriskIconStyles]; + } + + @property({ type: Boolean, reflect: true }) + public disabled = false; + + @property({ type: String }) + public override id = ''; + + @property({ type: String }) + public for = ''; + + @property({ type: Boolean, reflect: true }) + public required = false; + + @query('slot') + public slotEl!: HTMLSlotElement; + + @property({ type: String, reflect: true, attribute: 'side-aligned' }) + public sideAligned?: 'start' | 'end'; + + private target?: Labelable; + + private handleClick(event: Event): void { + if (!this.target || this.disabled || event.defaultPrevented) return; + this.target.focus(); + const parent = this.getRootNode() as ShadowRoot; + const target = this.target as AcceptsFocusVisisble; + const targetParent = target.getRootNode() as ShadowRoot; + const targetHost = targetParent.host as AcceptsFocusVisisble; + if (targetParent === parent && target.forceFocusVisible) { + target.forceFocusVisible(); + } else if (targetHost && targetHost.forceFocusVisible) { + targetHost.forceFocusVisible(); + } + } + + private resolvedElement = new ElementResolutionController(this); + + private applyTargetLabel(target?: Labelable): void { + // Apply new target when provided + this.target = target || this.target; + if (this.target) { + // When target is available add or remove label information + // depending on the value of `apply`. + const applyLabel = this.target.applyFocusElementLabel; + const focusable = this.target.focusElement || this.target; + const targetParent = focusable.getRootNode() as HTMLElement; + if (typeof applyLabel !== 'undefined') { + applyLabel(this.labelText, this); + } else if (targetParent === (this.getRootNode() as HTMLElement)) { + const conditionAttribute = target + ? conditionAttributeWithId + : conditionAttributeWithoutId; + conditionAttribute(focusable, 'aria-labelledby', [this.id]); + } else { + if (target) { + focusable.setAttribute('aria-label', this.labelText); + } else { + focusable.removeAttribute('aria-label'); + } + } + } + } + + private async manageTarget(): Promise { + this.applyTargetLabel(); + const target = this.resolvedElement.element as Focusable; + if (!target) { + this.target = target; + return; + } + if (target.localName.search('-') > 0) { + await customElements.whenDefined(target.localName); + } + if (typeof target.updateComplete !== 'undefined') { + await target.updateComplete; + } + this.applyTargetLabel(target); + } + + private get labelText(): string { + const assignedNodes = this.slotEl.assignedNodes({ flatten: true }); + if (!assignedNodes.length) { + return ''; + } + const labelText = assignedNodes.map((node) => + (node.textContent || /* c8 ignore next */ '').trim() + ); + return labelText.join(' '); + } + + protected override render(): TemplateResult { + return html` + + `; + } + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + this.addEventListener('click', this.handleClick); + } + + protected override willUpdate(changes: PropertyValues): void { + if (!this.hasAttribute('id')) { + this.setAttribute( + 'id', + `${this.tagName.toLowerCase()}-${randomID()}` + ); + } + if (changes.has('for')) { + this.resolvedElement.selector = this.for ? `#${this.for}` : ''; + } + if (changes.has('id') || changes.has(elementResolverUpdatedSymbol)) { + this.manageTarget(); + } + } +} diff --git a/1st-gen/packages/field-label/src/field-label-overrides.css b/1st-gen/packages/field-label/src/field-label-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/field-label/src/field-label-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/field-label/src/field-label.css b/1st-gen/packages/field-label/src/field-label.css new file mode 100644 index 00000000000..0982c449565 --- /dev/null +++ b/1st-gen/packages/field-label/src/field-label.css @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-field-label.css"); +@import url("./field-label-overrides.css"); + +label { + display: inline-block; +} diff --git a/1st-gen/packages/field-label/src/index.ts b/1st-gen/packages/field-label/src/index.ts new file mode 100644 index 00000000000..8434a5de3f0 --- /dev/null +++ b/1st-gen/packages/field-label/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './FieldLabel.js'; diff --git a/1st-gen/packages/field-label/src/spectrum-field-label.css b/1st-gen/packages/field-label/src/spectrum-field-label.css new file mode 100644 index 00000000000..efea42e1139 --- /dev/null +++ b/1st-gen/packages/field-label/src/spectrum-field-label.css @@ -0,0 +1,111 @@ +/*! + * Copyright 2025 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License./ + * + * Override divider background color when used inside alert-dialog/ + * .divider { + * --spectrum-divider-background-color: var(--system-alert-dialog-divider-background-color); + * --spectrum-divider-background-color-static-white: var(--spectrum-alert-dialog-divider-background-color-static-white); + * --spectrum-divider-background-color-static-black: var(--spectrum-alert-dialog-divider-background-color-static-black); + * } + */ + +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host, +:host { + --spectrum-field-label-min-height: var(--spectrum-component-height-75); + --spectrum-field-label-font-size: var(--spectrum-font-size-75); + --spectrum-field-label-side-margin-block-start: var(--spectrum-field-label-top-margin-medium); + --spectrum-field-label-side-padding-right: var(--spectrum-spacing-200); + --spectrum-field-label-text-to-asterisk: var(--spectrum-field-label-text-to-asterisk-medium); +} + +:host([size="s"]) { + --spectrum-field-label-min-height: var(--spectrum-component-height-75); + --spectrum-field-label-font-size: var(--spectrum-font-size-75); + --spectrum-field-label-side-margin-block-start: var(--spectrum-field-label-top-margin-small); + --spectrum-field-label-side-padding-right: var(--spectrum-spacing-100); + --spectrum-field-label-text-to-asterisk: var(--spectrum-field-label-text-to-asterisk-small); +} + +:host([size="l"]) { + --spectrum-field-label-min-height: var(--spectrum-component-height-100); + --spectrum-field-label-font-size: var(--spectrum-font-size-100); + --spectrum-field-label-side-margin-block-start: var(--spectrum-field-label-top-margin-large); + --spectrum-field-label-side-padding-right: var(--spectrum-spacing-200); + --spectrum-field-label-text-to-asterisk: var(--spectrum-field-label-text-to-asterisk-large); +} + +:host([size="xl"]) { + --spectrum-field-label-min-height: var(--spectrum-component-height-200); + --spectrum-field-label-font-size: var(--spectrum-font-size-200); + --spectrum-field-label-side-margin-block-start: var(--spectrum-field-label-top-margin-extra-large); + --spectrum-field-label-side-padding-right: var(--spectrum-spacing-200); + --spectrum-field-label-text-to-asterisk: var(--spectrum-field-label-text-to-asterisk-extra-large); +} + +:host { + box-sizing: border-box; + min-block-size: var(--mod-fieldlabel-min-height, var(--spectrum-field-label-min-height)); + padding-block: var(--mod-fieldlabel-padding-block, var(--mod-field-label-top-to-text, var(--spectrum-field-label-top-to-text)) var(--mod-field-label-bottom-to-text, var(--spectrum-field-label-bottom-to-text))); + padding-inline: 0; + padding-inline: var(--mod-fieldlabel-padding-inline, 0); + margin-block: 0; + margin-block: var(--mod-fieldlabel-margin-block, var(--mod-fieldlabel-margin-block-start, 0) var(--mod-fieldlabel-margin-block-end, 0)); + margin-inline: 0; + margin-inline: var(--mod-fieldlabel-margin-inline, var(--mod-fieldlabel-margin-inline-start, 0) var(--mod-fieldlabel-margin-inline-end, 0)); + font-size: var(--mod-fieldlabel-font-size, var(--spectrum-field-label-font-size)); + font-weight: var(--mod-fieldlabel-font-weight, var(--spectrum-regular-font-weight)); + line-height: var(--mod-fieldlabel-line-height, var(--spectrum-line-height-100)); + -webkit-font-smoothing: subpixel-antialiased; + -moz-osx-font-smoothing: auto; + color: var(--highcontrast-field-label-content-color, var(--mod-fieldlabel-color, var(--spectrum-neutral-subdued-content-color-default))); + display: block; +} + +:host(:lang(ja)), +:host(:lang(ko)), +:host(:lang(zh)) { + --mod-fieldlabel-line-height: var(--mod-fieldlabel-line-height-cjk, var(--spectrum-cjk-line-height-100)); +} + +:host([disabled]) { + --mod-fieldlabel-color: var(--mod-disabled-content-color, var(--spectrum-disabled-content-color)); +} + +.required-icon { + color: inherit; + margin-block: 0; + margin-inline: var(--mod-field-label-text-to-asterisk, var(--spectrum-field-label-text-to-asterisk)) 0; + vertical-align: initial; + vertical-align: var(--mod-field-label-asterisk-vertical-align, baseline); +} + +:host([side-aligned="start"]), +:host([side-aligned="end"]) { + vertical-align: top; + margin-block-start: var(--mod-fieldlabel-side-margin-block-start, var(--spectrum-field-label-side-margin-block-start)); + margin-block-end: 0; + margin-inline-end: var(--mod-fieldlabel-side-padding-right, var(--spectrum-field-label-side-padding-right)); + display: inline-block; +} + +:host([side-aligned="end"]) { + text-align: end; +} + +@media (forced-colors: active) { + :host([disabled]) { + --highcontrast-field-label-content-color: GrayText; + } +} diff --git a/1st-gen/packages/field-label/stories/field-label.stories.ts b/1st-gen/packages/field-label/stories/field-label.stories.ts new file mode 100644 index 00000000000..22ed289ffe5 --- /dev/null +++ b/1st-gen/packages/field-label/stories/field-label.stories.ts @@ -0,0 +1,133 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import '@spectrum-web-components/textfield/sp-textfield.js'; +import '@spectrum-web-components/picker/sp-picker.js'; + +import '@spectrum-web-components/field-label/sp-field-label.js'; + +export default { + title: 'Field Label', + component: 'sp-field-label', +}; + +export const standard = (): TemplateResult => { + return html` + Life Story + + + Life Story + + + `; +}; + +export const sideAlignStart = (): TemplateResult => { + return html` + + Life Story + + + `; +}; + +export const sideAlignEnd = (): TemplateResult => { + return html` + + Life Story + + + `; +}; + +export const required = (): TemplateResult => { + return html` + Life Story + + Life Story (Required) + +
+
+ + Life Story + + +
+
+ + Life Story + + + + Life Story + + + `; +}; + +export const picker = (): TemplateResult => { + return html` + + Select a Country with a very long label, too long in fact + + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + `; +}; + +export const nativeInput = (): TemplateResult => { + return html` + Life Story + + `; +}; diff --git a/1st-gen/packages/field-label/test/benchmark/basic-test.ts b/1st-gen/packages/field-label/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..109a8927123 --- /dev/null +++ b/1st-gen/packages/field-label/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/field-label/sp-field-label.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/field-label/test/field-label-memory.test.ts b/1st-gen/packages/field-label/test/field-label-memory.test.ts new file mode 100644 index 00000000000..4e2457d2d82 --- /dev/null +++ b/1st-gen/packages/field-label/test/field-label-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/field-label/test/field-label.test.ts b/1st-gen/packages/field-label/test/field-label.test.ts new file mode 100644 index 00000000000..f8129f2bb28 --- /dev/null +++ b/1st-gen/packages/field-label/test/field-label.test.ts @@ -0,0 +1,248 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import { stub } from 'sinon'; + +import '@spectrum-web-components/textfield/sp-textfield.js'; +import { Textfield } from '@spectrum-web-components/textfield'; +import '@spectrum-web-components/picker/sp-picker.js'; +import { Picker } from '@spectrum-web-components/picker'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; + +import '@spectrum-web-components/field-label/sp-field-label.js'; +import { FieldLabel } from '@spectrum-web-components/field-label'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('FieldLabel', () => { + testForLitDevWarnings( + async () => + await fixture(html` +
+ Input label + +
+ `) + ); + it('loads default field-label accessibly', async () => { + const el = await fixture(html` +
+ Input label + +
+ `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads [required] field-label accessibly', async () => { + const el = await fixture(html` +
+ + Required input label + + +
+ `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads with no "for"', async () => { + const el = await fixture(html` + Input label + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('observes based on `for` value', async () => { + const test = await fixture(html` +
+ Input label + + +
+ `); + + const fieldLabel = test.querySelector('sp-field-label') as FieldLabel; + const el = fieldLabel as unknown as { target: HTMLElement | undefined }; + const input1 = test.querySelector( + 'input:nth-of-type(1)' + ) as HTMLInputElement; + const input2 = test.querySelector( + 'input:nth-of-type(2)' + ) as HTMLInputElement; + + await elementUpdated(fieldLabel); + + expect(el.target === input1).to.be.true; + input1.remove(); + await elementUpdated(fieldLabel); + expect(el.target === input2).to.be.true; + fieldLabel.insertAdjacentElement('beforebegin', input1); + await elementUpdated(fieldLabel); + expect(el.target === input1).to.be.true; + input1.id = 'other'; + await elementUpdated(fieldLabel); + expect(el.target === input2).to.be.true; + input2.remove(); + await elementUpdated(fieldLabel); + expect(el.target).to.be.null; + input1.id = 'test'; + await elementUpdated(fieldLabel); + expect(el.target === input1).to.be.true; + fieldLabel.insertAdjacentElement('afterend', input2); + await elementUpdated(fieldLabel); + expect(el.target === input2).to.be.false; + input2.insertAdjacentElement('afterend', input1); + await elementUpdated(fieldLabel); + expect(el.target === input2).to.be.true; + }); + it('allows unfulfilled "for"', async () => { + const el = await fixture(html` + Input label + `); + await elementUpdated(el); + const manageSpy = stub( + el as unknown as { manageTarget(): Promise }, + 'manageTarget' + ); + manageSpy.callsFake(async (...args): Promise => { + try { + await ( + FieldLabel.prototype as unknown as { + manageTarget(): Promise; + } + ).manageTarget.apply(el, ...args); + } catch (error) { + return 'Error was thrown.'; + } + return 'No error was thrown.'; + }); + + el.for = 'not-available'; + el.id = 'force-manage-target'; + await elementUpdated(el); + const result = await manageSpy.returnValues[0]; + expect(result).to.equal('No error was thrown.'); + }); + it('associates itself to an element whose "id" matches its "for" attribute', async () => { + const test = await fixture(html` +
+ + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const input = test.querySelector('input') as HTMLInputElement; + + await elementUpdated(el); + + expect(input.hasAttribute('aria-labelledby')); + expect(input.getAttribute('aria-labelledby')).to.equal(el.id); + }); + it('associates via "id" starting with number', async () => { + const test = await fixture(html` +
+ + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const input = test.querySelector('input') as HTMLInputElement; + + await elementUpdated(el); + + expect(input.hasAttribute('aria-labelledby')); + expect(input.getAttribute('aria-labelledby')).to.equal(el.id); + }); + it('passed clicks to assiciated form element as focus', async () => { + const test = await fixture(html` +
+ + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const input = test.querySelector('input') as HTMLInputElement; + + await elementUpdated(el); + + el.click(); + await elementUpdated(el); + + expect(document.activeElement).to.equal(input); + }); + it('associates itself to an element with a focueElement whose "id" matches its "for" attribute', async () => { + const test = await fixture(html` +
+ + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const input = (test.querySelector('sp-textfield') as Textfield) + .focusElement as HTMLInputElement; + + await elementUpdated(el); + + expect(input.hasAttribute('aria-label')); + expect(input.getAttribute('aria-label')).to.equal( + (el.textContent || '').trim() + ); + }); + it('passed clicks to assiciated form element with a focueElement as focus', async () => { + const test = await fixture(html` +
+ + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const input = test.querySelector('sp-textfield') as Textfield; + + await elementUpdated(el); + + el.click(); + await elementUpdated(el); + + expect(document.activeElement).to.equal(input); + }); + it('forces focus visible when available', async () => { + const test = await fixture(html` +
+ + + Test + +
+ `); + const el = test.querySelector('sp-field-label') as FieldLabel; + const picker = test.querySelector('sp-picker') as Picker; + + await elementUpdated(el); + await elementUpdated(picker); + expect(picker.focused).to.be.false; + + el.click(); + await elementUpdated(el); + await elementUpdated(picker); + + expect(document.activeElement).to.equal(picker); + expect(picker.focused).to.be.true; + }); +}); diff --git a/1st-gen/packages/field-label/tsconfig.json b/1st-gen/packages/field-label/tsconfig.json new file mode 100644 index 00000000000..8e11016be75 --- /dev/null +++ b/1st-gen/packages/field-label/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../../tools/base" }, + { "path": "../icons-ui" }, + { "path": "../../tools/shared" } + ] +} diff --git a/1st-gen/packages/help-text/.npmignore b/1st-gen/packages/help-text/.npmignore new file mode 100644 index 00000000000..c50cbe188c0 --- /dev/null +++ b/1st-gen/packages/help-text/.npmignore @@ -0,0 +1,2 @@ +stories +test \ No newline at end of file diff --git a/1st-gen/packages/help-text/.npmrc b/1st-gen/packages/help-text/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/help-text/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/help-text/CHANGELOG.md b/1st-gen/packages/help-text/CHANGELOG.md new file mode 100644 index 00000000000..c17c93fe070 --- /dev/null +++ b/1st-gen/packages/help-text/CHANGELOG.md @@ -0,0 +1,387 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- [#5721](https://github.com/adobe/spectrum-web-components/pull/5721) [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c) Thanks [@iuliauta](https://github.com/iuliauta)! - - **Fixed**: Update block paddings for S2 and Express themes + +- Updated dependencies [[`bdf54c1`](https://github.com/adobe/spectrum-web-components/commit/bdf54c1bc6d3eb20da1a1bf3b40650e6ab1ba399)]: + - @spectrum-web-components/icons-workflow@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icons-workflow@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icons-workflow@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies [[`f6cebbd`](https://github.com/adobe/spectrum-web-components/commit/f6cebbd90008a2abb1232c355ae06e8566086093)]: + - @spectrum-web-components/icons-workflow@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/icons-workflow@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icons-workflow@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icons-workflow@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +### Bug Fixes + +- **help-text:** apply aria-live to ensure full help text is read to user ([#4210](https://github.com/adobe/spectrum-web-components/issues/4210)) ([049dc56](https://github.com/adobe/spectrum-web-components/commit/049dc568ddef88bdde0a72d26ced150c8edfc727)) + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) + +### Features + +- add Help Text pattern ([fdbb812](https://github.com/adobe/spectrum-web-components/commit/fdbb812e05a1202e5b5912a5e93cfba59a3dae9e)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) + +## [0.2.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.13...@spectrum-web-components/help-text@0.2.14) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.12...@spectrum-web-components/help-text@0.2.13) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.11...@spectrum-web-components/help-text@0.2.12) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.10...@spectrum-web-components/help-text@0.2.11) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.9...@spectrum-web-components/help-text@0.2.10) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.8...@spectrum-web-components/help-text@0.2.9) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.7...@spectrum-web-components/help-text@0.2.8) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.6...@spectrum-web-components/help-text@0.2.7) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.5...@spectrum-web-components/help-text@0.2.6) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.4...@spectrum-web-components/help-text@0.2.5) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.3...@spectrum-web-components/help-text@0.2.4) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.2...@spectrum-web-components/help-text@0.2.3) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.1...@spectrum-web-components/help-text@0.2.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.2.0...@spectrum-web-components/help-text@0.2.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.11...@spectrum-web-components/help-text@0.2.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.1.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.10...@spectrum-web-components/help-text@0.1.11) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.9...@spectrum-web-components/help-text@0.1.10) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.8...@spectrum-web-components/help-text@0.1.9) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.7...@spectrum-web-components/help-text@0.1.8) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.6...@spectrum-web-components/help-text@0.1.7) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.5...@spectrum-web-components/help-text@0.1.6) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.4...@spectrum-web-components/help-text@0.1.5) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.3...@spectrum-web-components/help-text@0.1.4) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.2...@spectrum-web-components/help-text@0.1.3) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.1...@spectrum-web-components/help-text@0.1.2) (2022-02-22) + +### Bug Fixes + +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/help-text@0.1.0...@spectrum-web-components/help-text@0.1.1) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/help-text + +# 0.1.0 (2021-12-13) + +### Features + +- add Help Text pattern ([fdbb812](https://github.com/adobe/spectrum-web-components/commit/fdbb812e05a1202e5b5912a5e93cfba59a3dae9e)) diff --git a/1st-gen/packages/help-text/README.md b/1st-gen/packages/help-text/README.md new file mode 100644 index 00000000000..75921e550c8 --- /dev/null +++ b/1st-gen/packages/help-text/README.md @@ -0,0 +1,160 @@ +## Overview + +An `` provides either an informative description or an error message that gives more context about what a user needs to input. It's commonly used in forms. + +## Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/help-text?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/help-text) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/help-text?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/help-text) + +``` +yarn add @spectrum-web-components/help-text +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/help-text/sp-help-text.js'; +``` + +When looking to leverage the `HelpText` base class as a type and/or for extension purposes, do so via: + +``` +import { HelpText } from '@spectrum-web-components/help-text'; +``` + +### Options + +#### Sizes + + +Small + + +```html demo +Password + + + Create a password with at least 8 characters. + + +``` + + +Medium + + +```html demo +Password + + + Create a password with at least 8 characters. + + +``` + + +Large + + +```html +Password + + + Create a password with at least 8 characters. + + +``` + + +Extra Large + + +```html +Password + + + Create a password with at least 8 characters. + + +``` + + + + +#### Negative + +The negative variant of `` is used to convey error messages. + +Help text displays either a description (the neutral variant) or an error message (the negative variant) in the same space. When a description is present and an error is triggered, it is replaced with an error message. Once the error is resolved, the help text description reappears. + +Since one gets replaced by the other, the language of the help text description and the error need to work together to convey the same messaging. The description text explains the requirements or adds supplementary context for how to successfully interact with a component. The error message text tells a user how to fix the error by re-stating the interaction requirements. Make sure that the help text description and error message include the same essential information so that it isn’t lost if one replaces the other. + +Communicate error messages in a human-centered way by guiding a user and showing them a solution — don’t simply state what’s wrong and then leave them guessing as to how to resolve it. Ambiguous error messages can be frustrating and even shame-inducing for users. Also, keep in mind that something that a system may deem an error may not actually be perceived as an error to a user. + +For help text, usually the error is related to something that needs to be fixed for in-line validation, so a [helpful tone](https://spectrum.adobe.com/page/voice-and-tone/#Tone) is most appropriate. For example, if someone were to miss filling out a required field that asks for their email address, write the error text like you’re offering a hint or a tip to help guide them to understand what needs to go in the missing field: “Enter your email address.” + +```html +Password + + + Create a password with at least 8 characters. + + + Passwords must be at least 8 characters + + +``` + +##### Icon + +When associated with content that does not supply an icon outlining the presence of an error, use the `icon` attribute to display one as part of the `` element. + +```html + + Apple + + Lettuce + + Strawberry + One of these is not a fruit. + + Choose actual fruit(s). + + +``` + +#### Disabled + +When the content associated to the element is disabled, use the `disabled` attribute to match the delivery of the `` element to that content. + +```html demo +Color + + Red + Green + Blue + + Choose or add at least one color. + + +``` + +### Accessibility + +#### Be descriptive + +Good, descriptive help text includes 1-2 short sentences of information such as: + +- An overall description of an input field or controls +- Hints for what kind of information needs to be inputted or selected +- Specific formatting examples or requirements + +#### Ensure help text and field share the same root + +It is [not currently possible](https://w3c.github.io/webcomponents-cg/#cross-root-aria) to provide accessible ARIA references between elements in different shadow roots. To ensure proper association between elements, help text must be included via the `slot="help-text"` or `slot="negative-help-text"` in an ``, ``, `` or ``. + +To add help text to your own custom element, see [Help Text Mixin](./help-text-mixin/). diff --git a/1st-gen/packages/help-text/help-text-mixin.md b/1st-gen/packages/help-text/help-text-mixin.md new file mode 100644 index 00000000000..326c3847e05 --- /dev/null +++ b/1st-gen/packages/help-text/help-text-mixin.md @@ -0,0 +1,275 @@ +## Description + +It is [not currently possible](https://w3c.github.io/webcomponents-cg/#cross-root-aria) to provide accessible ARIA references between elements in different shadow roots. When creating your own components, use the `ManageHelpText` mixin to associate slotted `` elements with the elements they describe. This functionality is also surfaced as a base class `HelpTextManagedElement` if you prefer to extend from there, instead. + +Spectrum Web Components leverages the `ManageHelpText` mixin to power elements like `sp-field-group`, `sp-number-field`, `sp-radio-group`, `sp-search` and `sp-textfield`. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/help-text?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/help-text) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/help-text?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/help-text) + +``` +yarn add @spectrum-web-components/help-text +``` + +Import `ManageHelpText` via: + +``` +import { ManageHelpText } from '@spectrum-web-components/help-text/mange-help-text.js'; +``` + +When looking to leverage the `HelpTextManagedElement` base class as a type and/or for extension purposes, do so via: + +``` +import { HelpTextManagedElement } from '@spectrum-web-components/help-text/HelpTextManagedElement.js'; +``` + +The `HelpTextManager` class is also available for import as: + +``` +import { HelpTextManager } from '@spectrum-web-components/help-text/HelpTextManager.js'; +``` + +## ManageHelpText mixin + +`ManageHelpText` mixes two properties into your class: + +- `helpTextId`: the `id` attribute of the associated `` +- `renderHelpText(negative?: boolean)`: a method that returns a `TemplateResult` with the `help-text` and `negative-help-text` slots + +## Internal + +To describe an element within your custom element's shadow root, use `mode: 'internal'` (the default) and set `aria-describedby` on the target element: + +```js +import { SpectrumElement, html } from '@spectrum-web-components/base'; +import { ManageHelpText } from '@spectrum-web-components/help-text/src/manage-hep-text.js'; + +export class MyElement extends ManageHelpText(SpectrumElement) { + invalid = false; + + render() { + return html` + + ${this.renderHelpText(this.invalid)} + `; + } +} +``` + +## External + +To describe the custom element itself, use `mode: 'external'`. This will automatically manage the application of the `aria-describedby` atribute on `MyElement`: + +```js +import { SpectrumElement, html } from '@spectrum-web-components/base'; +import { ManageHelpText } from '@spectrum-web-components/help-text/src/manage-help-text.js'; + +export class MyElement extends ManageHelpText(SpectrumElement, { + mode: 'external', +}) { + invalid = false; + + render() { + return html` + ${this.renderHelpText(this.invalid)} + `; + } +} +``` + +This functionality is powered by the `HelpTextManager` class which is also exported from this package and can be leveraged directly. It accepts the root element on which it will manage help text and an options object that accepts the `mode` by which that help text will be managed at construction time. Leveraged at render time, it surfaces an `id` property and a `render(invalid?: boolean)` method for use in your template. + +## Usage with self-managed validity + +Spectrum Web Components that have an `invalid` attribute, like `` and ``, automatically render either the `help-text` or `negative-help-text` slot based on validity. Provide both, and the appropriate `` element will be surfaced: + + +Field group + + +```html +What are your favorite fruits? + + Apple + + Lettuce + + Strawberry + One of these is not a fruit. + + Choose actual fruit(s). + + +``` + + +Radio group + + +```html + + What is your favorite ice cream flavor? + + + Vanilla + Chocolate + Strawberry + I don't like ice cream + Everyone likes ice cream. + + You can't not like ice cream. + + +``` + + +Textarea + + +```html +Stay "Positive" + + + Tell us how you are feeling today. + + Please be "Positive". + +``` + + +Textfield + + +```html +Stay "Positive" + + + Tell us how you are feeling today. + + Please be "Positive". + +``` + + + + +## Usage with validity managed from above + +When the parent element does not manage its own validity, or you would prefer to leverage the parent application in deciding what content and when to deliver within your `` element, place your content in the `help-text` slot to ensure that it is available for receiving stateful content/properties across the lifecycle of the parent element in question. + + +Field group + + +```html +What are your favorite fruits? + + Apple + + Lettuce + + Strawberry + One of these is not a fruit. + +``` + + +Radio group + + +```html + + What is your favorite ice cream flavor? + + + Vanilla + Chocolate + Strawberry + I don't like ice cream + Everyone likes ice cream. + +``` + + +Textarea + + +```html +Stay "Positive" + + + Tell us how you're feeling today. + + +``` + + +Textfield + + +```html +Stay "Positive" + + + Tell us how you are feeling today. + + +``` + + + diff --git a/1st-gen/packages/help-text/package.json b/1st-gen/packages/help-text/package.json new file mode 100644 index 00000000000..fddcff95e0b --- /dev/null +++ b/1st-gen/packages/help-text/package.json @@ -0,0 +1,97 @@ +{ + "name": "@spectrum-web-components/help-text", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "Web component implementation of a Spectrum design HelpText", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/help-text" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/help-text", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/HelpText.js": { + "development": "./src/HelpText.dev.js", + "default": "./src/HelpText.js" + }, + "./src/HelpTextManagedElement.js": { + "development": "./src/HelpTextManagedElement.dev.js", + "default": "./src/HelpTextManagedElement.js" + }, + "./src/HelpTextManager.js": { + "development": "./src/HelpTextManager.dev.js", + "default": "./src/HelpTextManager.js" + }, + "./src/help-text-overrides.css.js": "./src/help-text-overrides.css.js", + "./src/help-text.css.js": "./src/help-text.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/manage-help-text.js": { + "development": "./src/manage-help-text.dev.js", + "default": "./src/manage-help-text.js" + }, + "./help-text-manager.js": { + "development": "./help-text-manager.dev.js", + "default": "./help-text-manager.js" + }, + "./HelpTextManager.js": { + "development": "./HelpTextManager.dev.js", + "default": "./HelpTextManager.js" + }, + "./sp-help-text.js": { + "development": "./sp-help-text.dev.js", + "default": "./sp-help-text.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icons-workflow": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/help-text/sp-help-text.ts b/1st-gen/packages/help-text/sp-help-text.ts new file mode 100644 index 00000000000..f1d38ff1130 --- /dev/null +++ b/1st-gen/packages/help-text/sp-help-text.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { HelpText } from './src/HelpText.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-help-text', HelpText); + +declare global { + interface HTMLElementTagNameMap { + 'sp-help-text': HelpText; + } +} diff --git a/1st-gen/packages/help-text/src/HelpText.ts b/1st-gen/packages/help-text/src/HelpText.ts new file mode 100644 index 00000000000..082dbc50f36 --- /dev/null +++ b/1st-gen/packages/help-text/src/HelpText.ts @@ -0,0 +1,57 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + nothing, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js'; + +import styles from './help-text.css.js'; + +type HelpTextVariants = 'neutral' | 'negative'; + +/** + * @element sp-help-text + */ +export class HelpText extends SizedMixin(SpectrumElement, { + noDefaultSize: true, +}) { + public static override get styles(): CSSResultArray { + return [styles]; + } + + @property({ type: Boolean, reflect: true }) + public icon = false; + + /** + * The visual variant to apply to this help text. + */ + @property({ reflect: true }) + public variant: HelpTextVariants = 'neutral'; + + protected override render(): TemplateResult { + return html` + ${this.variant === 'negative' && this.icon + ? html` + + ` + : nothing} +
+ `; + } +} diff --git a/1st-gen/packages/help-text/src/HelpTextManagedElement.ts b/1st-gen/packages/help-text/src/HelpTextManagedElement.ts new file mode 100644 index 00000000000..355d778cc32 --- /dev/null +++ b/1st-gen/packages/help-text/src/HelpTextManagedElement.ts @@ -0,0 +1,20 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { SpectrumElement } from '@spectrum-web-components/base'; +import { ManageHelpText } from './manage-help-text.js'; + +/** + * @slot help-text - default or non-negative help text to associate to your form element + * @slot negative-help-text - negative help text to associate to your form element when `invalid` + */ +export class HelpTextManagedElement extends ManageHelpText(SpectrumElement) {} diff --git a/1st-gen/packages/help-text/src/HelpTextManager.ts b/1st-gen/packages/help-text/src/HelpTextManager.ts new file mode 100644 index 00000000000..3b1cb3e1190 --- /dev/null +++ b/1st-gen/packages/help-text/src/HelpTextManager.ts @@ -0,0 +1,120 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; +import type { HelpText } from './HelpText'; + +export class HelpTextManager { + private conditionId?: () => void; + private host!: HTMLElement; + public id!: string; + private mode: 'internal' | 'external' = 'internal'; + private previousTabindex?: -1 | 0 | undefined; + private helpTextElement!: Element; + private get isInternal(): boolean { + return this.mode === 'internal'; + } + + constructor( + host: HTMLElement, + { mode }: { mode: 'internal' | 'external' } = { mode: 'internal' } + ) { + this.host = host; + this.id = `sp-help-text-${randomID()}`; + this.mode = mode; + } + + public render(negative?: boolean): TemplateResult { + // `pass-through-help-text-${this.instanceCount}` makes the slot effectively unreachable from + // the outside allowing the `help-text` slot to be preferred while `negative === false`. + return html` +
+ + + +
+ `; + } + + private addId(): void { + const id = this.helpTextElement ? this.helpTextElement.id : this.id; + this.conditionId = conditionAttributeWithId( + this.host, + 'aria-describedby', + id + ); + if (this.host.hasAttribute('tabindex')) { + this.previousTabindex = parseFloat( + this.host.getAttribute('tabindex') as string + ) as -1 | 0; + } + this.host.tabIndex = 0; + } + + private removeId(): void { + if (this.conditionId) { + this.conditionId(); + delete this.conditionId; + } + if (this.helpTextElement) return; + if (this.previousTabindex) { + this.host.tabIndex = this.previousTabindex; + } else { + this.host.removeAttribute('tabindex'); + } + } + + private handleSlotchange = ({ + target, + }: Event & { target: HTMLSlotElement }): void => { + this.handleHelpText(target); + this.handleNegativeHelpText(target); + }; + + private handleHelpText(target: HTMLSlotElement): void { + if (this.isInternal) return; + + if (this.helpTextElement && this.helpTextElement.id === this.id) { + this.helpTextElement.removeAttribute('id'); + } + this.removeId(); + const assignedElements = target.assignedElements(); + const nextHelpTextElement = assignedElements[0]; + this.helpTextElement = nextHelpTextElement; + if (nextHelpTextElement) { + if (!nextHelpTextElement.id) { + nextHelpTextElement.id = this.id; + } + this.addId(); + } + } + + private handleNegativeHelpText(target: HTMLSlotElement): void { + if (target.name !== 'negative-help-text') return; + + const assignedElements = target.assignedElements(); + assignedElements.forEach( + (el) => ((el as unknown as HelpText).variant = 'negative') + ); + } +} diff --git a/1st-gen/packages/help-text/src/help-text-overrides.css b/1st-gen/packages/help-text/src/help-text-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/help-text/src/help-text-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/help-text/src/help-text.css b/1st-gen/packages/help-text/src/help-text.css new file mode 100644 index 00000000000..797c5e1ac36 --- /dev/null +++ b/1st-gen/packages/help-text/src/help-text.css @@ -0,0 +1,25 @@ +/*! + * Copyright 2025 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License./ + * + * Override divider background color when used inside alert-dialog/ + * .divider { + * --spectrum-divider-background-color: var(--system-alert-dialog-divider-background-color); + * --spectrum-divider-background-color-static-white: var(--spectrum-alert-dialog-divider-background-color-static-white); + * --spectrum-divider-background-color-static-black: var(--spectrum-alert-dialog-divider-background-color-static-black); + * } + */ + +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-help-text.css"); +@import url("./help-text-overrides.css"); diff --git a/1st-gen/packages/help-text/src/index.ts b/1st-gen/packages/help-text/src/index.ts new file mode 100644 index 00000000000..62df4f3826d --- /dev/null +++ b/1st-gen/packages/help-text/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './HelpText.js'; diff --git a/1st-gen/packages/help-text/src/manage-help-text.ts b/1st-gen/packages/help-text/src/manage-help-text.ts new file mode 100644 index 00000000000..be403b8e5fa --- /dev/null +++ b/1st-gen/packages/help-text/src/manage-help-text.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { ReactiveElement, TemplateResult } from '@spectrum-web-components/base'; +import { HelpTextManager } from './HelpTextManager.js'; + +type Constructor> = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + new (...args: any[]): T; + prototype: T; +}; + +export interface HelpTextElementInterface { + renderHelpText(negative?: boolean): TemplateResult; + helpTextId: string; +} + +export function ManageHelpText>( + constructor: T, + { mode }: { mode: 'internal' | 'external' } = { mode: 'internal' } +): T & Constructor { + class HelpTextElement extends constructor { + helpTextManager = new HelpTextManager(this, { mode }); + get helpTextId(): string { + return this.helpTextManager.id; + } + renderHelpText(negative?: boolean): TemplateResult { + return this.helpTextManager.render(negative); + } + } + return HelpTextElement; +} diff --git a/1st-gen/packages/help-text/src/spectrum-help-text.css b/1st-gen/packages/help-text/src/spectrum-help-text.css new file mode 100644 index 00000000000..2c3579d295e --- /dev/null +++ b/1st-gen/packages/help-text/src/spectrum-help-text.css @@ -0,0 +1,142 @@ +/*! + * Copyright 2025 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License./ + * + * Override divider background color when used inside alert-dialog/ + * .divider { + * --spectrum-divider-background-color: var(--system-alert-dialog-divider-background-color); + * --spectrum-divider-background-color-static-white: var(--spectrum-alert-dialog-divider-background-color-static-white); + * --spectrum-divider-background-color-static-black: var(--spectrum-alert-dialog-divider-background-color-static-black); + * } + */ + +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-helptext-content-color-default: CanvasText; + --highcontrast-helptext-icon-color-default: CanvasText; + } + + :host, + .text, + .icon { + forced-color-adjust: none; + } +} + +:host { + --spectrum-helptext-content-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-helptext-icon-color-default: var(--spectrum-neutral-subdued-content-color-default); + + color: var(--highcontrast-helptext-content-color-default, var(--mod-helptext-content-color-default, var(--spectrum-helptext-content-color-default))); + font-size: var(--mod-helptext-font-size, var(--spectrum-helptext-font-size)); + min-block-size: var(--mod-helptext-min-height, var(--spectrum-helptext-min-height)); + display: flex; +} + +:host([size="s"]) { + --spectrum-helptext-min-height: var(--spectrum-component-height-75); + --spectrum-helptext-icon-size: var(--spectrum-workflow-icon-size-75); + --spectrum-helptext-font-size: var(--spectrum-font-size-75); + --spectrum-helptext-text-to-visual: var(--spectrum-text-to-visual-75); + --spectrum-helptext-top-to-workflow-icon: var(--spectrum-help-text-top-to-workflow-icon-small); + --spectrum-helptext-bottom-to-workflow-icon: var(--spectrum-helptext-top-to-workflow-icon); +} + +:host, +:host { + --spectrum-helptext-min-height: var(--spectrum-component-height-75); + --spectrum-helptext-icon-size: var(--spectrum-workflow-icon-size-100); + --spectrum-helptext-font-size: var(--spectrum-font-size-75); + --spectrum-helptext-text-to-visual: var(--spectrum-text-to-visual-75); + --spectrum-helptext-top-to-workflow-icon: var(--spectrum-help-text-top-to-workflow-icon-medium); + --spectrum-helptext-bottom-to-workflow-icon: var(--spectrum-helptext-top-to-workflow-icon); +} + +:host([size="l"]) { + --spectrum-helptext-min-height: var(--spectrum-component-height-100); + --spectrum-helptext-icon-size: var(--spectrum-workflow-icon-size-200); + --spectrum-helptext-font-size: var(--spectrum-font-size-100); + --spectrum-helptext-text-to-visual: var(--spectrum-text-to-visual-100); + --spectrum-helptext-top-to-workflow-icon: var(--spectrum-help-text-top-to-workflow-icon-large); + --spectrum-helptext-bottom-to-workflow-icon: var(--spectrum-helptext-top-to-workflow-icon); +} + +:host([size="xl"]) { + --spectrum-helptext-min-height: var(--spectrum-component-height-200); + --spectrum-helptext-icon-size: var(--spectrum-workflow-icon-size-300); + --spectrum-helptext-font-size: var(--spectrum-font-size-200); + --spectrum-helptext-text-to-visual: var(--spectrum-text-to-visual-200); + --spectrum-helptext-top-to-workflow-icon: var(--spectrum-help-text-top-to-workflow-icon-extra-large); + --spectrum-helptext-bottom-to-workflow-icon: var(--spectrum-helptext-top-to-workflow-icon); +} + +:host([variant="neutral"]) { + --spectrum-helptext-content-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-helptext-icon-color-default: var(--spectrum-neutral-subdued-content-color-default); +} + +:host([variant="negative"]) { + --spectrum-helptext-content-color-default: var(--spectrum-negative-color-900); + --spectrum-helptext-icon-color-default: var(--spectrum-negative-color-900); +} + +:host([disabled]) { + --spectrum-helptext-content-color-default: var(--spectrum-disabled-content-color); + --spectrum-helptext-icon-color-default: var(--spectrum-disabled-content-color); +} + +:host(:lang(ja)), +:host(:lang(ko)), +:host(:lang(zh)) { + --mod-helptext-line-height: var(--mod-helptext-line-height-cjk, var(--spectrum-cjk-line-height-100)); +} + +.icon { + block-size: var(--mod-helptext-icon-size, var(--spectrum-helptext-icon-size)); + inline-size: var(--mod-helptext-icon-size, var(--spectrum-helptext-icon-size)); + flex-shrink: 0; + margin-inline-end: var(--mod-helptext-text-to-visual, var(--spectrum-helptext-text-to-visual)); + padding-block-start: var(--mod-helptext-top-to-workflow-icon, var(--spectrum-helptext-top-to-workflow-icon)); + padding-block-end: var(--mod-helptext-bottom-to-workflow-icon, var(--spectrum-helptext-bottom-to-workflow-icon)); +} + +.text { + line-height: var(--mod-helptext-line-height, var(--spectrum-line-height-100)); + padding-block-start: var(--mod-helptext-top-to-text, var(--spectrum-helptext-top-to-text)); + padding-block-end: var(--mod-helptext-bottom-to-text, var(--spectrum-helptext-bottom-to-text)); +} + +:host([variant="neutral"]) .text { + color: var(--highcontrast-helptext-content-color-default, var(--mod-helptext-content-color-default, var(--spectrum-helptext-content-color-default))); +} + +:host([variant="neutral"]) .icon { + color: var(--highcontrast-helptext-icon-color-default, var(--mod-helptext-icon-color-default, var(--spectrum-helptext-icon-color-default))); +} + +:host([variant="negative"]) .text { + color: var(--highcontrast-helptext-content-color-default, var(--mod-helptext-content-color-default, var(--spectrum-helptext-content-color-default))); +} + +:host([variant="negative"]) .icon { + color: var(--highcontrast-helptext-icon-color-default, var(--mod-helptext-icon-color-default, var(--spectrum-helptext-icon-color-default))); +} + +:host([disabled]) .text { + color: var(--highcontrast-helptext-content-color-default, var(--mod-helptext-content-color-default, var(--spectrum-helptext-content-color-default))); +} + +:host([disabled]) .icon { + color: var(--highcontrast-helptext-icon-color-default, var(--mod-helptext-icon-color-default, var(--spectrum-helptext-icon-color-default))); +} diff --git a/1st-gen/packages/help-text/stories/help-text-sizes.stories.ts b/1st-gen/packages/help-text/stories/help-text-sizes.stories.ts new file mode 100644 index 00000000000..536a7147e48 --- /dev/null +++ b/1st-gen/packages/help-text/stories/help-text-sizes.stories.ts @@ -0,0 +1,52 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/help-text/sp-help-text.js'; + +export default { + title: 'Help Text/Sizes', + component: 'sp-help-text', +}; + +export const s = (): TemplateResult => { + return html` + + Passwords must be at least 8 characters. + + `; +}; + +export const m = (): TemplateResult => { + return html` + + Passwords must be at least 8 characters. + + `; +}; + +export const l = (): TemplateResult => { + return html` + + Passwords must be at least 8 characters. + + `; +}; + +export const XL = (): TemplateResult => { + return html` + + Passwords must be at least 8 characters. + + `; +}; diff --git a/1st-gen/packages/help-text/stories/help-text.stories.ts b/1st-gen/packages/help-text/stories/help-text.stories.ts new file mode 100644 index 00000000000..540d1daafeb --- /dev/null +++ b/1st-gen/packages/help-text/stories/help-text.stories.ts @@ -0,0 +1,132 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/help-text/sp-help-text.js'; + +export default { + title: 'Help Text', + component: 'sp-help-text', + argTypes: { + icon: { + name: 'icon', + type: { name: 'boolean', required: false }, + discription: 'Whether the Help Text is delivered with an icon.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + disabled: { + name: 'disabled', + type: { name: 'boolean', required: false }, + description: 'Help Text for disabled form elements.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + variant: { + name: 'variant', + type: { name: 'string', required: false }, + description: 'The visual variant to apply to the Help Text.', + table: { + type: { summary: 'string' }, + defaultValue: { summary: 'cta' }, + }, + control: { + type: 'inline-radio', + options: ['neutral', 'negative'], + }, + }, + size: { + name: 'size', + type: { name: 'string', required: false }, + description: 'The visual variant to apply to the Help Text.', + table: { + type: { summary: 'string' }, + defaultValue: { summary: 'cta' }, + }, + control: { + type: 'inline-radio', + options: ['s', 'm', 'l', 'xl'], + }, + }, + }, + args: { + size: 'm', + }, +}; + +interface Properties { + content?: string; + disabled?: boolean; + icon?: boolean; + size?: 's' | 'm' | 'l' | 'xl'; + variant?: 'neutral' | 'negative'; +} + +const Template = (args: Properties): TemplateResult => html` + + ${args.content} + +`; + +export const neutral = (args: Properties = {}): TemplateResult => + Template({ + ...args, + content: 'Passwords must be at least 8 characters.', + }); +neutral.args = { + variant: 'neutral', +}; + +export const negative = (args: Properties = {}): TemplateResult => + Template({ + ...args, + content: 'Create a password with at least 8 characters.', + }); +negative.args = { + variant: 'negative', +}; + +export const negativeIcon = (args: Properties = {}): TemplateResult => + Template({ + ...args, + content: 'Create a password with at least 8 characters.', + }); +negativeIcon.args = { + icon: true, + variant: 'negative', +}; + +export const disabled = (args: Properties = {}): TemplateResult => + Template({ + ...args, + content: 'Passwords must be at least 8 characters.', + }); +disabled.args = { + disabled: true, + variant: 'neutral', +}; diff --git a/1st-gen/packages/help-text/test/benchmark/basic-test.ts b/1st-gen/packages/help-text/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..1892aae929b --- /dev/null +++ b/1st-gen/packages/help-text/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/help-text/sp-help-text.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/help-text/test/help-test-memory.test.ts b/1st-gen/packages/help-text/test/help-test-memory.test.ts new file mode 100644 index 00000000000..95fa433dc47 --- /dev/null +++ b/1st-gen/packages/help-text/test/help-test-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/help-text/sp-help-text.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/help-text/test/help-text.test.ts b/1st-gen/packages/help-text/test/help-text.test.ts new file mode 100644 index 00000000000..f3639832e63 --- /dev/null +++ b/1st-gen/packages/help-text/test/help-text.test.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +import '@spectrum-web-components/help-text/sp-help-text.js'; +import { HelpText } from '@spectrum-web-components/help-text'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('HelpText', () => { + testForLitDevWarnings( + async () => + await fixture(html` + This is help text. + `) + ); + it('loads default help-text accessibly', async () => { + const el = await fixture(html` + This is help text. + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads negative/icon help-text accessibly', async () => { + const el = await fixture(html` + + This is negative help text. + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); +}); diff --git a/1st-gen/packages/help-text/tsconfig.json b/1st-gen/packages/help-text/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/help-text/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/icon/.npmrc b/1st-gen/packages/icon/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/icon/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/icon/CHANGELOG.md b/1st-gen/packages/icon/CHANGELOG.md new file mode 100644 index 00000000000..ff2a6c069d3 --- /dev/null +++ b/1st-gen/packages/icon/CHANGELOG.md @@ -0,0 +1,652 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/iconset@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +### Features + +- **reactive-controllers:** Migrate to Colorjs from Tinycolor ([#4713](https://github.com/adobe/spectrum-web-components/issues/4713)) ([9d740f0](https://github.com/adobe/spectrum-web-components/commit/9d740f0c830aa44273097181e761e9a92d3df4be)) + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +### Features + +- add an optional chromatic vrt action ([7d2f840](https://github.com/adobe/spectrum-web-components/commit/7d2f8401cb05c5e23872424f132a1a8edd95b666)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +### Bug Fixes + +- **toast:** adds iconLabel to address accessibility ([#4944](https://github.com/adobe/spectrum-web-components/issues/4944)) ([8121057](https://github.com/adobe/spectrum-web-components/commit/8121057518062fb000279659b9597396753e21b7)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **icon:** remove size300 suffix from chevron and checkmark icons in Spectrum 2 ([#4904](https://github.com/adobe/spectrum-web-components/issues/4904)) ([a22f42b](https://github.com/adobe/spectrum-web-components/commit/a22f42bf508e1d0f2ddc9824b0f4d4e08eac659a)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **infield-button:** add infield-button package ([057b885](https://github.com/adobe/spectrum-web-components/commit/057b885276f3d5dcbe32bab5ab36a2bb82334bc3)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **alert-dialog:** add Alert Dialog package ([#3501](https://github.com/adobe/spectrum-web-components/issues/3501)) ([1062847](https://github.com/adobe/spectrum-web-components/commit/10628476d39ef45c23efa8b6ac53d4a2e334a92f)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Features + +- **action-bar:** use core tokens ([4e21edf](https://github.com/adobe/spectrum-web-components/commit/4e21edfa369dcdbba823e3cfc1b35d65f48cab6f)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +### Features + +- **icon:** image src invalid error api ([19e06f9](https://github.com/adobe/spectrum-web-components/commit/19e06f92ee5f90c149fb1fcf68eb47384ac2a97d)) +- **icon:** review comment changes ([ba75d94](https://github.com/adobe/spectrum-web-components/commit/ba75d9407635ed0f36d7568c4b1f508e08008d70)) +- **icon:** review comment changes ([4597713](https://github.com/adobe/spectrum-web-components/commit/4597713ec2a15235aa504114d161740e8df4b2a1)) +- **icon:** review comment changes ([19287fb](https://github.com/adobe/spectrum-web-components/commit/19287fbfd2f7ddf1686fc9f3d48e14809e461deb)) +- **icon:** review comment changes ([dee1929](https://github.com/adobe/spectrum-web-components/commit/dee192910a466bd47a6cbd3892516923be09ead0)) +- **icon:** review comment changes ([cb41b33](https://github.com/adobe/spectrum-web-components/commit/cb41b33e5fe480ce8512bc5a683237047affce85)) +- **icon:** skipping test case for webkit ([fa4b903](https://github.com/adobe/spectrum-web-components/commit/fa4b9034a719863d30f751d1628753931a3a944f)) + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- **icon:** prevent async race resulting in multiple inner SVG elements ([b05e2d5](https://github.com/adobe/spectrum-web-components/commit/b05e2d5c7891026fa5b9585b03444b6728a30d0a)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- manage updated node types ([0517fc1](https://github.com/adobe/spectrum-web-components/commit/0517fc19536325332543f95f5ecc0d6cb0c786c5)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843a049a6a37bbeee7bbfb50b4d5eb24f3fd)) +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **icon:** add UIIcon styles ([6f03b1a](https://github.com/adobe/spectrum-web-components/commit/6f03b1a0b898adf608d5ee2ca94f53416ecffe73)) +- **icon:** allow `` to accept a slotted icon ([cbf7a07](https://github.com/adobe/spectrum-web-components/commit/cbf7a078a6adb6e6d28e07d1429cc96e3207db7a)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **icon:** update spectrum css input ([42f17db](https://github.com/adobe/spectrum-web-components/commit/42f17db9ac249a12f224759fe4ead418720e85d4)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.12.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.10...@spectrum-web-components/icon@0.12.11) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.9...@spectrum-web-components/icon@0.12.10) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.8...@spectrum-web-components/icon@0.12.9) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.7...@spectrum-web-components/icon@0.12.8) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.6...@spectrum-web-components/icon@0.12.7) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.5...@spectrum-web-components/icon@0.12.6) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.4...@spectrum-web-components/icon@0.12.5) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.3...@spectrum-web-components/icon@0.12.4) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.2...@spectrum-web-components/icon@0.12.3) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.12.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.1...@spectrum-web-components/icon@0.12.2) (2022-10-28) + +### Bug Fixes + +- manage updated node types ([0517fc1](https://github.com/adobe/spectrum-web-components/commit/0517fc19536325332543f95f5ecc0d6cb0c786c5)) + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.12.0...@spectrum-web-components/icon@0.12.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.12...@spectrum-web-components/icon@0.12.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.11.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.11...@spectrum-web-components/icon@0.11.12) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.10...@spectrum-web-components/icon@0.11.11) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.9...@spectrum-web-components/icon@0.11.10) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.8...@spectrum-web-components/icon@0.11.9) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.7...@spectrum-web-components/icon@0.11.8) (2022-05-27) + +### Bug Fixes + +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) + +## [0.11.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.6...@spectrum-web-components/icon@0.11.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.5...@spectrum-web-components/icon@0.11.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.4...@spectrum-web-components/icon@0.11.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.3...@spectrum-web-components/icon@0.11.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.2...@spectrum-web-components/icon@0.11.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.1...@spectrum-web-components/icon@0.11.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.11.0...@spectrum-web-components/icon@0.11.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.10.1...@spectrum-web-components/icon@0.11.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.10.0...@spectrum-web-components/icon@0.10.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.11...@spectrum-web-components/icon@0.10.0) (2021-11-02) + +### Bug Fixes + +- **icon:** prevent async race resulting in multiple inner SVG elements ([b05e2d5](https://github.com/adobe/spectrum-web-components/commit/b05e2d5c7891026fa5b9585b03444b6728a30d0a)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.9.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.10...@spectrum-web-components/icon@0.9.11) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.9...@spectrum-web-components/icon@0.9.10) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.9.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.8...@spectrum-web-components/icon@0.9.9) (2021-08-03) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.7...@spectrum-web-components/icon@0.9.8) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.6...@spectrum-web-components/icon@0.9.7) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.5...@spectrum-web-components/icon@0.9.6) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.4...@spectrum-web-components/icon@0.9.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.3...@spectrum-web-components/icon@0.9.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.2...@spectrum-web-components/icon@0.9.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.1...@spectrum-web-components/icon@0.9.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.9.0...@spectrum-web-components/icon@0.9.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.8.3...@spectrum-web-components/icon@0.9.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.8.2...@spectrum-web-components/icon@0.8.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.8.1...@spectrum-web-components/icon@0.8.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.8.0...@spectrum-web-components/icon@0.8.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/icon + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.6.3...@spectrum-web-components/icon@0.8.0) (2021-01-21) + +### Bug Fixes + +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icon:** update spectrum css input ([42f17db](https://github.com/adobe/spectrum-web-components/commit/42f17db9ac249a12f224759fe4ead418720e85d4)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.6.3...@spectrum-web-components/icon@0.7.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icon:** update spectrum css input ([42f17db](https://github.com/adobe/spectrum-web-components/commit/42f17db9ac249a12f224759fe4ead418720e85d4)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.6.2...@spectrum-web-components/icon@0.6.3) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.6.1...@spectrum-web-components/icon@0.6.2) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.6.0...@spectrum-web-components/icon@0.6.1) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.5.2...@spectrum-web-components/icon@0.6.0) (2020-08-31) + +### Features + +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.5.1...@spectrum-web-components/icon@0.5.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.5.0...@spectrum-web-components/icon@0.5.1) (2020-07-24) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.8...@spectrum-web-components/icon@0.5.0) (2020-07-17) + +### Features + +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.4.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.7...@spectrum-web-components/icon@0.4.8) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.6...@spectrum-web-components/icon@0.4.7) (2020-05-08) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.5...@spectrum-web-components/icon@0.4.6) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.4...@spectrum-web-components/icon@0.4.5) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.3...@spectrum-web-components/icon@0.4.4) (2020-03-11) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.2...@spectrum-web-components/icon@0.4.3) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/icon + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.1...@spectrum-web-components/icon@0.4.2) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.4.0...@spectrum-web-components/icon@0.4.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.3.0...@spectrum-web-components/icon@0.4.0) (2019-11-19) + +### Features + +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.2.0...@spectrum-web-components/icon@0.3.0) (2019-11-01) + +### Bug Fixes + +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843)) + +### Features + +- **icon:** allow `` to accept a slotted icon ([cbf7a07](https://github.com/adobe/spectrum-web-components/commit/cbf7a07)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icon@0.1.3...@spectrum-web-components/icon@0.2.0) (2019-10-14) + +### Features + +- **icon:** add UIIcon styles ([6f03b1a](https://github.com/adobe/spectrum-web-components/commit/6f03b1a)) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/icon diff --git a/1st-gen/packages/icon/README.md b/1st-gen/packages/icon/README.md new file mode 100644 index 00000000000..822f1df2c81 --- /dev/null +++ b/1st-gen/packages/icon/README.md @@ -0,0 +1,98 @@ +## Overview + +`` renders an icon to the page. By default the `name` attribute will pair with separately registered icon sets to deliver the icons. When not present, `` will subsequently check for its `src` attribute which could populate the icon via an image, and then fallback to any slotted content for an element based icon. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/icon?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/icon) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/icon?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/icon) + +``` +yarn add @spectrum-web-components/icon +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/icon/sp-icon.js'; +``` + +When looking to leverage the `Icon` base class as a type and/or for extension purposes, do so via: + +``` +import { Icon } from '@spectrum-web-components/icon'; +``` + +### Example + +Names of the icons on this page are provided by the [`` icon set](components/icons). Learn how to create your own via [`sp-iconset`](components/iconset). + +```html + + +``` + +### Options + +#### Sizes + +Icons are available in various sizes in Spectrum ranging from `s` to `xxl`. By default an `sp-icon` without a `size` attribute will appear as if it were `size="m"`. We can specify the size via `size` attribute. + +```html + + + + + +``` + +#### Icon colors + +Icons apply their color as `currentColor`, so change the `color` property of the element for customization. + +```html + +``` + +#### Image icon + +An image icon can be supplied via the `src` attribute. Remember that you cannot style the contents of an image via CSS, so use graphics that are appropriate for your application's design requirements. + +```html + +``` + +#### HTML/SVG Element icon + +Icons can also be supplied via HTML elements and are applied via the default ``. + +```html + + + +``` + +### Accessibility + +If no meaning is lost by visually hiding an icon, it is considered decorative. Decorative icons should not have a label and should be hidden from assistive technology. `aria-hidden` is set to true by default for icons. + +If an icon does add meaning, a label is required. Use the `label` attribute to set the label's text as the `aria-label` of the icon and remove the `aria-hidden` attribute. + +```html + +``` diff --git a/1st-gen/packages/icon/package.json b/1st-gen/packages/icon/package.json new file mode 100644 index 00000000000..122d9f3b70d --- /dev/null +++ b/1st-gen/packages/icon/package.json @@ -0,0 +1,100 @@ +{ + "name": "@spectrum-web-components/icon", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/icon" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/icon", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Icon.js": { + "development": "./src/Icon.dev.js", + "default": "./src/Icon.js" + }, + "./src/IconBase.js": { + "development": "./src/IconBase.dev.js", + "default": "./src/IconBase.js" + }, + "./src/icon-arrow-overrides.css.js": "./src/icon-arrow-overrides.css.js", + "./src/icon-asterisk-overrides.css.js": "./src/icon-asterisk-overrides.css.js", + "./src/icon-checkmark-overrides.css.js": "./src/icon-checkmark-overrides.css.js", + "./src/icon-chevron-overrides.css.js": "./src/icon-chevron-overrides.css.js", + "./src/icon-corner-triangle-overrides.css.js": "./src/icon-corner-triangle-overrides.css.js", + "./src/icon-cross-overrides.css.js": "./src/icon-cross-overrides.css.js", + "./src/icon-dash-overrides.css.js": "./src/icon-dash-overrides.css.js", + "./src/icon-overrides.css.js": "./src/icon-overrides.css.js", + "./src/icon-single-gripper-overrides.css.js": "./src/icon-single-gripper-overrides.css.js", + "./src/icon-triple-gripper-overrides.css.js": "./src/icon-triple-gripper-overrides.css.js", + "./src/icon.css.js": "./src/icon.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/spectrum-icon-arrow.css.js": "./src/spectrum-icon-arrow.css.js", + "./src/spectrum-icon-asterisk.css.js": "./src/spectrum-icon-asterisk.css.js", + "./src/spectrum-icon-checkmark.css.js": "./src/spectrum-icon-checkmark.css.js", + "./src/spectrum-icon-chevron.css.js": "./src/spectrum-icon-chevron.css.js", + "./src/spectrum-icon-corner-triangle.css.js": "./src/spectrum-icon-corner-triangle.css.js", + "./src/spectrum-icon-cross.css.js": "./src/spectrum-icon-cross.css.js", + "./src/spectrum-icon-dash.css.js": "./src/spectrum-icon-dash.css.js", + "./src/spectrum-icon-double-gripper.css.js": "./src/spectrum-icon-double-gripper.css.js", + "./src/spectrum-icon-single-gripper.css.js": "./src/spectrum-icon-single-gripper.css.js", + "./src/spectrum-icon-triple-gripper.css.js": "./src/spectrum-icon-triple-gripper.css.js", + "./sp-icon.js": { + "development": "./sp-icon.dev.js", + "default": "./sp-icon.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/iconset": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/icon/sp-icon.ts b/1st-gen/packages/icon/sp-icon.ts new file mode 100644 index 00000000000..f059723362e --- /dev/null +++ b/1st-gen/packages/icon/sp-icon.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Icon } from './src/Icon.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-icon', Icon); + +declare global { + interface HTMLElementTagNameMap { + 'sp-icon': Icon; + } +} diff --git a/1st-gen/packages/icon/src/Icon.ts b/1st-gen/packages/icon/src/Icon.ts new file mode 100644 index 00000000000..3eaf7970ba0 --- /dev/null +++ b/1st-gen/packages/icon/src/Icon.ts @@ -0,0 +1,143 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +import { IconsetRegistry } from '@spectrum-web-components/iconset/src/iconset-registry.js'; + +import { IconBase } from './IconBase.js'; + +/** + * @element sp-icon + */ +export class Icon extends IconBase { + @property() + public src?: string; + + @property() + public name?: string; + + @query('#container') + private iconContainer?: HTMLElement; + + private updateIconPromise?: Promise; + + public override connectedCallback(): void { + super.connectedCallback(); + window.addEventListener('sp-iconset-added', this.iconsetListener); + } + + public override disconnectedCallback(): void { + super.disconnectedCallback(); + window.removeEventListener('sp-iconset-added', this.iconsetListener); + } + + public override firstUpdated(): void { + this.updateIconPromise = this.updateIcon(); + } + + public override attributeChangedCallback( + name: string, + old: string, + value: string + ): void { + super.attributeChangedCallback(name, old, value); + this.updateIconPromise = this.updateIcon(); // any of our attributes change, update our icon + } + + private iconsetListener = (event: CustomEvent): void => { + if (!this.name) { + return; + } + // parse the icon name to get iconset name + const icon = this.parseIcon(this.name); + if (event.detail.name === icon.iconset) { + this.updateIconPromise = this.updateIcon(); + } + }; + + private announceIconImageSrcError(): void { + this.dispatchEvent( + new Event('error', { + cancelable: false, + bubbles: false, + composed: false, + }) + ); + } + + protected override render(): TemplateResult { + if (this.name) { + return html` +
+ `; + } else if (this.src) { + return html` + ${ifDefined(this.label)} + `; + } + return super.render(); + } + + private async updateIcon(): Promise { + if (this.updateIconPromise) { + await this.updateIconPromise; + } + if (!this.name) { + return Promise.resolve(); + } + // parse the icon name to get iconset name + const icon = this.parseIcon(this.name); + // try to retrieve the iconset + const iconset = IconsetRegistry.getInstance().getIconset(icon.iconset); + if (!iconset) { + // we can stop here as there's nothing to be done till we get the iconset + return Promise.resolve(); + } + if (!this.iconContainer) { + return Promise.resolve(); + } + this.iconContainer.innerHTML = ''; + return iconset.applyIconToElement( + this.iconContainer, + icon.icon, + this.size || '', + this.label ? this.label : '' + ); + } + + private parseIcon(icon: string): { iconset: string; icon: string } { + const iconParts = icon.split(':'); + let iconsetName = 'default'; + let iconName = icon; + if (iconParts.length > 1) { + iconsetName = iconParts[0]; + iconName = iconParts[1]; + } + return { iconset: iconsetName, icon: iconName }; + } + + protected override async getUpdateComplete(): Promise { + const complete = (await super.getUpdateComplete()) as boolean; + await this.updateIconPromise; + return complete; + } +} diff --git a/1st-gen/packages/icon/src/IconBase.ts b/1st-gen/packages/icon/src/IconBase.ts new file mode 100644 index 00000000000..fb90095bf67 --- /dev/null +++ b/1st-gen/packages/icon/src/IconBase.ts @@ -0,0 +1,84 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + SystemResolutionController, + systemResolverUpdatedSymbol, +} from '@spectrum-web-components/reactive-controllers/src/SystemContextResolution.js'; + +import { + property, + state, +} from '@spectrum-web-components/base/src/decorators.js'; + +import iconStyles from './icon.css.js'; + +export class IconBase extends SpectrumElement { + public static override get styles(): CSSResultArray { + return [iconStyles]; + } + + private unsubscribeSystemContext: (() => void) | null = null; + + @state() + public spectrumVersion = 1; + + @property({ reflect: true }) + public label = ''; + + @property({ reflect: true }) + public size?: 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'; + + public override connectedCallback(): void { + super.connectedCallback(); + } + + public override disconnectedCallback(): void { + super.disconnectedCallback(); + if (this.unsubscribeSystemContext) { + this.unsubscribeSystemContext(); + this.unsubscribeSystemContext = null; + } + } + + private systemResolver = new SystemResolutionController(this); + + protected override update(changes: PropertyValues): void { + if (changes.has('label')) { + if (this.label) { + this.removeAttribute('aria-hidden'); + } else { + this.setAttribute('aria-hidden', 'true'); + } + } + + if (changes.has(systemResolverUpdatedSymbol)) { + this.spectrumVersion = + this.systemResolver.system === 'spectrum-two' ? 2 : 1; + } + + super.update(changes); + } + + protected override render(): TemplateResult { + return html` + + `; + } +} diff --git a/1st-gen/packages/icon/src/icon-arrow-overrides.css b/1st-gen/packages/icon/src/icon-arrow-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-arrow-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-asterisk-overrides.css b/1st-gen/packages/icon/src/icon-asterisk-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-asterisk-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-checkmark-overrides.css b/1st-gen/packages/icon/src/icon-checkmark-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-checkmark-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-chevron-overrides.css b/1st-gen/packages/icon/src/icon-chevron-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-chevron-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-corner-triangle-overrides.css b/1st-gen/packages/icon/src/icon-corner-triangle-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-corner-triangle-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-cross-overrides.css b/1st-gen/packages/icon/src/icon-cross-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-cross-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-dash-overrides.css b/1st-gen/packages/icon/src/icon-dash-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-dash-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-double-gripper-overrides.css b/1st-gen/packages/icon/src/icon-double-gripper-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-double-gripper-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-overrides.css b/1st-gen/packages/icon/src/icon-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-single-gripper-overrides.css b/1st-gen/packages/icon/src/icon-single-gripper-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-single-gripper-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon-triple-gripper-overrides.css b/1st-gen/packages/icon/src/icon-triple-gripper-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/icon-triple-gripper-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/icon.css b/1st-gen/packages/icon/src/icon.css new file mode 100644 index 00000000000..d60ede990ea --- /dev/null +++ b/1st-gen/packages/icon/src/icon.css @@ -0,0 +1,38 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-icon.css"); + +#container { + height: 100%; +} + +img, +svg, +::slotted(*) { + height: 100%; + width: 100%; + vertical-align: top; + color: inherit; +} + +@media (forced-colors: active) { + img, + svg, + ::slotted(*) { + forced-color-adjust: auto; + } +} + +:host(:not(:root)) { + overflow: hidden; +} diff --git a/1st-gen/packages/icon/src/index.ts b/1st-gen/packages/icon/src/index.ts new file mode 100644 index 00000000000..d5ccadf1a2d --- /dev/null +++ b/1st-gen/packages/icon/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './IconBase.js'; +export * from './Icon.js'; diff --git a/1st-gen/packages/icon/src/spectrum-icon-arrow.css b/1st-gen/packages/icon/src/spectrum-icon-arrow.css new file mode 100644 index 00000000000..b8018cdab38 --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-arrow.css @@ -0,0 +1,144 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-ArrowRight75 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-75); +} + +.spectrum-UIIcon-ArrowRight100 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-100); +} + +.spectrum-UIIcon-ArrowRight200 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-200); +} + +.spectrum-UIIcon-ArrowRight300 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-300); +} + +.spectrum-UIIcon-ArrowRight400 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-400); +} + +.spectrum-UIIcon-ArrowRight500 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-500); +} + +.spectrum-UIIcon-ArrowRight600 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-600); +} + +.spectrum-UIIcon-ArrowDown75 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-75); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown100 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-100); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown200 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-200); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown300 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-300); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown400 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-400); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown500 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-500); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowDown600 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-600); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ArrowLeft75 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-75); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft100 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-100); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft200 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-200); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft300 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-300); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft400 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-400); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft500 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-500); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowLeft600 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-600); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ArrowUp75 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-75); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp100 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-100); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp200 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-200); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp300 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-300); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp400 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-400); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp500 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-500); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ArrowUp600 { + --spectrum-icon-size: var(--spectrum-arrow-icon-size-600); + transform: rotate(270deg); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-asterisk.css b/1st-gen/packages/icon/src/spectrum-icon-asterisk.css new file mode 100644 index 00000000000..07ac73c2892 --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-asterisk.css @@ -0,0 +1,27 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-Asterisk75 { + --spectrum-icon-size: var(--spectrum-asterisk-icon-size-75); +} + +.spectrum-UIIcon-Asterisk100 { + --spectrum-icon-size: var(--spectrum-asterisk-icon-size-100); +} + +.spectrum-UIIcon-Asterisk200 { + --spectrum-icon-size: var(--spectrum-asterisk-icon-size-200); +} + +.spectrum-UIIcon-Asterisk300 { + --spectrum-icon-size: var(--spectrum-asterisk-icon-size-300); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-checkmark.css b/1st-gen/packages/icon/src/spectrum-icon-checkmark.css new file mode 100644 index 00000000000..9286ccdbedb --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-checkmark.css @@ -0,0 +1,43 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-Checkmark50 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-50); +} + +.spectrum-UIIcon-Checkmark75 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-75); +} + +.spectrum-UIIcon-Checkmark100 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-100); +} + +.spectrum-UIIcon-Checkmark200 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-200); +} + +.spectrum-UIIcon-Checkmark300 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-300); +} + +.spectrum-UIIcon-Checkmark400 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-400); +} + +.spectrum-UIIcon-Checkmark500 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-500); +} + +.spectrum-UIIcon-Checkmark600 { + --spectrum-icon-size: var(--spectrum-checkmark-icon-size-600); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-chevron.css b/1st-gen/packages/icon/src/spectrum-icon-chevron.css new file mode 100644 index 00000000000..7cda477e69f --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-chevron.css @@ -0,0 +1,144 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-ChevronRight50 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-50); +} + +.spectrum-UIIcon-ChevronRight75 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-75); +} + +.spectrum-UIIcon-ChevronRight100 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-100); +} + +.spectrum-UIIcon-ChevronRight200 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-200); +} + +.spectrum-UIIcon-ChevronRight300 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-300); +} + +.spectrum-UIIcon-ChevronRight400 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-400); +} + +.spectrum-UIIcon-ChevronRight500 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-500); +} + +.spectrum-UIIcon-ChevronDown50 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-50); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown75 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-75); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown100 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-100); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown200 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-200); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown300 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-300); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown400 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-400); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronDown500 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-500); + transform: rotate(90deg); +} + +.spectrum-UIIcon-ChevronLeft50 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-50); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft75 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-75); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft100 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-100); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft200 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-200); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft300 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-300); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft400 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-400); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronLeft500 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-500); + transform: rotate(180deg); +} + +.spectrum-UIIcon-ChevronUp50 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-50); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp75 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-75); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp100 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-100); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp200 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-200); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp300 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-300); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp400 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-400); + transform: rotate(270deg); +} + +.spectrum-UIIcon-ChevronUp500 { + --spectrum-icon-size: var(--spectrum-chevron-icon-size-500); + transform: rotate(270deg); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-corner-triangle.css b/1st-gen/packages/icon/src/spectrum-icon-corner-triangle.css new file mode 100644 index 00000000000..a397b229717 --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-corner-triangle.css @@ -0,0 +1,27 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-CornerTriangle75 { + --spectrum-icon-size: var(--spectrum-corner-triangle-icon-size-75); +} + +.spectrum-UIIcon-CornerTriangle100 { + --spectrum-icon-size: var(--spectrum-corner-triangle-icon-size-100); +} + +.spectrum-UIIcon-CornerTriangle200 { + --spectrum-icon-size: var(--spectrum-corner-triangle-icon-size-200); +} + +.spectrum-UIIcon-CornerTriangle300 { + --spectrum-icon-size: var(--spectrum-corner-triangle-icon-size-300); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-cross.css b/1st-gen/packages/icon/src/spectrum-icon-cross.css new file mode 100644 index 00000000000..ca3da6019a1 --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-cross.css @@ -0,0 +1,39 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-Cross75 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-75); +} + +.spectrum-UIIcon-Cross100 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-100); +} + +.spectrum-UIIcon-Cross200 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-200); +} + +.spectrum-UIIcon-Cross300 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-300); +} + +.spectrum-UIIcon-Cross400 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-400); +} + +.spectrum-UIIcon-Cross500 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-500); +} + +.spectrum-UIIcon-Cross600 { + --spectrum-icon-size: var(--spectrum-cross-icon-size-600); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-dash.css b/1st-gen/packages/icon/src/spectrum-icon-dash.css new file mode 100644 index 00000000000..654ed92cc1b --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-dash.css @@ -0,0 +1,43 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-UIIcon-Dash50 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-50); +} + +.spectrum-UIIcon-Dash75 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-75); +} + +.spectrum-UIIcon-Dash100 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-100); +} + +.spectrum-UIIcon-Dash200 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-200); +} + +.spectrum-UIIcon-Dash300 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-300); +} + +.spectrum-UIIcon-Dash400 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-400); +} + +.spectrum-UIIcon-Dash500 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-500); +} + +.spectrum-UIIcon-Dash600 { + --spectrum-icon-size: var(--spectrum-dash-icon-size-600); +} diff --git a/1st-gen/packages/icon/src/spectrum-icon-double-gripper.css b/1st-gen/packages/icon/src/spectrum-icon-double-gripper.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-double-gripper.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/spectrum-icon-single-gripper.css b/1st-gen/packages/icon/src/spectrum-icon-single-gripper.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-single-gripper.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/spectrum-icon-triple-gripper.css b/1st-gen/packages/icon/src/spectrum-icon-triple-gripper.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon-triple-gripper.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/icon/src/spectrum-icon.css b/1st-gen/packages/icon/src/spectrum-icon.css new file mode 100644 index 00000000000..193b426885e --- /dev/null +++ b/1st-gen/packages/icon/src/spectrum-icon.css @@ -0,0 +1,57 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-icon-inline-size: var(--mod-icon-inline-size, var(--mod-icon-size, var(--spectrum-icon-size))); + --spectrum-icon-block-size: var(--mod-icon-block-size, var(--mod-icon-size, var(--spectrum-icon-size))); + inline-size: var(--spectrum-icon-inline-size); + block-size: var(--spectrum-icon-block-size); + color: inherit; + color: var(--mod-icon-color, inherit); + fill: currentColor; + pointer-events: none; + display: inline-block; +} + +@media (forced-colors: active) { + :host { + forced-color-adjust: auto; + } +} + +:host { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-100); +} + +:host([size="xxs"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-xxs); +} + +:host([size="xs"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-50); +} + +:host([size="s"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-75); +} + +:host([size="l"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-200); +} + +:host([size="xl"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-300); +} + +:host([size="xxl"]) { + --spectrum-icon-size: var(--spectrum-workflow-icon-size-xxl); +} diff --git a/1st-gen/packages/icon/stories/icon.stories.ts b/1st-gen/packages/icon/stories/icon.stories.ts new file mode 100644 index 00000000000..77638000e77 --- /dev/null +++ b/1st-gen/packages/icon/stories/icon.stories.ts @@ -0,0 +1,114 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/icon/sp-icon.js'; +import { back } from './images'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import '@spectrum-web-components/icons/sp-icons-large.js'; + +const sizes = ['xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl']; + +export default { + component: 'sp-icon', + title: 'Icon', +}; + +export const Medium = (): TemplateResult => { + return html` + + ${sizes.map( + (size) => html` + + ` + )} + `; +}; + +export const Large = (): TemplateResult => { + return html` + + ${sizes.map( + (size) => html` + + ` + )} + `; +}; + +export const imageIcon = (): TemplateResult => { + return html` + ${sizes.map( + (size) => html` + + ` + )} + `; +}; + +imageIcon.storyName = 'Image Icon'; + +export const imageIconSrcError = (): TemplateResult => { + const invalidImgSrc = 'invalid-image-src'; + const error = (): void => { + console.error('Invalid sp-icon src provided'); + }; + + return html` + ${sizes.map( + (size) => html` + + ` + )} + `; +}; + +imageIconSrcError.storyName = 'Image Icon src invalid error'; + +imageIconSrcError.swc_vrt = { + skip: true, +}; + +imageIconSrcError.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const svgIcon = (): TemplateResult => { + return html` + ${sizes.map( + (size) => html` + + + + ` + )} + `; +}; + +svgIcon.storyName = 'SVG Icon'; diff --git a/1st-gen/packages/icon/stories/images.ts b/1st-gen/packages/icon/stories/images.ts new file mode 100644 index 00000000000..92efb2be410 --- /dev/null +++ b/1st-gen/packages/icon/stories/images.ts @@ -0,0 +1,14 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const back = + 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0yOTU3Ljk5NSAtNTUzMC4wMzIgNiAxMCI+PGRlZnM+PHN0eWxlPi5he2ZpbGw6bm9uZTtzdHJva2U6IzE0NzNlNjtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjJweDt9PC9zdHlsZT48L2RlZnM+PHBhdGggY2xhc3M9ImEiIGQ9Ik0yNTEuMywzMzNsNC00LTQtNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI3MDEuNjk1IC01MTk2LjAzMikgcm90YXRlKDE4MCkiLz48L3N2Zz4='; diff --git a/1st-gen/packages/icon/test/benchmark/test-basic.ts b/1st-gen/packages/icon/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..82feef5d2c7 --- /dev/null +++ b/1st-gen/packages/icon/test/benchmark/test-basic.ts @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +async function test(): Promise { + const iconset = document.createElement('sp-icons-medium'); + document.body.append(iconset); + await iconset.updateComplete; + + measureFixtureCreation(html` + + `); +} + +test(); diff --git a/1st-gen/packages/icon/test/icon-memory.test.ts b/1st-gen/packages/icon/test/icon-memory.test.ts new file mode 100644 index 00000000000..57b8c76e880 --- /dev/null +++ b/1st-gen/packages/icon/test/icon-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/icon/sp-icon.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/icon/test/icon.test.ts b/1st-gen/packages/icon/test/icon.test.ts new file mode 100644 index 00000000000..7bfe1e069a7 --- /dev/null +++ b/1st-gen/packages/icon/test/icon.test.ts @@ -0,0 +1,161 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import Sinon from 'sinon'; +import { isWebKit } from '@spectrum-web-components/shared'; +import '@spectrum-web-components/icon/sp-icon.js'; +import { Icon } from '@spectrum-web-components/icon'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { + elementUpdated, + expect, + fixture, + html, + waitUntil, +} from '@open-wc/testing'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('Icon', () => { + before(async () => { + const icons = document.createElement('sp-icons-medium'); + document.body.append(icons); + + await elementUpdated(icons); + }); + + it('loads', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + const container = el.shadowRoot + ? (el.shadowRoot.querySelector('#container') as HTMLDivElement) + : (el.querySelector('#container') as HTMLDivElement); + expect(container).to.exist; + const icon = container.querySelector('svg') as SVGElement; + expect(icon).to.exist; + expect(icon.getAttribute('aria-hidden')).to.equal('true'); + }); + + testForLitDevWarnings( + async () => + await fixture(html` + + `) + ); + + it('loads w/ src', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + + it('loads w/ invalid src, error dispatching', async () => { + const error = Sinon.spy(); + const el = await fixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + // Skipping the test case expectation for webkit because of error event not dispatching bug for the same, https://github.com/microsoft/playwright/issues/22332 + if (!isWebKit()) { + await waitUntil(() => error.calledOnce, 'The error was thrown.'); + } + }); + + it('loads w/ label', async () => { + const label = 'Chevron'; + const el = await fixture(html` + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + const container = el.shadowRoot + ? (el.shadowRoot.querySelector('#container') as HTMLDivElement) + : (el.querySelector('#container') as HTMLDivElement); + expect(container).to.exist; + const icon = container.querySelector('svg') as SVGElement; + expect(icon).to.exist; + expect(icon.hasAttribute('aria-hidden')).to.be.false; + expect(icon.getAttribute('aria-label')).to.equal(label); + }); + + it('does not error when name is missing', async () => { + const el = await fixture(html` + + `); + + return elementUpdated(el); + }); + + it('does not error with unknown set', async () => { + const el = await fixture(html` + + `); + + return elementUpdated(el); + }); + + it('does error with unknown icon', async () => { + const el = document.createElement('sp-icon'); + el.name = 'ui:unknown-icon'; + try { + document.body.appendChild(el); + await elementUpdated(el); + expect('failed').to.not.equal('failed'); + } catch (error) { + expect(() => { + throw error; + }).to.throw(); + } + el.remove(); + }); + + it('does not add multiple SVGs when removed and re-added to DOM', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + + const parent = el.parentNode as HTMLElement; + parent.removeChild(el); + parent.appendChild(el); + + // wait for updates + await el.updateComplete; + + const count = el.shadowRoot.querySelectorAll('svg').length; + expect(count).to.equal(1); + }); +}); diff --git a/1st-gen/packages/icon/tsconfig.json b/1st-gen/packages/icon/tsconfig.json new file mode 100644 index 00000000000..bf543cab638 --- /dev/null +++ b/1st-gen/packages/icon/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../iconset" }] +} diff --git a/1st-gen/packages/icons-ui/.gitignore b/1st-gen/packages/icons-ui/.gitignore new file mode 100644 index 00000000000..167e9e4eb30 --- /dev/null +++ b/1st-gen/packages/icons-ui/.gitignore @@ -0,0 +1,11 @@ +src/icons +src/icons-s2 +src/icons.ts +src/icons-s2.ts +src/elements +src/elements-s2 +icons/ +stories/icon-manifest.ts + +!bin/build.js +!src/DefaultIcon.ts \ No newline at end of file diff --git a/1st-gen/packages/icons-ui/.npmrc b/1st-gen/packages/icons-ui/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/icons-ui/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/icons-ui/CHANGELOG.md b/1st-gen/packages/icons-ui/CHANGELOG.md new file mode 100644 index 00000000000..971d6c6ea69 --- /dev/null +++ b/1st-gen/packages/icons-ui/CHANGELOG.md @@ -0,0 +1,541 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/iconset@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/iconset@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/iconset@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/iconset@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/iconset@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/iconset@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/iconset@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **icon:** remove size300 suffix from chevron and checkmark icons in Spectrum 2 ([#4904](https://github.com/adobe/spectrum-web-components/issues/4904)) ([a22f42b](https://github.com/adobe/spectrum-web-components/commit/a22f42bf508e1d0f2ddc9824b0f4d4e08eac659a)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **infield-button:** add infield-button package ([057b885](https://github.com/adobe/spectrum-web-components/commit/057b885276f3d5dcbe32bab5ab36a2bb82334bc3)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **icons-ui:** update spectrum css input ([4cb87ff](https://github.com/adobe/spectrum-web-components/commit/4cb87ff45cec625f273dd6e8ce7785b38cee448a)) +- **icons-ui:** vend fully registered icon components ([915a7b5](https://github.com/adobe/spectrum-web-components/commit/915a7b58294403943a331e40098b7947ffc87dc6)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.9.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.11...@spectrum-web-components/icons-ui@0.9.12) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.10...@spectrum-web-components/icons-ui@0.9.11) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.9...@spectrum-web-components/icons-ui@0.9.10) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.8...@spectrum-web-components/icons-ui@0.9.9) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.7...@spectrum-web-components/icons-ui@0.9.8) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.6...@spectrum-web-components/icons-ui@0.9.7) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.5...@spectrum-web-components/icons-ui@0.9.6) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.4...@spectrum-web-components/icons-ui@0.9.5) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.3...@spectrum-web-components/icons-ui@0.9.4) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.2...@spectrum-web-components/icons-ui@0.9.3) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.1...@spectrum-web-components/icons-ui@0.9.2) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.9.0...@spectrum-web-components/icons-ui@0.9.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.12...@spectrum-web-components/icons-ui@0.9.0) (2022-08-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.11...@spectrum-web-components/icons-ui@0.8.12) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.10...@spectrum-web-components/icons-ui@0.8.11) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.9...@spectrum-web-components/icons-ui@0.8.10) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.8...@spectrum-web-components/icons-ui@0.8.9) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.7...@spectrum-web-components/icons-ui@0.8.8) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.6...@spectrum-web-components/icons-ui@0.8.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.5...@spectrum-web-components/icons-ui@0.8.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.4...@spectrum-web-components/icons-ui@0.8.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.3...@spectrum-web-components/icons-ui@0.8.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.2...@spectrum-web-components/icons-ui@0.8.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.1...@spectrum-web-components/icons-ui@0.8.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.8.0...@spectrum-web-components/icons-ui@0.8.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.7.1...@spectrum-web-components/icons-ui@0.8.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.7.0...@spectrum-web-components/icons-ui@0.7.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.11...@spectrum-web-components/icons-ui@0.7.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.6.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.10...@spectrum-web-components/icons-ui@0.6.11) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.9...@spectrum-web-components/icons-ui@0.6.10) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.8...@spectrum-web-components/icons-ui@0.6.9) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.7...@spectrum-web-components/icons-ui@0.6.8) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.6...@spectrum-web-components/icons-ui@0.6.7) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.5...@spectrum-web-components/icons-ui@0.6.6) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.4...@spectrum-web-components/icons-ui@0.6.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.3...@spectrum-web-components/icons-ui@0.6.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.2...@spectrum-web-components/icons-ui@0.6.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.1...@spectrum-web-components/icons-ui@0.6.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.6.0...@spectrum-web-components/icons-ui@0.6.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.5.3...@spectrum-web-components/icons-ui@0.6.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.5.2...@spectrum-web-components/icons-ui@0.5.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.5.1...@spectrum-web-components/icons-ui@0.5.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.5.0...@spectrum-web-components/icons-ui@0.5.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.3.3...@spectrum-web-components/icons-ui@0.5.0) (2021-01-21) + +### Bug Fixes + +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **icons-ui:** update spectrum css input ([4cb87ff](https://github.com/adobe/spectrum-web-components/commit/4cb87ff45cec625f273dd6e8ce7785b38cee448a)) +- **icons-ui:** vend fully registered icon components ([915a7b5](https://github.com/adobe/spectrum-web-components/commit/915a7b58294403943a331e40098b7947ffc87dc6)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.3.3...@spectrum-web-components/icons-ui@0.4.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **icons-ui:** update spectrum css input ([4cb87ff](https://github.com/adobe/spectrum-web-components/commit/4cb87ff45cec625f273dd6e8ce7785b38cee448a)) +- **icons-ui:** vend fully registered icon components ([915a7b5](https://github.com/adobe/spectrum-web-components/commit/915a7b58294403943a331e40098b7947ffc87dc6)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.3.2...@spectrum-web-components/icons-ui@0.3.3) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.3.1...@spectrum-web-components/icons-ui@0.3.2) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.3.0...@spectrum-web-components/icons-ui@0.3.1) (2020-09-25) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.2.2...@spectrum-web-components/icons-ui@0.3.0) (2020-08-31) + +### Features + +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.2.1...@spectrum-web-components/icons-ui@0.2.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.2.0...@spectrum-web-components/icons-ui@0.2.1) (2020-07-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.1.2...@spectrum-web-components/icons-ui@0.2.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.1.1...@spectrum-web-components/icons-ui@0.1.2) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-ui + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-ui@0.1.0...@spectrum-web-components/icons-ui@0.1.1) (2020-05-08) + +### Bug Fixes + +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) + +# 0.1.0 (2020-04-16) + +### Features + +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) diff --git a/1st-gen/packages/icons-ui/README.md b/1st-gen/packages/icons-ui/README.md new file mode 100644 index 00000000000..1c5a7e30a63 --- /dev/null +++ b/1st-gen/packages/icons-ui/README.md @@ -0,0 +1,168 @@ +## Overview + +Deliver [Spectrum UI Icons](https://spectrum.adobe.com/page/icons/) as either: + +- Registered custom elements (``) +- Unregistered class definitions (`IconArrow75`) +- Functions with customizable template tags to be used across various frameworks (`Arrow75Icon()`) + +Search a full list of icons to [find an icon](#find-an-icon) for your project or find technical information about [extended use cases](#extended-use-cases), like consuming this package in various UI frameworks below. + +Remember to consult Spectrum's [Iconography Guidelines](https://spectrum.adobe.com/page/iconography/) when planning how to leverage these icons in the visual delivery of your application. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/icons-ui?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/icons-ui) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/icons-ui?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/icons-ui) + +``` +yarn add @spectrum-web-components/icons-ui +``` + +Import the side effectful registration of a single element (e.g. ``) via: + +``` +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow75.js'; +``` + +Leverage a single icon base class (e.g. `IconArrow75`) as a type, or for extension purposes, do so, via: + +``` +import { IconArrow75 } from '@spectrum-web-components/icons-ui/src/elements/IconArrow75.js'; +``` + +### Find an icon + +Search the available Spectrum Workflow icons below. + +

Complete search experience available at: https://opensource.adobe.com/spectrum-web-components/components/icons-ui/.

+ + + + + +### Alternative usage + +You can import raw icons (e.g. `Arrow75Icon()`) via: + +```js +import { Arrow75Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow75.js'; +``` + +`@spectrum-web-components/icons-ui` exports _all_ icons. If your build process [tree-shakes](https://rollupjs.org/guide/en/#tree-shaking) dependencies, you can import from it directly: + +```js +import { Arrow75Icon } from '@spectrum-web-components/icons-ui'; +``` + +These icon literals are prepared with the `html` template tag from `lit-html`, the default value of an icon export will be as follows: + +```js +import { LitElement, html } from 'lit-element'; +import '@spectrum-web-components/icon'; +import { Arrow75Icon } from '@spectrum-web-components/icons-ui'; + +class ElementWithIcon extends LitElement { + protected override render(): TemplateResult { + return html` + + ${Arrow75Icon()} + + ` + } +} + +customElements.define('element-with-icon', ElementWithIcon); +``` + +Every icons can be customized via the following options: + +```js +{ + width: 24, // number outlining the width to deliver the SVG element with + height: 24, // number outlining the height to delivery the SVG element with + hidden: false, // boolean representing whether to apply the `aria-hidden` attribute + title: 'Icon title', // string of the title to deliver the icon with +} +``` + +### Extended use cases + +The default exports of this package are pre-wrapped via `setCustomTemplateLiteralTag` in the `html` template tag from `lit-html`, and work like the following:: + +```js +import { Arrow75Icon } from '@spectrum-web-components/icons-ui'; + +console.log(Arrow75Icon()); + +/*** +TemplateResult {strings: Array[1], values: Array[0], type: "html", processor: DefaultTemplateProcessor, constructor: Object} +***/ +``` + +When working in the context of other frameworks, it is possible to import the icons with a generic template tag as follows: + +```js +import { Arrow75Icon } from '@spectrum-web-components/icons-ui/src/icons.js'; + +console.log(Arrow75Icon()); + +/*** + + + +***/ +``` + +What's more, if you're already working with a specific parser in your project, you can assign it as the one to use when delivering the icons in order to be sure that the SVG content is delivered as parsed content to your final template. The means if you were working with Preact via the `htm` tag as bound to the provided hyperscript function: + +```js +import { + Arrow75Icon, + setCustomTemplateLiteralTag, +} from '@spectrum-web-components/icons-ui/src/icons.js'; +import htm from 'htm'; +import { h } from 'preact'; + +const hPreact = htm.bind(h); + +setCustomTemplateLiteralTag(hPreact); + +console.log(Arrow75Icon()); + +/*** +VNode {nodeName: "svg", children: Array[1], attributes: Object, key: undefined, constructor: Object} +***/ +``` + +In this way, the icons exported by `@spectrum-web-components/icons-ui` can be leveraged in projects powered by the likes of hyperHTML, lighterhtml, lit-html, Preact, React, Vanilla JS, Vue.js, and more! + +### Accessibility + +Review the accessibility guidelines for the [icon](../icon#accessibility-guidelines). diff --git a/1st-gen/packages/icons-ui/bin/build.js b/1st-gen/packages/icons-ui/bin/build.js new file mode 100644 index 00000000000..5438d3155a8 --- /dev/null +++ b/1st-gen/packages/icons-ui/bin/build.js @@ -0,0 +1,415 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import fs from 'fs'; +import fg from 'fast-glob'; +import path from 'path'; +import { load } from 'cheerio'; +import prettier from 'prettier'; +import Case from 'case'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const rootDir = path.join(__dirname, '../../../'); + +const disclaimer = ` +/* +Copyright 2025 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/`; + +const S1IConsPackageDir = '@spectrum-css/ui-icons/dist/medium'; +const S2IConsPackageDir = '@spectrum-css/ui-icons-s2/dist/medium'; +const keepColors = ''; + +if (!fs.existsSync(`${rootDir}packages/icons-ui/src`)) { + fs.mkdirSync(`${rootDir}packages/icons-ui/src`); +} +if (!fs.existsSync(`${rootDir}packages/icons-ui/src/icons`)) { + fs.mkdirSync(`${rootDir}packages/icons-ui/src/icons`); +} +if (!fs.existsSync(`${rootDir}packages/icons-ui/src/icons-s2`)) { + fs.mkdirSync(`${rootDir}packages/icons-ui/src/icons-s2`); +} +if (!fs.existsSync(`${rootDir}packages/icons-ui/src/elements`)) { + fs.mkdirSync(`${rootDir}packages/icons-ui/src/elements`); +} +if (!fs.existsSync(`${rootDir}packages/icons-ui/icons`)) { + fs.mkdirSync(`${rootDir}packages/icons-ui/icons`); +} +fs.writeFileSync( + path.join(rootDir, 'packages', 'icons-ui', 'src', 'icons.ts'), + disclaimer, + 'utf-8' +); +fs.writeFileSync( + path.join(rootDir, 'packages', 'icons-ui', 'src', 'icons-s2.ts'), + disclaimer, + 'utf-8' +); +const manifestPath = path.join( + rootDir, + 'packages', + 'icons-ui', + 'stories', + 'icon-manifest.ts' +); +fs.writeFileSync(manifestPath, disclaimer, 'utf-8'); +let manifestImports = `import { + html, + TemplateResult +} from '@spectrum-web-components/base';\r\n`; +let manifestListings = `\r\nexport const iconManifest = [\r\n`; + +const defaultIconImport = `import { DefaultIcon as AlternateIcon } from '../DefaultIcon.js';\r\n`; + +async function buildIcons(icons, tag, iconsNameList) { + console.log('Building icons for', { icons, tag, iconsNameList }); + icons.forEach((i) => { + const svg = fs.readFileSync(i, 'utf-8'); + let id = path + .basename(i, '.svg') + .replace('S2_Icon_', '') + .replace('_20_N', '') + .replace('_22x20_N', ''); + if (id.search(/^Ad[A-Z]/) !== -1) { + id = id.replace(/^Ad/, ''); + id += 'Advert'; + } + + if (id === 'UnLink') { + id = 'Unlink'; + } + if (id === 'TextStrikeThrough') { + id = 'TextStrikethrough'; + } + + let ComponentName = id === 'github' ? 'GitHub' : Case.pascal(id); + + if (ComponentName === 'TextStrikeThrough') { + ComponentName = 'TextStrikethrough'; + } + if (ComponentName === 'UnLink') { + ComponentName = 'Unlink'; + } + + const $ = load(svg, { + xmlMode: true, + }); + const title = Case.capital(id); + const fileName = `${id}.ts`; + const location = path.join( + rootDir, + 'packages/icons-ui/src', + tag, + fileName + ); + + if (!Number.isNaN(Number(ComponentName[0]))) { + return; + } + + $('*').each((index, el) => { + if (el.name === 'svg') { + $(el).attr('aria-hidden', '...'); + $(el).attr('role', 'img'); + if (keepColors !== 'keep') { + $(el).attr('fill', 'currentColor'); + } + $(el).attr('aria-label', '...'); + $(el).removeAttr('id'); + $(el).attr('width', '...'); + $(el).attr('height', '...'); + } + if (el.name === 'defs') { + $(el).remove(); + } + Object.keys(el.attribs).forEach((x) => { + if (x === 'class') { + $(el).removeAttr(x); + } + if (keepColors !== 'keep' && x === 'stroke') { + $(el).attr(x, 'currentColor'); + } + if (keepColors !== 'keep' && x === 'fill') { + $(el).attr(x, 'currentColor'); + } + }); + }); + + const iconLiteral = ` + ${disclaimer} + + import {tag as html, TemplateResult} from '../custom-tag.js'; + + export {setCustomTemplateLiteralTag} from '../custom-tag.js'; + export const ${ComponentName}Icon = ({ + width = 24, + height = 24, + hidden = false, + title = '${title}', + } = {},): string | TemplateResult => { + return html\`${$('svg') + .toString() + .replace( + 'aria-hidden="..."', + "aria-hidden=${hidden ? 'true' : 'false'}" + ) + .replace('width="..."', 'width="${width}"') + .replace('height="..."', 'height="${height}"') + .replace('aria-label="..."', 'aria-label="${title}"')}\`; + } + `; + + prettier + .format(iconLiteral, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((icon) => { + fs.writeFileSync(location, icon, 'utf-8'); + }); + + const exportString = `export {${ComponentName}Icon} from './${tag}/${id}.js';\r\n`; + fs.appendFileSync( + path.join(rootDir, 'packages', 'icons-ui', 'src', tag + '.ts'), + exportString, + 'utf-8' + ); + + const iconElementName = `sp-icon-${Case.kebab(ComponentName)}`; + + const currenVersionIconImport = `import { ${ComponentName}Icon as CurrentIcon } from '../${tag}/${id}.js';\r\n`; + + // check if the icon is present in the other version + let otherVersionIconImport = defaultIconImport; + + if (iconsNameList.includes(ComponentName)) { + const alternateTag = tag === 'icons' ? 'icons-s2' : 'icons'; + otherVersionIconImport = `import { ${ComponentName}Icon as AlternateIcon } from '../${alternateTag}/${id}.js';\r\n`; + } + + const spectrumVersion = tag === 'icons' ? 1 : 2; + + const iconElement = ` + ${disclaimer} + + import { + html, + TemplateResult + } from '@spectrum-web-components/base'; + import { + IconBase + } from '@spectrum-web-components/icon'; + import { + setCustomTemplateLiteralTag + } from '../custom-tag.js'; + + ${currenVersionIconImport} + ${otherVersionIconImport} + + /** + * @element ${iconElementName} + */ + export class Icon${ComponentName} extends IconBase { + protected override render(): TemplateResult { + setCustomTemplateLiteralTag(html); + + if(this.spectrumVersion === ${spectrumVersion}){ + return CurrentIcon({ hidden: !this.label, title: this.label }) as TemplateResult; + } + return AlternateIcon({ hidden: !this.label, title: this.label }) as TemplateResult; + + } + } + `; + + prettier + .format(iconElement, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((iconElementFile) => { + fs.writeFileSync( + path.join( + rootDir, + 'packages', + 'icons-ui', + 'src', + 'elements', + `Icon${id}.ts` + ), + iconElementFile, + 'utf-8' + ); + }); + + const iconRegistration = ` + ${disclaimer} + + import { Icon${ComponentName} } from '../src/elements/Icon${id}.js'; + import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + + defineElement('${iconElementName}', Icon${ComponentName}); + + declare global { + interface HTMLElementTagNameMap { + '${iconElementName}': Icon${ComponentName}; + } + } + `; + + prettier + .format(iconRegistration, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((iconRegistrationFile) => { + fs.writeFileSync( + path.join( + rootDir, + 'packages', + 'icons-ui', + 'icons', + `${iconElementName}.ts` + ), + iconRegistrationFile, + 'utf-8' + ); + }); + + const importStatement = `\r\nimport '@spectrum-web-components/icons-ui/icons/${iconElementName}.js';`; + const metadata = `{name: '${Case.sentence( + ComponentName + )}', tag: '<${iconElementName}>', story: (size: string): TemplateResult => html\`<${iconElementName} size=\$\{size\}>\`},\r\n`; + manifestImports += importStatement; + manifestListings += metadata; + }); +} + +const iconsV1 = ( + await fg(`${rootDir}/../node_modules/${S1IConsPackageDir}/**.svg`) +).sort(); + +const iconsV2 = ( + await fg(`${rootDir}/../node_modules/${S2IConsPackageDir}/**.svg`) +).sort(); + +const iconsV1NameList = iconsV1.map((i) => { + let id = path + .basename(i, '.svg') + .replace('S2_Icon_', '') + .replace('_20_N', '') + .replace('_22x20_N', ''); + + if (id.search(/^Ad[A-Z]/) !== -1) { + id = id.replace(/^Ad/, ''); + id += 'Advert'; + } + + if (id === 'UnLink') { + id = 'Unlink'; + } + if (id === 'TextStrikeThrough') { + id = 'TextStrikethrough'; + } + + let ComponentName = id === 'github' ? 'GitHub' : Case.pascal(id); + + if (ComponentName === 'TextStrikeThrough') { + ComponentName = 'TextStrikethrough'; + } + if (ComponentName === 'UnLink') { + ComponentName = 'Unlink'; + } + + return ComponentName; +}); +const iconsV2NameList = iconsV2.map((i) => { + let id = path + .basename(i, '.svg') + .replace('S2_Icon_', '') + .replace('_20_N', '') + .replace('_22x20_N', ''); + + if (id.search(/^Ad[A-Z]/) !== -1) { + id = id.replace(/^Ad/, ''); + id += 'Advert'; + } + + if (id === 'UnLink') { + id = 'Unlink'; + } + if (id === 'TextStrikeThrough') { + id = 'TextStrikethrough'; + } + + let ComponentName = id === 'github' ? 'GitHub' : Case.pascal(id); + + if (ComponentName === 'TextStrikeThrough') { + ComponentName = 'TextStrikethrough'; + } + if (ComponentName === 'UnLink') { + ComponentName = 'Unlink'; + } + + return ComponentName; +}); + +await buildIcons(iconsV1, 'icons', iconsV2NameList); +await buildIcons(iconsV2, 'icons-s2', iconsV1NameList); + +const exportString = `\r\nexport { setCustomTemplateLiteralTag } from './custom-tag.js';\r\n`; +fs.appendFileSync( + path.join(rootDir, 'packages', 'icons-ui', 'src', 'icons.ts'), + exportString, + 'utf-8' +); + +fs.appendFileSync( + manifestPath, + `${manifestImports}${manifestListings}];\r\n`, + 'utf-8' +); diff --git a/1st-gen/packages/icons-ui/package.json b/1st-gen/packages/icons-ui/package.json new file mode 100644 index 00000000000..e196e33930c --- /dev/null +++ b/1st-gen/packages/icons-ui/package.json @@ -0,0 +1,72 @@ +{ + "name": "@spectrum-web-components/icons-ui", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/icons-ui" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/icons-ui", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": "./src/index.js", + "./src/*": "./src/*", + "./icons/*": "./icons/*", + "./package.json": "./package.json" + }, + "scripts": { + "build": "node ./bin/build.js" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "!bin/", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/iconset": "1.9.0" + }, + "devDependencies": { + "@spectrum-css/ui-icons": "1.1.2", + "@spectrum-css/ui-icons-s2": "npm:@spectrum-css/ui-icons@2.0.0-s2-foundations.10", + "case": "1.6.3", + "cheerio": "1.1.2", + "fast-glob": "3.3.3", + "prettier": "3.6.2" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./src/index.js", + "./icons/*", + "./icons-s2/*" + ] +} diff --git a/1st-gen/packages/icons-ui/src/custom-tag.ts b/1st-gen/packages/icons-ui/src/custom-tag.ts new file mode 100644 index 00000000000..b626b39b34b --- /dev/null +++ b/1st-gen/packages/icons-ui/src/custom-tag.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +export type { TemplateResult }; + +export type GenericTemplateLiteralTagType = ( + strings: TemplateStringsArray, + ...values: unknown[] +) => string; +type TemplateLiteralTagType = GenericTemplateLiteralTagType | typeof html; +let customTemplateLiteralTag: TemplateLiteralTagType; + +export const tag = function ( + strings: TemplateStringsArray, + ...values: unknown[] +): string | TemplateResult { + if (customTemplateLiteralTag) { + return customTemplateLiteralTag(strings, ...values); + } + return values.reduce( + (acc: string, v, idx) => + (acc as string) + (v as string) + strings[idx + 1], + strings[0] + ); +}; + +export const setCustomTemplateLiteralTag = ( + tag: TemplateLiteralTagType +): void => { + customTemplateLiteralTag = tag; +}; diff --git a/1st-gen/packages/icons-ui/src/index.ts b/1st-gen/packages/icons-ui/src/index.ts new file mode 100644 index 00000000000..5ead36ed48d --- /dev/null +++ b/1st-gen/packages/icons-ui/src/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@spectrum-web-components/base'; +import { setCustomTemplateLiteralTag } from './custom-tag.js'; + +setCustomTemplateLiteralTag(html); + +export { setCustomTemplateLiteralTag }; +export * from './icons.js'; diff --git a/1st-gen/packages/icons-ui/stories/icons-ui.stories.ts b/1st-gen/packages/icons-ui/stories/icons-ui.stories.ts new file mode 100644 index 00000000000..f639730c070 --- /dev/null +++ b/1st-gen/packages/icons-ui/stories/icons-ui.stories.ts @@ -0,0 +1,127 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '../../iconset/stories/icons-demo.js'; +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { until } from '@spectrum-web-components/base/src/directives.js'; + +export default { + title: 'Icons/UI', + argTypes: { + color: { control: 'color' }, + size: { + control: { + type: 'inline-radio', + options: ['s', 'm', 'l', 'xl'], + }, + }, + }, + args: { + color: '#000000', + size: 'm', + }, + swc_vrt: { + preload: async (): Promise => { + await import('./icon-manifest.js'); + }, + }, +}; + +interface Properties { + color: string; + size: 's' | 'm' | 'l' | 'xl'; +} + +export const elements = ({ color, size }: Properties): TemplateResult => { + const content = import('./icon-manifest.js').then( + (iconManifest) => html` + + ` + ); + return html` + + + ${until( + content, + html` + Loading... + ` + )} + + `; +}; + +export const Icons = ({ color, size }: Properties): TemplateResult => { + const content = import('../').then((icons) => { + const iconTemplates: { + template: () => TemplateResult; + name: string; + }[] = []; + for (const icon in icons) { + if (icon === 'setCustomTemplateLiteralTag') continue; + iconTemplates.push({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + template: (icons as any)[icon], + name: icon, + }); + } + return html` + + ${iconTemplates.map( + (icon) => html` + + ${icon.template()} + ${icon.name} + + ` + )} + + `; + }); + return html` + + + ${until( + content, + html` + Loading... + ` + )} + + `; +}; diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-attribute-many.ts b/1st-gen/packages/icons-ui/test/benchmark/test-attribute-many.ts new file mode 100644 index 00000000000..75080b2fabc --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-attribute-many.ts @@ -0,0 +1,70 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const iconset = document.createElement('sp-icons-medium'); +document.body.append(iconset); + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-attribute.ts b/1st-gen/packages/icons-ui/test/benchmark/test-attribute.ts new file mode 100644 index 00000000000..08fa56b18a6 --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-attribute.ts @@ -0,0 +1,70 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const iconset = document.createElement('sp-icons-medium'); +document.body.append(iconset); + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-injected-many.ts b/1st-gen/packages/icons-ui/test/benchmark/test-injected-many.ts new file mode 100644 index 00000000000..a9bd9a7367f --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-injected-many.ts @@ -0,0 +1,117 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import { Arrow75Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow75.js'; +import { Arrow100Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow100.js'; +import { Arrow200Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow200.js'; +import { Arrow300Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow300.js'; +import { Arrow400Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow400.js'; +import { Arrow500Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow500.js'; +import { Arrow600Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow600.js'; +import { Asterisk75Icon } from '@spectrum-web-components/icons-ui/src/icons/Asterisk75.js'; +import { Asterisk100Icon } from '@spectrum-web-components/icons-ui/src/icons/Asterisk100.js'; +import { Asterisk200Icon } from '@spectrum-web-components/icons-ui/src/icons/Asterisk200.js'; +import { Asterisk300Icon } from '@spectrum-web-components/icons-ui/src/icons/Asterisk300.js'; +import { Checkmark50Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark50.js'; +import { Checkmark75Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark75.js'; +import { Checkmark100Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark100.js'; +import { Checkmark200Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark200.js'; +import { Checkmark300Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark300.js'; +import { Checkmark400Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark400.js'; +import { Checkmark500Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark500.js'; +import { Checkmark600Icon } from '@spectrum-web-components/icons-ui/src/icons/Checkmark600.js'; +import { Chevron75Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron75.js'; +import { Chevron100Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron100.js'; +import { Chevron200Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron200.js'; +import { Chevron300Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron300.js'; +import { Chevron400Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron400.js'; +import { Chevron500Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron500.js'; +import { Chevron600Icon } from '@spectrum-web-components/icons-ui/src/icons/Chevron600.js'; +import { CornerTriangle75Icon } from '@spectrum-web-components/icons-ui/src/icons/CornerTriangle75.js'; +import { CornerTriangle100Icon } from '@spectrum-web-components/icons-ui/src/icons/CornerTriangle100.js'; +import { CornerTriangle200Icon } from '@spectrum-web-components/icons-ui/src/icons/CornerTriangle200.js'; +import { CornerTriangle300Icon } from '@spectrum-web-components/icons-ui/src/icons/CornerTriangle300.js'; +import { Cross75Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross75.js'; +import { Cross100Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross100.js'; +import { Cross200Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross200.js'; +import { Cross300Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross300.js'; +import { Cross400Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross400.js'; +import { Cross500Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross500.js'; +import { Cross600Icon } from '@spectrum-web-components/icons-ui/src/icons/Cross600.js'; +import { Dash50Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash50.js'; +import { Dash75Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash75.js'; +import { Dash100Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash100.js'; +import { Dash200Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash200.js'; +import { Dash300Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash300.js'; +import { Dash400Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash400.js'; +import { Dash500Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash500.js'; +import { Dash600Icon } from '@spectrum-web-components/icons-ui/src/icons/Dash600.js'; +import { DoubleGripperIcon } from '@spectrum-web-components/icons-ui/src/icons/DoubleGripper.js'; +import { SingleGripperIcon } from '@spectrum-web-components/icons-ui/src/icons/SingleGripper.js'; +import { TripleGripperIcon } from '@spectrum-web-components/icons-ui/src/icons/TripleGripper.js'; +import { setCustomTemplateLiteralTag } from '@spectrum-web-components/icons-ui/src/custom-tag.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +setCustomTemplateLiteralTag(html); + +measureFixtureCreation(html` + ${Arrow75Icon()} + ${Arrow100Icon()} + ${Arrow200Icon()} + ${Arrow300Icon()} + ${Arrow400Icon()} + ${Arrow500Icon()} + ${Arrow600Icon()} + ${Asterisk75Icon()} + ${Asterisk100Icon()} + ${Asterisk200Icon()} + ${Asterisk300Icon()} + ${Checkmark50Icon()} + ${Checkmark75Icon()} + ${Checkmark100Icon()} + ${Checkmark200Icon()} + ${Checkmark300Icon()} + ${Checkmark400Icon()} + ${Checkmark500Icon()} + ${Checkmark600Icon()} + ${Chevron75Icon()} + ${Chevron100Icon()} + ${Chevron200Icon()} + ${Chevron300Icon()} + ${Chevron400Icon()} + ${Chevron500Icon()} + ${Chevron600Icon()} + ${CornerTriangle75Icon()} + ${CornerTriangle100Icon()} + ${CornerTriangle200Icon()} + ${CornerTriangle300Icon()} + ${Cross75Icon()} + ${Cross100Icon()} + ${Cross200Icon()} + ${Cross300Icon()} + ${Cross400Icon()} + ${Cross500Icon()} + ${Cross600Icon()} + ${Dash50Icon()} + ${Dash75Icon()} + ${Dash100Icon()} + ${Dash200Icon()} + ${Dash300Icon()} + ${Dash400Icon()} + ${Dash500Icon()} + ${Dash600Icon()} + ${DoubleGripperIcon()} + ${SingleGripperIcon()} + ${TripleGripperIcon()} +`); diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-injected.ts b/1st-gen/packages/icons-ui/test/benchmark/test-injected.ts new file mode 100644 index 00000000000..f912f897925 --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-injected.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import { Arrow75Icon } from '@spectrum-web-components/icons-ui/src/icons/Arrow75.js'; +import { setCustomTemplateLiteralTag } from '@spectrum-web-components/icons-ui/src/custom-tag.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +setCustomTemplateLiteralTag(html); + +measureFixtureCreation(html` + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} + ${Arrow75Icon()} +`); diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-registered-many.ts b/1st-gen/packages/icons-ui/test/benchmark/test-registered-many.ts new file mode 100644 index 00000000000..52deff40468 --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-registered-many.ts @@ -0,0 +1,113 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow400.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow500.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow600.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-asterisk75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-asterisk100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-asterisk200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-asterisk300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark50.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark400.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark500.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark600.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron400.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron500.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron600.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-corner-triangle75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-corner-triangle100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-corner-triangle200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-corner-triangle300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross400.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross500.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-cross600.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash50.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash75.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash300.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash400.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash500.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-dash600.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-double-gripper.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-single-gripper.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-triple-gripper.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-ui/test/benchmark/test-registered.ts b/1st-gen/packages/icons-ui/test/benchmark/test-registered.ts new file mode 100644 index 00000000000..e653e380740 --- /dev/null +++ b/1st-gen/packages/icons-ui/test/benchmark/test-registered.ts @@ -0,0 +1,65 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow100.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-ui/tsconfig.json b/1st-gen/packages/icons-ui/tsconfig.json new file mode 100644 index 00000000000..b58bd73c9fc --- /dev/null +++ b/1st-gen/packages/icons-ui/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": [ + "icons/**/*.ts", + "icons-s2/**/*.ts", + "src/**/*.ts", + "../../global.d.ts" + ], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }, { "path": "../icon" }] +} diff --git a/1st-gen/packages/icons-workflow/.gitignore b/1st-gen/packages/icons-workflow/.gitignore new file mode 100644 index 00000000000..c12e52301e8 --- /dev/null +++ b/1st-gen/packages/icons-workflow/.gitignore @@ -0,0 +1,15 @@ +src/icons +src/icons-s2 +src/icons.ts +src/icons-s2.ts +src/elements +src/elements-s2 +src/DefaultIcon.ts +icons +stories/icon-manifest.ts + +!bin/build.js +!bin/build-icons-mapping.js +!bin/icons-mapping.json +!src/DefaultIcon.ts +bin/*.csv \ No newline at end of file diff --git a/1st-gen/packages/icons-workflow/.npmrc b/1st-gen/packages/icons-workflow/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/icons-workflow/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/icons-workflow/CHANGELOG.md b/1st-gen/packages/icons-workflow/CHANGELOG.md new file mode 100644 index 00000000000..d0c43ec1d76 --- /dev/null +++ b/1st-gen/packages/icons-workflow/CHANGELOG.md @@ -0,0 +1,557 @@ +# Change Log + +## 1.9.0 + +### Minor Changes + +- [#5735](https://github.com/adobe/spectrum-web-components/pull/5735) [`bdf54c1`](https://github.com/adobe/spectrum-web-components/commit/bdf54c1bc6d3eb20da1a1bf3b40650e6ab1ba399) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - - Upgraded to `@adobe/spectrum-css-workflow-icons@5.0.0`. - Includes changes from previous a4u upstream releases: - Added `S2_Icon_HeartFilled_20_N.svg`, updated `S2_Icon_SpeedFast_20_N.svg`. - Replaced all 22×20px Cloud State icons with 20px variants. - Removed deprecated multi-colored error icon. Added new Cloud State icons (`Disconnected`, `Error`, `InProgress`, `Online`, `Paused`, `Pending`, `SlowConnection`). - Updated several other icons (`CloseCaptions`, `CommentHide`, `Community`, etc.). + - For the full changelog, see: https://github.com/adobe/spectrum-css-workflow-icons/pull/50 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Minor Changes + +- [#5367](https://github.com/adobe/spectrum-web-components/pull/5367) [`f6cebbd`](https://github.com/adobe/spectrum-web-components/commit/f6cebbd90008a2abb1232c355ae06e8566086093) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Added missing S2 icons + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **icon:** remove size300 suffix from chevron and checkmark icons in Spectrum 2 ([#4904](https://github.com/adobe/spectrum-web-components/issues/4904)) ([a22f42b](https://github.com/adobe/spectrum-web-components/commit/a22f42bf508e1d0f2ddc9824b0f4d4e08eac659a)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **infield-button:** add infield-button package ([057b885](https://github.com/adobe/spectrum-web-components/commit/057b885276f3d5dcbe32bab5ab36a2bb82334bc3)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **alert-dialog:** add Alert Dialog package ([#3501](https://github.com/adobe/spectrum-web-components/issues/3501)) ([1062847](https://github.com/adobe/spectrum-web-components/commit/10628476d39ef45c23efa8b6ac53d4a2e334a92f)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- **icons-workflow:** rename icons/files to avoid ad blocking ([842b081](https://github.com/adobe/spectrum-web-components/commit/842b0810089b567b5d3dfca70ddc5935c4c6f477)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) + +### Features + +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) +- **icons-workflow:** add workflow icons package ([6b09287](https://github.com/adobe/spectrum-web-components/commit/6b09287d5c169205f0cc332b2158d57e7ef4a4b7)) +- **icons-workflow:** update spectrum css input ([549b4b6](https://github.com/adobe/spectrum-web-components/commit/549b4b6b3743ac6ca3b8fe1048188ab96ba85eee)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- track the associated Spectrum CSS package ([86b1be5](https://github.com/adobe/spectrum-web-components/commit/86b1be5d1d2b6e870049a8642dabc3520c359716)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.9.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.11...@spectrum-web-components/icons-workflow@0.9.12) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.10...@spectrum-web-components/icons-workflow@0.9.11) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.9...@spectrum-web-components/icons-workflow@0.9.10) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.8...@spectrum-web-components/icons-workflow@0.9.9) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.7...@spectrum-web-components/icons-workflow@0.9.8) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.6...@spectrum-web-components/icons-workflow@0.9.7) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.5...@spectrum-web-components/icons-workflow@0.9.6) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.4...@spectrum-web-components/icons-workflow@0.9.5) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.3...@spectrum-web-components/icons-workflow@0.9.4) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.2...@spectrum-web-components/icons-workflow@0.9.3) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.1...@spectrum-web-components/icons-workflow@0.9.2) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.9.0...@spectrum-web-components/icons-workflow@0.9.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.12...@spectrum-web-components/icons-workflow@0.9.0) (2022-08-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.11...@spectrum-web-components/icons-workflow@0.8.12) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.10...@spectrum-web-components/icons-workflow@0.8.11) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.9...@spectrum-web-components/icons-workflow@0.8.10) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.8...@spectrum-web-components/icons-workflow@0.8.9) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.7...@spectrum-web-components/icons-workflow@0.8.8) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.6...@spectrum-web-components/icons-workflow@0.8.7) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.5...@spectrum-web-components/icons-workflow@0.8.6) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.4...@spectrum-web-components/icons-workflow@0.8.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.3...@spectrum-web-components/icons-workflow@0.8.4) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.2...@spectrum-web-components/icons-workflow@0.8.3) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.1...@spectrum-web-components/icons-workflow@0.8.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.8.0...@spectrum-web-components/icons-workflow@0.8.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.7.1...@spectrum-web-components/icons-workflow@0.8.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.7.0...@spectrum-web-components/icons-workflow@0.7.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.11...@spectrum-web-components/icons-workflow@0.7.0) (2021-11-02) + +### Features + +- track the associated Spectrum CSS package ([86b1be5](https://github.com/adobe/spectrum-web-components/commit/86b1be5d1d2b6e870049a8642dabc3520c359716)) + +## [0.6.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.10...@spectrum-web-components/icons-workflow@0.6.11) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.9...@spectrum-web-components/icons-workflow@0.6.10) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.8...@spectrum-web-components/icons-workflow@0.6.9) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.7...@spectrum-web-components/icons-workflow@0.6.8) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.6...@spectrum-web-components/icons-workflow@0.6.7) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.5...@spectrum-web-components/icons-workflow@0.6.6) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.4...@spectrum-web-components/icons-workflow@0.6.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.3...@spectrum-web-components/icons-workflow@0.6.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.2...@spectrum-web-components/icons-workflow@0.6.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.1...@spectrum-web-components/icons-workflow@0.6.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.6.0...@spectrum-web-components/icons-workflow@0.6.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.5.3...@spectrum-web-components/icons-workflow@0.6.0) (2021-03-04) + +### Bug Fixes + +- **icons-workflow:** rename icons/files to avoid ad blocking ([842b081](https://github.com/adobe/spectrum-web-components/commit/842b0810089b567b5d3dfca70ddc5935c4c6f477)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.5.2...@spectrum-web-components/icons-workflow@0.5.3) (2021-02-11) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.5.1...@spectrum-web-components/icons-workflow@0.5.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.5.0...@spectrum-web-components/icons-workflow@0.5.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.6...@spectrum-web-components/icons-workflow@0.5.0) (2021-01-21) + +### Bug Fixes + +- **icon:** clean up docs and types for available size values ([c38850d](https://github.com/adobe/spectrum-web-components/commit/c38850d1120a8599d8c623302bbc2c21485c99bc)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) + +### Features + +- **icons-workflow:** update spectrum css input ([549b4b6](https://github.com/adobe/spectrum-web-components/commit/549b4b6b3743ac6ca3b8fe1048188ab96ba85eee)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.6...@spectrum-web-components/icons-workflow@0.4.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) + +### Features + +- **icons-workflow:** update spectrum css input ([549b4b6](https://github.com/adobe/spectrum-web-components/commit/549b4b6b3743ac6ca3b8fe1048188ab96ba85eee)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.5...@spectrum-web-components/icons-workflow@0.3.6) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.4...@spectrum-web-components/icons-workflow@0.3.5) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.3...@spectrum-web-components/icons-workflow@0.3.4) (2020-09-25) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.2...@spectrum-web-components/icons-workflow@0.3.3) (2020-08-31) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.1...@spectrum-web-components/icons-workflow@0.3.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.3.0...@spectrum-web-components/icons-workflow@0.3.1) (2020-07-24) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.2.2...@spectrum-web-components/icons-workflow@0.3.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.2.1...@spectrum-web-components/icons-workflow@0.2.2) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons-workflow + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.2.0...@spectrum-web-components/icons-workflow@0.2.1) (2020-05-08) + +### Bug Fixes + +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons-workflow@0.1.0...@spectrum-web-components/icons-workflow@0.2.0) (2020-04-16) + +### Features + +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +# 0.1.0 (2020-04-07) + +### Features + +- **icons-workflow:** add workflow icons package ([6b09287](https://github.com/adobe/spectrum-web-components/commit/6b09287d5c169205f0cc332b2158d57e7ef4a4b7)) diff --git a/1st-gen/packages/icons-workflow/README.md b/1st-gen/packages/icons-workflow/README.md new file mode 100644 index 00000000000..fe806106037 --- /dev/null +++ b/1st-gen/packages/icons-workflow/README.md @@ -0,0 +1,171 @@ +## Overview + +Deliver [Spectrum Workflow Icons](https://spectrum.adobe.com/page/icons/) as either: + +- Registered custom elements (``) +- Unregistered class definitions (`IconAbc`) +- Functions with customizable template tags to be used across various frameworks (`AbcIcon()`) + +Search a full list of icons to [find an icon](#find-an-icon) for your project or find technical information about [extended use cases](#extended-use-cases), like consuming this package in various UI frameworks below. + +When planning how to leverage these icons in the visual delivery of your application, remember to consult Spectrum's [Iconography Guidelines](https://spectrum.adobe.com/page/iconography/). + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/icons-workflow?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/icons-workflow) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/icons-workflow?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/icons-workflow) + +``` +yarn add @spectrum-web-components/icons-workflow +``` + +Import the side effectful registration of a single element (e.g. ``) via: + +``` +import '@spectrum-web-components/icons-workflow/icons/sp-icon-abc.js'; +``` + +Leverage a single icon base class (e.g. `IconAbc`) as a type, or for extension purposes, do so, via: + +``` +import { IconAbc } from '@spectrum-web-components/icons-workflow/src/elements/IconAbc.js'; +``` + +### Find an icon + +Search the available Spectrum Workflow icons below. + +

Complete search experience available at: https://opensource.adobe.com/spectrum-web-components/components/icons-workflow/.

+ + + + + +### Alternative usage + +You can import raw icons (e.g. `AbcIcon()`) via: + +```js +import { AbcIcon } from '@spectrum-web-components/icons-workflow/src/icons/ABC.js'; +``` + +`@spectrum-web-components/icons-workflow` exports _all_ icons. If your build process [tree-shakes](https://rollupjs.org/guide/en/#tree-shaking) dependencies, you can import from it directly: + +```js +import { AbcIcon } from '@spectrum-web-components/icons-workflow'; +``` + +These icon literals are prepared with the `html` template tag from `lit-html`, the default value of an icon export will be as follows: + +```js +import { LitElement, html } from 'lit-element'; +import '@spectrum-web-components/icon'; +import { AbcIcon } from '@spectrum-web-components/icons-workflow'; + +class ElementWithIcon extends LitElement { + protected override render(): TemplateResult { + return html` + + ${AbcIcon()} + + ` + } +} + +customElements.define('element-with-icon', ElementWithIcon); +``` + +Every icons can be customized via the following options: + +```js +{ + width: 24, // number outlining the width to deliver the SVG element with + height: 24, // number outlining the height to delivery the SVG element with + hidden: false, // boolean representing whether to apply the `aria-hidden` attribute + title: 'Icon title', // string of the title to deliver the icon with +} +``` + +### Extended use cases + +The default exports of this package are pre-wrapped via `setCustomTemplateLiteralTag` in the `html` template tag from `lit-html`, and work like the following:: + +```js +import { AbcIcon } from '@spectrum-web-components/icons-workflow'; + +console.log(AbcIcon()); + +/*** +TemplateResult {strings: Array[1], values: Array[0], type: "html", processor: DefaultTemplateProcessor, constructor: Object} +***/ +``` + +When working in the context of other frameworks, it is possible to import the icons with a generic template tag as follows: + +```js +import { AbcIcon } from '@spectrum-web-components/icons-workflow/src/icons.js'; + +console.log(AbcIcon()); + +/*** + + + + +***/ +``` + +What's more, if you're already working with a specific parser in your project, you can assign it as the one to use when delivering the icons in order to be sure that the SVG content is delivered as parsed content to your final template. The means if you were working with Preact via the `htm` tag as bound to the provided hyperscript function: + +```js +import { + AbcIcon, + setCustomTemplateLiteralTag, +} from '@spectrum-web-components/icons-workflow/src/icons.js'; +import htm from 'htm'; +import { h } from 'preact'; + +const hPreact = htm.bind(h); + +setCustomTemplateLiteralTag(hPreact); + +console.log(AbcIcon()); + +/*** +VNode {nodeName: "svg", children: Array[1], attributes: Object, key: undefined, constructor: Object} +***/ +``` + +In this way the icons exported by `@spectrum-web-components/icons-workflow` can be leveraged in projects powered by the the likes of hyperHTML, lighterhtml, lit-html, Preact, React, Vanilla JS, Vue.js, and more! + +### Accessibility + +Review the accessibility guidelines for the [icon](../icon#accessibility-guidelines). diff --git a/1st-gen/packages/icons-workflow/bin/build-icons-mapping.js b/1st-gen/packages/icons-workflow/bin/build-icons-mapping.js new file mode 100644 index 00000000000..5e74794b755 --- /dev/null +++ b/1st-gen/packages/icons-workflow/bin/build-icons-mapping.js @@ -0,0 +1,100 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +import { getComponentName } from './build.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +/* + * You can run this script by running the `build-icons-mapping ` on `packages/icons-workflow/package.json`, + * which generates the icons mapping from an internal CSV file. + * This is a manual step and should only be run when the icons team provides updates. + * Place the CSV file under the `packages/icons-workflow/bin` folder and run the script to generate the new JSON mapping file. + * This JSON mapping should be committed to the repository. + */ +const saveIconsMapping = async () => { + // check if there is file with .csv extension in the bin folder + const files = fs.promises.readdir(__dirname); + let data = ''; + try { + const fileNames = await files; + const csvFile = fileNames.find((file) => file.endsWith('.csv')); + if (csvFile) { + data = await fs.promises.readFile( + path.join(__dirname, csvFile), + 'utf8' + ); + } + } catch (error) { + throw new Error(`Error reading the bin directory: ${error.message}`); + } + + if (!data) { + throw new Error( + 'No csv file found in the src folder. Please make sure you have the csv file in the "packages/icons-workflow/bin" folder' + ); + } + + const rows = data.split('\n'); + const mapping = {}; + rows.forEach((row) => { + const columns = row.split(','); + // if the third column says "name change" + if (columns.length >= 3 && columns[2] === 'name change') { + const oldName = getComponentName(columns[0]); + const newName = getComponentName(columns[1]); + + // skip if the old or new name is a number + if ( + !Number.isNaN(Number(oldName)) || + !Number.isNaN(Number(newName)) + ) { + return; + } + + mapping[oldName] = newName; + mapping[newName] = oldName; + } + }); + + if (Object.keys(mapping).length === 0) { + console.warn('No valid name changes found in the CSV file.'); + } + + const outputPath = path.join(__dirname, './icons-mapping.json'); + try { + await fs.promises.writeFile( + outputPath, + JSON.stringify(mapping), + 'utf8' + ); + } catch (error) { + throw new Error(`Error saving the icons mapping: ${error.message}`); + } +}; + +await saveIconsMapping(); diff --git a/1st-gen/packages/icons-workflow/bin/build.js b/1st-gen/packages/icons-workflow/bin/build.js new file mode 100644 index 00000000000..dcb63a3980e --- /dev/null +++ b/1st-gen/packages/icons-workflow/bin/build.js @@ -0,0 +1,458 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ + +import fs from 'fs'; +import fg from 'fast-glob'; +import path from 'path'; +import { load } from 'cheerio'; +import prettier from 'prettier'; +import Case from 'case'; +import { fileURLToPath } from 'url'; + +import systemsIconMapping from './icons-mapping.json' with { type: 'json' }; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const rootDir = path.join(__dirname, '../../../'); + +const disclaimer = ` +/* +Copyright 2025 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/`; + +const S1IconsPackagePath = path.dirname( + fileURLToPath( + import.meta.resolve('@adobe/spectrum-css-workflow-icons/package.json') + ) +); +const S2IconsPackagePath = path.dirname( + fileURLToPath( + import.meta.resolve( + '@adobe/spectrum-css-workflow-icons-s2/package.json' + ) + ) +); + +const S1IconsDir = path.join(S1IconsPackagePath, 'dist/18'); +const S2IconsDir = path.join(S2IconsPackagePath, 'dist/assets/svg'); +const keepColors = ''; + +const ensureDirectoryExists = (dirPath) => { + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath); + } +}; + +const directories = [ + `${rootDir}packages/icons-workflow/src`, + `${rootDir}packages/icons-workflow/src/icons`, + `${rootDir}packages/icons-workflow/src/icons-s2`, + `${rootDir}packages/icons-workflow/src/elements`, + `${rootDir}packages/icons-workflow/icons`, +]; + +directories.forEach(ensureDirectoryExists); +fs.writeFileSync( + path.join(rootDir, 'packages', 'icons-workflow', 'src', 'icons.ts'), + disclaimer, + 'utf-8' +); +fs.writeFileSync( + path.join(rootDir, 'packages', 'icons-workflow', 'src', 'icons-s2.ts'), + disclaimer, + 'utf-8' +); +const manifestPath = path.join( + rootDir, + 'packages', + 'icons-workflow', + 'stories', + 'icon-manifest.ts' +); +fs.writeFileSync(manifestPath, disclaimer, 'utf-8'); +let manifestImports = `import { + html, + TemplateResult +} from '@spectrum-web-components/base';\r\n`; +let manifestListings = `\r\nexport const iconManifest = [\r\n`; + +const defaultIconImport = `import { DefaultIcon as AlternateIcon } from '../DefaultIcon.js';\r\n`; + +// Temporary replacements for a few icon names that have different names in the new S2 icon set +const replacements = { + UnLink: 'Unlink', + TextStrikeThrough: 'TextStrikethrough', + ChevronDownSize300: 'ChevronDown', + CheckmarkSize300: 'Checkmark', +}; + +// A function that process the raw svg name and returns the component name +export const getComponentName = (i) => { + let id = path + .basename(i, '.svg') + .replace(/^(S2_Icon_|S_)/, '') + .replace(/(_20_N|_22x20_N|_18_N@2x)$/, ''); + if (i.startsWith('Ad')) { + id = i.replace(/^Ad/, '') + 'Advert'; + } + return Case.pascal(replacements[id] || id); +}; + +async function buildIcons(icons, tag, iconsNameList) { + icons.forEach((i) => { + const svg = fs.readFileSync(i, 'utf-8'); + let id = path + .basename(i, '.svg') + .replace('S2_Icon_', '') + .replace('_20_N', '') + .replace('_22x20_N', ''); + if (id.search(/^Ad[A-Z]/) !== -1) { + id = id.replace(/^Ad/, ''); + id += 'Advert'; + } + + // use replacements for icons that have different names in the icon set and update the id + id = replacements[id] || id; + + const ComponentName = Case.pascal(id); + + const $ = load(svg, { + xmlMode: true, + }); + const title = Case.capital(id); + const fileName = `${id}.ts`; + const location = path.join( + rootDir, + 'packages/icons-workflow/src', + tag, + fileName + ); + + if (!Number.isNaN(Number(ComponentName[0]))) { + return; + } + + $('*').each((index, el) => { + if (el.name === 'svg') { + $(el).attr('aria-hidden', '...'); + $(el).attr('role', 'img'); + if (keepColors !== 'keep') { + $(el).attr('fill', 'currentColor'); + } + $(el).attr('aria-label', '...'); + $(el).removeAttr('id'); + $(el).attr('width', '...'); + $(el).attr('height', '...'); + } + if (el.name === 'defs') { + $(el).remove(); + } + Object.keys(el.attribs).forEach((x) => { + if (x === 'class') { + $(el).removeAttr(x); + } + if (keepColors !== 'keep' && x === 'stroke') { + $(el).attr(x, 'currentColor'); + } + if (keepColors !== 'keep' && x === 'fill') { + $(el).attr(x, 'currentColor'); + } + }); + }); + + const iconLiteral = ` + ${disclaimer} + + import {tag as html, TemplateResult} from '../custom-tag.js'; + + export {setCustomTemplateLiteralTag} from '../custom-tag.js'; + export const ${ComponentName}Icon = ({ + width = 24, + height = 24, + hidden = false, + title = '${title}', + } = {},): string | TemplateResult => { + return html\`${$('svg') + .toString() + .replace( + 'aria-hidden="..."', + "aria-hidden=${hidden ? 'true' : 'false'}" + ) + .replace('width="..."', 'width="${width}"') + .replace('height="..."', 'height="${height}"') + .replace('aria-label="..."', 'aria-label="${title}"')}\`; + } + `; + + prettier + .format(iconLiteral, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((icon) => { + fs.writeFileSync(location, icon, 'utf-8'); + }); + + const exportString = `export {${ComponentName}Icon} from './${tag}/${id}.js';\r\n`; + fs.appendFileSync( + path.join( + rootDir, + 'packages', + 'icons-workflow', + 'src', + tag + '.ts' + ), + exportString, + 'utf-8' + ); + + const iconElementName = `sp-icon-${Case.kebab(ComponentName)}`; + + const currenVersionIconImport = `import { ${ComponentName}Icon as CurrentIcon } from '../${tag}/${id}.js';\r\n`; + + // check if the icon is present in the other version + let otherVersionIconImport = defaultIconImport; + + const alternateTag = tag === 'icons' ? 'icons-s2' : 'icons'; + // if there is a mapping icon found from the above iconset update otherVersionIconImport + if (systemsIconMapping[ComponentName]) { + otherVersionIconImport = `import { ${systemsIconMapping[ComponentName]}Icon as AlternateIcon } from '../${alternateTag}/${systemsIconMapping[ComponentName]}.js';\r\n`; + } else if (iconsNameList.includes(ComponentName)) { + // if there is a no mapping icon found reset to DefaultIcon + otherVersionIconImport = `import { ${ComponentName}Icon as AlternateIcon } from '../${alternateTag}/${id}.js';\r\n`; + } + + const spectrumVersion = tag === 'icons' ? 1 : 2; + + const iconElement = ` + ${disclaimer} + + import { + html, + TemplateResult + } from '@spectrum-web-components/base'; + import { + IconBase + } from '@spectrum-web-components/icon'; + import { + setCustomTemplateLiteralTag + } from '../custom-tag.js'; + + ${currenVersionIconImport} + ${otherVersionIconImport} + + /** + * @element ${iconElementName} + */ + export class Icon${ComponentName} extends IconBase { + protected override render(): TemplateResult { + setCustomTemplateLiteralTag(html); + + if(this.spectrumVersion === ${spectrumVersion}){ + return CurrentIcon({ hidden: !this.label, title: this.label }) as TemplateResult; + } + return AlternateIcon({ hidden: !this.label, title: this.label }) as TemplateResult; + + } + } + `; + + prettier + .format(iconElement, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((iconElementFile) => { + fs.writeFileSync( + path.join( + rootDir, + 'packages', + 'icons-workflow', + 'src', + 'elements', + `Icon${id}.ts` + ), + iconElementFile, + 'utf-8' + ); + }); + + const iconRegistration = ` + ${disclaimer} + + import { Icon${ComponentName} } from '../src/elements/Icon${id}.js'; + import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + + defineElement('${iconElementName}', Icon${ComponentName}); + + declare global { + interface HTMLElementTagNameMap { + '${iconElementName}': Icon${ComponentName}; + } + } + `; + + prettier + .format(iconRegistration, { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'avoid', + parser: 'typescript', + }) + .then((iconRegistrationFile) => { + fs.writeFileSync( + path.join( + rootDir, + 'packages', + 'icons-workflow', + 'icons', + `${iconElementName}.ts` + ), + iconRegistrationFile, + 'utf-8' + ); + }); + + const importStatement = `\r\nimport '@spectrum-web-components/icons-workflow/icons/${iconElementName}.js';`; + const metadata = `{name: '${Case.sentence( + ComponentName + )}', tag: '<${iconElementName}>', story: (size: string): TemplateResult => html\`<${iconElementName} size=\$\{size\}>\`},\r\n`; + manifestImports += importStatement; + manifestListings += metadata; + }); +} + +const iconsV1 = (await fg(`${S1IconsDir}/**.svg`)).sort(); + +const iconsV2 = (await fg(`${S2IconsDir}/**.svg`)).sort(); + +const iconsV1NameList = iconsV1.map((i) => { + return getComponentName(i); +}); +const iconsV2NameList = iconsV2.map((i) => { + return getComponentName(i); +}); +console.log('iconsV1', iconsV1); +console.log('iconsV2', iconsV2); +await buildIcons(iconsV1, 'icons', iconsV2NameList); +await buildIcons(iconsV2, 'icons-s2', iconsV1NameList); + +const exportString = `\r\nexport { setCustomTemplateLiteralTag } from './custom-tag.js';\r\n`; +fs.appendFileSync( + path.join(rootDir, 'packages', 'icons-workflow', 'src', 'icons.ts'), + exportString, + 'utf-8' +); + +fs.appendFileSync( + manifestPath, + `${manifestImports}${manifestListings}];\r\n`, + 'utf-8' +); + +/** + * Generates iconsList.json for filtering icons in Storybook demos and documentation website. + * + * This function processes the available S1 and S2 icon component names and creates a JSON file + * that serves as an allowlist for filtering icons in the iconset Storybook demos. The filtering + * ensures that only icons available in the current Spectrum version are displayed to users. + * + * The function performs the following transformations: + * 1. Converts PascalCase component names (e.g., "HeartFilled") to lowercase (e.g., "heartfilled") + * 2. Filters out any names that start with numbers (invalid icon names) + * 3. Sorts the lists alphabetically for consistent output + * 4. Creates separate arrays for S1 and S2 icons + * 5. Writes the prettifiedformatted JSON to packages/iconset/stories/iconsList.json + * + * @example + * Input: ["HeartFilled", "AddCircle", "20Asset"] + * Output: ["addcircle", "heartfilled"] (20Asset filtered out) + * + * @example + * Generated JSON structure: + * { + * "s1": ["abc", "addcircle", "heart", ...], + * "s2": ["accessibility", "addcontent", "heartfilled", ...] + * } + * + * */ +const generateIconsList = () => { + // Helper function to transform component names to lowercase format for iconsList.json + const transformIconNames = (nameList) => { + return nameList + .map((name) => + name.replace(/([A-Z])/g, (match, letter) => + letter.toLowerCase() + ) + ) + .filter((name) => !Number.isNaN(Number(name[0])) === false) + .sort(); + }; + + const iconsListData = { + s1: transformIconNames(iconsV1NameList), + s2: transformIconNames(iconsV2NameList), + }; + + const iconsListPath = path.join( + rootDir, + 'packages', + 'iconset', + 'stories', + 'iconsList.json' + ); + + prettier + .format(JSON.stringify(iconsListData), { + parser: 'json', + printWidth: 100, + tabWidth: 4, + useTabs: false, + }) + .then((formattedJson) => { + fs.writeFileSync(iconsListPath, formattedJson, 'utf-8'); + }); +}; + +generateIconsList(); diff --git a/1st-gen/packages/icons-workflow/bin/icons-mapping.json b/1st-gen/packages/icons-workflow/bin/icons-mapping.json new file mode 100644 index 00000000000..009084e20a3 --- /dev/null +++ b/1st-gen/packages/icons-workflow/bin/icons-mapping.json @@ -0,0 +1,164 @@ +{ + "Alert": "AlertTriangle", + "AlertTriangle": "Alert", + "AlertCircle": "AlertDiamond", + "AlertDiamond": "AlertCircleFilled", + "AlertCircleFilled": "AlertDiamond", + "AnchorSelect": "DirectSelect", + "DirectSelect": "AnchorSelect", + "AssetsAdded": "AddContent", + "AddContent": "AssetsAdded", + "At": "Mention", + "Mention": "At", + "Audio": "MusicNote", + "MusicNote": "Audio", + "Beaker": "BetaApp", + "BetaApp": "Beaker", + "Boolean": "Toggle", + "Toggle": "Boolean", + "Border": "EffectBorder", + "EffectBorder": "Border", + "Browse": "Binoculars", + "Binoculars": "Browse", + "Capitals": "TextCapsAll", + "TextCapsAll": "Capitals", + "CircleFilled": "Circle", + "Circle": "CircleFilled", + "ClassicGridView": "ViewGrid", + "ViewGrid": "ClassicGridView", + "CloneStamp": "StampClone", + "StampClone": "CloneStamp", + "CloudDisconnected": "CloudStateDisconnected", + "CloudStateDisconnected": "CloudDisconnected", + "CloudError": "CloudStateError", + "CloudStateError": "CloudError", + "CloudOutline": "Cloud", + "Cloud": "CloudOutline", + "Compass": "Discover", + "Discover": "Compass", + "Date": "CalendarDay", + "CalendarDay": "Date", + "Deselect": "SelectNo", + "SelectNo": "Deselect", + "DesktopAndMobile": "DeviceDesktopMobile", + "DeviceDesktopMobile": "DesktopAndMobile", + "Devices": "DeviceMobile", + "DeviceMobile": "Devices", + "DeviceTablet": "DeviceTablet", + "DistributeHorizontally": "DistributeSpaceHorizontally", + "DistributeSpaceHorizontally": "DistributeSpaceHoriz", + "DistributeSpaceHoriz": "DistributeSpaceHorizontally", + "DistributeSpaceVert": "DistributeSpaceVertically", + "DistributeSpaceVertically": "DistributeVertically", + "DistributeVertically": "DistributeSpaceVertically", + "Document": "File", + "File": "DocumentOutline", + "DocumentOutline": "File", + "EmailOutline": "Email", + "Email": "EmailOutline", + "Engagement": "Interaction", + "Interaction": "Engagement", + "Events": "CursorClick", + "CursorClick": "Events", + "Export": "Export", + "ExportTo": "MoveTo", + "FileTxt": "FileText", + "FileText": "FileTxt", + "FolderOutline": "Folder", + "Folder": "FolderOutline", + "Help": "HelpCircle", + "HelpCircle": "Help", + "Homepage": "WebPage", + "WebPage": "Homepage", + "ImageProfile": "UserAvatar", + "UserAvatar": "RealTimeCustomerProfile", + "Info": "InfoCircle", + "InfoCircle": "InfoOutline", + "InfoOutline": "InfoCircle", + "InvertAdj": "Invert", + "Invert": "InvertAdj", + "Label": "Tag", + "Tag": "Label", + "Landscape": "OrientationLandscape", + "OrientationLandscape": "Landscape", + "Light": "Lighten", + "Lighten": "Light", + "LinearGradient": "GradientHorizontal", + "GradientHorizontal": "LinearGradient", + "LinkOff": "Unlink", + "Unlink": "LinkOff", + "LinkOut": "ExportTo", + "LockClosed": "Lock", + "Lock": "LockClosed", + "LockOpen": "LockOpen", + "Looks": "Filters", + "Filters": "Looks", + "Magnify": "Search", + "Search": "Magnify", + "Measure": "Ruler", + "Ruler": "Measure", + "Move": "Move", + "MoveTo": "ExportTo", + "NewItem": "New", + "New": "NewItem", + "NoEdit": "EditNo", + "EditNo": "NoEdit", + "Pending": "ClockPending", + "ClockPending": "Pending", + "Portrait": "OrientationPortrait", + "OrientationPortrait": "Portrait", + "ProjectAdd": "ProjectCreate", + "ProjectCreate": "ProjectAdd", + "PublishRemove": "PublishNo", + "PublishNo": "PublishRemove", + "RadialGradient": "GradientRadial", + "GradientRadial": "RadialGradient", + "RealTimeCustomerProfile": "UserAvatar", + "Rectangle": "RectangleHoriz", + "RectangleHoriz": "Rectangle", + "RectSelect": "SelectRectangle", + "SelectRectangle": "RectSelect", + "RegionSelect": "LassoSelect", + "LassoSelect": "RegionSelect", + "RotateRight": "RotateOrientation", + "RotateOrientation": "RotateRight", + "Sampler": "Eyedropper", + "Eyedropper": "Sampler", + "SaveTo": "Download", + "Download": "SaveTo", + "SelectBox": "CheckBox", + "CheckBox": "SelectBox", + "SelectBoxAll": "SelectMulti", + "SelectMulti": "SelectBoxAll", + "Shop": "Market", + "Market": "Shop", + "ShowMenu": "MenuHamburger", + "MenuHamburger": "ShowMenu", + "SmallCaps": "TextCapsSmall", + "TextCapsSmall": "SmallCaps", + "SortOrderDown": "SortDown", + "SortDown": "SortOrderDown", + "SortOrderUp": "SortUp", + "SortUp": "SortOrderUp", + "Star": "StarOutline", + "StarFilled": "Star", + "StarOutline": "Star", + "TaskList": "ListMultiSelect", + "ListMultiSelect": "TaskList", + "TextBulleted": "ListBulleted", + "ListBulleted": "TextBulleted", + "Tips": "Lightbulb", + "Lightbulb": "Tips", + "Transparency": "ViewTransparency", + "ViewTransparency": "Transparency", + "Underline": "TextUnderline", + "TextUnderline": "Underline", + "Ungroup": "GroupNo", + "GroupNo": "Ungroup", + "ViewWeek": "CalendarWeek", + "CalendarWeek": "ViewWeek", + "VoiceOver": "Microphone", + "Microphone": "VoiceOver", + "VolumeMute": "VolumeOff", + "VolumeOff": "VolumeMute" +} diff --git a/1st-gen/packages/icons-workflow/package.json b/1st-gen/packages/icons-workflow/package.json new file mode 100644 index 00000000000..0344f6c1bfd --- /dev/null +++ b/1st-gen/packages/icons-workflow/package.json @@ -0,0 +1,71 @@ +{ + "name": "@spectrum-web-components/icons-workflow", + "version": "1.9.0", + "description": "", + "license": "Apache-2.0", + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/icons-workflow", + "repository": { + "directory": "1st-gen/packages/icons-workflow", + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git" + }, + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "type": "module", + "exports": { + ".": "./src/index.js", + "./icons/*": "./icons/*", + "./package.json": "./package.json", + "./src/*": "./src/*" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "!bin/", + "custom-elements.json", + "!stories/", + "!test/" + ], + "scripts": { + "build": "node ./bin/build.js", + "build-icons-mapping": "node ./bin/build-icons-mapping.js" + }, + "sideEffects": [ + "./src/index.js", + "./icons/*" + ], + "types": "./src/index.d.ts", + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icon": "1.9.0" + }, + "devDependencies": { + "@adobe/spectrum-css-workflow-icons": "1.7.0", + "@adobe/spectrum-css-workflow-icons-s2": "npm:@adobe/spectrum-css-workflow-icons@5.0.0", + "case": "1.6.3", + "cheerio": "1.1.2", + "fast-glob": "3.3.3", + "prettier": "3.6.2" + }, + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "customElements": "custom-elements.json", + "publishConfig": { + "access": "public" + } +} diff --git a/1st-gen/packages/icons-workflow/src/DefaultIcon.ts b/1st-gen/packages/icons-workflow/src/DefaultIcon.ts new file mode 100644 index 00000000000..ad3dca37f85 --- /dev/null +++ b/1st-gen/packages/icons-workflow/src/DefaultIcon.ts @@ -0,0 +1,40 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { tag as html, TemplateResult } from './custom-tag.js'; + +export { setCustomTemplateLiteralTag } from './custom-tag.js'; +export const DefaultIcon = ({ + width = 24, + height = 24, + hidden = false, + title = 'Default', +} = {}): string | TemplateResult => { + return html` + + + + `; +}; diff --git a/1st-gen/packages/icons-workflow/src/custom-tag.ts b/1st-gen/packages/icons-workflow/src/custom-tag.ts new file mode 100644 index 00000000000..b626b39b34b --- /dev/null +++ b/1st-gen/packages/icons-workflow/src/custom-tag.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +export type { TemplateResult }; + +export type GenericTemplateLiteralTagType = ( + strings: TemplateStringsArray, + ...values: unknown[] +) => string; +type TemplateLiteralTagType = GenericTemplateLiteralTagType | typeof html; +let customTemplateLiteralTag: TemplateLiteralTagType; + +export const tag = function ( + strings: TemplateStringsArray, + ...values: unknown[] +): string | TemplateResult { + if (customTemplateLiteralTag) { + return customTemplateLiteralTag(strings, ...values); + } + return values.reduce( + (acc: string, v, idx) => + (acc as string) + (v as string) + strings[idx + 1], + strings[0] + ); +}; + +export const setCustomTemplateLiteralTag = ( + tag: TemplateLiteralTagType +): void => { + customTemplateLiteralTag = tag; +}; diff --git a/1st-gen/packages/icons-workflow/src/index.ts b/1st-gen/packages/icons-workflow/src/index.ts new file mode 100644 index 00000000000..5ead36ed48d --- /dev/null +++ b/1st-gen/packages/icons-workflow/src/index.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@spectrum-web-components/base'; +import { setCustomTemplateLiteralTag } from './custom-tag.js'; + +setCustomTemplateLiteralTag(html); + +export { setCustomTemplateLiteralTag }; +export * from './icons.js'; diff --git a/1st-gen/packages/icons-workflow/stories/icons-workflow.stories.ts b/1st-gen/packages/icons-workflow/stories/icons-workflow.stories.ts new file mode 100644 index 00000000000..3967be481a8 --- /dev/null +++ b/1st-gen/packages/icons-workflow/stories/icons-workflow.stories.ts @@ -0,0 +1,126 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/icon/sp-icon.js'; +import '../../iconset/stories/icons-demo.js'; +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { until } from '@spectrum-web-components/base/src/directives.js'; + +export default { + title: 'Icons/Workflow', + argTypes: { + color: { control: 'color' }, + size: { + control: { + type: 'inline-radio', + options: ['s', 'm', 'l', 'xl'], + }, + }, + }, + args: { + color: '#000000', + size: 'm', + }, + swc_vrt: { + preload: async (): Promise => { + await import('./icon-manifest.js'); + }, + }, +}; + +interface Properties { + color: string; + size: 's' | 'm' | 'l' | 'xl'; +} + +export const elements = ({ color, size }: Properties): TemplateResult => { + const content = import('./icon-manifest.js').then( + (iconManifest) => html` + + ` + ); + return html` + + + ${until( + content, + html` + Loading... + ` + )} + + `; +}; + +export const Icons = ({ color, size }: Properties): TemplateResult => { + const content = import('../').then((icons) => { + const iconTemplates: { + template: () => TemplateResult; + name: string; + }[] = []; + for (const icon in icons) { + if (icon === 'setCustomTemplateLiteralTag') continue; + iconTemplates.push({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + template: (icons as any)[icon], + name: icon, + }); + } + return html` + + ${iconTemplates.map( + (icon) => html` + + ${icon.template()} + ${icon.name} + + ` + )} + + `; + }); + return html` + + + ${until( + content, + html` + Loading... + ` + )} + + `; +}; diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-attribute-many.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-attribute-many.ts new file mode 100644 index 00000000000..a7b14fff198 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-attribute-many.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const iconset = document.createElement('sp-icons-medium'); +document.body.append(iconset); + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-attribute.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-attribute.ts new file mode 100644 index 00000000000..3f86e212a93 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-attribute.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const iconset = document.createElement('sp-icons-medium'); +document.body.append(iconset); + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-injected-many.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-injected-many.ts new file mode 100644 index 00000000000..633291fbde9 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-injected-many.ts @@ -0,0 +1,93 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import { AbcIcon } from '@spectrum-web-components/icons-workflow/src/icons/ABC.js'; +import { ActionsIcon } from '@spectrum-web-components/icons-workflow/src/icons/Actions.js'; +import { DisplayAdvertIcon } from '@spectrum-web-components/icons-workflow/src/icons/DisplayAdvert.js'; +import { PrintAdvertIcon } from '@spectrum-web-components/icons-workflow/src/icons/PrintAdvert.js'; +import { AddIcon } from '@spectrum-web-components/icons-workflow/src/icons/Add.js'; +import { AddCircleIcon } from '@spectrum-web-components/icons-workflow/src/icons/AddCircle.js'; +import { AddToIcon } from '@spectrum-web-components/icons-workflow/src/icons/AddTo.js'; +import { AddToSelectionIcon } from '@spectrum-web-components/icons-workflow/src/icons/AddToSelection.js'; +import { AEMScreensIcon } from '@spectrum-web-components/icons-workflow/src/icons/AEMScreens.js'; +import { AirplaneIcon } from '@spectrum-web-components/icons-workflow/src/icons/Airplane.js'; +import { AlertIcon } from '@spectrum-web-components/icons-workflow/src/icons/Alert.js'; +import { AlertAddIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlertAdd.js'; +import { AlertCheckIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlertCheck.js'; +import { AlertCircleIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlertCircle.js'; +import { AlertCircleFilledIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlertCircleFilled.js'; +import { AlgorithmIcon } from '@spectrum-web-components/icons-workflow/src/icons/Algorithm.js'; +import { AliasIcon } from '@spectrum-web-components/icons-workflow/src/icons/Alias.js'; +import { ArrowLeftIcon } from '@spectrum-web-components/icons-workflow/src/icons/ArrowLeft.js'; +import { AlignCenterIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlignCenter.js'; +import { AlignTopIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlignTop.js'; +import { AlignBottomIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlignBottom.js'; +import { AlignLeftIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlignLeft.js'; +import { AlignRightIcon } from '@spectrum-web-components/icons-workflow/src/icons/AlignRight.js'; +import { AnnotateIcon } from '@spectrum-web-components/icons-workflow/src/icons/Annotate.js'; +import { AnnotatePenIcon } from '@spectrum-web-components/icons-workflow/src/icons/AnnotatePen.js'; +import { AssetIcon } from '@spectrum-web-components/icons-workflow/src/icons/Asset.js'; +import { AssetsAddedIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsAdded.js'; +import { AssetsDownloadedIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsDownloaded.js'; +import { AssetsExpiredIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsExpired.js'; +import { AssetsLinkedPublishedIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsLinkedPublished.js'; +import { AssetsModifiedIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsModified.js'; +import { AssetsPublishedIcon } from '@spectrum-web-components/icons-workflow/src/icons/AssetsPublished.js'; +import { BookIcon } from '@spectrum-web-components/icons-workflow/src/icons/Book.js'; +import { BookmarkIcon } from '@spectrum-web-components/icons-workflow/src/icons/Bookmark.js'; +import { BookmarkSingleIcon } from '@spectrum-web-components/icons-workflow/src/icons/BookmarkSingle.js'; +import { BookmarkSingleOutlineIcon } from '@spectrum-web-components/icons-workflow/src/icons/BookmarkSingleOutline.js'; +import { setCustomTemplateLiteralTag } from '@spectrum-web-components/icons-workflow/src/custom-tag.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +setCustomTemplateLiteralTag(html); + +measureFixtureCreation(html` + ${AbcIcon({ hidden: true })} + ${ActionsIcon({ hidden: true })} + ${DisplayAdvertIcon({ hidden: true })} + ${PrintAdvertIcon({ hidden: true })} + ${AddIcon({ hidden: true })} + ${AddCircleIcon({ hidden: true })} + ${AddToIcon({ hidden: true })} + ${AddToSelectionIcon({ hidden: true })} + ${AEMScreensIcon({ hidden: true })} + ${AirplaneIcon({ hidden: true })} + ${AlertIcon({ hidden: true })} + ${AlertAddIcon({ hidden: true })} + ${AlertCheckIcon({ hidden: true })} + ${AlertCircleIcon({ hidden: true })} + ${AlertCircleFilledIcon({ hidden: true })} + ${AlgorithmIcon({ hidden: true })} + ${AliasIcon({ hidden: true })} + ${ArrowLeftIcon({ hidden: true })} + ${AlignCenterIcon({ hidden: true })} + ${AlignTopIcon({ hidden: true })} + ${AlignBottomIcon({ hidden: true })} + ${AlignLeftIcon({ hidden: true })} + ${AlignRightIcon({ hidden: true })} + ${AnnotateIcon({ hidden: true })} + ${AnnotatePenIcon({ hidden: true })} + ${AssetIcon({ hidden: true })} + ${AssetsAddedIcon({ hidden: true })} + ${AssetsDownloadedIcon({ hidden: true })} + ${AssetsExpiredIcon({ hidden: true })} + ${AssetsLinkedPublishedIcon({ hidden: true })} + ${AssetsModifiedIcon({ hidden: true })} + ${AssetsPublishedIcon({ hidden: true })} + ${BookIcon({ hidden: true })} + ${BookmarkIcon({ hidden: true })} + ${BookmarkSingleIcon({ hidden: true })} + ${BookmarkSingleOutlineIcon({ hidden: true })} +`); diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-injected.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-injected.ts new file mode 100644 index 00000000000..3efc7f918b4 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-injected.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icon/sp-icon.js'; +import { CheckmarkIcon } from '@spectrum-web-components/icons-workflow/src/icons/Checkmark.js'; +import { setCustomTemplateLiteralTag } from '@spectrum-web-components/icons-workflow/src/custom-tag.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +setCustomTemplateLiteralTag(html); + +measureFixtureCreation(html` + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} + ${CheckmarkIcon({ hidden: true })} +`); diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-registered-many.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-registered-many.ts new file mode 100644 index 00000000000..b1f918c2236 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-registered-many.ts @@ -0,0 +1,89 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icons-workflow/icons/sp-icon-abc.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-actions.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-display-advert.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-print-advert.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add-circle.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add-to.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add-to-selection.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-aemscreens.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-airplane.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert-add.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert-check.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert-circle.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert-circle-filled.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-algorithm.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-alias.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-arrow-left.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-center.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-top.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-bottom.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-left.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-align-right.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-annotate.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-annotate-pen.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-asset.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-added.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-downloaded.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-expired.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-linked-published.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-modified.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-assets-published.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-book.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-bookmark.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-bookmark-single.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-bookmark-single-outline.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-workflow/test/benchmark/test-registered.ts b/1st-gen/packages/icons-workflow/test/benchmark/test-registered.ts new file mode 100644 index 00000000000..7881d35b763 --- /dev/null +++ b/1st-gen/packages/icons-workflow/test/benchmark/test-registered.ts @@ -0,0 +1,54 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); diff --git a/1st-gen/packages/icons-workflow/tsconfig.json b/1st-gen/packages/icons-workflow/tsconfig.json new file mode 100644 index 00000000000..3114412c878 --- /dev/null +++ b/1st-gen/packages/icons-workflow/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["icons/**/*.ts", "src/**/*.ts", "../../global.d.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }, { "path": "../icon" }] +} diff --git a/1st-gen/packages/icons/.npmrc b/1st-gen/packages/icons/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/icons/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/icons/CHANGELOG.md b/1st-gen/packages/icons/CHANGELOG.md new file mode 100644 index 00000000000..007f03f8bd8 --- /dev/null +++ b/1st-gen/packages/icons/CHANGELOG.md @@ -0,0 +1,520 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/iconset@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- **icons:** process icons for use as UIIcons ([47a43d7](https://github.com/adobe/spectrum-web-components/commit/47a43d7ef2c89d1510abb8bef3a42425781aeff6)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843a049a6a37bbeee7bbfb50b4d5eb24f3fd)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icons-workflow:** add workflow icons package ([6b09287](https://github.com/adobe/spectrum-web-components/commit/6b09287d5c169205f0cc332b2158d57e7ef4a4b7)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **icons:** update spectrum css input ([296738e](https://github.com/adobe/spectrum-web-components/commit/296738ee582c760812214f0181db3503856db608)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.6...@spectrum-web-components/icons@0.9.7) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.5...@spectrum-web-components/icons@0.9.6) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.4...@spectrum-web-components/icons@0.9.5) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.3...@spectrum-web-components/icons@0.9.4) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.2...@spectrum-web-components/icons@0.9.3) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.1...@spectrum-web-components/icons@0.9.2) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.9.0...@spectrum-web-components/icons@0.9.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.9...@spectrum-web-components/icons@0.9.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.8...@spectrum-web-components/icons@0.8.9) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.7...@spectrum-web-components/icons@0.8.8) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.6...@spectrum-web-components/icons@0.8.7) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.5...@spectrum-web-components/icons@0.8.6) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.4...@spectrum-web-components/icons@0.8.5) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.3...@spectrum-web-components/icons@0.8.4) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.2...@spectrum-web-components/icons@0.8.3) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.1...@spectrum-web-components/icons@0.8.2) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.8.0...@spectrum-web-components/icons@0.8.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.9...@spectrum-web-components/icons@0.8.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.8...@spectrum-web-components/icons@0.7.9) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.7...@spectrum-web-components/icons@0.7.8) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.6...@spectrum-web-components/icons@0.7.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.5...@spectrum-web-components/icons@0.7.6) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.4...@spectrum-web-components/icons@0.7.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.3...@spectrum-web-components/icons@0.7.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.2...@spectrum-web-components/icons@0.7.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.1...@spectrum-web-components/icons@0.7.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.7.0...@spectrum-web-components/icons@0.7.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.6.3...@spectrum-web-components/icons@0.7.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.6.2...@spectrum-web-components/icons@0.6.3) (2021-02-11) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.6.1...@spectrum-web-components/icons@0.6.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.6.0...@spectrum-web-components/icons@0.6.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/icons + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.5...@spectrum-web-components/icons@0.6.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icons:** update spectrum css input ([296738e](https://github.com/adobe/spectrum-web-components/commit/296738ee582c760812214f0181db3503856db608)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.5...@spectrum-web-components/icons@0.5.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icons:** update spectrum css input ([296738e](https://github.com/adobe/spectrum-web-components/commit/296738ee582c760812214f0181db3503856db608)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.4...@spectrum-web-components/icons@0.4.5) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.3...@spectrum-web-components/icons@0.4.4) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.2...@spectrum-web-components/icons@0.4.3) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.1...@spectrum-web-components/icons@0.4.2) (2020-08-31) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.4.0...@spectrum-web-components/icons@0.4.1) (2020-08-19) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.3.3...@spectrum-web-components/icons@0.4.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.3.2...@spectrum-web-components/icons@0.3.3) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.3.1...@spectrum-web-components/icons@0.3.2) (2020-05-08) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.3.0...@spectrum-web-components/icons@0.3.1) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.2.3...@spectrum-web-components/icons@0.3.0) (2020-04-07) + +### Features + +- **icons-workflow:** add workflow icons package ([6b09287](https://github.com/adobe/spectrum-web-components/commit/6b09287d5c169205f0cc332b2158d57e7ef4a4b7)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.2.2...@spectrum-web-components/icons@0.2.3) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.2.1...@spectrum-web-components/icons@0.2.2) (2019-12-02) + +**Note:** Version bump only for package @spectrum-web-components/icons + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.2.0...@spectrum-web-components/icons@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.1.5...@spectrum-web-components/icons@0.2.0) (2019-11-19) + +### Features + +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.1.4...@spectrum-web-components/icons@0.1.5) (2019-11-01) + +### Bug Fixes + +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/icons@0.1.3...@spectrum-web-components/icons@0.1.4) (2019-10-14) + +### Bug Fixes + +- **icons:** process icons for use as UIIcons ([47a43d7](https://github.com/adobe/spectrum-web-components/commit/47a43d7)) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/icons diff --git a/1st-gen/packages/icons/README.md b/1st-gen/packages/icons/README.md new file mode 100644 index 00000000000..bb5a9e1f451 --- /dev/null +++ b/1st-gen/packages/icons/README.md @@ -0,0 +1,38 @@ +## Overview + +The `` and `` elements included in this package supply your application with the Spectrum CSS medium and large icons for use in the `` element. Include at least one of these elements in a project that makes use of icons in these sets. You can also include these sets in the scope of any element that leverages them, as they will be deduplicated to ensure all of your components can deliver the icons included therein. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/icons?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/icons) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/icons?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/icons) + +``` +yarn add @spectrum-web-components/icons +``` + +Import the side effectful registration of `` or `` via: + +``` +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import '@spectrum-web-components/icons/sp-icons-large.js'; +``` + +When looking to leverage the `IconsMedium` or `IconsLarge` base classes as a type and/or for extension purposes, do so via: + +``` +import { IconsMedium, IconsLarge } from '@spectrum-web-components/icons'; +``` + +### Deprecated + +The `Icons` package has been deprecated as part of the removal of the `Iconset` package from the library and will be removed in an upcoming release. To optimize your build and ensure smaller bundles and higher performance for your users, consider using techniques that include only the icons actually used in your application. For Spectrum icons, you can use [UI Icons](../icons-ui/) or [Workflow Icons](../icons-workflow/). + +For non-Spectrum icons, you can still: + +1. Slot SVG or image content into an [`sp-icon` element](../icon/), or +2. Sanitize the SVG and convert it to a template literal to use within the `render()` method of an extension of `IconBase` to create your own custom named icon element.``` + +### Accessibility + +Review the accessibility guidelines for the [icon](../icon#accessibility-guidelines). diff --git a/1st-gen/packages/icons/package.json b/1st-gen/packages/icons/package.json new file mode 100644 index 00000000000..f695550b318 --- /dev/null +++ b/1st-gen/packages/icons/package.json @@ -0,0 +1,91 @@ +{ + "name": "@spectrum-web-components/icons", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/icons" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/icons", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/IconsLarge.js": { + "development": "./src/IconsLarge.dev.js", + "default": "./src/IconsLarge.js" + }, + "./src/IconsMedium.js": { + "development": "./src/IconsMedium.dev.js", + "default": "./src/IconsMedium.js" + }, + "./src/icons-large.svg.js": { + "development": "./src/icons-large.svg.dev.js", + "default": "./src/icons-large.svg.js" + }, + "./src/icons-medium.svg.js": { + "development": "./src/icons-medium.svg.dev.js", + "default": "./src/icons-medium.svg.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-icons-large.js": { + "development": "./sp-icons-large.dev.js", + "default": "./sp-icons-large.js" + }, + "./sp-icons-medium.js": { + "development": "./sp-icons-medium.dev.js", + "default": "./sp-icons-medium.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/iconset": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "deprecationNotice": "@spectrum-web-components/icons is deprecated and will be removed in an upcoming release.", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/icons/sp-icons-large.ts b/1st-gen/packages/icons/sp-icons-large.ts new file mode 100644 index 00000000000..6a12f954ca0 --- /dev/null +++ b/1st-gen/packages/icons/sp-icons-large.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { IconsLarge } from './src/IconsLarge.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-icons-large', IconsLarge); + +declare global { + interface HTMLElementTagNameMap { + 'sp-icons-large': IconsLarge; + } +} diff --git a/1st-gen/packages/icons/sp-icons-medium.ts b/1st-gen/packages/icons/sp-icons-medium.ts new file mode 100644 index 00000000000..66d015e8c01 --- /dev/null +++ b/1st-gen/packages/icons/sp-icons-medium.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { IconsMedium } from './src/IconsMedium.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-icons-medium', IconsMedium); + +declare global { + interface HTMLElementTagNameMap { + 'sp-icons-medium': IconsMedium; + } +} diff --git a/1st-gen/packages/icons/src/IconsLarge.ts b/1st-gen/packages/icons/src/IconsLarge.ts new file mode 100644 index 00000000000..3a52bfc4a03 --- /dev/null +++ b/1st-gen/packages/icons/src/IconsLarge.ts @@ -0,0 +1,54 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; + +import { IconsetSVG } from '@spectrum-web-components/iconset/src/iconset-svg.js'; + +import iconsSVG from './icons-large.svg.js'; + +/** + * @element sp-icons-large + */ +export class IconsLarge extends IconsetSVG { + public constructor() { + super(); + this.name = 'ui'; // default iconset name for these icons + } + + protected override firstUpdated(): void { + super.firstUpdated(); + if (window.__swc.DEBUG) { + window.__swc.warn( + this, + 'Icons package has been deprecated and will be removed from the project in an upcoming release. For default Spectrum Icons, learn more about leveraging UI Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-ui/) or Workflow Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-workflow/) as an alternative.', + 'https://opensource.adobe.com/spectrum-web-components/components/icons/#deprecated', + { level: 'deprecation' } + ); + } + } + + protected override renderDefaultContent(): TemplateResult { + return iconsSVG; + } + /** + * Overrides createIconName to make icon strings compatible with spectrum-icon id format + * @param icon + * @param size + */ + protected override getSVGIconName(icon: string): string { + return `spectrum-icon-${icon}`; + } + protected override getSanitizedIconName(icon: string): string { + return icon.replace('spectrum-icon-', ''); + } +} diff --git a/1st-gen/packages/icons/src/IconsMedium.ts b/1st-gen/packages/icons/src/IconsMedium.ts new file mode 100644 index 00000000000..035fd544d95 --- /dev/null +++ b/1st-gen/packages/icons/src/IconsMedium.ts @@ -0,0 +1,54 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; + +import { IconsetSVG } from '@spectrum-web-components/iconset/src/iconset-svg.js'; + +import iconsSVG from './icons-medium.svg.js'; + +/** + * @element sp-icons-medium + */ +export class IconsMedium extends IconsetSVG { + public constructor() { + super(); + this.name = 'ui'; // default iconset name for these icons + } + + protected override firstUpdated(): void { + super.firstUpdated(); + if (window.__swc.DEBUG) { + window.__swc.warn( + this, + 'Icons package has been deprecated and will be removed from the project in an upcoming release. For default Spectrum Icons, learn more about leveraging UI Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-ui/) or Workflow Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-workflow/) as an alternative.', + 'https://opensource.adobe.com/spectrum-web-components/components/icons/#deprecated', + { level: 'deprecation' } + ); + } + } + + protected override renderDefaultContent(): TemplateResult { + return iconsSVG; + } + /** + * Overrides createIconName to make icon strings compatible with spectrum-icon id format + * @param icon + * @param size + */ + protected override getSVGIconName(icon: string): string { + return `spectrum-icon-${icon}`; + } + protected override getSanitizedIconName(icon: string): string { + return icon.replace('spectrum-icon-', ''); + } +} diff --git a/1st-gen/packages/icons/src/icons-large.svg.ts b/1st-gen/packages/icons/src/icons-large.svg.ts new file mode 100644 index 00000000000..abacfaffd9c --- /dev/null +++ b/1st-gen/packages/icons/src/icons-large.svg.ts @@ -0,0 +1 @@ +import { svg } from '@spectrum-web-components/base'; export default svg``; \ No newline at end of file diff --git a/1st-gen/packages/icons/src/icons-medium.svg.ts b/1st-gen/packages/icons/src/icons-medium.svg.ts new file mode 100644 index 00000000000..f49351f19b8 --- /dev/null +++ b/1st-gen/packages/icons/src/icons-medium.svg.ts @@ -0,0 +1 @@ +import { svg } from '@spectrum-web-components/base'; export default svg``; \ No newline at end of file diff --git a/1st-gen/packages/icons/src/index.ts b/1st-gen/packages/icons/src/index.ts new file mode 100644 index 00000000000..21c587c2350 --- /dev/null +++ b/1st-gen/packages/icons/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './IconsLarge.js'; +export * from './IconsMedium.js'; diff --git a/1st-gen/packages/icons/stories/icons.stories.ts b/1st-gen/packages/icons/stories/icons.stories.ts new file mode 100644 index 00000000000..5f9d3a570bf --- /dev/null +++ b/1st-gen/packages/icons/stories/icons.stories.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/icons/sp-icons-large.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import '../../iconset/stories/icons-demo.js'; +import { html, TemplateResult } from '@spectrum-web-components/base'; + +export default { + title: 'Icons', + argTypes: { + color: { control: 'color' }, + }, + args: { + color: '#000000', + }, +}; + +interface Properties { + color: string; +} + +export const listMedium = ({ color }: Properties): TemplateResult => html` + + + +`; + +listMedium.storyName = 'UI Icons - Medium'; + +export const listLarge = ({ color }: Properties): TemplateResult => html` + + + +`; + +listLarge.storyName = 'UI Icons - Large'; diff --git a/1st-gen/packages/icons/test/benchmark/test-basic.ts b/1st-gen/packages/icons/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..48d629f42c3 --- /dev/null +++ b/1st-gen/packages/icons/test/benchmark/test-basic.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/icons/test/icons-memory.test.ts b/1st-gen/packages/icons/test/icons-memory.test.ts new file mode 100644 index 00000000000..c548cd7a026 --- /dev/null +++ b/1st-gen/packages/icons/test/icons-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/icons/test/icons.test.ts b/1st-gen/packages/icons/test/icons.test.ts new file mode 100644 index 00000000000..8c98f71f1b2 --- /dev/null +++ b/1st-gen/packages/icons/test/icons.test.ts @@ -0,0 +1,108 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/icons/sp-icons-large.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import { IconsLarge, IconsMedium } from '../'; +import IconsetSVG from '../src/icons-large.svg.js'; +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import { stub } from 'sinon'; + +describe('icons', () => { + it('large', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + expect(el.getIconList().length).to.be.above(0); + }); + it('medium', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + expect(el.getIconList().length).to.be.above(0); + }); + it('listens to slotchange events', async () => { + const el = await fixture(html` + ${IconsetSVG} + `); + + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + expect(el.getIconList().length).to.equal(48); + }); +}); + +describe('dev mode', () => { + let consoleWarnStub!: ReturnType; + before(() => { + window.__swc.verbose = true; + consoleWarnStub = stub(console, 'warn'); + }); + afterEach(() => { + consoleWarnStub.resetHistory(); + }); + after(() => { + window.__swc.verbose = false; + consoleWarnStub.restore(); + }); + + it('warns in devMode for deprecated usage - medium', async () => { + const el = await fixture(html` + ${IconsetSVG} + `); + + await elementUpdated(el); + expect(consoleWarnStub.called).to.be.true; + + const spyCall = consoleWarnStub.getCall(0); + expect( + (spyCall.args.at(0) as string).includes('deprecated'), + 'confirm deprecated variant warning' + ).to.be.true; + expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({ + data: { + localName: 'sp-icons-medium', + type: 'api', + level: 'deprecation', + }, + }); + }); + it('warns in devMode for deprecated usage - large', async () => { + const el = await fixture(html` + ${IconsetSVG} + `); + + await elementUpdated(el); + expect(consoleWarnStub.called).to.be.true; + + const spyCall = consoleWarnStub.getCall(0); + expect( + (spyCall.args.at(0) as string).includes('deprecated'), + 'confirm deprecated variant warning' + ).to.be.true; + expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({ + data: { + localName: 'sp-icons-large', + type: 'api', + level: 'deprecation', + }, + }); + }); +}); diff --git a/1st-gen/packages/icons/tsconfig.json b/1st-gen/packages/icons/tsconfig.json new file mode 100644 index 00000000000..6d676e316d5 --- /dev/null +++ b/1st-gen/packages/icons/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../icon" }, { "path": "../iconset" }] +} diff --git a/1st-gen/packages/iconset/.gitignore b/1st-gen/packages/iconset/.gitignore new file mode 100644 index 00000000000..d7dc01e274d --- /dev/null +++ b/1st-gen/packages/iconset/.gitignore @@ -0,0 +1 @@ +!stories/iconsList.json \ No newline at end of file diff --git a/1st-gen/packages/iconset/.npmrc b/1st-gen/packages/iconset/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/iconset/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/iconset/CHANGELOG.md b/1st-gen/packages/iconset/CHANGELOG.md new file mode 100644 index 00000000000..1123744c71e --- /dev/null +++ b/1st-gen/packages/iconset/CHANGELOG.md @@ -0,0 +1,502 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **icon:** remove size300 suffix from chevron and checkmark icons in Spectrum 2 ([#4904](https://github.com/adobe/spectrum-web-components/issues/4904)) ([a22f42b](https://github.com/adobe/spectrum-web-components/commit/a22f42bf508e1d0f2ddc9824b0f4d4e08eac659a)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- lint away debugger statements ([34a498e](https://github.com/adobe/spectrum-web-components/commit/34a498e784221f98dbf26e9366114c82fabc9c5b)) +- manage updated node types ([0517fc1](https://github.com/adobe/spectrum-web-components/commit/0517fc19536325332543f95f5ecc0d6cb0c786c5)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843a049a6a37bbeee7bbfb50b4d5eb24f3fd)) +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) + +### Features + +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **iconset:** update spectrum css input ([914150a](https://github.com/adobe/spectrum-web-components/commit/914150a60e9e123ee68e9a26c8a72653846cd3ea)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.6...@spectrum-web-components/iconset@0.7.7) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.5...@spectrum-web-components/iconset@0.7.6) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.4...@spectrum-web-components/iconset@0.7.5) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.3...@spectrum-web-components/iconset@0.7.4) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.2...@spectrum-web-components/iconset@0.7.3) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.1...@spectrum-web-components/iconset@0.7.2) (2022-10-28) + +### Bug Fixes + +- manage updated node types ([0517fc1](https://github.com/adobe/spectrum-web-components/commit/0517fc19536325332543f95f5ecc0d6cb0c786c5)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.7.0...@spectrum-web-components/iconset@0.7.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.9...@spectrum-web-components/iconset@0.7.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.8...@spectrum-web-components/iconset@0.6.9) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.7...@spectrum-web-components/iconset@0.6.8) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.6...@spectrum-web-components/iconset@0.6.7) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.5...@spectrum-web-components/iconset@0.6.6) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.4...@spectrum-web-components/iconset@0.6.5) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.3...@spectrum-web-components/iconset@0.6.4) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.2...@spectrum-web-components/iconset@0.6.3) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.1...@spectrum-web-components/iconset@0.6.2) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.6.0...@spectrum-web-components/iconset@0.6.1) (2021-12-13) + +### Bug Fixes + +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.8...@spectrum-web-components/iconset@0.6.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.7...@spectrum-web-components/iconset@0.5.8) (2021-11-08) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.6...@spectrum-web-components/iconset@0.5.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.5...@spectrum-web-components/iconset@0.5.6) (2021-06-16) + +### Bug Fixes + +- lint away debugger statements ([34a498e](https://github.com/adobe/spectrum-web-components/commit/34a498e784221f98dbf26e9366114c82fabc9c5b)) + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.4...@spectrum-web-components/iconset@0.5.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.3...@spectrum-web-components/iconset@0.5.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.2...@spectrum-web-components/iconset@0.5.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.1...@spectrum-web-components/iconset@0.5.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.5.0...@spectrum-web-components/iconset@0.5.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.4.3...@spectrum-web-components/iconset@0.5.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.4.2...@spectrum-web-components/iconset@0.4.3) (2021-02-11) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.4.1...@spectrum-web-components/iconset@0.4.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.4.0...@spectrum-web-components/iconset@0.4.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.5...@spectrum-web-components/iconset@0.4.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) + +### Features + +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **iconset:** update spectrum css input ([914150a](https://github.com/adobe/spectrum-web-components/commit/914150a60e9e123ee68e9a26c8a72653846cd3ea)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.5...@spectrum-web-components/iconset@0.3.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) + +### Features + +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **iconset:** update spectrum css input ([914150a](https://github.com/adobe/spectrum-web-components/commit/914150a60e9e123ee68e9a26c8a72653846cd3ea)) + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.4...@spectrum-web-components/iconset@0.2.5) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.3...@spectrum-web-components/iconset@0.2.4) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.2...@spectrum-web-components/iconset@0.2.3) (2020-09-25) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.1...@spectrum-web-components/iconset@0.2.2) (2020-08-31) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.2.0...@spectrum-web-components/iconset@0.2.1) (2020-08-19) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.11...@spectrum-web-components/iconset@0.2.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.1.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.10...@spectrum-web-components/iconset@0.1.11) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.1.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.9...@spectrum-web-components/iconset@0.1.10) (2020-05-08) + +### Bug Fixes + +- remove "type: "module"" in package.json for node 12 ([c9f76e2](https://github.com/adobe/spectrum-web-components/commit/c9f76e21e24bb844466158fe96512ab19c37c5a9)) + +## [0.1.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.8...@spectrum-web-components/iconset@0.1.9) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.1.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.7...@spectrum-web-components/iconset@0.1.8) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/iconset + +## [0.1.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.6...@spectrum-web-components/iconset@0.1.7) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.1.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.5...@spectrum-web-components/iconset@0.1.6) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.4...@spectrum-web-components/iconset@0.1.5) (2019-11-01) + +### Bug Fixes + +- remove ":" based namespacing of events ([d77a843](https://github.com/adobe/spectrum-web-components/commit/d77a843)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/iconset@0.1.3...@spectrum-web-components/iconset@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/iconset diff --git a/1st-gen/packages/iconset/README.md b/1st-gen/packages/iconset/README.md new file mode 100644 index 00000000000..e0340af4406 --- /dev/null +++ b/1st-gen/packages/iconset/README.md @@ -0,0 +1,38 @@ +## Overview + +Extend either the `Iconset` or `IconsetSVG` exports of this package to supply your application with a custom icon set to power the use of `` elements throughout. Give your new icon set a custom name, and you'll be ready to supply them as `` across your application. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/iconset?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/iconset) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/iconset?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/iconset) + +``` +yarn add @spectrum-web-components/iconset +``` + +```ts +import { TemplateResult } from 'lit-element'; +import { IconsetSVG } from '@spectrum-web-components/iconset/src/iconset-svg.js'; + +import { CustomIconSet } from 'your-icon-set.js'; + +export class IconsLarge extends IconsetSVG { + public constructor() { + super(); + this.name = 'custom-icons'; // default iconset name for these icons + } + + protected renderDefaultContent(): TemplateResult { + return CustomIconSet; + } +} +``` + +### Deprecated + +Iconsets have been deprecated and will be removed from the project in an upcoming version. Using a technique that ensures only the icons actually leveraged in your application are present in your build, like UI Icons (../icons-ui/) or Workflow Icons (../icons-workflow/), will ensure smaller bundles and higher performance for you visitor. For non-Spectrum icons, you can still slot SVG and image content into an [`sp-icon` element](../icon/) or sanitize the SVG to a template literal so that it can be returned from the `render()` method in an extension of `IconBase` to create your own named icon element. + +### Accessibility + +Review the accessibility guidelines for the [icon](../icon#accessibility-guidelines). diff --git a/1st-gen/packages/iconset/package.json b/1st-gen/packages/iconset/package.json new file mode 100644 index 00000000000..5bb679626c8 --- /dev/null +++ b/1st-gen/packages/iconset/package.json @@ -0,0 +1,80 @@ +{ + "name": "@spectrum-web-components/iconset", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/iconset" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/iconset", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/iconset-registry.js": { + "development": "./src/iconset-registry.dev.js", + "default": "./src/iconset-registry.js" + }, + "./src/iconset-svg.js": { + "development": "./src/iconset-svg.dev.js", + "default": "./src/iconset-svg.js" + }, + "./src/iconset.js": { + "development": "./src/iconset.dev.js", + "default": "./src/iconset.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "deprecationNotice": "@spectrum-web-components/iconset is deprecated and will be removed in an upcoming release.", + "sideEffects": [ + "./src/index.js", + "./stories/icons-demo.js", + "./stories/iconsList.json", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/iconset/src/iconset-registry.ts b/1st-gen/packages/iconset/src/iconset-registry.ts new file mode 100644 index 00000000000..7afa60ed58b --- /dev/null +++ b/1st-gen/packages/iconset/src/iconset-registry.ts @@ -0,0 +1,72 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Iconset } from './iconset.js'; +export interface IconsetAddedDetail { + name: string; + iconset: Iconset; +} +export interface IconsetRemovedDetail { + name: string; +} + +export class IconsetRegistry { + // singleton getter + public static getInstance(): IconsetRegistry { + if (!IconsetRegistry.instance) { + IconsetRegistry.instance = new IconsetRegistry(); + } + return IconsetRegistry.instance; + } + private static instance: IconsetRegistry; + + private iconsetMap = new Map(); + + public addIconset(name: string, iconset: Iconset): void { + this.iconsetMap.set(name, iconset); + + // dispatch a sp-iconset-added event on window to let everyone know we have a new iconset + // note we're using window here for efficiency since we don't need to bubble through the dom since everyone + // will know where to look for this event + const event = new CustomEvent('sp-iconset-added', { + bubbles: true, + composed: true, + detail: { name, iconset }, + }); + // we're dispatching this event in the next tick to allow the iconset to finish any slotchange or other event + // listeners caused by connection to the dom and first render to complete, this way any icons listening for + // this iconset will be able to access the completed iconset + setTimeout(() => window.dispatchEvent(event), 0); + } + public removeIconset(name: string): void { + this.iconsetMap.delete(name); + // dispatch a sp-iconset-removed event on window to let everyone know we have a new iconset + // note we're using window here for efficiency since we don't need to bubble through the dom since everyone + // will know where to look for this event + const event = new CustomEvent('sp-iconset-removed', { + bubbles: true, + composed: true, + detail: { name }, + }); + // we're dispatching this event in the next tick To keep the event model consistent with the added event + setTimeout(() => window.dispatchEvent(event), 0); + } + public getIconset(name: string): Iconset | undefined { + return this.iconsetMap.get(name); + } +} + +declare global { + interface GlobalEventHandlersEventMap { + 'sp-iconset-added': CustomEvent; + 'sp-iconset-removed': CustomEvent; + } +} diff --git a/1st-gen/packages/iconset/src/iconset-svg.ts b/1st-gen/packages/iconset/src/iconset-svg.ts new file mode 100644 index 00000000000..8cab9333e18 --- /dev/null +++ b/1st-gen/packages/iconset/src/iconset-svg.ts @@ -0,0 +1,147 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + html, + PropertyValues, + TemplateResult, +} from '@spectrum-web-components/base'; +import { query } from '@spectrum-web-components/base/src/decorators.js'; + +import { Iconset } from './iconset.js'; + +export abstract class IconsetSVG extends Iconset { + private iconMap: Map = new Map(); + + @query('slot') + private slotContainer?: HTMLSlotElement; + + /** + * First updated handler just ensures we've processed any slotted symbols + */ + public override updated(changedProperties: PropertyValues): void { + if (!this.slotContainer) { + return; + } + const currentSVGNodes = this.getSVGNodes(this.slotContainer); + this.updateSVG(currentSVGNodes); + super.updated(changedProperties); + } + /** + * Applies the requested icon from this iconset instance to the given element. + * + * @param el - the element to apply the icon to + * @param icon - the name of the icon within this set to apply. + */ + public async applyIconToElement( + el: HTMLElement, + icon: string, + _size: string, + label: string + ): Promise { + await this.updateComplete; + const iconSymbol = this.iconMap.get(icon); + if (!iconSymbol) { + throw new Error(`Unable to find icon ${icon}`); + } + // we cannot share a single SVG globally across shadowroot boundaries + // so copy the template node so we can inject it where we need it + const clonedNode = this.prepareSvgClone(iconSymbol); + clonedNode.setAttribute('role', 'img'); + if (label) { + clonedNode.setAttribute('aria-label', label); + } else { + clonedNode.setAttribute('aria-hidden', 'true'); + } + // append the svg to the node either in its shadowroot or directly into its dom + if (el.shadowRoot) { + el.shadowRoot.appendChild(clonedNode); + } else { + el.appendChild(clonedNode); + } + } + + /** + * Returns a list of all icons in this iconset. + */ + public getIconList(): string[] { + return [...this.iconMap.keys()]; + } + + protected prepareSvgClone(sourceSvg: SVGSymbolElement): SVGSVGElement { + const content = sourceSvg.cloneNode(true) as SVGSymbolElement; + // we're going to create a new svg element that will have our symbol geometry inside + const svg = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg' + ); + const viewBox = content.getAttribute('viewBox') || ''; + // inline style isn't ideal but will work in all cases and means our icons don't need to know + // if they are svg or spritesheet provided + const cssText = + 'pointer-events: none; display: block; width: 100%; height: 100%;'; + svg.style.cssText = cssText; + // copy the viewbox and other properties into the svg + svg.setAttribute('viewBox', viewBox); + svg.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + svg.setAttribute('focusable', 'false'); + // move all the child nodes over to the svg + while (content.childNodes.length > 0) { + svg.appendChild(content.childNodes[0]); + } + return svg; + } + protected getSVGIconName(icon: string): string { + return icon; + } + protected getSanitizedIconName(icon: string): string { + return icon; + } + protected renderDefaultContent(): TemplateResult { + return html``; + } + + protected override render(): TemplateResult { + return html` + + ${this.renderDefaultContent()} + + `; + } + + protected updateSVG(nodes: SVGElement[]): void { + // iterate over the nodes that were passed in, and find all the top level symbols + const symbols = nodes.reduce((prev, svgNode) => { + const containedSymbols = svgNode.querySelectorAll('symbol'); + prev.push(...containedSymbols); + return prev; + }, [] as SVGSymbolElement[]); + symbols.forEach((symbol) => { + this.iconMap.set(this.getSanitizedIconName(symbol.id), symbol); + }); + } + + protected getSVGNodes(slotTarget: HTMLSlotElement): SVGElement[] { + const nodes = slotTarget.assignedNodes({ flatten: true }); + // find all the svg nodes + const svgNodes = nodes.filter((node) => { + return node.nodeName === 'svg'; + }) as SVGElement[]; + return svgNodes; + } + + private onSlotChange(event: Event): void { + const slotTarget = event.target as HTMLSlotElement; + const svgNodes = this.getSVGNodes(slotTarget); + this.updateSVG(svgNodes); + } +} diff --git a/1st-gen/packages/iconset/src/iconset.ts b/1st-gen/packages/iconset/src/iconset.ts new file mode 100644 index 00000000000..a8984673b62 --- /dev/null +++ b/1st-gen/packages/iconset/src/iconset.ts @@ -0,0 +1,118 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { IconsetRegistry } from './iconset-registry.js'; + +import { LitElement } from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; + +export abstract class Iconset extends LitElement { + protected registered = false; + + private _name!: string; + + protected override firstUpdated(): void { + // force no display for all iconsets + this.style.display = 'none'; + if (window.__swc.DEBUG) { + window.__swc.warn( + this, + 'Iconsets have been deprecated and will be removed from the project in an upcoming version. For default Spectrum Icons, learn more about leveraging UI Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-ui/) or Workflow Icons (https://opensource.adobe.com/spectrum-web-components/components/icons-workflow/) as an alternative.', + 'https://opensource.adobe.com/spectrum-web-components/components/iconset/#deprecated', + { level: 'deprecation' } + ); + } + } + + /** + * Name of the iconset, used by the IconsetRegistry to serve this icon set + * to consuming icons. + */ + @property() + public set name(value: string) { + // if we're already registered in the iconset registry + // we'll need to update our registration + if (this.registered) { + if (this._name) { + // remove from the iconset map using the old name + IconsetRegistry.getInstance().removeIconset(this._name); + } + + if (value) { + // set in the map using the new name + IconsetRegistry.getInstance().addIconset(value, this); + } + } + this._name = value; + } + public get name(): string { + return this._name; + } + + /** + * Applies an icon to the given element + */ + public abstract applyIconToElement( + el: HTMLElement, + icon: string, + size: string, + label: string + ): void; + + /** + * Returns a list of all icons in this iconset. + */ + public abstract getIconList(): string[]; + + private handleRemoved = ({ + detail, + }: { + detail: { name: string }; + }): void => { + if (detail.name === this.name) { + this.registered = false; + this.addIconset(); + } + }; + + /** + * On updated we register the iconset if we're not already registered + */ + public override connectedCallback(): void { + super.connectedCallback(); + this.addIconset(); + window.addEventListener('sp-iconset-removed', this.handleRemoved); + } + /** + * On disconnected we remove the iconset + */ + public override disconnectedCallback(): void { + super.disconnectedCallback(); + window.removeEventListener('sp-iconset-removed', this.handleRemoved); + this.removeIconset(); + } + + private addIconset(): void { + if (!this.name || this.registered) { + return; + } + IconsetRegistry.getInstance().addIconset(this.name, this); + this.registered = true; + } + + private removeIconset(): void { + if (!this.name) { + return; + } + IconsetRegistry.getInstance().removeIconset(this.name); + this.registered = false; + } +} diff --git a/1st-gen/packages/iconset/src/index.ts b/1st-gen/packages/iconset/src/index.ts new file mode 100644 index 00000000000..92b97ca6596 --- /dev/null +++ b/1st-gen/packages/iconset/src/index.ts @@ -0,0 +1,14 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './iconset.js'; +export * from './iconset-svg.js'; +export * from './iconset-registry.js'; diff --git a/1st-gen/packages/iconset/stories/icons-demo.ts b/1st-gen/packages/iconset/stories/icons-demo.ts new file mode 100644 index 00000000000..26e454f8e00 --- /dev/null +++ b/1st-gen/packages/iconset/stories/icons-demo.ts @@ -0,0 +1,314 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { IconsetAddedDetail } from '@spectrum-web-components/iconset'; +import { + css, + CSSResultGroup, + html, + PropertyValues, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + customElement, + property, + state, +} from '@spectrum-web-components/base/src/decorators.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import { Search } from '@spectrum-web-components/search'; +import '@spectrum-web-components/search/sp-search.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import bodyStyles from '@spectrum-web-components/styles/body.js'; +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/help-text/sp-help-text.js'; + +import iconsList from './iconsList.json' with { type: 'json' }; + +import { + SystemResolutionController, + systemResolverUpdatedSymbol, +} from '@spectrum-web-components/reactive-controllers/src/SystemContextResolution.js'; + +@customElement('delayed-ready') +export class DelayedReady extends SpectrumElement { + _delayedReady!: Promise; + _resolveDelayedReady!: () => void; + + protected override render(): TemplateResult { + return html` + + `; + } + + protected override firstUpdated(): void { + this._delayedReady = new Promise( + (res) => (this._resolveDelayedReady = res) + ); + } + + protected override async getUpdateComplete(): Promise { + const complete = (await super.getUpdateComplete()) as boolean; + await this._delayedReady; + return complete; + } + + public handleSlotchange({ + target, + }: Event & { target: HTMLSlotElement }): void { + if (target.assignedElements({ flatten: true }).length) { + requestAnimationFrame(() => { + this._resolveDelayedReady(); + }); + } + } +} + +@customElement('icons-demo') +export class IconsDemo extends SpectrumElement { + @property() + public name = 'ui'; + + @property() + public package = ''; + + @property() + public size = 'm'; + + @property() + public search = ''; + + @property({ attribute: false }) + public icons: { + name: string; + story(size: string): TemplateResult; + tag: string; + }[] = []; + + private filteredIcons: { + name: string; + story(size: string): TemplateResult; + tag: string; + }[] = []; + + private unsubscribeSystemContext: (() => void) | null = null; + + @state() + public spectrumVersion = 1; + + private iconset: string[] = []; + public constructor() { + super(); + this.iconset = []; + this.handleIconSetAdded = this.handleIconSetAdded.bind(this); + } + + public override async connectedCallback(): Promise { + super.connectedCallback(); + window.addEventListener('sp-iconset-added', this.handleIconSetAdded); + } + public override disconnectedCallback(): void { + window.removeEventListener('sp-iconset-added', this.handleIconSetAdded); + super.disconnectedCallback(); + if (this.unsubscribeSystemContext) { + this.unsubscribeSystemContext(); + this.unsubscribeSystemContext = null; + } + } + + private filterIconsBySpectrumVersion(): void { + const iconVersion = this.spectrumVersion === 2 ? 's2' : 's1'; + let filteredIcons = this.icons; + // Filter out icons that are not in the current version for workflow icons + if (this.name === 'workflow') { + filteredIcons = filteredIcons.filter((icon) => { + const iconName = icon.name.replace(/\s/g, '').toLowerCase(); + return iconsList[iconVersion].includes(iconName); + }); + } + + // Use a Set to remove duplicates that may get added because of the same icon name in both versions + const iconSet = new Set(); + filteredIcons = filteredIcons.filter((icon) => { + if (iconSet.has(icon.name)) { + return false; + } + iconSet.add(icon.name); + return true; + }); + + this.filteredIcons = filteredIcons; + } + + private systemResolver = new SystemResolutionController(this); + + protected override update(changes: PropertyValues): void { + if (changes.has(systemResolverUpdatedSymbol)) { + this.spectrumVersion = + this.systemResolver.system === 'spectrum-two' ? 2 : 1; + this.filterIconsBySpectrumVersion(); + } + + if (changes.has('icons')) { + this.filterIconsBySpectrumVersion(); + } + + super.update(changes); + } + + public handleIconSetAdded(event: CustomEvent): void { + const { iconset } = event.detail; + this.iconset = iconset.getIconList(); + this.requestUpdate(); + } + public static override get styles(): CSSResultGroup { + return [ + ...bodyStyles, + css` + :host { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 20px; + align-items: flex-start; + } + .icon { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + border-radius: var( + --spectrum-alias-focus-ring-gap, + var(--spectrum-spacing-50) + ); + } + :host([package]) .icon { + cursor: pointer; + } + sp-icon { + margin-bottom: 10px; + } + .search { + grid-column-start: 1; + grid-column-end: -1; + } + .icon[tabindex]:focus { + outline: none; + } + .icon[tabindex]:focus-visible { + outline: var(--spectrum-alias-focus-ring-size) solid + var(--spectrum-alias-focus-ring-color); + outline-offset: calc( + var( + --spectrum-alias-focus-ring-gap, + var(--spectrum-spacing-50) + ) * + 2 + ); + } + `, + ]; + } + private handleKeydown(event: KeyboardEvent, tag: string): void { + const { code } = event; + if (code !== 'Enter' && code !== 'NumpadEnter' && code !== 'Space') { + return; + } + event.preventDefault(); + this.shouldCopy(tag); + } + + private shouldCopy(tag: string): void { + if (!this.package) return; + const conditionedTag = tag.slice(1, tag.length - 1); + const importURL = `import '@spectrum-web-components/${this.package}/icons/${conditionedTag}.js';`; + this.dispatchEvent( + new CustomEvent('copy-text', { + bubbles: true, + composed: true, + detail: { + message: 'Import statement copied to clipboard!', + text: importURL, + }, + }) + ); + } + private updateSearch(event: Event & { target: Search }): void { + event.stopPropagation(); + this.search = event.target.value; + } + private submit(event: Event & { target: Search }): void { + event.stopPropagation(); + this.updateSearch(event); + } + private renderSearch(): TemplateResult { + const matchingIcons = this.search + ? this.filteredIcons.filter((icon) => + icon.name.toLowerCase().includes(this.search.toLowerCase()) + ) + : this.filteredIcons; + + return html` + + ${matchingIcons.map((icon) => { + return html` + this.shouldCopy(icon.tag)} + @keydown=${(event: KeyboardEvent) => + this.handleKeydown(event, icon.tag)} + tabindex=${ifDefined(this.package ? '0' : undefined)} + > + ${icon.story(this.size)} ${icon.tag} + + `; + })} + `; + } + protected override render(): TemplateResult { + return html` + ${this.filteredIcons.length + ? this.renderSearch() + : html` + + `} + ${this.iconset.map( + (icon) => html` + + + ${icon} + + ` + )} + `; + } +} diff --git a/1st-gen/packages/iconset/stories/iconsList.json b/1st-gen/packages/iconset/stories/iconsList.json new file mode 100644 index 00000000000..9e4e1e7873f --- /dev/null +++ b/1st-gen/packages/iconset/stories/iconsList.json @@ -0,0 +1,1304 @@ +{ + "s1": [ + "abc", + "actions", + "add", + "addcircle", + "addisplay", + "addto", + "addtoselection", + "adprint", + "aemscreens", + "airplane", + "alert", + "alertadd", + "alertcheck", + "alertcircle", + "alertcirclefilled", + "algorithm", + "alias", + "alignbottom", + "aligncenter", + "alignleft", + "alignmiddle", + "alignright", + "aligntop", + "amusementpark", + "anchor", + "anchorselect", + "annotate", + "annotatepen", + "answer", + "answerfavorite", + "app", + "applefiles", + "applicationdelivery", + "apprefresh", + "approvereject", + "apps", + "archive", + "archiveremove", + "arrowdown", + "arrowleft", + "arrowright", + "arrowup", + "arrowupright", + "artboard", + "article", + "asset", + "assetcheck", + "assetsadded", + "assetsdownloaded", + "assetsexpired", + "assetslinkedpublished", + "assetsmodified", + "assetspublished", + "asterisk", + "at", + "attach", + "attachmentexclude", + "attributes", + "audio", + "automatedsegment", + "back", + "back30seconds", + "backandroid", + "beaker", + "beakercheck", + "beakershare", + "bell", + "bidrule", + "bidruleadd", + "blower", + "blur", + "book", + "bookmark", + "bookmarksingle", + "bookmarksingleoutline", + "bookmarksmall", + "bookmarksmalloutline", + "boolean", + "border", + "box", + "boxadd", + "boxexport", + "boximport", + "brackets", + "bracketssquare", + "branch1", + "branch2", + "branch3", + "branchcircle", + "breadcrumbnavigation", + "breakdown", + "breakdownadd", + "briefcase", + "browse", + "brush", + "bug", + "building", + "bulkeditusers", + "button", + "calculator", + "calendar", + "calendaradd", + "calendarlocked", + "calendarunlocked", + "callcenter", + "camera", + "cameraflip", + "camerarefresh", + "campaign", + "campaignadd", + "campaignclose", + "campaigndelete", + "campaignedit", + "cancel", + "capitals", + "captcha", + "car", + "card", + "cclibrary", + "channel", + "chat", + "chatadd", + "checkmark", + "checkmarkcircle", + "checkmarkcircleoutline", + "checkpause", + "chevrondoubleleft", + "chevrondoubleright", + "chevrondown", + "chevronleft", + "chevronright", + "chevronup", + "chevronupdown", + "circle", + "circlefilled", + "classicgridview", + "clock", + "clockcheck", + "clonestamp", + "close", + "closecaptions", + "closecircle", + "cloud", + "clouddisconnected", + "clouderror", + "cloudoutline", + "code", + "collection", + "collectionadd", + "collectionaddto", + "collectioncheck", + "collectionedit", + "collectionexclude", + "collectionlink", + "colorfill", + "colorpalette", + "colorwheel", + "columnsettings", + "columntwoa", + "columntwob", + "columntwoc", + "comment", + "compare", + "compass", + "condition", + "confidencefour", + "confidenceone", + "confidencethree", + "confidencetwo", + "contrast", + "conversionfunnel", + "copy", + "coverimage", + "creditcard", + "crop", + "croplightning", + "croprotate", + "crosshairs", + "curate", + "cut", + "dashboard", + "data", + "dataadd", + "databook", + "datacheck", + "datacorrelated", + "datadownload", + "dataedit", + "datamapping", + "datarefresh", + "dataremove", + "datasettings", + "dataunavailable", + "dataupload", + "datauser", + "date", + "dateinput", + "deduplication", + "delegate", + "delete", + "deleteoutline", + "demographic", + "deselect", + "deselectcircular", + "desktopandmobile", + "devicedesktop", + "devicelaptop", + "devicephone", + "devicephonerefresh", + "devicepreview", + "devicerotatelandscape", + "devicerotateportrait", + "devices", + "devicetablet", + "devicetv", + "discover", + "discoveroutline", + "distributebottomedge", + "distributehorizontalcenter", + "distributehorizontally", + "distributeleftedge", + "distributerightedge", + "distributespacehoriz", + "distributespacevert", + "distributetopedge", + "distributeverticalcenter", + "distributevertically", + "divide", + "dividepath", + "document", + "documentfragment", + "documentfragmentgroup", + "documentoutline", + "documentrefresh", + "dolly", + "download", + "downloadfromcloud", + "downloadfromcloudoutline", + "draft", + "draghandle", + "draw", + "dropdown", + "duplicate", + "edit", + "editcircle", + "editexclude", + "editin", + "editinlight", + "education", + "effects", + "efficient", + "ellipse", + "email", + "emailcancel", + "emailcheck", + "emailexclude", + "emailexcludeoutline", + "emailgear", + "emailgearoutline", + "emailkey", + "emailkeyoutline", + "emaillightning", + "emailnotification", + "emailoutline", + "emailrefresh", + "emailschedule", + "engagement", + "enterprise", + "erase", + "event", + "eventexclude", + "events", + "eventshare", + "excludeoverlap", + "experience", + "experienceadd", + "experienceaddto", + "experienceexport", + "experienceimport", + "export", + "exportoriginal", + "exposure", + "extension", + "facebookcoverimage", + "fast", + "fastforward", + "fastforwardcircle", + "feature", + "feed", + "feedadd", + "feedback", + "feedmanagement", + "fileadd", + "filecampaign", + "filechart", + "filecheckedout", + "filecode", + "filecsv", + "filedata", + "fileemail", + "fileexcel", + "filefolder", + "filegear", + "fileglobe", + "filehtml", + "fileimportant", + "filejson", + "filekey", + "filemobile", + "filepdf", + "fileshare", + "filesinglewebpage", + "filespace", + "filetemplate", + "filetxt", + "fileuser", + "fileword", + "fileworkflow", + "filexml", + "filezip", + "filingcabinet", + "filmroll", + "filmrollautoadd", + "filter", + "filteradd", + "filtercheck", + "filterdelete", + "filteredit", + "filterheart", + "filterremove", + "filterstar", + "findandreplace", + "flag", + "flagexclude", + "flashauto", + "flashlight", + "flashlightoff", + "flashlighton", + "flashoff", + "flashon", + "fliphorizontal", + "flipvertical", + "folder", + "folder2color", + "folderadd", + "folderaddto", + "folderarchive", + "folderdelete", + "foldergear", + "folderlocked", + "folderopen", + "folderopenoutline", + "folderoutline", + "folderremove", + "foldersearch", + "folderuser", + "follow", + "followoff", + "forecast", + "form", + "forplacementonly", + "forward", + "fullscreen", + "fullscreenexit", + "function", + "game", + "gauge1", + "gauge2", + "gauge3", + "gauge4", + "gauge5", + "gears", + "gearsadd", + "gearsdelete", + "gearsedit", + "genderfemale", + "gendermale", + "gift", + "globe", + "globecheck", + "globeclock", + "globeenter", + "globeexit", + "globegrid", + "globeoutline", + "globeremove", + "globesearch", + "globestrike", + "globestrikeclock", + "government", + "gradient", + "grapharea", + "graphareastacked", + "graphbarhorizontal", + "graphbarhorizontaladd", + "graphbarhorizontalstacked", + "graphbarvertical", + "graphbarverticaladd", + "graphbarverticalstacked", + "graphbubble", + "graphbullet", + "graphconfidencebands", + "graphdonut", + "graphdonutadd", + "graphgantt", + "graphhistogram", + "graphic", + "graphpathing", + "graphpie", + "graphprofitcurve", + "graphscatter", + "graphstream", + "graphstreamranked", + "graphstreamrankedadd", + "graphsunburst", + "graphtree", + "graphtrend", + "graphtrendadd", + "graphtrendalert", + "group", + "hammer", + "hand", + "hand0", + "hand1", + "hand2", + "hand3", + "hand4", + "heal", + "heart", + "help", + "helpoutline", + "histogram", + "history", + "home", + "homepage", + "hotelbed", + "hotfixes", + "identityservice", + "image", + "imageadd", + "imagealbum", + "imageautomode", + "imagecarousel", + "imagecheck", + "imagecheckedout", + "imagemapcircle", + "imagemappolygon", + "imagemaprectangle", + "imagenext", + "imageprofile", + "images", + "imagesearch", + "imagetext", + "import", + "inbox", + "individual", + "info", + "infooutline", + "intersectoverlap", + "invertadj", + "invite", + "journey", + "journeyaction", + "journeydata", + "journeyevent", + "journeyevent2", + "journeyreports", + "journeyvoyager", + "jumptotop", + "key", + "keyboard", + "keyclock", + "keyexclude", + "label", + "labelexclude", + "labels", + "landscape", + "launch", + "layers", + "layersbackward", + "layersbringtofront", + "layersforward", + "layerssendtoback", + "learn", + "light", + "line", + "lineargradient", + "lineheight", + "link", + "linkcheck", + "linkglobe", + "linknav", + "linkoff", + "linkout", + "linkoutlight", + "linkpage", + "linkuser", + "location", + "locationbaseddate", + "locationbasedevent", + "locationcontribution", + "lockclosed", + "lockopen", + "login", + "logout", + "looks", + "loupeview", + "magicwand", + "magnify", + "mailbox", + "mapview", + "marginbottom", + "marginleft", + "marginright", + "margintop", + "marketingactivities", + "maximize", + "mbox", + "measure", + "menu", + "merge", + "mergelayers", + "messenger", + "minimize", + "mobileservices", + "moderngridview", + "money", + "monitoring", + "moon", + "more", + "morecircle", + "moresmall", + "moresmalllist", + "moresmalllistvert", + "morevertical", + "move", + "moveleftright", + "moveto", + "moveupdown", + "moviecamera", + "multiple", + "multipleadd", + "multiplecheck", + "multipleexclude", + "namingorder", + "newitem", + "news", + "newsadd", + "noedit", + "note", + "noteadd", + "offer", + "offeractivities", + "offerdelete", + "offers", + "onair", + "openin", + "openinlight", + "openrecent", + "openrecentoutline", + "orbit", + "organisations", + "organize", + "os", + "outlinepath", + "paddingbottom", + "paddingleft", + "paddingright", + "paddingtop", + "pagebreak", + "pageexclude", + "pagegear", + "pagerule", + "pagesexclude", + "pageshare", + "pagetag", + "pan", + "panel", + "paste", + "pastehtml", + "pastelist", + "pastetext", + "pattern", + "pause", + "pausecircle", + "pawn", + "pending", + "peoplegroup", + "personalizationfield", + "perspective", + "pinoff", + "pinon", + "pivot", + "placeholder", + "platformdatamapping", + "play", + "playcircle", + "plug", + "polygon", + "polygonselect", + "popin", + "portrait", + "preset", + "preview", + "print", + "printpreview", + "project", + "projectadd", + "projectedit", + "projectnameedit", + "promote", + "properties", + "propertiescopy", + "publishcheck", + "publishpending", + "publishreject", + "publishremove", + "publishschedule", + "pushnotification", + "question", + "quickselect", + "radialgradient", + "rail", + "railbottom", + "railleft", + "railright", + "railrightclose", + "railrightopen", + "railtop", + "rangemask", + "realtimecustomerprofile", + "rectangle", + "rectselect", + "redo", + "refresh", + "regionselect", + "relevance", + "remove", + "removecircle", + "rename", + "reorder", + "replay", + "replies", + "reply", + "replyall", + "report", + "reportadd", + "resize", + "resolvedcomment", + "retweet", + "reuse", + "revenue", + "revert", + "rewind", + "rewindcircle", + "ribbon", + "rotateccw", + "rotateccwbold", + "rotatecw", + "rotatecwbold", + "rotateleft", + "rotateleftoutline", + "rotateright", + "rotaterightoutline", + "rss", + "sampler", + "sandbox", + "saveasfloppy", + "savefloppy", + "saveto", + "savetolight", + "scribble", + "search", + "seat", + "seatadd", + "segmentation", + "segments", + "select", + "selectadd", + "selectbox", + "selectboxall", + "selectcircular", + "selectcontainer", + "selectgear", + "selectintersect", + "selection", + "selectionchecked", + "selectionmove", + "selectsubtract", + "send", + "sentimentnegative", + "sentimentneutral", + "sentimentpositive", + "separator", + "servers", + "settings", + "shapes", + "share", + "shareandroid", + "sharecheck", + "sharelight", + "sharewindows", + "sharpen", + "shield", + "ship", + "shop", + "shoppingcart", + "showalllayers", + "showmenu", + "showonelayer", + "shuffle", + "slice", + "slow", + "smallcaps", + "sms", + "smskey", + "smslightning", + "smsrefresh", + "snapshot", + "socialnetwork", + "sortorderdown", + "sortorderup", + "spam", + "spellcheck", + "spin", + "splitview", + "spotheal", + "sqlquery", + "stadium", + "stage", + "stamp", + "star", + "starburst", + "staroutline", + "stepbackward", + "stepbackwardcircle", + "stepforward", + "stepforwardcircle", + "stop", + "stopcircle", + "stopwatch", + "straighten", + "straightenoutline", + "strokewidth", + "subscribe", + "subtractbackpath", + "subtractfromselection", + "subtractfrontpath", + "successmetric", + "summarize", + "survey", + "switch", + "sync", + "syncremove", + "table", + "tableadd", + "tableandchart", + "tablecolumnaddleft", + "tablecolumnaddright", + "tablecolumnmerge", + "tablecolumnremovecenter", + "tablecolumnsplit", + "tableedit", + "tablehistogram", + "tablemergecells", + "tablerowaddbottom", + "tablerowaddtop", + "tablerowmerge", + "tablerowremovecenter", + "tablerowsplit", + "tableselectcolumn", + "tableselectrow", + "tagbold", + "tagitalic", + "tagunderline", + "target", + "targeted", + "tasklist", + "teapot", + "temperature", + "testab", + "testabedit", + "testabgear", + "testabremove", + "testprofile", + "text", + "textadd", + "textaligncenter", + "textalignjustify", + "textalignleft", + "textalignright", + "textbaselineshift", + "textbold", + "textbulleted", + "textbulletedattach", + "textbulletedhierarchy", + "textbulletedhierarchyexclude", + "textcolor", + "textdecrease", + "textedit", + "textexclude", + "textincrease", + "textindentdecrease", + "textindentincrease", + "textitalic", + "textkerning", + "textletteredlowercase", + "textlettereduppercase", + "textnumbered", + "textparagraph", + "textromanlowercase", + "textromanuppercase", + "textsize", + "textsizeadd", + "textspaceafter", + "textspacebefore", + "textstrikethrough", + "textstroke", + "textstyle", + "textsubscript", + "textsuperscript", + "texttracking", + "textunderline", + "thumbdown", + "thumbdownoutline", + "thumbup", + "thumbupoutline", + "tips", + "train", + "transfertoplatform", + "transparency", + "trap", + "treecollapse", + "treecollapseall", + "treeexpand", + "treeexpandall", + "treeview", + "trendinspect", + "trimpath", + "trophy", + "type", + "underline", + "undo", + "ungroup", + "unlink", + "unmerge", + "unresolvedcomment", + "uploadtocloud", + "uploadtocloudoutline", + "usa", + "user", + "useractivity", + "useradd", + "useradmin", + "userarrow", + "usercheckedout", + "userdeveloper", + "useredit", + "userexclude", + "usergroup", + "userlock", + "usersadd", + "usersexclude", + "usershare", + "userslock", + "usersshare", + "variable", + "vectordraw", + "verticalmasonrygridview", + "videocheckedout", + "videofilled", + "videooutline", + "viewalltags", + "viewbiweek", + "viewcard", + "viewcardonecol", + "viewcolumn", + "viewday", + "viewdetail", + "viewedmarkas", + "viewgrid", + "viewlist", + "viewrow", + "viewsingle", + "viewstack", + "viewtable", + "viewweek", + "vignette", + "visibility", + "visibilityoff", + "visit", + "visitshare", + "voiceover", + "volumemute", + "volumeone", + "volumethree", + "volumetwo", + "watch", + "webpage", + "webpages", + "workflow", + "workflowadd", + "wrench", + "zoomin", + "zoomout" + ], + "s2": [ + "abc", + "accessibility", + "add", + "addcircle", + "addcontent", + "alertdiamond", + "alerttriangle", + "alignbottom", + "aligncenter", + "alignleft", + "alignmiddle", + "alignright", + "aligntop", + "animation", + "animationno", + "app", + "apps", + "appsall", + "archive", + "arrowheadtool", + "artboard", + "aspectratio", + "asset", + "attach", + "audiowave", + "autoselectsubject", + "background", + "badgeverified", + "bell", + "bellrotated", + "betaapp", + "binoculars", + "blur", + "bookmark", + "brand", + "briefcase", + "brightnesscontrast", + "brush", + "bug", + "building", + "buildings", + "calendar", + "calendaradd", + "calendarday", + "calendaredit", + "calendarweek", + "callcenter", + "camera", + "cameraproperties", + "cancel", + "cclibrary", + "channel", + "chartbarvert", + "chartpie", + "charttrend", + "chat", + "checkbox", + "checkmark", + "checkmarkcircle", + "chevrondoubleleft", + "chevrondoubleright", + "chevrondown", + "chevronleft", + "chevronright", + "chevronup", + "circle", + "clock", + "clockpending", + "close", + "closecaptions", + "closecircle", + "cloud", + "cloudstatedisconnected", + "cloudstateerror", + "cloudstateinprogress", + "cloudstateonline", + "cloudstatepaused", + "cloudstatepending", + "cloudstateslowconnection", + "code", + "collection", + "color", + "colorfill", + "colorharmony", + "comment", + "commentcheckmark", + "commenthide", + "commentremove", + "commentshow", + "commenttext", + "community", + "compare", + "contextualtaskbar", + "contrast", + "copy", + "cornerradius", + "cornerradiusbottomleft", + "cornerradiusbottomright", + "cornerradiuseach", + "cornerradiustopleft", + "cornerradiustopright", + "crop", + "croprotate", + "cursorclick", + "cut", + "data", + "dataadd", + "datarefresh", + "datasettings", + "dataupload", + "delete", + "deviceall", + "devicedesktop", + "devicedesktopmobile", + "devicelaptop", + "devicemobile", + "devicemultiscreen", + "devicephone", + "devicetablet", + "directselect", + "discover", + "distributebottomedge", + "distributehorizontalcenter", + "distributeleftedge", + "distributerightedge", + "distributespacehorizontally", + "distributespacevertically", + "distributetopedge", + "distributeverticalcenter", + "download", + "draw", + "duplicate", + "edit", + "editno", + "education", + "effectborder", + "effects", + "email", + "emoji", + "enterprise", + "erase", + "export", + "exportto", + "exposure", + "eyedropper", + "feedback", + "file", + "fileadd", + "fileconvert", + "files", + "filetext", + "fileuser", + "filmstrip", + "filter", + "filters", + "findandreplace", + "flag", + "fliphorizontal", + "flipvertical", + "folder", + "folderadd", + "folderbreadcrumb", + "folderclock", + "foldermoveto", + "folderopen", + "foldersearch", + "fontpicker", + "fullscreen", + "fullscreenexit", + "gift", + "globegrid", + "gradient", + "gradienthorizontal", + "gradientradial", + "gridsandrulers", + "gridtypedots", + "gridtypelines", + "group", + "groupno", + "hand", + "heart", + "heartfilled", + "helpcircle", + "history", + "home", + "image", + "imageadd", + "imagebackgroundremove", + "images", + "import", + "infocircle", + "interaction", + "invert", + "invite", + "key", + "keyboard", + "lassoselect", + "layers", + "layout", + "leave", + "lightbulb", + "lighten", + "line", + "lineheight", + "link", + "linkvertical", + "listbulleted", + "listmultiselect", + "listnumbered", + "location", + "lock", + "lockopen", + "logo", + "magicwand", + "market", + "mask", + "maskdisable", + "maximize", + "mention", + "menuhamburger", + "microphone", + "microphoneoff", + "minimize", + "more", + "move", + "moviecamera", + "musicnote", + "namingorder", + "new", + "nudge", + "openin", + "order", + "orderbottom", + "orderonedown", + "orderoneup", + "ordertop", + "orientationlandscape", + "orientationportrait", + "paste", + "path", + "pattern", + "pause", + "pausecircle", + "penbrush", + "people", + "peoplegroup", + "percentage", + "pinoff", + "pinon", + "play", + "plugin", + "plugingear", + "polygon3", + "polygon4", + "polygon5", + "polygon6", + "preview", + "print", + "project", + "projectaddinto", + "projectcreate", + "promote", + "prompt", + "properties", + "prototyping", + "publish", + "publishno", + "radiobutton", + "rectanglehoriz", + "redo", + "refresh", + "removecircle", + "rename", + "replace", + "reportabuse", + "resize", + "revert", + "reviewlink", + "ribbon", + "rocketquickactions", + "rotateccw", + "rotatecw", + "rotateorientation", + "ruler", + "saturation", + "savefloppy", + "search", + "select", + "selectallitems", + "selectandmove", + "selectmulti", + "selectno", + "selectnone", + "selectrectangle", + "send", + "settings", + "shapes", + "share", + "shareandroid", + "shoppingcart", + "shuffle", + "similar", + "slideshow", + "slowconnectioncircle", + "socialnetwork", + "sort", + "sortdown", + "sortup", + "speedfast", + "stampclone", + "star", + "starfilled", + "stepbackward", + "stepforward", + "stickynote", + "strokedotted", + "strokesolid", + "strokewidth", + "switch", + "switchvertical", + "table", + "tag", + "target", + "temperature", + "template", + "text", + "textadd", + "textaligncenter", + "textalignjustify", + "textalignjustifylastcenter", + "textalignjustifylastleft", + "textalignjustifylastright", + "textalignleft", + "textalignright", + "textbold", + "textcapsall", + "textcapssmall", + "texthighlight", + "textincrease", + "textitalic", + "textnumbers", + "textparagraph", + "textreplacecomment", + "textsize", + "textstrikethrough", + "textsubscript", + "textsuperscript", + "textunderline", + "textvariablefontsettings", + "thumbdown", + "thumbup", + "toggle", + "tools", + "touchonefingerswipeleftright", + "transcript", + "transformdistort", + "transformgeneric", + "transformperspective", + "transformskew", + "transformwarp", + "translate", + "tutorials", + "undo", + "unlink", + "unlinkhoriz", + "unlinkvertical", + "upload", + "uploadtocloud", + "user", + "useradd", + "useravatar", + "useravatarcursor", + "useredit", + "userfollowing", + "usergroup", + "userlock", + "usersettings", + "userslock", + "vectordraw", + "video", + "viewgrid", + "viewgridfluid", + "viewlist", + "viewtransparency", + "visibility", + "visibilityoff", + "volumeoff", + "volumeone", + "volumetwo", + "webnavbar", + "webpage", + "zoomin", + "zoomout" + ] +} diff --git a/1st-gen/packages/iconset/test/iconset.test.ts b/1st-gen/packages/iconset/test/iconset.test.ts new file mode 100644 index 00000000000..27003bf215d --- /dev/null +++ b/1st-gen/packages/iconset/test/iconset.test.ts @@ -0,0 +1,149 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { waitForPredicate } from '../../../test/testing-helpers.js'; +import '@spectrum-web-components/icons/sp-icons-medium.js'; +import '@spectrum-web-components/icon/sp-icon.js'; +import { IconsMedium } from '@spectrum-web-components/icons'; +import { Icon } from '@spectrum-web-components/icon'; +import { IconsetRegistry } from '@spectrum-web-components/iconset/src/iconset-registry.js'; +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import { stub } from 'sinon'; + +describe('Iconset', () => { + after(() => { + const sets = [...document.querySelectorAll('sp-icons-medium')]; + sets.map((set) => set.remove()); + }); + it('warns in Dev Mode of deprecation', async () => { + const consoleWarnStub = stub(console, 'warn'); + const el = document.createElement('sp-icons-medium'); + document.body.append(el); + + await elementUpdated(el); + + expect(consoleWarnStub.called).to.be.true; + const spyCall = consoleWarnStub.getCall(0); + expect( + spyCall.args.at(0).includes('deprecated'), + 'confirm deprecation message' + ).to.be.true; + expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({ + data: { + localName: 'sp-icons-medium', + type: 'api', + level: 'deprecation', + }, + }); + consoleWarnStub.restore(); + }); + + it('will re-register with new name', async () => { + const icons = document.createElement('sp-icons-medium'); + document.body.append(icons); + icons.name = 'first-name'; + + const registry = IconsetRegistry.getInstance(); + + expect(registry.getIconset('first-name')).to.not.be.undefined; + expect(registry.getIconset('')).to.be.undefined; + expect(registry.getIconset('second-name')).to.be.undefined; + expect(registry.getIconset('ui')).to.be.undefined; + + icons.name = ''; + + expect(registry.getIconset('first-name')).to.be.undefined; + expect(registry.getIconset('')).to.be.undefined; + expect(registry.getIconset('second-name')).to.be.undefined; + expect(registry.getIconset('ui')).to.be.undefined; + + icons.name = 'second-name'; + + expect(registry.getIconset('first-name')).to.be.undefined; + expect(registry.getIconset('')).to.be.undefined; + expect(registry.getIconset('second-name')).to.not.be.undefined; + expect(registry.getIconset('ui')).to.be.undefined; + }); + it('will not re-register on (dis)connect without a name', async () => { + const icons = document.createElement('sp-icons-medium'); + document.body.append(icons); + + const registry = IconsetRegistry.getInstance(); + + expect(registry.getIconset('ui')).to.not.be.undefined; + + icons.name = ''; + + expect(registry.getIconset('ui')).to.be.undefined; + + icons.remove(); + + document.body.append(icons); + + expect(registry.getIconset('ui')).to.be.undefined; + }); + it('renders after adding and removing a second iconset of same name', async () => { + const icons = document.createElement('sp-icons-medium'); + document.body.append(icons); + + const icons2 = document.createElement('sp-icons-medium'); + document.body.append(icons2); + + icons2.remove(); + + window.dispatchEvent( + new CustomEvent('sp-iconset-removed', { + detail: { name: 'Other Set' }, + }) + ); + + const el = await fixture(html` + + `); + + let svg = el.shadowRoot + ? el.shadowRoot.querySelector('[role="img"]') + : null; + + function getSVG(): boolean { + svg = el.shadowRoot + ? el.shadowRoot.querySelector('[role="img"]') + : null; + + return svg !== null; + } + + await waitForPredicate(getSVG); + + expect(svg).to.not.be.null; + }); + + it('can be after `` in the DOM order', async () => { + const el = await fixture(html` +
+ + +
+ `); + + const icon = el.querySelector('sp-icon') as Icon; + const iconSet = el.querySelector('sp-icons-medium') as IconsMedium; + + await elementUpdated(iconSet); + await elementUpdated(icon); + + const svg = icon.shadowRoot + ? icon.shadowRoot.querySelector('[role="img"]') + : null; + expect(svg).to.not.be.null; + }); +}); diff --git a/1st-gen/packages/iconset/tsconfig.json b/1st-gen/packages/iconset/tsconfig.json new file mode 100644 index 00000000000..f8cdeba25b9 --- /dev/null +++ b/1st-gen/packages/iconset/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./", + "resolveJsonModule": true + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/illustrated-message/.npmrc b/1st-gen/packages/illustrated-message/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/illustrated-message/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/illustrated-message/CHANGELOG.md b/1st-gen/packages/illustrated-message/CHANGELOG.md new file mode 100644 index 00000000000..fc1799d0a7d --- /dev/null +++ b/1st-gen/packages/illustrated-message/CHANGELOG.md @@ -0,0 +1,592 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/styles@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`77bdef6`](https://github.com/adobe/spectrum-web-components/commit/77bdef68a40e0f6cd5476271b01b4c0f00531f4f), [`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/styles@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies [[`1126cf2`](https://github.com/adobe/spectrum-web-components/commit/1126cf22c0076c8728b86e9c0bf7f67fdd8fde07)]: + - @spectrum-web-components/styles@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5349](https://github.com/adobe/spectrum-web-components/pull/5349) [`a9727d2`](https://github.com/adobe/spectrum-web-components/commit/a9727d2975b01f440c09789c9e7e0122063b6f7e) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies [[`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd), [`a9727d2`](https://github.com/adobe/spectrum-web-components/commit/a9727d2975b01f440c09789c9e7e0122063b6f7e)]: + - @spectrum-web-components/styles@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies [[`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0), [`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5), [`fa4be70`](https://github.com/adobe/spectrum-web-components/commit/fa4be70e9ab9dbeff26867edd3bdeb3f41c423e3), [`daeb11f`](https://github.com/adobe/spectrum-web-components/commit/daeb11f18792cf650518099fd29857139b6380b4), [`6c58f50`](https://github.com/adobe/spectrum-web-components/commit/6c58f50f7b1f5489c11e0d3484e3f4a9d576f1c8), [`fa4be70`](https://github.com/adobe/spectrum-web-components/commit/fa4be70e9ab9dbeff26867edd3bdeb3f41c423e3)]: + - @spectrum-web-components/styles@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies [[`3cca7ea`](https://github.com/adobe/spectrum-web-components/commit/3cca7eacf127c3fd759953db38a2b5a561bfb8dc)]: + - @spectrum-web-components/styles@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/styles@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- **illustrated-message:** use accessibile tagnames ([e47b469](https://github.com/adobe/spectrum-web-components/commit/e47b469b5e1b9465b7bf0c4574f0ccb57acbb4f7)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **illustrated-message:** update spectrum css input ([25c0545](https://github.com/adobe/spectrum-web-components/commit/25c054583f944bf2fd0b10c4abdd70f65b4a5f20)) +- **illustrated-message:** use core tokens ([5f34473](https://github.com/adobe/spectrum-web-components/commit/5f34473343bbd40df090c8fe23f8df6dee860598)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **styles:** vend CSS literal versions of the typography system ([6406c96](https://github.com/adobe/spectrum-web-components/commit/6406c96377557a88ad7756147e6e5777f5d1f746)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.14...@spectrum-web-components/illustrated-message@0.10.0) (2023-04-24) + +### Features + +- **illustrated-message:** use core tokens ([5f34473](https://github.com/adobe/spectrum-web-components/commit/5f34473343bbd40df090c8fe23f8df6dee860598)) + +## [0.9.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.13...@spectrum-web-components/illustrated-message@0.9.14) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.12...@spectrum-web-components/illustrated-message@0.9.13) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.11...@spectrum-web-components/illustrated-message@0.9.12) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.10...@spectrum-web-components/illustrated-message@0.9.11) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.9...@spectrum-web-components/illustrated-message@0.9.10) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.8...@spectrum-web-components/illustrated-message@0.9.9) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.7...@spectrum-web-components/illustrated-message@0.9.8) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.6...@spectrum-web-components/illustrated-message@0.9.7) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.5...@spectrum-web-components/illustrated-message@0.9.6) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.4...@spectrum-web-components/illustrated-message@0.9.5) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.3...@spectrum-web-components/illustrated-message@0.9.4) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.2...@spectrum-web-components/illustrated-message@0.9.3) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.1...@spectrum-web-components/illustrated-message@0.9.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.9.0...@spectrum-web-components/illustrated-message@0.9.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.13...@spectrum-web-components/illustrated-message@0.9.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.8.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.12...@spectrum-web-components/illustrated-message@0.8.13) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.11...@spectrum-web-components/illustrated-message@0.8.12) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.10...@spectrum-web-components/illustrated-message@0.8.11) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.9...@spectrum-web-components/illustrated-message@0.8.10) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.8...@spectrum-web-components/illustrated-message@0.8.9) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.7...@spectrum-web-components/illustrated-message@0.8.8) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.6...@spectrum-web-components/illustrated-message@0.8.7) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.5...@spectrum-web-components/illustrated-message@0.8.6) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.4...@spectrum-web-components/illustrated-message@0.8.5) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.3...@spectrum-web-components/illustrated-message@0.8.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.2...@spectrum-web-components/illustrated-message@0.8.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.1...@spectrum-web-components/illustrated-message@0.8.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.8.0...@spectrum-web-components/illustrated-message@0.8.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.7.1...@spectrum-web-components/illustrated-message@0.8.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.7.0...@spectrum-web-components/illustrated-message@0.7.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.12...@spectrum-web-components/illustrated-message@0.7.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.6.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.11...@spectrum-web-components/illustrated-message@0.6.12) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.10...@spectrum-web-components/illustrated-message@0.6.11) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.9...@spectrum-web-components/illustrated-message@0.6.10) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.8...@spectrum-web-components/illustrated-message@0.6.9) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.7...@spectrum-web-components/illustrated-message@0.6.8) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.6...@spectrum-web-components/illustrated-message@0.6.7) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.5...@spectrum-web-components/illustrated-message@0.6.6) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.4...@spectrum-web-components/illustrated-message@0.6.5) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.3...@spectrum-web-components/illustrated-message@0.6.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.2...@spectrum-web-components/illustrated-message@0.6.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.1...@spectrum-web-components/illustrated-message@0.6.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.6.0...@spectrum-web-components/illustrated-message@0.6.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.5.1...@spectrum-web-components/illustrated-message@0.6.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.5.0...@spectrum-web-components/illustrated-message@0.5.1) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.3.3...@spectrum-web-components/illustrated-message@0.5.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **illustrated-message:** update spectrum css input ([25c0545](https://github.com/adobe/spectrum-web-components/commit/25c054583f944bf2fd0b10c4abdd70f65b4a5f20)) +- **styles:** vend CSS literal versions of the typography system ([6406c96](https://github.com/adobe/spectrum-web-components/commit/6406c96377557a88ad7756147e6e5777f5d1f746)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.3.3...@spectrum-web-components/illustrated-message@0.4.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **illustrated-message:** update spectrum css input ([25c0545](https://github.com/adobe/spectrum-web-components/commit/25c054583f944bf2fd0b10c4abdd70f65b4a5f20)) +- **styles:** vend CSS literal versions of the typography system ([6406c96](https://github.com/adobe/spectrum-web-components/commit/6406c96377557a88ad7756147e6e5777f5d1f746)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.3.2...@spectrum-web-components/illustrated-message@0.3.3) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.3.1...@spectrum-web-components/illustrated-message@0.3.2) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.3.0...@spectrum-web-components/illustrated-message@0.3.1) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.2.2...@spectrum-web-components/illustrated-message@0.3.0) (2020-08-31) + +### Features + +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.2.1...@spectrum-web-components/illustrated-message@0.2.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.2.0...@spectrum-web-components/illustrated-message@0.2.1) (2020-07-22) + +### Bug Fixes + +- **illustrated-message:** use accessibile tagnames ([e47b469](https://github.com/adobe/spectrum-web-components/commit/e47b469b5e1b9465b7bf0c4574f0ccb57acbb4f7)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.11...@spectrum-web-components/illustrated-message@0.2.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.1.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.10...@spectrum-web-components/illustrated-message@0.1.11) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.1.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.9...@spectrum-web-components/illustrated-message@0.1.10) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.1.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.8...@spectrum-web-components/illustrated-message@0.1.9) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.1.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.7...@spectrum-web-components/illustrated-message@0.1.8) (2020-03-11) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.1.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.6...@spectrum-web-components/illustrated-message@0.1.7) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.1.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.5...@spectrum-web-components/illustrated-message@0.1.6) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.4...@spectrum-web-components/illustrated-message@0.1.5) (2019-11-19) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/illustrated-message@0.1.3...@spectrum-web-components/illustrated-message@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/illustrated-message diff --git a/1st-gen/packages/illustrated-message/README.md b/1st-gen/packages/illustrated-message/README.md new file mode 100644 index 00000000000..295172350c3 --- /dev/null +++ b/1st-gen/packages/illustrated-message/README.md @@ -0,0 +1,171 @@ +## Overview + +An `` displays an outline illustration and a message, usually in an empty state or on an error page. It is also used inside a [DropZone](/components/dropzone). + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/illustrated-message?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/illustrated-message) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/illustrated-message?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/illustrated-message) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-qrvmdaws) + +```zsh +yarn add @spectrum-web-components/illustrated-message +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +``` + +When looking to leverage the `IllustratedMessage` base class as a type and/or for extension purposes, do so via: + +```js +import { IllustratedMessage } from '@spectrum-web-components/illustrated-message'; +``` + +### Anatomy + +An illustrated message consists of the following parts: + +- An **outline illustration** that supports the messaging. The illustrated message accepts an `` into its default slot. This SVG is displayed as an illustration above the heading and description. +- A required **heading** that appears in bold below the illustration, using a few words to convey what a user needs to do or know about. +- An optional **body area** that elaborates on the heading and offers more information about how to complete the interaction, including buttons or links to show the user what to do next. + +### Examples + + +Call to action with link + + +```html + + + + + + + + + + + + + + + + +

+ Select a file + from your computer. +

+
+``` + + +Call to action with buttons + + +```html + +
+

+ This page isn't available. Try checking the URL or visit a different + page. +

+ + Back + Refresh + +
+ + + +
+``` + +
+Informative + + +```html + + + + + +``` + + + + +### Accessibility + +The `` component provides a semantic structure for displaying illustrated content with proper heading hierarchy. However, there are several considerations to keep in mind for accessibility: + +- **Always include a clear, standalone heading.** All illustrated messages must include a heading or title. This heading communicates the result of why the UI is appearing in the way that it is. If included, the description elaborates on the heading and offers more information. +- **Ensure that text and image work together.** The illustration within an illustrated message adds value to the language that it’s paired with, and vice versa. An illustration’s meaning should be readily clear, contextual, and relevant to the overall message described in the text. +- **Provide actionable solutions.** Offer an actionable solution when possible by using [links](/components/link) or [buttons](/components/button). +- **Make error codes meaningful and contextual.** If an illustrated message is for an error state, use the heading to summarize the error. Only include an error code or other technical information if it’s useful and relevant for the user. Put the error code either at the beginning of the heading using a colon, or at the end of the message using parentheses; don’t hide it in the middle of the heading or bury it in the description. diff --git a/1st-gen/packages/illustrated-message/package.json b/1st-gen/packages/illustrated-message/package.json new file mode 100644 index 00000000000..ae6cbbcc1b7 --- /dev/null +++ b/1st-gen/packages/illustrated-message/package.json @@ -0,0 +1,76 @@ +{ + "name": "@spectrum-web-components/illustrated-message", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/illustrated-message" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/illustrated-message", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/IllustratedMessage.js": { + "development": "./src/IllustratedMessage.dev.js", + "default": "./src/IllustratedMessage.js" + }, + "./src/illustrated-message.css.js": "./src/illustrated-message.css.js", + "./src/illustratedmessage-overrides.css.js": "./src/illustratedmessage-overrides.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./sp-illustrated-message.js": { + "development": "./sp-illustrated-message.dev.js", + "default": "./sp-illustrated-message.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/styles": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/illustrated-message/sp-illustrated-message.ts b/1st-gen/packages/illustrated-message/sp-illustrated-message.ts new file mode 100644 index 00000000000..6096676f2c5 --- /dev/null +++ b/1st-gen/packages/illustrated-message/sp-illustrated-message.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { IllustratedMessage } from './src/IllustratedMessage.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-illustrated-message', IllustratedMessage); + +declare global { + interface HTMLElementTagNameMap { + 'sp-illustrated-message': IllustratedMessage; + } +} diff --git a/1st-gen/packages/illustrated-message/src/IllustratedMessage.ts b/1st-gen/packages/illustrated-message/src/IllustratedMessage.ts new file mode 100644 index 00000000000..edc08100f70 --- /dev/null +++ b/1st-gen/packages/illustrated-message/src/IllustratedMessage.ts @@ -0,0 +1,59 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; + +import messageStyles from './illustrated-message.css.js'; +import headingStyles from '@spectrum-web-components/styles/heading.js'; +import bodyStyles from '@spectrum-web-components/styles/body.js'; + +/** + * @element sp-illustrated-message + * + * @slot - The SVG that represents the illustration + * @slot heading - Headline for the message + * @slot description - Description text for the illustration + */ +export class IllustratedMessage extends SpectrumElement { + public static readonly is = 'sp-illustrated-message'; + + public static override get styles(): CSSResultArray { + return [headingStyles, bodyStyles, messageStyles]; + } + + @property() + public heading = ''; + + @property() + public description = ''; + + protected override render(): TemplateResult { + return html` +
+

+ ${this.heading} +

+
+ ${this.description} +
+ `; + } +} diff --git a/1st-gen/packages/illustrated-message/src/illustrated-message.css b/1st-gen/packages/illustrated-message/src/illustrated-message.css new file mode 100644 index 00000000000..a93ebc71220 --- /dev/null +++ b/1st-gen/packages/illustrated-message/src/illustrated-message.css @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-illustratedmessage.css"); +@import url("./illustratedmessage-overrides.css"); + +/* Ensure that SVGs with viewBox attributes size correctly. */ +::slotted(svg[viewBox]) { + width: 100%; +} diff --git a/1st-gen/packages/illustrated-message/src/illustratedmessage-overrides.css b/1st-gen/packages/illustrated-message/src/illustratedmessage-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/illustrated-message/src/illustratedmessage-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/illustrated-message/src/index.ts b/1st-gen/packages/illustrated-message/src/index.ts new file mode 100644 index 00000000000..28dac245319 --- /dev/null +++ b/1st-gen/packages/illustrated-message/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './IllustratedMessage.js'; diff --git a/1st-gen/packages/illustrated-message/src/spectrum-illustratedmessage.css b/1st-gen/packages/illustrated-message/src/spectrum-illustratedmessage.css new file mode 100644 index 00000000000..c03ef4adf1e --- /dev/null +++ b/1st-gen/packages/illustrated-message/src/spectrum-illustratedmessage.css @@ -0,0 +1,96 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-illustrated-message-illustration-color: CanvasText; + --highcontrast-illustrated-message-illustration-accent-color: Highlight; + } +} + +:host { + --spectrum-illustrated-message-description-max-inline-size: var(--spectrum-illustrated-message-maximum-width); + --spectrum-illustrated-message-heading-max-inline-size: var(--spectrum-illustrated-message-maximum-width); + --spectrum-illustrated-message-title-to-heading: var(--spectrum-spacing-400); + --spectrum-illustrated-message-heading-to-description: var(--spectrum-spacing-75); + --spectrum-illustrated-message-illustration-color: var(--spectrum-neutral-visual-color); + --spectrum-illustrated-message-illustration-accent-color: var(--spectrum-accent-visual-color); + --spectrum-illustrated-message-title-font-family: var(--spectrum-sans-font-family-stack); + --spectrum-illustrated-message-title-font-weight: var(--spectrum-heading-sans-serif-font-weight); + --spectrum-illustrated-message-title-font-style: var(--spectrum-heading-sans-serif-font-style); + --spectrum-illustrated-message-title-font-size: var(--spectrum-illustrated-message-title-size); + --spectrum-illustrated-message-title-line-height: var(--spectrum-heading-line-height); + --spectrum-illustrated-message-title-color: var(--spectrum-heading-color); + --spectrum-illustrated-message-description-font-family: var(--spectrum-sans-font-family-stack); + --spectrum-illustrated-message-description-font-weight: var(--spectrum-body-sans-serif-font-weight); + --spectrum-illustrated-message-description-font-style: var(--spectrum-body-sans-serif-font-style); + --spectrum-illustrated-message-description-font-size: var(--spectrum-illustrated-message-body-size); + --spectrum-illustrated-message-description-line-height: var(--spectrum-body-line-height); + --spectrum-illustrated-message-description-color: var(--spectrum-body-color); + block-size: 100%; + display: flex; + display: var(--mod-illustrated-message-display, flex); + text-align: center; + pointer-events: auto; + pointer-events: var(--mod-illustrated-message-pointer-events, auto); + max-inline-size: var(--mod-illustrated-message-content-maximum-width); + flex-direction: column; + justify-content: center; + align-items: center; +} + +:host:lang(ja), +:host:lang(ko), +:host:lang(zh) { + --spectrum-illustrated-message-title-font-size: var(--spectrum-illustrated-message-cjk-title-size); +} + +#illustration { + color: var(--highcontrast-illustrated-message-illustration-color, var(--mod-illustrated-message-illustration-color, var(--spectrum-illustrated-message-illustration-color))); + fill: currentColor; + stroke: currentColor; + margin-block-end: var(--mod-illustrated-message-title-to-heading, var(--spectrum-illustrated-message-title-to-heading)); +} + +.spectrum-IllustratedMessage-accent { + color: var(--highcontrast-illustrated-message-illustration-accent-color, var(--mod-illustrated-message-illustration-accent-color, var(--spectrum-illustrated-message-illustration-accent-color))); + fill: currentColor; + stroke: currentColor; +} + +#heading { + font-family: var(--mod-illustrated-message-title-font-family, var(--spectrum-illustrated-message-title-font-family)); + font-weight: var(--mod-illustrated-message-title-font-weight, var(--spectrum-illustrated-message-title-font-weight)); + font-style: var(--mod-illustrated-message-title-font-style, var(--spectrum-illustrated-message-title-font-style)); + font-size: var(--mod-illustrated-message-title-font-size, var(--spectrum-illustrated-message-title-font-size)); + line-height: var(--mod-illustrated-message-title-line-height, var(--spectrum-illustrated-message-title-line-height)); + color: var(--mod-illustrated-message-title-color, var(--spectrum-illustrated-message-title-color)); + max-inline-size: var(--mod-illustrated-message-heading-max-inline-size, var(--spectrum-illustrated-message-heading-max-inline-size)); + margin-block-start: 0; + margin-block-end: var(--mod-illustrated-message-heading-to-body, 0); +} + +#description { + position: var(--mod-illustrated-message-description-position); + z-index: var(--mod-illustrated-message-description-z-index); + pointer-events: auto; + pointer-events: var(--mod-illustrated-message-description-pointer-events, auto); + font-family: var(--mod-illustrated-message-description-font-family, var(--spectrum-illustrated-message-description-font-family)); + font-weight: var(--mod-illustrated-message-description-font-weight, var(--spectrum-illustrated-message-description-font-weight)); + font-style: var(--mod-illustrated-message-description-font-style, var(--spectrum-illustrated-message-description-font-style)); + font-size: var(--mod-illustrated-message-description-font-size, var(--spectrum-illustrated-message-description-font-size)); + line-height: var(--mod-illustrated-message-description-line-height, var(--spectrum-illustrated-message-description-line-height)); + color: var(--mod-illustrated-message-description-color, var(--spectrum-illustrated-message-description-color)); + max-inline-size: var(--mod-illustrated-message-description-max-inline-size, var(--spectrum-illustrated-message-description-max-inline-size)); + margin-block-start: var(--mod-illustrated-message-heading-to-description, var(--spectrum-illustrated-message-heading-to-description)); + margin-block-end: 0; +} diff --git a/1st-gen/packages/illustrated-message/stories/illustrated-message.stories.ts b/1st-gen/packages/illustrated-message/stories/illustrated-message.stories.ts new file mode 100644 index 00000000000..1b8ccd0e62a --- /dev/null +++ b/1st-gen/packages/illustrated-message/stories/illustrated-message.stories.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +import { illustration } from '../../dropzone/test/test-svg.js'; + +export default { + component: 'sp-illustrated-message', + title: 'IllustratedMessage', +}; + +export const Default = (): TemplateResult => { + return html` + + ${illustration} + + `; +}; diff --git a/1st-gen/packages/illustrated-message/test/benchmark/test-basic.ts b/1st-gen/packages/illustrated-message/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..bdcf190a0ba --- /dev/null +++ b/1st-gen/packages/illustrated-message/test/benchmark/test-basic.ts @@ -0,0 +1,34 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + + + +`); diff --git a/1st-gen/packages/illustrated-message/test/illustrated-message-memory.test.ts b/1st-gen/packages/illustrated-message/test/illustrated-message-memory.test.ts new file mode 100644 index 00000000000..7517fe49540 --- /dev/null +++ b/1st-gen/packages/illustrated-message/test/illustrated-message-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/illustrated-message/test/illustrated-message.test.ts b/1st-gen/packages/illustrated-message/test/illustrated-message.test.ts new file mode 100644 index 00000000000..02cd7042f18 --- /dev/null +++ b/1st-gen/packages/illustrated-message/test/illustrated-message.test.ts @@ -0,0 +1,42 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js'; +import { IllustratedMessage } from '../'; +import { expect, fixture, html } from '@open-wc/testing'; + +describe('Illustrated Message', () => { + it('loads', async () => { + const el = await fixture(html` + + + + + + `); + expect(el).to.not.equal(undefined); + if (!el.shadowRoot) throw new Error('No shadowRoot'); + const slot = el.shadowRoot.querySelector('slot') as HTMLSlotElement; + expect(slot).to.not.equal(undefined); + return true; + }); +}); diff --git a/1st-gen/packages/illustrated-message/tsconfig.json b/1st-gen/packages/illustrated-message/tsconfig.json new file mode 100644 index 00000000000..a472e69fc8e --- /dev/null +++ b/1st-gen/packages/illustrated-message/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }, { "path": "../../tools/styles" }] +} diff --git a/1st-gen/packages/infield-button/.npmignore b/1st-gen/packages/infield-button/.npmignore new file mode 100644 index 00000000000..c50cbe188c0 --- /dev/null +++ b/1st-gen/packages/infield-button/.npmignore @@ -0,0 +1,2 @@ +stories +test \ No newline at end of file diff --git a/1st-gen/packages/infield-button/.npmrc b/1st-gen/packages/infield-button/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/infield-button/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/infield-button/CHANGELOG.md b/1st-gen/packages/infield-button/CHANGELOG.md new file mode 100644 index 00000000000..a9ec5c2ce40 --- /dev/null +++ b/1st-gen/packages/infield-button/CHANGELOG.md @@ -0,0 +1,302 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5157](https://github.com/adobe/spectrum-web-components/pull/5157) [`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - # Release Note + + ## Infield Button + + ### 6.1.2 + - [#3615](https://github.com/adobe/spectrum-css/pull/3615) [`f09c84a`](https://github.com/adobe/spectrum-css/commit/f09c84ae9922d67b6fe237d693afee0fab53fa67) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - ### Infield button fast follows + - Updated infield button disabled border color to use `-spectrum-gray-300` for spectrum-two theme and `-spectrum-gray-200` for other themes. + + ### 6.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 6.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/icon@9.1.0 + - @spectrum-css/tokens@16.0.1 + + ## Number Field + + Bump @spectrum-css/stepper to 7.1.3 + + ### 7.1.3 + - [#3621](https://github.com/adobe/spectrum-css/pull/3621) [`3aec28a`](https://github.com/adobe/spectrum-css/commit/3aec28aac60bdf32a585fa8ff38559d80b57ff86) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - Updates `-spectrum-stepper-buttons-border-color-keyboard-focus` from `gray-900` to `gray-800` to match the rest of the border color on keyboardFocus. + + ### 7.1.2 + + 📝 [#3594](https://github.com/adobe/spectrum-css/pull/3594) [`6200a63`](https://github.com/adobe/spectrum-css/commit/6200a63f2c7dc1d2b0481c33b17c86427726c0bd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updates Stepper's key-focus border color (`-spectrum-stepper-border-color-keyboard-focus`) to `-spectrum-gray-800`. + + ### 7.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 7.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/actionbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/infieldbutton@7.0.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Textfield + + ### 8.1.1 + + 📝 [#3575](https://github.com/adobe/spectrum-css/pull/3575) [`2e17d10`](https://github.com/adobe/spectrum-css/commit/2e17d109ebec3c2745c32a15840af5c636c8dc5d) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updated border color on keyboard focus state for textfield in spectrum-two theme. + + ### 8.1.0 + + 📝 [#3539](https://github.com/adobe/spectrum-css/pull/3539) [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! + - Updates invalid icon spacing to be vertically centered for S2. + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + - Dependency alignment across the project. + + Set component peerDependencies as optional to reduce console warnings on downstream projects. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/helptext@8.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Search + + ### 8.1.2 + - [#3658](https://github.com/adobe/spectrum-css/pull/3658) [`e9fde67`](https://github.com/adobe/spectrum-css/commit/e9fde67bf341798a6ab34f227b2e7a417d1e5da7) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! - Change S2 theme border color to gray-800 on keyfocus per design request in order to align with text field. + + ### 8.1.1 + + 📝 [#3593](https://github.com/adobe/spectrum-css/pull/3593) [`d829abb`](https://github.com/adobe/spectrum-css/commit/d829abb44f1eaa1874090e52caee553d776684e7) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + + Updated `--spectrum-search-background-color-disabled` to `--spectrum-gray-25` and `--spectrum-search-border-color-disabled` to `--spectrum-gray-300` for the S2 foundations contexts. + + Also defines disabled quiet border and background colors (`--system-search-quiet-background-color-disabled` and `--system-search-quiet-border-color-disabled`) in order to maintain disabled quiet styling. + + ### 8.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/clearbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + +- Updated dependencies [[`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e)]: + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies [[`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5)]: + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/infield-button + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **infield-button:** add infield-button package ([057b885](https://github.com/adobe/spectrum-web-components/commit/057b885276f3d5dcbe32bab5ab36a2bb82334bc3)) diff --git a/1st-gen/packages/infield-button/README.md b/1st-gen/packages/infield-button/README.md new file mode 100644 index 00000000000..85de45d11de --- /dev/null +++ b/1st-gen/packages/infield-button/README.md @@ -0,0 +1,122 @@ +## Description + +When composing complex form fields, an `` can visually associate button functionality with other form fields to delivery enhanced capabilities to your visitors. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/infield-button?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/infield-button) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/infield-button?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/infield-button) + +``` +yarn add @spectrum-web-components/infield-button +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +``` + +When looking to leverage the `InfieldButton` base class as a type and/or for extension purposes, do so via: + +``` +import { InfieldButton } from '@spectrum-web-components/infield-button'; +``` + +## Sizes + + +Small + + +```html + + + +``` + + +Medium + + +```html + + + +``` + + +Large + + +```html + + + +``` + + +Extra Large + + +```html + + + +``` + + + + +## Inline buttons + +Use the `inline` attribute to describe whether the `` should be visually at the `start` or `end` of the field is associated to: + +### inline="start" + +```html + + + +``` + +### inline="end" + +```html + + + +``` + +## Stacked buttons + +The `block` attribute can be used to create a vertial stack of buttons. You can place buttons visually on the stack with the `start` or `end` values: + +```html + + + + + + +``` + +## Disabled + +An `` with the `disabled` attribute will become non-interactive and dimmed: + +```html + + + +``` + +## Quiet + +An `` with the `quiet` attribute will feature a diminished visual presence: + +```html + + + +``` diff --git a/1st-gen/packages/infield-button/package.json b/1st-gen/packages/infield-button/package.json new file mode 100644 index 00000000000..de83b85ebc2 --- /dev/null +++ b/1st-gen/packages/infield-button/package.json @@ -0,0 +1,77 @@ +{ + "name": "@spectrum-web-components/infield-button", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "Web component implementation of a Spectrum design InfieldButton", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/infield-button" + }, + "author": "Adobe", + "homepage": "https://adobe.github.io/spectrum-web-components/components/infield-button", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/InfieldButton.js": { + "development": "./src/InfieldButton.dev.js", + "default": "./src/InfieldButton.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/infield-button-overrides.css.js": "./src/infield-button-overrides.css.js", + "./src/infield-button.css.js": "./src/infield-button.css.js", + "./sp-infield-button.js": { + "development": "./sp-infield-button.dev.js", + "default": "./sp-infield-button.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/button": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/infield-button/sp-infield-button.ts b/1st-gen/packages/infield-button/sp-infield-button.ts new file mode 100644 index 00000000000..8e4530af24c --- /dev/null +++ b/1st-gen/packages/infield-button/sp-infield-button.ts @@ -0,0 +1,20 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { InfieldButton } from './src/InfieldButton.js'; + +customElements.define('sp-infield-button', InfieldButton); + +declare global { + interface HTMLElementTagNameMap { + 'sp-infield-button': InfieldButton; + } +} diff --git a/1st-gen/packages/infield-button/src/InfieldButton.ts b/1st-gen/packages/infield-button/src/InfieldButton.ts new file mode 100644 index 00000000000..20fd85f3112 --- /dev/null +++ b/1st-gen/packages/infield-button/src/InfieldButton.ts @@ -0,0 +1,59 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + CSSResultArray, + html, + SizedMixin, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { ButtonBase } from '@spectrum-web-components/button/src/ButtonBase.js'; + +import styles from './infield-button.css.js'; + +/** + * @element sp-infield-button + */ +export class InfieldButton extends SizedMixin(ButtonBase, { + noDefaultSize: true, + validSizes: ['s', 'm', 'l', 'xl'], +}) { + public static override get styles(): CSSResultArray { + return [...super.styles, styles]; + } + + /** + * Whether to style the button as if it is at the start or end of a vertical stack + * @type {'start' | 'end'} + */ + @property() + block?: 'start' | 'end'; + + /** + * Whether to style the button as if it is at the start or end of a horizontal group + * @type {'start' | 'end'} + */ + @property() + inline?: 'start' | 'end'; + + @property({ type: Boolean, reflect: true }) + quiet = false; + + protected override get buttonContent(): TemplateResult[] { + const buttonContent = html` +
+ +
+ `; + return [buttonContent]; + } +} diff --git a/1st-gen/packages/infield-button/src/index.ts b/1st-gen/packages/infield-button/src/index.ts new file mode 100644 index 00000000000..b8ec9be6e98 --- /dev/null +++ b/1st-gen/packages/infield-button/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './InfieldButton.js'; diff --git a/1st-gen/packages/infield-button/src/infield-button-overrides.css b/1st-gen/packages/infield-button/src/infield-button-overrides.css new file mode 100644 index 00000000000..195f9826dc1 --- /dev/null +++ b/1st-gen/packages/infield-button/src/infield-button-overrides.css @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-infield-button-border-width: var(--system-infield-button-border-width); + --spectrum-infield-button-border-color: var(--system-infield-button-border-color); + --spectrum-infield-button-border-radius: var(--system-infield-button-border-radius); + --spectrum-infield-button-border-radius-reset: var(--system-infield-button-border-radius-reset); + --spectrum-infield-button-stacked-top-border-radius-start-start: var(--system-infield-button-stacked-top-border-radius-start-start); + --spectrum-infield-button-stacked-bottom-border-radius-end-start: var(--system-infield-button-stacked-bottom-border-radius-end-start); + --spectrum-infield-button-background-color: var(--system-infield-button-background-color); + --spectrum-infield-button-background-color-hover: var(--system-infield-button-background-color-hover); + --spectrum-infield-button-background-color-down: var(--system-infield-button-background-color-down); + --spectrum-infield-button-background-color-key-focus: var(--system-infield-button-background-color-key-focus); +} + +:host([disabled]) { + --spectrum-infield-button-border-color: var(--system-infield-button-disabled-border-color); +} diff --git a/1st-gen/packages/infield-button/src/infield-button.css b/1st-gen/packages/infield-button/src/infield-button.css new file mode 100644 index 00000000000..346c844079d --- /dev/null +++ b/1st-gen/packages/infield-button/src/infield-button.css @@ -0,0 +1,23 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-infield-button.css"); +@import url("./infield-button-overrides.css"); + +:host { + box-sizing: border-box; + user-select: none; +} + +::slotted(*) { + --spectrum-icon-size: inherit; +} diff --git a/1st-gen/packages/infield-button/src/spectrum-infield-button.css b/1st-gen/packages/infield-button/src/spectrum-infield-button.css new file mode 100644 index 00000000000..a3570226fbf --- /dev/null +++ b/1st-gen/packages/infield-button/src/spectrum-infield-button.css @@ -0,0 +1,230 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-infield-button-height: var(--spectrum-component-height-100); + --spectrum-infield-button-width: var(--spectrum-component-height-100); + --spectrum-infield-button-stacked-border-radius-reset: var(--spectrum-in-field-button-fill-stacked-inner-border-rounding); + --spectrum-infield-button-edge-to-fill: var(--spectrum-in-field-button-edge-to-fill); + --spectrum-infield-button-inner-edge-to-fill: var(--spectrum-in-field-button-stacked-inner-edge-to-fill); + --spectrum-infield-button-fill-padding: 0px; + --spectrum-infield-button-stacked-fill-padding-inline: var(--spectrum-in-field-button-edge-to-disclosure-icon-stacked-medium); + --spectrum-infield-button-stacked-fill-padding-outer: var(--spectrum-in-field-button-outer-edge-to-disclosure-icon-stacked-medium); + --spectrum-infield-button-stacked-fill-padding-inner: var(--spectrum-in-field-button-inner-edge-to-disclosure-icon-stacked-medium); + --spectrum-infield-button-icon-color: var(--spectrum-neutral-content-color-default); + --spectrum-infield-button-icon-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-infield-button-icon-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-infield-button-icon-color-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-infield-button-fill-justify-content: center; +} + +:host([disabled]) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-disabled, var(--spectrum-disabled-background-color)); + --mod-infield-button-background-color-hover: var(--mod-infield-button-background-color-hover-disabled, var(--spectrum-disabled-background-color)); + --mod-infield-button-background-color-down: var(--mod-infield-button-background-color-down-disabled, var(--spectrum-disabled-background-color)); + --mod-infield-button-border-color: var(--mod-infield-button-border-color-disabled, var(--spectrum-infield-button-border-color)); + --mod-infield-button-icon-color: var(--mod-infield-button-icon-color-disabled, var(--spectrum-disabled-content-color)); + --mod-infield-button-icon-color-hover: var(--mod-infield-button-icon-color-hover-disabled, var(--spectrum-disabled-content-color)); + --mod-infield-button-icon-color-down: var(--mod-infield-button-icon-color-down-disabled, var(--spectrum-disabled-content-color)); + --mod-infield-button-icon-color-key-focus: var(--mod-infield-button-icon-color-key-focus-disabled, var(--spectrum-disabled-content-color)); +} + +:host([size="s"]) { + --spectrum-infield-button-height: var(--spectrum-component-height-75); + --spectrum-infield-button-width: var(--spectrum-component-height-75); + --spectrum-infield-button-stacked-fill-padding-inline: var(--spectrum-in-field-button-edge-to-disclosure-icon-stacked-small); + --spectrum-infield-button-stacked-fill-padding-outer: var(--spectrum-in-field-button-outer-edge-to-disclosure-icon-stacked-small); + --spectrum-infield-button-stacked-fill-padding-inner: var(--spectrum-in-field-button-inner-edge-to-disclosure-icon-stacked-small); +} + +:host([size="l"]) { + --spectrum-infield-button-height: var(--spectrum-component-height-200); + --spectrum-infield-button-width: var(--spectrum-component-height-200); + --spectrum-infield-button-stacked-fill-padding-inline: var(--spectrum-in-field-button-edge-to-disclosure-icon-stacked-large); + --spectrum-infield-button-stacked-fill-padding-outer: var(--spectrum-in-field-button-outer-edge-to-disclosure-icon-stacked-large); + --spectrum-infield-button-stacked-fill-padding-inner: var(--spectrum-in-field-button-inner-edge-to-disclosure-icon-stacked-large); +} + +:host([size="xl"]) { + --spectrum-infield-button-height: var(--spectrum-component-height-300); + --spectrum-infield-button-width: var(--spectrum-component-height-300); + --spectrum-infield-button-stacked-fill-padding-inline: var(--spectrum-in-field-button-edge-to-disclosure-icon-stacked-extra-large); + --spectrum-infield-button-stacked-fill-padding-outer: var(--spectrum-in-field-button-outer-edge-to-disclosure-icon-stacked-extra-large); + --spectrum-infield-button-stacked-fill-padding-inner: var(--spectrum-in-field-button-inner-edge-to-disclosure-icon-stacked-extra-large); +} + +:host([block="end"]), +:host([block="start"]) { + --mod-infield-button-width: var(--mod-infield-button-width-stacked, var(--spectrum-in-field-button-width-stacked-medium)); +} + +:host([block="end"][size="s"]), +:host([block="start"][size="s"]) { + --mod-infield-button-width: var(--mod-infield-button-width-stacked, var(--spectrum-in-field-button-width-stacked-small)); +} + +:host([block="end"][size="l"]), +:host([block="start"][size="l"]) { + --mod-infield-button-width: var(--mod-infield-button-width-stacked, var(--spectrum-in-field-button-width-stacked-large)); +} + +:host([block="end"][size="xl"]), +:host([block="start"][size="xl"]) { + --mod-infield-button-width: var(--mod-infield-button-width-stacked, var(--spectrum-in-field-button-width-stacked-extra-large)); +} + +:host([quiet]) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-quiet, transparent); + --mod-infield-button-background-color-hover: var(--mod-infield-button-background-color-hover-quiet, transparent); + --mod-infield-button-background-color-down: var(--mod-infield-button-background-color-down-quiet, transparent); + --mod-infield-button-background-color-key-focus: var(--mod-infield-button-background-color-key-focus-quiet, transparent); + --mod-infield-border-color: var(--mod-infield-border-color-quiet, transparent); + --mod-infield-button-border-width: var(--mod-infield-button-border-width-quiet, 0); +} + +:host([quiet][disabled]) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-quiet-disabled, transparent); + --mod-infield-button-border-color: var(--mod-infield-button-border-color-quiet-disabled, transparent); +} + +@media (hover: hover) { + :host(:hover) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-hover, var(--spectrum-infield-button-background-color-hover)); + --mod-infield-button-icon-color: var(--mod-infield-button-icon-color-hover, var(--spectrum-infield-button-icon-color-hover)); + } +} + +:host(:is(:active, [active])) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-down, var(--spectrum-infield-button-background-color-down)); + --mod-infield-button-icon-color: var(--mod-infield-button-icon-color-down, var(--spectrum-infield-button-icon-color-down)); +} + +:host(:focus-visible) { + --mod-infield-button-background-color: var(--mod-infield-button-background-color-key-focus, var(--spectrum-infield-button-background-color-key-focus)); + --mod-infield-button-icon-color: var(--mod-infield-button-icon-color-key-focus, var(--spectrum-infield-button-icon-color-key-focus)); +} + +@media (forced-colors: active) { + :host { + --highcontrast-infield-button-border-color: ButtonText; + --highcontrast-infield-button-border-color-active: Highlight; + } + + :host([disabled]) { + --highcontrast-infield-button-border-color: inherit; + } + + :host(:is(:active, [active])):not(:disabled), + :host:not(:disabled):focus-visible { + --highcontrast-infield-button-border-color: var(--highcontrast-infield-button-border-color-active); + } + + @media (hover: hover) { + :host:not(:disabled):hover { + --highcontrast-infield-button-border-color: var(--highcontrast-infield-button-border-color-active); + } + } +} + +:host { + background-color: initial; + cursor: pointer; + block-size: var(--mod-infield-button-height, var(--spectrum-infield-button-height)); + inline-size: var(--mod-infield-button-width, var(--spectrum-infield-button-width)); + padding: var(--mod-infield-button-edge-to-fill, var(--spectrum-infield-button-edge-to-fill)); + border-style: none; + justify-content: center; + align-items: center; + display: flex; +} + +:host([disabled]) { + cursor: auto; +} + +:host(:focus-visible) { + outline: none; +} + +:host([block="end"]), +:host([block="start"]) { + block-size: calc(var(--mod-infield-button-height, var(--spectrum-infield-button-height)) / 2); +} + +:host([block="start"]) { + padding-block-end: var(--mod-infield-button-inner-edge-to-fill, var(--spectrum-infield-button-inner-edge-to-fill)); +} + +:host([block="end"]) { + padding-block-start: var(--mod-infield-button-inner-edge-to-fill, var(--spectrum-infield-button-inner-edge-to-fill)); +} + +.fill { + block-size: 100%; + inline-size: 100%; + background-color: var(--mod-infield-button-background-color, var(--spectrum-infield-button-background-color)); + border-width: var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width)); + border-style: solid; + border-color: var(--highcontrast-infield-button-border-color, var(--mod-infield-button-border-color, var(--spectrum-infield-button-border-color))); + padding: var(--mod-infield-button-fill-padding, var(--spectrum-infield-button-fill-padding)); + align-items: center; + justify-content: var(--mod-infield-button-fill-justify-content, var(--spectrum-infield-button-fill-justify-content)); + transition: border-color var(--spectrum-animation-duration-100) ease-in-out; + border-start-start-radius: var(--mod-infield-button-border-radius, var(--spectrum-infield-button-border-radius)); + border-start-end-radius: var(--mod-infield-button-border-radius, var(--spectrum-infield-button-border-radius)); + border-end-end-radius: var(--mod-infield-button-border-radius, var(--spectrum-infield-button-border-radius)); + border-end-start-radius: var(--mod-infield-button-border-radius, var(--spectrum-infield-button-border-radius)); + display: flex; +} + +:host([inline="end"]) .fill { + border-start-start-radius: var(--mod-infield-button-border-radius-reset, var(--spectrum-infield-button-border-radius-reset)); + border-end-start-radius: var(--mod-infield-button-border-radius-reset, var(--spectrum-infield-button-border-radius-reset)); +} + +:host([inline="start"]) .fill { + border-start-end-radius: var(--mod-infield-button-border-radius-reset, var(--spectrum-infield-button-border-radius-reset)); + border-end-end-radius: var(--mod-infield-button-border-radius-reset, var(--spectrum-infield-button-border-radius-reset)); +} + +:host([block="end"]) .fill, +:host([block="start"]) .fill { + box-sizing: border-box; + padding-inline-start: calc(var(--mod-infield-button-stacked-fill-padding-inline, var(--spectrum-infield-button-stacked-fill-padding-inline)) - var(--mod-infield-button-edge-to-fill, var(--spectrum-infield-button-edge-to-fill)) - var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); + padding-inline-end: calc(var(--mod-infield-button-stacked-fill-padding-inline, var(--spectrum-infield-button-stacked-fill-padding-inline)) - var(--mod-infield-button-edge-to-fill, var(--spectrum-infield-button-edge-to-fill)) - var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); +} + +:host([block="start"]) .fill { + border-block-end: none; + border-start-start-radius: var(--mod-infield-button-stacked-top-border-radius-start-start, var(--spectrum-infield-button-stacked-top-border-radius-start-start)); + border-end-end-radius: var(--mod-infield-button-stacked-border-radius-reset, var(--spectrum-infield-button-stacked-border-radius-reset)); + border-end-start-radius: var(--mod-infield-button-stacked-border-radius-reset, var(--spectrum-infield-button-stacked-border-radius-reset)); + padding-block-start: calc(var(--mod-infield-button-stacked-fill-padding-outer, var(--spectrum-infield-button-stacked-fill-padding-outer)) - var(--mod-infield-button-edge-to-fill, var(--spectrum-infield-button-edge-to-fill)) - var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); + padding-block-end: calc(var(--mod-infield-button-stacked-fill-padding-inner, var(--spectrum-infield-button-stacked-fill-padding-inner)) - var(--mod-infield-button-inner-edge-to-fill, var(--spectrum-infield-button-inner-edge-to-fill))); +} + +:host([block="end"]) .fill { + border-block-end-width: var(--mod-infield-button-stacked-bottom-border-block-end-width, var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); + border-start-start-radius: var(--mod-infield-button-stacked-border-radius-reset, var(--spectrum-infield-button-stacked-border-radius-reset)); + border-start-end-radius: var(--mod-infield-button-stacked-border-radius-reset, var(--spectrum-infield-button-stacked-border-radius-reset)); + border-end-end-radius: var(--mod-infield-button-stacked-bottom-border-radius-end-end, var(--mod-infield-button-border-radius, var(--spectrum-infield-button-border-radius))); + border-end-start-radius: var(--mod-infield-button-stacked-bottom-border-radius-end-start, var(--spectrum-infield-button-stacked-bottom-border-radius-end-start)); + padding-block-start: calc(var(--mod-infield-button-stacked-fill-padding-inner, var(--spectrum-infield-button-stacked-fill-padding-inner)) - var(--mod-infield-button-edge-to-fill, var(--spectrum-infield-button-edge-to-fill)) - var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); + padding-block-end: calc(var(--mod-infield-button-stacked-fill-padding-outer, var(--spectrum-infield-button-stacked-fill-padding-outer)) - var(--mod-infield-button-inner-edge-to-fill, var(--spectrum-infield-button-inner-edge-to-fill)) - var(--mod-infield-button-border-width, var(--spectrum-infield-button-border-width))); +} + +::slotted(*) { + display: initial; + color: var(--mod-infield-button-icon-color, var(--spectrum-infield-button-icon-color)); + flex-shrink: 0; + margin: 0 !important; +} diff --git a/1st-gen/packages/infield-button/stories/index.ts b/1st-gen/packages/infield-button/stories/index.ts new file mode 100644 index 00000000000..127b8d5ef12 --- /dev/null +++ b/1st-gen/packages/infield-button/stories/index.ts @@ -0,0 +1,138 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron75.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js'; + +document.adoptedStyleSheets = [ + ...document.adoptedStyleSheets, + chevronStyles.styleSheet as CSSStyleSheet, +]; + +export type StoryArgs = { + block?: 'start' | 'end'; + content?: () => TemplateResult; + disabled?: boolean; + inline?: 'start' | 'end'; + label?: string; + size?: 's' | 'm' | 'l' | 'xl'; + quiet?: boolean; +}; + +export const args = { + block: undefined, + disabled: false, + inline: undefined, + label: 'Add', + size: undefined, + quiet: false, +} as StoryArgs; + +export const argTypes = { + block: { + name: 'block', + type: { name: 'text', required: false }, + description: 'Where to place the button along the block axis.', + table: { + type: { summary: '"start" | "end"' }, + defaultValue: { summary: '' }, + }, + control: 'select', + options: ['none', 'start', 'end'], + }, + disabled: { + name: 'disabled', + type: { name: 'boolean', required: false }, + description: 'Whether the button is disabled or not.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + inline: { + name: 'inline', + type: { name: 'text', required: false }, + description: 'Where to place the button along the inline axis.', + table: { + type: { summary: '"start" | "end"' }, + defaultValue: { summary: '' }, + }, + control: 'select', + options: ['none', 'start', 'end'], + }, + size: { + name: 'size', + type: { name: 'text', required: false }, + description: 'The t-shit size of the button.', + table: { + type: { summary: '"s" | "m" | "l" | "xl"' }, + defaultValue: { summary: '' }, + }, + control: 'select', + options: ['s', 'm', 'l', 'xl'], + }, + quiet: { + name: 'quiet', + type: { name: 'boolean', required: false }, + description: 'Whether the button is quiet or not.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, +}; + +export const Template = ({ + block, + content, + disabled, + inline, + label, + size, + quiet, +}: StoryArgs): TemplateResult => { + return html` + + ${content + ? content() + : html` + + `} + + `; +}; + +export const chevronUp = (): TemplateResult => html` + +`; +export const chevronDown = (): TemplateResult => html` + +`; diff --git a/1st-gen/packages/infield-button/stories/infield-button-sizes.stories.ts b/1st-gen/packages/infield-button/stories/infield-button-sizes.stories.ts new file mode 100644 index 00000000000..289f8fe7cc5 --- /dev/null +++ b/1st-gen/packages/infield-button/stories/infield-button-sizes.stories.ts @@ -0,0 +1,102 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import { + args, + argTypes, + chevronDown, + chevronUp, + StoryArgs, + Template, +} from './index.js'; + +export default { + title: 'Infield Button/Sizes', + component: 'sp-infield-button', + argTypes, + args, +}; + +export const s = (args: StoryArgs): TemplateResult => Template(args); +s.args = { + size: 's', +}; +export const m = (args: StoryArgs): TemplateResult => Template(args); +m.args = { + size: 'm', +}; +export const l = (args: StoryArgs): TemplateResult => Template(args); +l.args = { + size: 'l', +}; +export const XL = (args: StoryArgs): TemplateResult => Template(args); +XL.args = { + size: 'xl', +}; + +export const stackedS = (): TemplateResult => html` + ${Template({ + block: 'start', + content: chevronUp, + size: 's', + label: 'Increase', + })} + ${Template({ + block: 'end', + content: chevronDown, + size: 's', + label: 'Decrease', + })} +`; +export const stackedM = (): TemplateResult => html` + ${Template({ + block: 'start', + content: chevronUp, + size: 'm', + label: 'Increase', + })} + ${Template({ + block: 'end', + content: chevronDown, + size: 'm', + label: 'Decrease', + })} +`; +export const stackedL = (): TemplateResult => html` + ${Template({ + block: 'start', + content: chevronUp, + size: 'l', + label: 'Increase', + })} + ${Template({ + block: 'end', + content: chevronDown, + size: 'l', + label: 'Decrease', + })} +`; +export const stackedXL = (): TemplateResult => html` + ${Template({ + block: 'start', + content: chevronUp, + size: 'xl', + label: 'Increase', + })} + ${Template({ + block: 'end', + content: chevronDown, + size: 'xl', + label: 'Decrease', + })} +`; diff --git a/1st-gen/packages/infield-button/stories/infield-button.stories.ts b/1st-gen/packages/infield-button/stories/infield-button.stories.ts new file mode 100644 index 00000000000..d30419044ea --- /dev/null +++ b/1st-gen/packages/infield-button/stories/infield-button.stories.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import { + args, + argTypes, + chevronDown, + chevronUp, + StoryArgs, + Template, +} from './index.js'; + +export default { + title: 'Infield Button', + component: 'sp-infield-button', + argTypes, + args, +}; + +export const Default = (args: StoryArgs): TemplateResult => Template(args); +export const disabled = (args: StoryArgs): TemplateResult => Template(args); +disabled.args = { + disabled: true, +}; + +export const inlineStart = (args: StoryArgs): TemplateResult => Template(args); +inlineStart.args = { + inline: 'start', +}; + +export const inlineEnd = (args: StoryArgs): TemplateResult => Template(args); +inlineEnd.args = { + inline: 'end', +}; + +export const stacked = (): TemplateResult => html` + ${Template({ + block: 'start', + content: chevronUp, + label: 'Increase', + })} + ${Template({ + block: 'end', + content: chevronDown, + label: 'Decrease', + })} +`; + +export const quiet = (args: StoryArgs): TemplateResult => Template(args); +quiet.args = { + quiet: true, +}; diff --git a/1st-gen/packages/infield-button/test/benchmark/basic-test.ts b/1st-gen/packages/infield-button/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..155d62a5a17 --- /dev/null +++ b/1st-gen/packages/infield-button/test/benchmark/basic-test.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/infield-button/test/infield-button-memory.test.ts b/1st-gen/packages/infield-button/test/infield-button-memory.test.ts new file mode 100644 index 00000000000..20c09319ce1 --- /dev/null +++ b/1st-gen/packages/infield-button/test/infield-button-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/infield-button/test/infield-button.test.ts b/1st-gen/packages/infield-button/test/infield-button.test.ts new file mode 100644 index 00000000000..3af0f9bbe9a --- /dev/null +++ b/1st-gen/packages/infield-button/test/infield-button.test.ts @@ -0,0 +1,38 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { elementUpdated, expect, fixture } from '@open-wc/testing'; + +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +import { InfieldButton } from '@spectrum-web-components/infield-button'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; +import { Default, stacked } from '../stories/infield-button.stories.js'; +import { args } from '../stories/index.js'; + +describe('InfieldButton', () => { + testForLitDevWarnings( + async () => await fixture(Default(args)) + ); + it('loads default infield-button accessibly', async () => { + const el = await fixture(Default(args)); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads stacked infield-button accessibly', async () => { + const el = await fixture(stacked()); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); +}); diff --git a/1st-gen/packages/infield-button/tsconfig.json b/1st-gen/packages/infield-button/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/infield-button/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/link/.npmrc b/1st-gen/packages/link/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/link/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/link/CHANGELOG.md b/1st-gen/packages/link/CHANGELOG.md new file mode 100644 index 00000000000..c4ff73416a7 --- /dev/null +++ b/1st-gen/packages/link/CHANGELOG.md @@ -0,0 +1,685 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- [#5695](https://github.com/adobe/spectrum-web-components/pull/5695) [`aa411d0`](https://github.com/adobe/spectrum-web-components/commit/aa411d0db3586e2ace255c701c15a1a21e8425c4) Thanks [@TiffanyAltieri](https://github.com/TiffanyAltieri)! - **Fixed** quiet variant links not showing keyboard focus state in Safari. Links with the `quiet` attribute now properly display focus indicators when navigating with keyboard, improving accessibility for keyboard users. + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +### BREAKING CHANGES + +- remove deprecated 'static' references ([#4818](https://github.com/adobe/spectrum-web-components/issues/4818)) + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Features + +- add `static-color` to replace `static` ([#4808](https://github.com/adobe/spectrum-web-components/issues/4808)) ([43cf086](https://github.com/adobe/spectrum-web-components/commit/43cf0865d902346568c755650f53410c7788f2a1)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +### Features + +- **breadcrumbs:** add Breadcrumbs component ([#4578](https://github.com/adobe/spectrum-web-components/issues/4578)) ([acd4b5e](https://github.com/adobe/spectrum-web-components/commit/acd4b5e4401dad8cf26b50ee5dcda80a28b62999)) + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **link:** added feature to stop click propagation for disabled link ([#4251](https://github.com/adobe/spectrum-web-components/issues/4251)) ([64f26a5](https://github.com/adobe/spectrum-web-components/commit/64f26a5d2dd729d5cbae2418fd8bca8481ed6cf6)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +### Bug Fixes + +- **link:** added feature to stop click propagation for disabled link ([#4251](https://github.com/adobe/spectrum-web-components/issues/4251)) ([64f26a5](https://github.com/adobe/spectrum-web-components/commit/64f26a5d2dd729d5cbae2418fd8bca8481ed6cf6)) + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +### Bug Fixes + +- **shared:** update and expand attribute coverage in likeAnchor ([5cb5f1d](https://github.com/adobe/spectrum-web-components/commit/5cb5f1d67c3afe4d62941632d65177a2cd8804c6)) + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/link + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- add the missing quiet property to Link component ([867ea43](https://github.com/adobe/spectrum-web-components/commit/867ea43bc609b2516142c08ee90c598a1531fb99)) +- apply Focuable styles in class extensions ([38f7afd](https://github.com/adobe/spectrum-web-components/commit/38f7afd7cdb317d5c8b6e69f1301decd21364b1d)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- **link:** correct custom CSS processing configuration ([2a24d5a](https://github.com/adobe/spectrum-web-components/commit/2a24d5a034ea185c385fe09feafa3b3f094c848e)) +- **link:** correct white space in template/docs site ([a48bd06](https://github.com/adobe/spectrum-web-components/commit/a48bd06a177ed5f6ec52d44676f61f313bc90022)) +- **link:** correct white space management ([a7a63dc](https://github.com/adobe/spectrum-web-components/commit/a7a63dcbb5f048a9f7178861e4f5d9dbde63ad04)) +- **link:** process Spectrum CSS without overwriting specificity ([9eb3d5c](https://github.com/adobe/spectrum-web-components/commit/9eb3d5c1ef535d61133ce745059bfc7193e32dd4)) +- **link:** support "secondary" variant ([3808b96](https://github.com/adobe/spectrum-web-components/commit/3808b968f483748e98b6e4d3ea6640c63e29cc5f)) +- **link:** test inner anchor attribute by accessing via focusElement ([f4e97a1](https://github.com/adobe/spectrum-web-components/commit/f4e97a1a4958a979a391d5bb330bc67289e354c0)) +- prevent tabindex=-1 elements from placing focus on their host ([1ac1293](https://github.com/adobe/spectrum-web-components/commit/1ac12931771c6d5fdbc99f5d214702ed644cb81a)) +- review deque accessibility testing of docs site ([31f43aa](https://github.com/adobe/spectrum-web-components/commit/31f43aaf0c4092a2aca209538e48417a159dbd0b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) +- **link:** add download attribute to `` ([fb02104](https://github.com/adobe/spectrum-web-components/commit/fb02104104c856d2601a70d9de59fbbe3a79e5d7)) +- **link:** add download attribute to `` ([fefb28e](https://github.com/adobe/spectrum-web-components/commit/fefb28ef29f382401d2d8160c15012af59d0053c)) +- **link:** add download attribute to `` ([16894ba](https://github.com/adobe/spectrum-web-components/commit/16894ba672882178b09a33c4834e42144e6b081d)) +- **link:** add download attribute to `` ([0763504](https://github.com/adobe/spectrum-web-components/commit/07635046b2943e8461a82f564c168d7a9f27ddc2)) +- **link:** support rel attribute ([df4b5a8](https://github.com/adobe/spectrum-web-components/commit/df4b5a831aa35f5992b183cbba3cad18eb3dbb53)) +- **link:** update spectrum css input ([e8cd359](https://github.com/adobe/spectrum-web-components/commit/e8cd3592e780608afeda5bbfb5830a64a0b2caa1)) +- **link:** use core tokens ([510173b](https://github.com/adobe/spectrum-web-components/commit/510173bad82b61138c31d680ca11319590b3aaa3)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc77960de8e57dd9c49bb7669df689f0ebaa)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.14.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.7...@spectrum-web-components/link@0.14.8) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.6...@spectrum-web-components/link@0.14.7) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.5...@spectrum-web-components/link@0.14.6) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.4...@spectrum-web-components/link@0.14.5) (2023-03-08) + +### Bug Fixes + +- add the missing quiet property to Link component ([867ea43](https://github.com/adobe/spectrum-web-components/commit/867ea43bc609b2516142c08ee90c598a1531fb99)) + +## [0.14.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.3...@spectrum-web-components/link@0.14.4) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.2...@spectrum-web-components/link@0.14.3) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.1...@spectrum-web-components/link@0.14.2) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.14.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.14.0...@spectrum-web-components/link@0.14.1) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.14.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.13.2...@spectrum-web-components/link@0.14.0) (2022-11-21) + +### Features + +- **link:** use core tokens ([510173b](https://github.com/adobe/spectrum-web-components/commit/510173bad82b61138c31d680ca11319590b3aaa3)) + +## [0.13.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.13.1...@spectrum-web-components/link@0.13.2) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.13.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.13.0...@spectrum-web-components/link@0.13.1) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.13.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.8...@spectrum-web-components/link@0.13.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.12.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.7...@spectrum-web-components/link@0.12.8) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.6...@spectrum-web-components/link@0.12.7) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.5...@spectrum-web-components/link@0.12.6) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.4...@spectrum-web-components/link@0.12.5) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.3...@spectrum-web-components/link@0.12.4) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.2...@spectrum-web-components/link@0.12.3) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.1...@spectrum-web-components/link@0.12.2) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.12.0...@spectrum-web-components/link@0.12.1) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.11.4...@spectrum-web-components/link@0.12.0) (2022-03-04) + +### Features + +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) + +## [0.11.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.11.3...@spectrum-web-components/link@0.11.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.11.2...@spectrum-web-components/link@0.11.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.11.1...@spectrum-web-components/link@0.11.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.11.0...@spectrum-web-components/link@0.11.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.10.1...@spectrum-web-components/link@0.11.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.10.0...@spectrum-web-components/link@0.10.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.8...@spectrum-web-components/link@0.10.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.9.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.7...@spectrum-web-components/link@0.9.8) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.9.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.6...@spectrum-web-components/link@0.9.7) (2021-09-20) + +### Bug Fixes + +- **link:** support "secondary" variant ([3808b96](https://github.com/adobe/spectrum-web-components/commit/3808b968f483748e98b6e4d3ea6640c63e29cc5f)) + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.5...@spectrum-web-components/link@0.9.6) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.4...@spectrum-web-components/link@0.9.5) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.3...@spectrum-web-components/link@0.9.4) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.2...@spectrum-web-components/link@0.9.3) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.1...@spectrum-web-components/link@0.9.2) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.9.0...@spectrum-web-components/link@0.9.1) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.5...@spectrum-web-components/link@0.9.0) (2021-05-24) + +### Bug Fixes + +- prevent tabindex=-1 elements from placing focus on their host ([1ac1293](https://github.com/adobe/spectrum-web-components/commit/1ac12931771c6d5fdbc99f5d214702ed644cb81a)) + +### Features + +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.4...@spectrum-web-components/link@0.8.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.3...@spectrum-web-components/link@0.8.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.2...@spectrum-web-components/link@0.8.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.1...@spectrum-web-components/link@0.8.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.8.0...@spectrum-web-components/link@0.8.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.7.1...@spectrum-web-components/link@0.8.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.7.0...@spectrum-web-components/link@0.7.1) (2021-02-11) + +### Bug Fixes + +- expand sized functionality to support no default and returning to default values ([acf3cfb](https://github.com/adobe/spectrum-web-components/commit/acf3cfb000033d1ef1e22ca571cb8dbbeaadae77)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.6...@spectrum-web-components/link@0.7.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **link:** update spectrum css input ([e8cd359](https://github.com/adobe/spectrum-web-components/commit/e8cd3592e780608afeda5bbfb5830a64a0b2caa1)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.6...@spectrum-web-components/link@0.6.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **link:** update spectrum css input ([e8cd359](https://github.com/adobe/spectrum-web-components/commit/e8cd3592e780608afeda5bbfb5830a64a0b2caa1)) + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.5...@spectrum-web-components/link@0.5.6) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.4...@spectrum-web-components/link@0.5.5) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.3...@spectrum-web-components/link@0.5.4) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.2...@spectrum-web-components/link@0.5.3) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.1...@spectrum-web-components/link@0.5.2) (2020-08-31) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.5.0...@spectrum-web-components/link@0.5.1) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.4.1...@spectrum-web-components/link@0.5.0) (2020-07-27) + +### Bug Fixes + +- **link:** test inner anchor attribute by accessing via focusElement ([f4e97a1](https://github.com/adobe/spectrum-web-components/commit/f4e97a1a4958a979a391d5bb330bc67289e354c0)) + +### Features + +- **link:** support rel attribute ([df4b5a8](https://github.com/adobe/spectrum-web-components/commit/df4b5a831aa35f5992b183cbba3cad18eb3dbb53)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.4.0...@spectrum-web-components/link@0.4.1) (2020-07-22) + +**Note:** Version bump only for package @spectrum-web-components/link + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.3.4...@spectrum-web-components/link@0.4.0) (2020-07-17) + +### Bug Fixes + +- review deque accessibility testing of docs site ([31f43aa](https://github.com/adobe/spectrum-web-components/commit/31f43aaf0c4092a2aca209538e48417a159dbd0b)) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.3.3...@spectrum-web-components/link@0.3.4) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.3.2...@spectrum-web-components/link@0.3.3) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.3.1...@spectrum-web-components/link@0.3.2) (2020-04-10) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.3.0...@spectrum-web-components/link@0.3.1) (2020-04-07) + +### Bug Fixes + +- **link:** correct white space in template/docs site ([a48bd06](https://github.com/adobe/spectrum-web-components/commit/a48bd06a177ed5f6ec52d44676f61f313bc90022)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.8...@spectrum-web-components/link@0.3.0) (2020-03-11) + +### Features + +- **link:** add download attribute to `` ([fb02104](https://github.com/adobe/spectrum-web-components/commit/fb02104)) +- **link:** add download attribute to `` ([fefb28e](https://github.com/adobe/spectrum-web-components/commit/fefb28e)) +- **link:** add download attribute to `` ([16894ba](https://github.com/adobe/spectrum-web-components/commit/16894ba)) +- **link:** add download attribute to `` ([0763504](https://github.com/adobe/spectrum-web-components/commit/0763504)) + +## [0.2.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.7...@spectrum-web-components/link@0.2.8) (2020-02-24) + +### Bug Fixes + +- **link:** correct custom CSS processing configuration ([2a24d5a](https://github.com/adobe/spectrum-web-components/commit/2a24d5a)) +- **link:** process Spectrum CSS without overwriting specificity ([9eb3d5c](https://github.com/adobe/spectrum-web-components/commit/9eb3d5c)) + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.6...@spectrum-web-components/link@0.2.7) (2020-02-05) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.5...@spectrum-web-components/link@0.2.6) (2020-02-01) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.4...@spectrum-web-components/link@0.2.5) (2020-01-30) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.3...@spectrum-web-components/link@0.2.4) (2020-01-06) + +### Bug Fixes + +- **link:** correct white space management ([a7a63dc](https://github.com/adobe/spectrum-web-components/commit/a7a63dc)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.2...@spectrum-web-components/link@0.2.3) (2019-12-12) + +### Bug Fixes + +- apply Focuable styles in class extensions ([38f7afd](https://github.com/adobe/spectrum-web-components/commit/38f7afd)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.1...@spectrum-web-components/link@0.2.2) (2019-12-02) + +**Note:** Version bump only for package @spectrum-web-components/link + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.2.0...@spectrum-web-components/link@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.1.4...@spectrum-web-components/link@0.2.0) (2019-11-19) + +### Features + +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc7)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/link@0.1.3...@spectrum-web-components/link@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/link diff --git a/1st-gen/packages/link/README.md b/1st-gen/packages/link/README.md new file mode 100644 index 00000000000..8cb283485b1 --- /dev/null +++ b/1st-gen/packages/link/README.md @@ -0,0 +1,155 @@ +## Overview + +An `` allows users to navigate to a different location. They can be presented in-line inside a paragraph or as a standalone text. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/link?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/link) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/link?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/link) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-jp2cck3i) + +```bash +yarn add @spectrum-web-components/link +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/link/sp-link.js'; +``` + +When looking to leverage the `Link` base class as a type and/or for extension purposes, do so via: + +```js +import { Link } from '@spectrum-web-components/link'; +``` + +### Variants + + +Primary + + +Primary links are blue and should be used to call attention to the link or for when the blue color won’t feel too overwhelming in the experience. + + +```html +This is a primary link. +``` + + +Secondary + + +The secondary variant is the same color as the paragraph text inline of which it appears. Its subdued appearance is optimal for when the primary variant is too overwhelming, such as in blocks of text with several references linked throughout. + + +```html +This is a secondary link. +``` + + +Quiet + + +All links can have a quiet style, which means they don’t have an underline. This style should only be used when the placement and context of the link is explicit enough that a visible underline isn’t necessary. +Quiet links are less accessible because users may not recognise them as links. Use only when context and placement make their purpose unmistakable, and avoid using quiet links for critical navigation. + + +```html +

This is a quiet primary link.

+

This is a quiet secondary link.

+
+

+ This is a + quiet link + over a background. +

+
+``` + +
+
+ +#### Static colored links + +When a link needs to be placed on top of a colored background or a visual it may be appropriate to ship it with a static color, regardless of the theme settings with which it is delivered. Leverage the `static-color` attribute with its `white` or `black` values to ensure the delivery is the same in all contexts. + + +White + + +```html +
+

+ This + link + is over a background. +

+
+``` + +
+Black + + +```html +
+

+ This + link + is over a background. +

+
+``` + +
+
+ +### States + +#### Disabled links + +Disabled links are blue, unfocusable, unclickable and should not propagate any events. + + +```html +This is a disabled link. +``` + +### Download attribute + +The download attribute on an `` tag prompts a user to download a link as opposed to navigating to it. This attribute has been carried forward to `` to function the same. + +While it functions this way without assigning a value, actually assigning the value allows custom naming of the download link in accordance +with standard `` [rules](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) defined by the browser. + + +```html +This is a download link. +``` + +### Accessibility + +#### Best Practices + +- Use links in body copy and not in titles. For a larger call to action, consider using a [button](/components/button/) instead. +- Identify the target of each link directly in the link text to communicate context and set clear expectations about where the link will go. +- Be mindful of link placement and language, and create experiences that are inclusive of users navigating with screen readers, who may navigate links without their surrounding language. +- It’s more accessible and inclusive to write link text as unique descriptions of the navigational target or function. +- Implement skip links to improve navigation for keyboard and screen reader users when necessary, especially when the page has many sections and lengthy scroll. +- For links that open in a new tab, add `target="_blank"`, `rel="noopener noreferrer"` and a UI icon to the link. +- Add `aria-label` or `aria-labelledby` to links for screen readers who need additional context. Links can be more concise to lessen visible noise, but adding these attributes can help make the purpose of the link more clear. +- Ensure strong color contrast between the link and its background. For users with low vision,consider using 7:1 ratio for critical links and 21:1 ratio for severe vision impairments. + +#### Keyboard Interaction + +- `Tab`: Move focus to the next focusable element. +- `Enter`: Activate the link. +- `Shift + F10` (Optional): Open the context menu for the link. diff --git a/1st-gen/packages/link/package.json b/1st-gen/packages/link/package.json new file mode 100644 index 00000000000..cf3e1be1609 --- /dev/null +++ b/1st-gen/packages/link/package.json @@ -0,0 +1,76 @@ +{ + "name": "@spectrum-web-components/link", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/link" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/link", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Link.js": { + "development": "./src/Link.dev.js", + "default": "./src/Link.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/link-overrides.css.js": "./src/link-overrides.css.js", + "./src/link.css.js": "./src/link.css.js", + "./sp-link.js": { + "development": "./sp-link.dev.js", + "default": "./sp-link.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/link/sp-link.ts b/1st-gen/packages/link/sp-link.ts new file mode 100644 index 00000000000..2785febe4fc --- /dev/null +++ b/1st-gen/packages/link/sp-link.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Link } from './src/Link.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-link', Link); + +declare global { + interface HTMLElementTagNameMap { + 'sp-link': Link; + } +} diff --git a/1st-gen/packages/link/src/Link.ts b/1st-gen/packages/link/src/Link.ts new file mode 100644 index 00000000000..8ce2afdc982 --- /dev/null +++ b/1st-gen/packages/link/src/Link.ts @@ -0,0 +1,53 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { CSSResultArray, TemplateResult } from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; +import { LikeAnchor } from '@spectrum-web-components/shared/src/like-anchor.js'; +import { Focusable } from '@spectrum-web-components/shared/src/focusable.js'; + +import linkStyles from './link.css.js'; + +/** + * @element sp-link + */ +export class Link extends LikeAnchor(Focusable) { + public static override get styles(): CSSResultArray { + return [linkStyles]; + } + + @query('#anchor') + anchorElement!: HTMLAnchorElement; + + @property({ type: String, reflect: true }) + public variant: 'secondary' | undefined; + + @property({ reflect: true, attribute: 'static-color' }) + public staticColor?: 'black' | 'white'; + + /** + * Uses quiet styles or not + */ + @property({ type: Boolean, reflect: true, attribute: 'quiet' }) + public quiet = false; + + public override get focusElement(): HTMLElement { + return this.anchorElement; + } + + protected override render(): TemplateResult { + return this.renderAnchor({ id: 'anchor' }); + } +} diff --git a/1st-gen/packages/link/src/index.ts b/1st-gen/packages/link/src/index.ts new file mode 100644 index 00000000000..b55e95596ac --- /dev/null +++ b/1st-gen/packages/link/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Link.js'; diff --git a/1st-gen/packages/link/src/link-overrides.css b/1st-gen/packages/link/src/link-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/link/src/link-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/link/src/link.css b/1st-gen/packages/link/src/link.css new file mode 100644 index 00000000000..b9b4435d559 --- /dev/null +++ b/1st-gen/packages/link/src/link.css @@ -0,0 +1,32 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-link.css"); +@import url("./link-overrides.css"); + +:host { + display: inline; +} + +:host(:focus) { + outline: none; +} + +:host([href]) a:focus-visible { + /* .spectrum-Link.focus-ring */ + text-decoration: underline; + text-decoration-style: double; +} + +:host([disabled]) { + pointer-events: none; +} diff --git a/1st-gen/packages/link/src/spectrum-link.css b/1st-gen/packages/link/src/spectrum-link.css new file mode 100644 index 00000000000..9d15062cf1e --- /dev/null +++ b/1st-gen/packages/link/src/spectrum-link.css @@ -0,0 +1,85 @@ +/*! + * Copyright 2025 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License./ + * + * Override divider background color when used inside alert-dialog/ + * .divider { + * --spectrum-divider-background-color: var(--system-alert-dialog-divider-background-color); + * --spectrum-divider-background-color-static-white: var(--spectrum-alert-dialog-divider-background-color-static-white); + * --spectrum-divider-background-color-static-black: var(--spectrum-alert-dialog-divider-background-color-static-black); + * } + */ + +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-link-text-color: LinkText; + } +} + +:host([variant="secondary"]) a { + --mod-link-text-color: var(--mod-link-text-color-secondary-default, var(--spectrum-neutral-content-color-default)); + --mod-link-text-color-hover: var(--mod-link-text-color-secondary-hover, var(--spectrum-neutral-content-color-hover)); + --mod-link-text-color-active: var(--mod-link-text-color-secondary-active, var(--spectrum-neutral-content-color-down)); + --mod-link-text-color-focus: var(--mod-link-text-color-secondary-focus, var(--spectrum-neutral-content-color-key-focus)); +} + +a { + background-color: initial; + text-decoration-skip: objects; + transition: color var(--mod-link-animation-duration, var(--spectrum-animation-duration-100)) ease-in-out; + cursor: pointer; + color: var(--highcontrast-link-text-color, var(--mod-link-text-color, var(--mod-link-text-color-primary-default, var(--spectrum-accent-content-color-default)))); + outline: none; + text-decoration: underline; +} + +a:active { + --mod-link-text-color: var(--mod-link-text-color-active, var(--mod-link-text-color-primary-active, var(--spectrum-accent-content-color-down))); +} + +:host([quiet]) a { + text-decoration: none; +} + +a:focus-visible, +:host([quiet]) a:focus-visible { + --mod-link-text-color: var(--mod-link-text-color-focus, var(--mod-link-text-color-primary-focus, var(--spectrum-accent-content-color-key-focus))); + + text-decoration: underline double; + text-decoration-color: inherit; +} + +@media (hover: hover) { + a:hover { + --mod-link-text-color: var(--mod-link-text-color-hover, var(--mod-link-text-color-primary-hover, var(--spectrum-accent-content-color-hover))); + } + + :host([quiet]) a:hover { + text-decoration: underline; + } +} + +:host([static-color="white"]) a { + --mod-link-text-color: var(--mod-link-text-color-white, var(--spectrum-white)); + --mod-link-text-color-hover: var(--mod-link-text-color-white, var(--spectrum-white)); + --mod-link-text-color-active: var(--mod-link-text-color-white, var(--spectrum-white)); + --mod-link-text-color-focus: var(--mod-link-text-color-white, var(--spectrum-white)); +} + +:host([static-color="black"]) a { + --mod-link-text-color: var(--mod-link-text-color-black, var(--spectrum-black)); + --mod-link-text-color-hover: var(--mod-link-text-color-black, var(--spectrum-black)); + --mod-link-text-color-active: var(--mod-link-text-color-black, var(--spectrum-black)); + --mod-link-text-color-focus: var(--mod-link-text-color-black, var(--spectrum-black)); +} diff --git a/1st-gen/packages/link/stories/link.stories.ts b/1st-gen/packages/link/stories/link.stories.ts new file mode 100644 index 00000000000..73e6904d305 --- /dev/null +++ b/1st-gen/packages/link/stories/link.stories.ts @@ -0,0 +1,123 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/link/sp-link.js'; + +export default { + component: 'sp-link', + title: 'Link', +}; + +export const Default = (): TemplateResult => { + // prettier-ignore + return html` + This is a link in a sentence. + `; +}; + +export const Quiet = (): TemplateResult => { + // prettier-ignore + return html` + This is a quiet link in a sentence. + `; +}; + +export const Disabled = (): TemplateResult => { + // prettier-ignore + return html` + This is a disabled non focusable link in a sentence. + `; +}; + +export const secondary = (): TemplateResult => { + // prettier-ignore + return html` + This is a link in a sentence. + `; +}; + +export const secondaryQuiet = (): TemplateResult => { + // prettier-ignore + return html` + This is a quiet link in a sentence. + `; +}; + +export const staticWhite = (): TemplateResult => { + return html` +
+

+ This + link + has a background. +

+
+ `; +}; + +export const staticBlack = (): TemplateResult => { + return html` +
+

+ This + link + has a background. +

+
+ `; +}; + +export const staticWhiteQuiet = (): TemplateResult => { + return html` +
+

+ This + link + has a background. +

+
+ `; +}; + +export const staticBlackQuiet = (): TemplateResult => { + return html` +
+

+ This + link + has a background. +

+
+ `; +}; + +export const Download = (): TemplateResult => { + const blob = new Blob(['some text for the file'], { + type: 'text/plain;charset=utf-8', + }); + return html` + This is a + + downloadable file + + for you to click on. + `; +}; diff --git a/1st-gen/packages/link/test/benchmark/test-basic.ts b/1st-gen/packages/link/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..c3f2cefd20c --- /dev/null +++ b/1st-gen/packages/link/test/benchmark/test-basic.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/link/sp-link.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + Default Link +`); diff --git a/1st-gen/packages/link/test/link-memory.test.ts b/1st-gen/packages/link/test/link-memory.test.ts new file mode 100644 index 00000000000..15e37df9cdc --- /dev/null +++ b/1st-gen/packages/link/test/link-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/link/sp-link.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/link/test/link.test.ts b/1st-gen/packages/link/test/link.test.ts new file mode 100644 index 00000000000..47896b6fe3c --- /dev/null +++ b/1st-gen/packages/link/test/link.test.ts @@ -0,0 +1,79 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/link/sp-link.js'; +import { Link } from '@spectrum-web-components/link'; +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; +import { spy } from 'sinon'; + +describe('Link', () => { + testForLitDevWarnings( + async () => + await fixture(html` + Default Link + `) + ); + it('loads', async () => { + const el = await fixture(html` + Default Link + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + expect(el.textContent).to.include('Default Link'); + + await expect(el).to.be.accessible(); + }); + + it('loads[download]', async () => { + const el = await fixture(html` + + Default Link + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + expect(el.textContent).to.include('Default Link'); + + await expect(el).to.be.accessible(); + }); + + it('loads[rel]', async () => { + const el = await fixture(html` + Default Link + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + expect(el.focusElement.getAttribute('rel')).to.eq('external'); + + await expect(el).to.be.accessible(); + }); + + it('no click triggers for disabled link', async () => { + const clickSpy = spy(); + const el = await fixture(html` + clickSpy()}> + Disabled Link + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + expect(el.disabled).to.eq(true); + await expect(el).to.be.accessible(); + el.click(); + expect(clickSpy.callCount).to.equal(0); + }); +}); diff --git a/1st-gen/packages/link/tsconfig.json b/1st-gen/packages/link/tsconfig.json new file mode 100644 index 00000000000..b10d59338e5 --- /dev/null +++ b/1st-gen/packages/link/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"] +} diff --git a/1st-gen/packages/menu/.npmrc b/1st-gen/packages/menu/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/menu/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/menu/CHANGELOG.md b/1st-gen/packages/menu/CHANGELOG.md new file mode 100644 index 00000000000..0a2b43a8209 --- /dev/null +++ b/1st-gen/packages/menu/CHANGELOG.md @@ -0,0 +1,976 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- [#5732](https://github.com/adobe/spectrum-web-components/pull/5732) [`4880da4`](https://github.com/adobe/spectrum-web-components/commit/4880da4f80a25ae1b475f52ce4ba7914cdcd9de4) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - - **Fixed**: MenuItem focus stealing from input elements on mouseover by enhancing MenuItem's `handleMouseover` method to detect when an input element currently has focus and prevent stealing focus in those cases. + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/action-button@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/overlay@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/popover@1.9.0 + - @spectrum-web-components/divider@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Minor Changes + +- [#5616](https://github.com/adobe/spectrum-web-components/pull/5616) [`f27ab09`](https://github.com/adobe/spectrum-web-components/commit/f27ab096f4d53543dc53f75ec196c696b78b3baa) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixed** : Fix iPad scrolling issue in picker dropdown where scrolling through menu items would accidentally select the first touched item and close the picker. + + The fix implements touch gesture detection to distinguish between scrolling and selection. Added `isScrolling` getter for public API access. Test on iPad devices with long menus to validate scrolling behavior and selection accuracy. + +### Patch Changes + +- Updated dependencies [[`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7), [`ee1bae6`](https://github.com/adobe/spectrum-web-components/commit/ee1bae6f9a7401dc31ebc84e4e27f9d39be692d1), [`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7), [`826a2d5`](https://github.com/adobe/spectrum-web-components/commit/826a2d533e46a6f945daefa8999fadca78bd8688)]: + - @spectrum-web-components/overlay@1.8.0 + - @spectrum-web-components/divider@1.8.0 + - @spectrum-web-components/popover@1.8.0 + - @spectrum-web-components/action-button@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- [#5402](https://github.com/adobe/spectrum-web-components/pull/5402) [`3aeafdd`](https://github.com/adobe/spectrum-web-components/commit/3aeafddab98fe30f4db538ded9052997aaa05b07) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixes**: Icons in menu stories weren't properly responding to theme changes when used in functional story components. + Switching to class-based LitElement components ensures proper component lifecycle hooks and shadow DOM context for icon initialization and theme integration. +- Updated dependencies [[`a646ae8`](https://github.com/adobe/spectrum-web-components/commit/a646ae8b0e652308d359226740d2cb189e492e45), [`c1669d2`](https://github.com/adobe/spectrum-web-components/commit/c1669d2dc5e1ceeb84486ce49a428f86a3173caa)]: + - @spectrum-web-components/overlay@1.7.0 + - @spectrum-web-components/action-button@1.7.0 + - @spectrum-web-components/popover@1.7.0 + - @spectrum-web-components/divider@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5349](https://github.com/adobe/spectrum-web-components/pull/5349) [`a9727d2`](https://github.com/adobe/spectrum-web-components/commit/a9727d2975b01f440c09789c9e7e0122063b6f7e) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies [[`03a4439`](https://github.com/adobe/spectrum-web-components/commit/03a443946b760aedc668630f33ac660443ff915e), [`53f3769`](https://github.com/adobe/spectrum-web-components/commit/53f3769f07b6e7853a8a4c0dc63b21fe14cf3d4b)]: + - @spectrum-web-components/popover@1.6.0 + - @spectrum-web-components/overlay@1.6.0 + - @spectrum-web-components/action-button@1.6.0 + - @spectrum-web-components/divider@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Minor Changes + +- [#5350](https://github.com/adobe/spectrum-web-components/pull/5350) [`86bcd12`](https://github.com/adobe/spectrum-web-components/commit/86bcd122003e99d490a64d466dab3e7d609a6ff3) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - change display property from inline-flex to flex to eliminate unwanted spacing between menu items + +### Patch Changes + +- [#5313](https://github.com/adobe/spectrum-web-components/pull/5313) [`4c2f908`](https://github.com/adobe/spectrum-web-components/commit/4c2f908a92b383d49eb7197d954966fe1798aa20) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - Tapping on an `sp-menu-item` was causing the tap event to propagate to an `sp-checkbox` underneath it, resulting in the checkbox being checked unintentionally. The fix involves capturing the `touchend` event on the `sp-menu` to prevent this propagation. + +- [#5270](https://github.com/adobe/spectrum-web-components/pull/5270) [`a69accb`](https://github.com/adobe/spectrum-web-components/commit/a69accb8b44b2612d53d31ba52c99aa751ce9f3a) Thanks [@nikkimk](https://github.com/nikkimk)! - correctly applies menuitem hover styling with pointerenter actions and only applies menuitem focus styling with keyboard/click action [#5269](https://github.com/adobe/spectrum-web-components/issues/5269) + +- Updated dependencies [[`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0), [`8f8735c`](https://github.com/adobe/spectrum-web-components/commit/8f8735c9ec3eac3b6473424c78257cb46ee17f70), [`6c58f50`](https://github.com/adobe/spectrum-web-components/commit/6c58f50f7b1f5489c11e0d3484e3f4a9d576f1c8)]: + - @spectrum-web-components/divider@1.5.0 + - @spectrum-web-components/overlay@1.5.0 + - @spectrum-web-components/action-button@1.5.0 + - @spectrum-web-components/popover@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Minor Changes + +- [#5187](https://github.com/adobe/spectrum-web-components/pull/5187) [`2a0422e`](https://github.com/adobe/spectrum-web-components/commit/2a0422ec1b667a9f236858f8cc9dca261ba27f9f) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - Disabled drag and select functionality of picker in mobile devices. This is done to prevent click event being captured behind the menu-tray combination because the menu was closing immediately on pointerup. + - Fixed a bug where the picker in a dialog was not closing when clicking outside the dialog. ([#5111](https://github.com/adobe/spectrum-web-components/issues/5111)) + - Fixed another bug where the elements behind the menu were receiving click events. ([#5060](https://github.com/adobe/spectrum-web-components/issues/5060)) + +### Patch Changes + +- [#5197](https://github.com/adobe/spectrum-web-components/pull/5197) [`6618422`](https://github.com/adobe/spectrum-web-components/commit/6618422848df234e420eed95f4a5a30557e1e46f) Thanks [@nikkimk](https://github.com/nikkimk)! - `` - fixes `` focus on hover ([#5180](https://github.com/adobe/spectrum-web-components/issues/5180)) + +- Updated dependencies [[`72dbe62`](https://github.com/adobe/spectrum-web-components/commit/72dbe629cddfc57171eaaadf7206df47c19d3c98), [`46cd782`](https://github.com/adobe/spectrum-web-components/commit/46cd7828f65491fc08790e5ba0aec412ee89199d), [`70f5f6f`](https://github.com/adobe/spectrum-web-components/commit/70f5f6f3a97b530fb20f9f5ee049e9a8c124b02d)]: + - @spectrum-web-components/action-button@1.4.0 + - @spectrum-web-components/overlay@1.4.0 + - @spectrum-web-components/popover@1.4.0 + - @spectrum-web-components/divider@1.4.0 + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Minor Changes + +- [#5031](https://github.com/adobe/spectrum-web-components/pull/5031) [`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f) Thanks [@nikkimk](https://github.com/nikkimk)! - Used WAI ARIA Authoring Practices Guide (APG) to make accessibility improvements for ``, ``, and ``, including: + - Numpad keys now work with `` and `` -``'s `` elements can now be read by a screen reader ([#4556](https://github.com/adobe/spectrum-web-components/issues/4556)) + - `` href can now be clicked by a screen reader ([#4997](https://github.com/adobe/spectrum-web-components/issues/4997)) + - Opening a ``, ``, and `` with a keyboard now sets focus on an item within the menu. ([#4557](https://github.com/adobe/spectrum-web-components/issues/4557)) + + See the following APG examples for more information: + - [Navigation Menu Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/) + - [Editor Menubar Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-editor/) + +### Patch Changes + +- [#5176](https://github.com/adobe/spectrum-web-components/pull/5176) [`468314f`](https://github.com/adobe/spectrum-web-components/commit/468314f45cf5fedb2e9029da210a5886260abca9) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - 1. chore(checkbox): updated to latest css v10.1.1 for s2 fast follow 2. chore(dialog): + The error property was not properly deprecated with a full migration plan in place. This has caused confusion and false sense of urgency for consumers to migrate. We are removing it to eliminate those pain points for consumers while we take a deep look at our dialogs and patterns. 3. chore(menu): updated to latest css v9.1.1 for s2 fast follow 4. fix(overlay): + sp-overlay with type="manual" should close on pressing ESC key. When the last item is on overlay stack we are triggering the close method on esc key event. + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f), [`468314f`](https://github.com/adobe/spectrum-web-components/commit/468314f45cf5fedb2e9029da210a5886260abca9)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/overlay@1.3.0 + - @spectrum-web-components/popover@1.3.0 + - @spectrum-web-components/action-button@1.3.0 + - @spectrum-web-components/divider@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +### Bug Fixes + +- **action menu:** keyboard accessibility omnibus ([#5031](https://github.com/adobe/spectrum-web-components/issues/5031)) ([ea38ef0](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)), closes [#4623](https://github.com/adobe/spectrum-web-components/issues/4623) +- **menu:** make submenu scrollable ([#5082](https://github.com/adobe/spectrum-web-components/issues/5082)) ([a13dac2](https://github.com/adobe/spectrum-web-components/commit/a13dac26e51fa953e36232ce2b10dc0f121ef6a8)) +- **picker:** update picker when menu item icons change ([#5088](https://github.com/adobe/spectrum-web-components/issues/5088)) ([63ef1ad](https://github.com/adobe/spectrum-web-components/commit/63ef1adad473ce58647ffe4d5e2a8727caaee07b)) + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +### Features + +- add an optional chromatic vrt action ([7d2f840](https://github.com/adobe/spectrum-web-components/commit/7d2f8401cb05c5e23872424f132a1a8edd95b666)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **menu:** prevent sp-menu-item text-align cascading ([#4868](https://github.com/adobe/spectrum-web-components/issues/4868)) ([6663820](https://github.com/adobe/spectrum-web-components/commit/666382067e20a48a91d440ca1427698f9b58bc06)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +### Bug Fixes + +- **menu:** allow menu-item to support arbitrary element as the submenu root ([#4720](https://github.com/adobe/spectrum-web-components/issues/4720)) ([4c6a0dc](https://github.com/adobe/spectrum-web-components/commit/4c6a0dcf7c67560c664c1f7c0f93d0ef3f0005ab)) + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +### Features + +- **breadcrumbs:** add Breadcrumbs component ([#4578](https://github.com/adobe/spectrum-web-components/issues/4578)) ([acd4b5e](https://github.com/adobe/spectrum-web-components/commit/acd4b5e4401dad8cf26b50ee5dcda80a28b62999)) + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +### Bug Fixes + +- **menu:** should not make a selection on right click ([#4642](https://github.com/adobe/spectrum-web-components/issues/4642)) ([d269629](https://github.com/adobe/spectrum-web-components/commit/d269629a64063515eddee9b178b6240b92b9bc76)) + +### Features + +- upgrade menu and dialog grid css ([#4638](https://github.com/adobe/spectrum-web-components/issues/4638)) ([ab9d468](https://github.com/adobe/spectrum-web-components/commit/ab9d468a5a1cf5721e169bd8dd8724be78c148a1)) + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +### Features + +- **action-bar:** support for action-menus ([#3780](https://github.com/adobe/spectrum-web-components/issues/3780)) ([4aff599](https://github.com/adobe/spectrum-web-components/commit/4aff5995f6a22eefae0dd8e580d743c27ceb2c2d)) + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +### Bug Fixes + +- **menu:** enable numpad arrow and Enter keys ([#4492](https://github.com/adobe/spectrum-web-components/issues/4492)) ([012c411](https://github.com/adobe/spectrum-web-components/commit/012c4116dac62031e5a329cf4da7fb9cd149bfdf)) + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **action-menu:** allow menu groups to handle their own selections ([#4397](https://github.com/adobe/spectrum-web-components/issues/4397)) ([5a19051](https://github.com/adobe/spectrum-web-components/commit/5a190518814f85cfd2e345ad6a0add1378c05bf4)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **menu:** release synthetic "click" promise to unblock keyboard interactions ([f8aecf3](https://github.com/adobe/spectrum-web-components/commit/f8aecf33cfa94ee1e1b791dc203fc46ead84eb10)) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +### Bug Fixes + +- **menu:** fix css for `disabled` "value" slots in menu items ([#4113](https://github.com/adobe/spectrum-web-components/issues/4113)) ([3c5855d](https://github.com/adobe/spectrum-web-components/commit/3c5855d606739b29c7da7a6250cc7636ee15fad1)) + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +### Bug Fixes + +- **menu:** correct disabled menu item's chevron to appropriate colour ([#4052](https://github.com/adobe/spectrum-web-components/issues/4052)) ([30f5bb5](https://github.com/adobe/spectrum-web-components/commit/30f5bb58d376822f990545970581ebee943738f7)) + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Bug Fixes + +- support generating random IDs outside of secure contexts ([485a67c](https://github.com/adobe/spectrum-web-components/commit/485a67c5401094705b711350f8ee74182a6dd64b)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +### Bug Fixes + +- **menu:** process ":active" styles ([7917583](https://github.com/adobe/spectrum-web-components/commit/79175833e8121cef1419b547802721324472965d)) + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +### Bug Fixes + +- **picker,action-menu,split-button:** update interaction model ([#3935](https://github.com/adobe/spectrum-web-components/issues/3935)) ([bae7d52](https://github.com/adobe/spectrum-web-components/commit/bae7d527e513d2588267c62cc70f5e1c1289f903)) + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +### Bug Fixes + +- **overlay:** move closed overlays to "display: none" ([fc0278b](https://github.com/adobe/spectrum-web-components/commit/fc0278b917759ed58c3ac62a6e962633914481c0)) + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +### Bug Fixes + +- **menu:** support navigating to and selecting Menu Items in Menu Groups ([8469ab2](https://github.com/adobe/spectrum-web-components/commit/8469ab235bf4049b7ce9fca008494df1cde012a7)) + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +### Bug Fixes + +- update deps graph, fix imports ([f633005](https://github.com/adobe/spectrum-web-components/commit/f633005e26bff640615f157b54830bfb0677d682)) + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +### Bug Fixes + +- **menu:** conditionally access slots for their assigned content ([#3717](https://github.com/adobe/spectrum-web-components/issues/3717)) ([c045822](https://github.com/adobe/spectrum-web-components/commit/c04582216c67051fa6c78f27b299a9fdfd076597)) + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +### Bug Fixes + +- **menu:** allow `change` events to be direct ([#3689](https://github.com/adobe/spectrum-web-components/issues/3689)) ([b2cd3da](https://github.com/adobe/spectrum-web-components/commit/b2cd3da1384c577f27f604c42847953bb7121cb2)) + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **menu:** allow Menu elements to be controlled ([74ed7fb](https://github.com/adobe/spectrum-web-components/commit/74ed7fb7d593199c333392f89c4827fcb8248cab)) +- **menu:** manage deeply slotted menu items and initial focus ([7f9ad69](https://github.com/adobe/spectrum-web-components/commit/7f9ad69282b6e740efb04fa2933d3163164259c7)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- **menu:** added support for menu item description ([#3559](https://github.com/adobe/spectrum-web-components/issues/3559)) ([ce99528](https://github.com/adobe/spectrum-web-components/commit/ce99528b4ad61ba8185cde7eaacfa98a2a9fd619)) +- **menu:** correct types import for .d.ts file creation ([a11d264](https://github.com/adobe/spectrum-web-components/commit/a11d2645863d23d3557fdb5803b68365cc373cb6)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +### Bug Fixes + +- ensure submenus stay open when root it clicked again ([83ced1c](https://github.com/adobe/spectrum-web-components/commit/83ced1c913f262620e7b87ad3b7e58dff0697442)) + +### Features + +- **menu:** prepare for Overlay v2 and less connnected/disconnected responsibilities ([5dfb71e](https://github.com/adobe/spectrum-web-components/commit/5dfb71e5ed26cf8af83ca335a7658938f3f135a6)) + +### Performance Improvements + +- make lots of things lazy ([b8fa3ad](https://github.com/adobe/spectrum-web-components/commit/b8fa3ada062bf54bbb42e76ab156c716d5820c7c)) +- make submenus lazier ([a2d661c](https://github.com/adobe/spectrum-web-components/commit/a2d661cf4095f4ccb826d17b6f2e665c8c5bf70f)) +- make submenus lazy ([93531b9](https://github.com/adobe/spectrum-web-components/commit/93531b9624259d519f6f9cab264f8485c9a32fdb)) + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +### Features + +- **menu:** convert to core tokens ([#3254](https://github.com/adobe/spectrum-web-components/issues/3254)) ([da43540](https://github.com/adobe/spectrum-web-components/commit/da43540abcea3db75bf145194be800b61153ebe0)) + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Bug Fixes + +- menu item missing aria labels ([#3417](https://github.com/adobe/spectrum-web-components/issues/3417)) ([0d04869](https://github.com/adobe/spectrum-web-components/commit/0d048696792522af0d849b64983ae793dfeae289)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.33.1](https://github.com/adobe/spectrum-web-components/compare/v0.33.0...v0.33.1) (2023-06-14) + +### Bug Fixes + +- **menu:** [#3164](https://github.com/adobe/spectrum-web-components/issues/3164) plug memory leak with gobal events ([ff589d4](https://github.com/adobe/spectrum-web-components/commit/ff589d4ec86f8dcda15c386907d27c7b3cc8c325)) + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) +- add "value" slot to sp-menu-item ([e1bd264](https://github.com/adobe/spectrum-web-components/commit/e1bd2646a5198d9ef64710ad0a3749606f08c74e)) +- add icon present and icon-only support to Picker ([f6887a3](https://github.com/adobe/spectrum-web-components/commit/f6887a34e228473e33893c81017492bf3e8fd6c3)) +- add value/selection checks to the tests and fix up the value logic ([933106f](https://github.com/adobe/spectrum-web-components/commit/933106f88dfa99f22fc1046c1395eb53f051b5c4)) +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- correctly delivery visuals and mouse interactions for litAnchor and extensions ([0ae889a](https://github.com/adobe/spectrum-web-components/commit/0ae889a8aab9b3417a021b917dfc817a8310f50f)) +- **dropdown:** improve accessibility ([389d9d9](https://github.com/adobe/spectrum-web-components/commit/389d9d94a13bf31e10f58ee498bd848929e9d67c)) +- ensure Action Menu Item with [href] close the menu ([6b3d87f](https://github.com/adobe/spectrum-web-components/commit/6b3d87f8c922df782432bca3ef93d21637bad78b)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- ensure that an overlay can be released even if it does not complete its fade in animation ([4cbb36f](https://github.com/adobe/spectrum-web-components/commit/4cbb36f91569ce9b7f926437142950fc8fbd59f9)) +- ensure that entering an ancestor Menu Item without a submen closes related submenus ([efe5fa1](https://github.com/adobe/spectrum-web-components/commit/efe5fa1ff50c45487f370847444b940e1d6d8a4e)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- match "pointerup" listeners with "pointercancel" for full coverage ([7f2ce92](https://github.com/adobe/spectrum-web-components/commit/7f2ce924ce03fb0881505e6f144184bd3d25355d)) +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) +- **menu:** allow for settign "selected" async from above ([9d7f622](https://github.com/adobe/spectrum-web-components/commit/9d7f6220313278a90d0482f27a507519a77df549)) +- **menu:** cache item parent element to correct disconnecting event dispatch ([f375510](https://github.com/adobe/spectrum-web-components/commit/f3755109ebf64623ba4884871ad8f6eb3b02bc33)) +- **menu:** clarify menu internal focus management via preventScroll option ([9ae092c](https://github.com/adobe/spectrum-web-components/commit/9ae092c7d09ef9359dbf9ed9373aef0650967f40)) +- **menu:** disabled menu-item should not open submenu ([33848bc](https://github.com/adobe/spectrum-web-components/commit/33848bc0aa64733e356831a5f4968fcb01476df4)) +- **menu:** ensure active descendant is in view when activated ([6edc351](https://github.com/adobe/spectrum-web-components/commit/6edc3518fd305cbd35b74f013546bb32aef7616b)) +- **menu:** ensure that Groups in Action Menus are rendered with the correct width ([a996a10](https://github.com/adobe/spectrum-web-components/commit/a996a1078bd3a00d3025f0eeadb39330bafdc26d)) +- **menu:** include all direct dependencies ([aa7327f](https://github.com/adobe/spectrum-web-components/commit/aa7327f748b829fa6f6eec2412ac104e9dbeff76)) +- **menu:** manage tabindex and focus entry correctly ([3b1a250](https://github.com/adobe/spectrum-web-components/commit/3b1a250c0ec4ad2b3553bbf100c8c7015ff3cbc6)) +- **menu:** only scrollIntoView when keyboard navigating ([f4e9278](https://github.com/adobe/spectrum-web-components/commit/f4e9278048287a45bba2da25144834b0b8297c66)) +- **menu:** pass current focus visibility to menu items ([2d3bf80](https://github.com/adobe/spectrum-web-components/commit/2d3bf8046379fe8caff926af81e62806e77f6a49)) +- **menu:** patch undefined lastFocusedItem ([772a7ea](https://github.com/adobe/spectrum-web-components/commit/772a7ea63507b69432e8fac33354578873c3585c)) +- **menu:** prevent infinite loop when focus() ([e4e98a3](https://github.com/adobe/spectrum-web-components/commit/e4e98a358a1991c1d6048b01e2899dd28d56dc7e)) +- **menu:** support menu item list change in deep decendents ([b2b47f3](https://github.com/adobe/spectrum-web-components/commit/b2b47f305cab9720d29b4214b3330b95f33a56d3)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- **picker:** allow menu items to be added, updated, and removed ([73511ba](https://github.com/adobe/spectrum-web-components/commit/73511ba996154c006602dfd1c7f1d94746049782)) +- prepare for querying child items while disconnected ([f4152a5](https://github.com/adobe/spectrum-web-components/commit/f4152a5474b661d72b69e7a8cab41639ec7fb8c0)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- prevent leaving multiple submenus open at a time ([d2bfbb2](https://github.com/adobe/spectrum-web-components/commit/d2bfbb2d8334ae1a6bd21381092d54914b8f708c)) +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) +- simplify focus application in Menu ([6140169](https://github.com/adobe/spectrum-web-components/commit/61401699b36298b6f11cc80703aff664cbb867a7)) +- **split-button:** hide "selected" item from menu ([322a966](https://github.com/adobe/spectrum-web-components/commit/322a96655855f42b390ba2c94d0b017bf93aebd9)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- style clean up ([49e1537](https://github.com/adobe/spectrum-web-components/commit/49e15377f3a839d0ed5dc2504dd71396aa156eb5)) +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update Picker label via MutationObserver instead of "slotchange" ([196998e](https://github.com/adobe/spectrum-web-components/commit/196998e9433dc938d86bfbe77db9e3accd6d9bbc)) +- update role application logic to not overwrite menu\* roles ([94b6aec](https://github.com/adobe/spectrum-web-components/commit/94b6aecffc1e5686feab09361d4e07ec3e854726)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- add screenshot regression testing to CI ([8205dfe](https://github.com/adobe/spectrum-web-components/commit/8205dfe33c725e13f74f411779c2ff3b6061a913)) +- add selects attribute to menu ([bdf2578](https://github.com/adobe/spectrum-web-components/commit/bdf25780e56c7b92368904dce2a02f2594c364a2)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- allow dir management by sp-theme elements ([2d10158](https://github.com/adobe/spectrum-web-components/commit/2d1015883bc0c3a03862c0de8b4d996cd954291f)) +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- **menu:** update spectrum css input ([8c7e18a](https://github.com/adobe/spectrum-web-components/commit/8c7e18ac16f2747bd2f10173bcac0d5e53a0bcac)) +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **split-button:** add split-button pattern ([4833a59](https://github.com/adobe/spectrum-web-components/commit/4833a598bb3da3552d194586350a3888dba79543)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- update Menu Divider for new Spectrum CSS output ([aca7e2d](https://github.com/adobe/spectrum-web-components/commit/aca7e2dd1b42016d16c5e7a3484e0963ffce4d9a)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc77960de8e57dd9c49bb7669df689f0ebaa)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- reorganize inheritance and composition in Menu Items ([d96ccb6](https://github.com/adobe/spectrum-web-components/commit/d96ccb621833277444d69535126c3669343c2eaf)) +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.16.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.16...@spectrum-web-components/menu@0.16.17) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.15...@spectrum-web-components/menu@0.16.16) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.14...@spectrum-web-components/menu@0.16.15) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.13...@spectrum-web-components/menu@0.16.14) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.12...@spectrum-web-components/menu@0.16.13) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.11...@spectrum-web-components/menu@0.16.12) (2023-02-08) + +### Bug Fixes + +- **menu:** patch undefined lastFocusedItem ([772a7ea](https://github.com/adobe/spectrum-web-components/commit/772a7ea63507b69432e8fac33354578873c3585c)) +- prepare for querying child items while disconnected ([f4152a5](https://github.com/adobe/spectrum-web-components/commit/f4152a5474b661d72b69e7a8cab41639ec7fb8c0)) + +## [0.16.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.10...@spectrum-web-components/menu@0.16.11) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.9...@spectrum-web-components/menu@0.16.10) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.8...@spectrum-web-components/menu@0.16.9) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.7...@spectrum-web-components/menu@0.16.8) (2022-11-21) + +### Bug Fixes + +- ensure that an overlay can be released even if it does not complete its fade in animation ([4cbb36f](https://github.com/adobe/spectrum-web-components/commit/4cbb36f91569ce9b7f926437142950fc8fbd59f9)) + +## [0.16.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.6...@spectrum-web-components/menu@0.16.7) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.5...@spectrum-web-components/menu@0.16.6) (2022-10-28) + +### Bug Fixes + +- ensure Action Menu Item with [href] close the menu ([6b3d87f](https://github.com/adobe/spectrum-web-components/commit/6b3d87f8c922df782432bca3ef93d21637bad78b)) + +## [0.16.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.4...@spectrum-web-components/menu@0.16.5) (2022-10-17) + +### Bug Fixes + +- **menu:** ensure that Groups in Action Menus are rendered with the correct width ([a996a10](https://github.com/adobe/spectrum-web-components/commit/a996a1078bd3a00d3025f0eeadb39330bafdc26d)) + +## [0.16.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.3...@spectrum-web-components/menu@0.16.4) (2022-10-10) + +### Bug Fixes + +- match "pointerup" listeners with "pointercancel" for full coverage ([7f2ce92](https://github.com/adobe/spectrum-web-components/commit/7f2ce924ce03fb0881505e6f144184bd3d25355d)) + +## [0.16.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.2...@spectrum-web-components/menu@0.16.3) (2022-09-15) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.1...@spectrum-web-components/menu@0.16.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.16.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.16.0...@spectrum-web-components/menu@0.16.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.16.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.15.0...@spectrum-web-components/menu@0.16.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +# [0.15.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.14.4...@spectrum-web-components/menu@0.15.0) (2022-08-04) + +### Features + +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) + +## [0.14.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.14.3...@spectrum-web-components/menu@0.14.4) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.14.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.14.2...@spectrum-web-components/menu@0.14.3) (2022-06-29) + +### Bug Fixes + +- ensure that entering an ancestor Menu Item without a submen closes related submenus ([efe5fa1](https://github.com/adobe/spectrum-web-components/commit/efe5fa1ff50c45487f370847444b940e1d6d8a4e)) +- update Picker label via MutationObserver instead of "slotchange" ([196998e](https://github.com/adobe/spectrum-web-components/commit/196998e9433dc938d86bfbe77db9e3accd6d9bbc)) + +## [0.14.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.14.1...@spectrum-web-components/menu@0.14.2) (2022-06-07) + +### Bug Fixes + +- prevent leaving multiple submenus open at a time ([d2bfbb2](https://github.com/adobe/spectrum-web-components/commit/d2bfbb2d8334ae1a6bd21381092d54914b8f708c)) +- **menu:** disabled menu-item should not open submenu ([33848bc](https://github.com/adobe/spectrum-web-components/commit/33848bc0aa64733e356831a5f4968fcb01476df4)) + +## [0.14.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.14.0...@spectrum-web-components/menu@0.14.1) (2022-05-27) + +### Bug Fixes + +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) + +# [0.14.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.13.0...@spectrum-web-components/menu@0.14.0) (2022-05-12) + +### Features + +- update Menu Divider for new Spectrum CSS output ([aca7e2d](https://github.com/adobe/spectrum-web-components/commit/aca7e2dd1b42016d16c5e7a3484e0963ffce4d9a)) + +# [0.13.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.5...@spectrum-web-components/menu@0.13.0) (2022-04-21) + +### Features + +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) + +## [0.12.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.4...@spectrum-web-components/menu@0.12.5) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.12.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.3...@spectrum-web-components/menu@0.12.4) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.12.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.2...@spectrum-web-components/menu@0.12.3) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.12.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.1...@spectrum-web-components/menu@0.12.2) (2022-03-04) + +### Bug Fixes + +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.12.0...@spectrum-web-components/menu@0.12.1) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.11.3...@spectrum-web-components/menu@0.12.0) (2022-02-02) + +### Features + +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.11.2...@spectrum-web-components/menu@0.11.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.11.1...@spectrum-web-components/menu@0.11.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.11.0...@spectrum-web-components/menu@0.11.1) (2021-12-13) + +### Bug Fixes + +- **picker:** allow menu items to be added, updated, and removed ([73511ba](https://github.com/adobe/spectrum-web-components/commit/73511ba996154c006602dfd1c7f1d94746049782)) + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.10.1...@spectrum-web-components/menu@0.11.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.10.0...@spectrum-web-components/menu@0.10.1) (2021-11-08) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.6...@spectrum-web-components/menu@0.10.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.9.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.5...@spectrum-web-components/menu@0.9.6) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.4...@spectrum-web-components/menu@0.9.5) (2021-10-05) + +### Bug Fixes + +- **menu:** cache item parent element to correct disconnecting event dispatch ([f375510](https://github.com/adobe/spectrum-web-components/commit/f3755109ebf64623ba4884871ad8f6eb3b02bc33)) + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.3...@spectrum-web-components/menu@0.9.4) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.2...@spectrum-web-components/menu@0.9.3) (2021-09-13) + +### Bug Fixes + +- simplify focus application in Menu ([6140169](https://github.com/adobe/spectrum-web-components/commit/61401699b36298b6f11cc80703aff664cbb867a7)) + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.1...@spectrum-web-components/menu@0.9.2) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.9.0...@spectrum-web-components/menu@0.9.1) (2021-08-17) + +### Performance Improvements + +- reorganize inheritance and composition in Menu Items ([d96ccb6](https://github.com/adobe/spectrum-web-components/commit/d96ccb621833277444d69535126c3669343c2eaf)) + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.10...@spectrum-web-components/menu@0.9.0) (2021-08-03) + +### Bug Fixes + +- add value/selection checks to the tests and fix up the value logic ([933106f](https://github.com/adobe/spectrum-web-components/commit/933106f88dfa99f22fc1046c1395eb53f051b5c4)) +- **split-button:** hide "selected" item from menu ([322a966](https://github.com/adobe/spectrum-web-components/commit/322a96655855f42b390ba2c94d0b017bf93aebd9)) + +### Features + +- add selects attribute to menu ([bdf2578](https://github.com/adobe/spectrum-web-components/commit/bdf25780e56c7b92368904dce2a02f2594c364a2)) + +## [0.8.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.9...@spectrum-web-components/menu@0.8.10) (2021-07-22) + +### Bug Fixes + +- style clean up ([49e1537](https://github.com/adobe/spectrum-web-components/commit/49e15377f3a839d0ed5dc2504dd71396aa156eb5)) + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.8...@spectrum-web-components/menu@0.8.9) (2021-07-01) + +### Bug Fixes + +- add "value" slot to sp-menu-item ([e1bd264](https://github.com/adobe/spectrum-web-components/commit/e1bd2646a5198d9ef64710ad0a3749606f08c74e)) +- add icon present and icon-only support to Picker ([f6887a3](https://github.com/adobe/spectrum-web-components/commit/f6887a34e228473e33893c81017492bf3e8fd6c3)) + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.7...@spectrum-web-components/menu@0.8.8) (2021-06-16) + +### Bug Fixes + +- update role application logic to not overwrite menu\* roles ([94b6aec](https://github.com/adobe/spectrum-web-components/commit/94b6aecffc1e5686feab09361d4e07ec3e854726)) + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.6...@spectrum-web-components/menu@0.8.7) (2021-06-07) + +### Bug Fixes + +- **menu:** clarify menu internal focus management via preventScroll option ([9ae092c](https://github.com/adobe/spectrum-web-components/commit/9ae092c7d09ef9359dbf9ed9373aef0650967f40)) + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.5...@spectrum-web-components/menu@0.8.6) (2021-05-24) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.4...@spectrum-web-components/menu@0.8.5) (2021-05-12) + +### Bug Fixes + +- **menu:** pass current focus visibility to menu items ([2d3bf80](https://github.com/adobe/spectrum-web-components/commit/2d3bf8046379fe8caff926af81e62806e77f6a49)) + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.3...@spectrum-web-components/menu@0.8.4) (2021-04-15) + +### Bug Fixes + +- **menu:** manage tabindex and focus entry correctly ([3b1a250](https://github.com/adobe/spectrum-web-components/commit/3b1a250c0ec4ad2b3553bbf100c8c7015ff3cbc6)) +- **menu:** only scrollIntoView when keyboard navigating ([f4e9278](https://github.com/adobe/spectrum-web-components/commit/f4e9278048287a45bba2da25144834b0b8297c66)) + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.2...@spectrum-web-components/menu@0.8.3) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.1...@spectrum-web-components/menu@0.8.2) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.8.0...@spectrum-web-components/menu@0.8.1) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.7.1...@spectrum-web-components/menu@0.8.0) (2021-03-22) + +### Bug Fixes + +- correctly delivery visuals and mouse interactions for litAnchor and extensions ([0ae889a](https://github.com/adobe/spectrum-web-components/commit/0ae889a8aab9b3417a021b917dfc817a8310f50f)) +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) + +### Features + +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.7.0...@spectrum-web-components/menu@0.7.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.6.3...@spectrum-web-components/menu@0.7.0) (2021-03-04) + +### Bug Fixes + +- **menu:** ensure active descendant is in view when activated ([6edc351](https://github.com/adobe/spectrum-web-components/commit/6edc3518fd305cbd35b74f013546bb32aef7616b)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.6.2...@spectrum-web-components/menu@0.6.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.6.1...@spectrum-web-components/menu@0.6.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.6.0...@spectrum-web-components/menu@0.6.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.4...@spectrum-web-components/menu@0.6.0) (2021-01-21) + +### Bug Fixes + +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- **menu:** prevent infinite loop when focus() ([e4e98a3](https://github.com/adobe/spectrum-web-components/commit/e4e98a358a1991c1d6048b01e2899dd28d56dc7e)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **menu:** update spectrum css input ([8c7e18a](https://github.com/adobe/spectrum-web-components/commit/8c7e18ac16f2747bd2f10173bcac0d5e53a0bcac)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.4...@spectrum-web-components/menu@0.5.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled](<[2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)>) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- **menu:** prevent infinite loop when focus() ([e4e98a3](https://github.com/adobe/spectrum-web-components/commit/e4e98a358a1991c1d6048b01e2899dd28d56dc7e)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **action-group:** manage "one" and "multiple" selections ([6fad59e](https://github.com/adobe/spectrum-web-components/commit/6fad59e0df1210108fe6b54ab075c0cbd94cae78)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **menu:** update spectrum css input ([8c7e18a](https://github.com/adobe/spectrum-web-components/commit/8c7e18ac16f2747bd2f10173bcac0d5e53a0bcac)) + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.3...@spectrum-web-components/menu@0.4.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.2...@spectrum-web-components/menu@0.4.3) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- **dropdown:** improve accessibility ([389d9d9](https://github.com/adobe/spectrum-web-components/commit/389d9d94a13bf31e10f58ee498bd848929e9d67c)) + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.1...@spectrum-web-components/menu@0.4.2) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.4.0...@spectrum-web-components/menu@0.4.1) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/menu + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.3.2...@spectrum-web-components/menu@0.4.0) (2020-08-31) + +### Features + +- allow dir management by sp-theme elements ([2d10158](https://github.com/adobe/spectrum-web-components/commit/2d1015883bc0c3a03862c0de8b4d996cd954291f)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- **split-button:** add split-button pattern ([4833a59](https://github.com/adobe/spectrum-web-components/commit/4833a598bb3da3552d194586350a3888dba79543)) + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.3.1...@spectrum-web-components/menu@0.3.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.3.0...@spectrum-web-components/menu@0.3.1) (2020-08-13) + +### Bug Fixes + +- **menu:** include all direct dependencies ([aa7327f](https://github.com/adobe/spectrum-web-components/commit/aa7327f748b829fa6f6eec2412ac104e9dbeff76)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.7...@spectrum-web-components/menu@0.3.0) (2020-07-17) + +### Features + +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.6...@spectrum-web-components/menu@0.2.7) (2020-06-08) + +### Bug Fixes + +- **menu:** support menu item list change in deep decendents ([b2b47f3](https://github.com/adobe/spectrum-web-components/commit/b2b47f305cab9720d29b4214b3330b95f33a56d3)) + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.5...@spectrum-web-components/menu@0.2.6) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.4...@spectrum-web-components/menu@0.2.5) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.3...@spectrum-web-components/menu@0.2.4) (2020-03-11) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.2...@spectrum-web-components/menu@0.2.3) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/menu + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.1...@spectrum-web-components/menu@0.2.2) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.2.0...@spectrum-web-components/menu@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.1.4...@spectrum-web-components/menu@0.2.0) (2019-11-19) + +### Bug Fixes + +- **menu:** allow for settign "selected" async from above ([9d7f622](https://github.com/adobe/spectrum-web-components/commit/9d7f622)) + +### Features + +- add screenshot regression testing to CI ([8205dfe](https://github.com/adobe/spectrum-web-components/commit/8205dfe)) +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc7)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/menu@0.1.3...@spectrum-web-components/menu@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/menu diff --git a/1st-gen/packages/menu/README.md b/1st-gen/packages/menu/README.md new file mode 100644 index 00000000000..abdf0123851 --- /dev/null +++ b/1st-gen/packages/menu/README.md @@ -0,0 +1,339 @@ +## Overview + +An `` is used for creating a menu list. The various elements inside a menu are given as [``](../menu-group), [``](../menu-item), or ``. Often a `` element will appear in a [``](../popover) element so that it displays as a toggling menu. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/menu?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/menu) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/menu?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/menu) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-ascdqv3p) + +``` +yarn add @spectrum-web-components/menu +``` + +Import the side effectful registration of ``, ``, ``, or `` individually as follows: + +``` +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +``` + +When looking to leverage the `Menu`, `MenuGroup`, `MenuItem`, or `MenuDivider` base classes as a type and/or for extension purposes, do so via: + +``` +import { + Menu, + MenuGroup, + MenuItem, + MenuDivider +} from '@spectrum-web-components/menu'; +``` + +### Anatomy + + +```html + + + Deselect + + + Select inverse + + + Feather... + + + Select and mask... + + + Save selection + + + Make work path + + +``` + +#### Popover menus + +Often an `` element will be delivered inside of an `` element when displaying it above other content. + +```html + + + Deselect + Select inverse + Feather... + Select and mask... + Save selection + Make work path + + +``` + +#### Labels + +To render accessibly, an `` element or its parent `` must have a label. For an accessible label that is visibly hidden, but can still be read by assistive technology, use the `label` attribute. + + +Menu with label + + +```html demo + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + +``` + + +Popover with label + + +```html demo + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + +``` + + + + +### Options + +#### Sizes + + +Small + + +```html demo + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + +``` + + +Medium + + +```html demo + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + +``` + + +Large + + +```html demo + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + +``` + + +Extra Large + + +```html demo + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + +``` + + + + +#### Selection + +The `` element can be instructed to maintain a selection via the `selects` attribute. Depending on the chosen algorithm, the `` element will hold a `value` property and manage the `selected` state of its `` descendants. + +- When `selects="single"`, the `` element will maintain one selected item after an initial selection is made. +- When `selects` is set to `multiple`, the `` element will maintain zero or more selected items. +- When `selects` is set to `inherit`, the `` element will allow its `` children to participate in the selection of its nearest `` ancestor. + + +Single + + +```html demo +

+ The value of the `<sp-menu>` element is: + +

+ + Square + Triangle + Parallelogram + Star + Hexagon + Circle + +``` + +
+Multiple + + +```html demo +

+ The value of the `<sp-menu>` element is: + item-3,item-4 +

+ + Apple + Banana + Goji berry + Grapes + Kumquat + Orange + +``` + +
+Inherit + + +```html demo +

+ The value of the `<sp-menu>` element is: + item-3 || item-4 || item-8 || item-11 +

+ + + Apple + Banana + Goji berry + Grapes + Kumquat + Orange + + + Carrot + Garlic + Lettuce + Onion + Potato + Tomato + + +``` + +
+
+ +### Behaviors + +#### "change" event + +Regardless of whether or not `` carries a selection, when one of the `` children that it manages is activated, the `` element will dispatch a `change` event. At dispatch time, even when a selection is not held due to the absence of the `selects` attribute, the `value` of the `` will correspond to the `` that was activated. When the `selects` attribute is present, this `value` will persist beyond the lifecycle of the `change` event. When `selects="multiple"`, the values of multiple items will be comma separated, unless otherwise set via the `value-separator` attribute. + +Note: The `change` event is only dispatched on a left mouse click or Enter/Space keypress. Right/Middle mouse clicks will not dispatch the `change` event. + +### Accessibility + +Review the accessibility guidelines for the [menu-item](../menu-item#accessibility-guidelines) and [menu-group](../menu-group#accessibility-guidelines) descendants. + +#### Include a label + +A menu is required to have an accessible label. diff --git a/1st-gen/packages/menu/menu-group.md b/1st-gen/packages/menu/menu-group.md new file mode 100644 index 00000000000..97c923e88dc --- /dev/null +++ b/1st-gen/packages/menu/menu-group.md @@ -0,0 +1,235 @@ +## Overview + +An `` will gather a collection of [``](../menu-item) elements into a group as part of the content delivered in an [``](../menu) element. Supplying content to the `header` slot will allow it label the group both visually and for screen readers. Like ``, an `` element can maintain a selection as outlined by the value or absence of its `selects` attribute. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/menu?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/menu) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/menu?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/menu) + +``` +yarn add @spectrum-web-components/menu +``` + +Import the side effectful registration of `` as follows: + +``` +import '@spectrum-web-components/menu/sp-menu-group.js'; +``` + +When looking to leverage the `MenuGroup` base class as a type and/or for extension purposes, do so via: + +``` +import { MenuGroup } from '@spectrum-web-components/menu'; +``` + +### Anatomy + +An `` can be used to organize `` elements in an `` into collections with a shared header. Use an element addressed to the `slot="header"` to pass in the content of that header. + + +```html demo + + + New York + + Central Park + + + Flushing Meadows Corona Park + + + Prospect Park + + + + San Francisco + + Golden Gate Park + + + John McLaren Park + + + Lake Merced Park + + + +
+``` + +### Behavior + +#### Selection + +The `` element can be instructed to maintain a selection via the `selects` attribute. Depending on the chosen algorithm, the `` element will hold a `value` property and manage the `selected` state of its `` descendants. + +- When `selects` is set to `single`, the `` element will maintain one selected item after an initial selection is made. +- When `selects` is set to `multiple`, the `` element will maintain zero or more selected items. +- When `selects` is set to `inherit`, the `` element will allow its `` children to participate in the selection of its nearest `` ancestor. + + +Single + + + +```html demo +

+ Your favorite park in New York is: +

+ Your favorite park in San Francisco is: +

+ + + + New York + + Central Park + + + Flushing Meadows Corona Park + + + Prospect Park + + + + San Francisco + + Golden Gate Park + + + John McLaren Park + + + Lake Merced Park + + + + +``` + +
+Multiple + + + +```html demo +

+ Your favorite parks in New York are: +

+ Your favorite parks in San Francisco are: +

+ + + + New York + + Central Park + + + Flushing Meadows Corona Park + + + Prospect Park + + + + San Francisco + + Golden Gate Park + + + John McLaren Park + + + Lake Merced Park + + + + +``` + +
+Inherit + + + +```html demo +

+ Your favorite park is: +

+ + + + New York + + Central Park + + + Flushing Meadows Corona Park + + + Prospect Park + + + + San Francisco + + Golden Gate Park + + + John McLaren Park + + + Lake Merced Park + + + + +``` + +
+
+ +### Accessibility + +Review the accessibility guidelines for the [menu-item](../menu-item#accessibility-guidelines) children and the guidelines for the parent [menu](../menu#accessibility-guidelines). diff --git a/1st-gen/packages/menu/menu-item.md b/1st-gen/packages/menu/menu-item.md new file mode 100644 index 00000000000..1954ec7e218 --- /dev/null +++ b/1st-gen/packages/menu/menu-item.md @@ -0,0 +1,368 @@ +## Description + +For use within an `` element, an `` represents a single item in a menu. + +## Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/menu?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/menu) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/menu?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/menu) + +``` +yarn add @spectrum-web-components/menu +``` + +Import the side effectful registration of `` as follows: + +``` +import '@spectrum-web-components/menu/sp-menu-item.js'; +``` + +When looking to leverage the `MenuItem` base class as a type and/or for extension purposes, do so via: + +``` +import { MenuItem } from '@spectrum-web-components/menu'; +``` + +### Anatomy + +Menus are a collection of ``s that can be modified via a `disabled` or `selected` attribute to represent an item in that state. + +```html + + Active Menu Item + Disabled Menu Item + Selected Menu Item + +``` + +#### Icon + +Content assigned to the `icon` slot will be placed at the beginning of the ``. + +```html + + + + Save + + + + Finish + + + + Review + + +``` + +##### Icon management + +When you use `` elements without text content, you will need to be sure to use the `value` attribute so that the `` or `` element can differentiate between the available options. Further, it is important that you apply accessible labeling to the `[slot="icon"]` content as follows: + +```html +Choose an action... + + + + + + + + + + + +``` + +### Description + +Content assigned to the `description` slot will be placed below the ``, like help text for users to understand the context of corresponding ``. + +```html + + + Quick export + Share a snapshot + + + Open a copy + Illustrator for iPad + + + Share link + Enable comments and download + + +``` + +#### Value + +##### Value slot + +Content assigned to the `value` slot will be placed at the end of the ``, like values, keyboard shortcuts, etc., based on the current text direction. + +```html + + + Save + ⌘S + + + Completed + 47% + + + Activity + More info + + +``` + +#### Value attribute + +When displayed as a descendent of an element that manages selection (e.g. ``, ``, ``, etc.), an `` will represent the "selected" value of that ancestor when its `value` attribute or the trimmed `textContent` (represeted by `el.itemText`) matches the `value` of the ancestor element. + +In the following example, the selected `` represents a `value` of `"Text that is really long and useful to a visitor, but not exactly good to use in your application or component state."` for the ancestor element. + + +Picker + + +```html demo +Value attribute usage: + + + Text that is really long and useful to a visitor, but not exactly good + to use in your application or component state. + + Not selected + +``` + + +Action menu + + +```html demo + + Menu items examples + + Text that is really long and useful to a visitor, but not exactly good + to use in your application or component state. + + Not selected + +``` + + + + +When the `value` attribute is leveraged, the selected `` represents a `value` of `"short-key"` for the `` element. + + +Picker + + +```html demo +Value attribute usage: + + Menu items examples + Not selected + + Text that is really long and useful to a visitor, but not exactly good + to use in your application or component state. + + +``` + + +Action menu + + +```html demo + + Menu items examples + Not selected + + Text that is really long and useful to a visitor, but not exactly good + to use in your application or component state. + + +``` + + + + +#### Submenu + +An `` can also accept content addressed to its `"submenu"` slot. An `` element with this slot name surfaces the options in an adjacent popover, which can be activated by hovering over the parent menu item with your pointer or focusing the menu item and pressing the appropriate `ArrowRight` or `ArrowLeft` key based on text direction to move into the submenu. + +```html +

+ Your favorite park in New York is: + +
+
+ Your favorite park in San Francisco is: + +

+ + + New York + + Central Park + Flushing Meadows Corona Park + Prospect Park + + + + San Francisco + + Golden Gate Park + John McLaren Park + Lake Merced Park + + + +``` + +Note: While `sp-menu-item` can accommodate any custom content in the `submenu` slot, it will not handle selection or keyboard navigation for such content. To ensure proper management of selection and keyboard navigation, it is recommended to use `sp-menu` within the `submenu` slot``` + +```html + + + Item with arbitrary content in submenu +
+ Kitten +

I am an arbitrary content in submenu

+
+
+
+``` + +### Value attribute + +When displayed as a descendent of an element that manages selection (e.g. ``, ``, etc.), an `` will represent the "selected" value of that ancestor when its `value` attribute or the trimmed `textContent` (represeted by `el.itemText`) matches the `value` of the ancestor element. + +In the following example, the selected `` represents a `value` of `Text that is really long and useful to a visitor, but not exactly good to use in your application or component state.` for the ancestor element. + +```html + + + Item with arbitrary content in submenu +
+ Kitten +

I am an arbitrary content in submenu

+
+
+
+``` + +Note: While `sp-menu-item` can accommodate any custom content in the `submenu` slot, it will not handle selection or keyboard navigation for such content. To ensure proper management of selection and keyboard navigation, it is recommended to use `sp-menu` within the `submenu` slot``` + +```html + + + Item with arbitrary content in submenu +
+ Kitten +

I am an arbitrary content in submenu

+
+
+
+``` + +### Accessibility + +Review the accessibility guidelines for the parent [menu](../menu#accessibility-guidelines) and [menu-group](../menu-group#accessibility-guidelines). + +#### Include a label + +Either place visible text in the component's slot or use `label` attribute to ensure menu items can be read by assistive technology. + + +Using slotted text + + +```html demo +Choose an action... + + + + Save + + + + Finish + + + + Review + + +``` + + +Using label attribute + + +```html demo +Choose an action... + + + + + + + + + + + +``` + + + diff --git a/1st-gen/packages/menu/package.json b/1st-gen/packages/menu/package.json new file mode 100644 index 00000000000..4c0acc29bd6 --- /dev/null +++ b/1st-gen/packages/menu/package.json @@ -0,0 +1,115 @@ +{ + "name": "@spectrum-web-components/menu", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/menu" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/menu", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Menu.js": { + "development": "./src/Menu.dev.js", + "default": "./src/Menu.js" + }, + "./src/MenuDivider.js": { + "development": "./src/MenuDivider.dev.js", + "default": "./src/MenuDivider.js" + }, + "./src/MenuGroup.js": { + "development": "./src/MenuGroup.dev.js", + "default": "./src/MenuGroup.js" + }, + "./src/MenuItem.js": { + "development": "./src/MenuItem.dev.js", + "default": "./src/MenuItem.js" + }, + "./src/checkmark-overrides.css.js": "./src/checkmark-overrides.css.js", + "./src/chevron-overrides.css.js": "./src/chevron-overrides.css.js", + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/menu-divider-overrides.css.js": "./src/menu-divider-overrides.css.js", + "./src/menu-divider.css.js": "./src/menu-divider.css.js", + "./src/menu-group.css.js": "./src/menu-group.css.js", + "./src/menu-item-overrides.css.js": "./src/menu-item-overrides.css.js", + "./src/menu-item.css.js": "./src/menu-item.css.js", + "./src/menu-overrides.css.js": "./src/menu-overrides.css.js", + "./src/menu.css.js": "./src/menu.css.js", + "./sp-menu.js": { + "development": "./sp-menu.dev.js", + "default": "./sp-menu.js" + }, + "./sp-menu-divider.js": { + "development": "./sp-menu-divider.dev.js", + "default": "./sp-menu-divider.js" + }, + "./sp-menu-group.js": { + "development": "./sp-menu-group.dev.js", + "default": "./sp-menu-group.js" + }, + "./sp-menu-item.js": { + "development": "./sp-menu-item.dev.js", + "default": "./sp-menu-item.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@lit-labs/observers": "2.0.2", + "@spectrum-web-components/action-button": "1.9.0", + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/divider": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-ui": "1.9.0", + "@spectrum-web-components/overlay": "1.9.0", + "@spectrum-web-components/popover": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/menu/sp-menu-divider.ts b/1st-gen/packages/menu/sp-menu-divider.ts new file mode 100644 index 00000000000..b873f96681d --- /dev/null +++ b/1st-gen/packages/menu/sp-menu-divider.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { MenuDivider } from './src/MenuDivider.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-menu-divider', MenuDivider); + +declare global { + interface HTMLElementTagNameMap { + 'sp-menu-divider': MenuDivider; + } +} diff --git a/1st-gen/packages/menu/sp-menu-group.ts b/1st-gen/packages/menu/sp-menu-group.ts new file mode 100644 index 00000000000..b8c8c5ae542 --- /dev/null +++ b/1st-gen/packages/menu/sp-menu-group.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { MenuGroup } from './src/MenuGroup.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-menu-group', MenuGroup); + +declare global { + interface HTMLElementTagNameMap { + 'sp-menu-group': MenuGroup; + } +} diff --git a/1st-gen/packages/menu/sp-menu-item.ts b/1st-gen/packages/menu/sp-menu-item.ts new file mode 100644 index 00000000000..c4274444246 --- /dev/null +++ b/1st-gen/packages/menu/sp-menu-item.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { MenuItem } from './src/MenuItem.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-menu-item', MenuItem); + +declare global { + interface HTMLElementTagNameMap { + 'sp-menu-item': MenuItem; + } +} diff --git a/1st-gen/packages/menu/sp-menu.ts b/1st-gen/packages/menu/sp-menu.ts new file mode 100644 index 00000000000..ca79a76cf5a --- /dev/null +++ b/1st-gen/packages/menu/sp-menu.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Menu } from './src/Menu.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-menu', Menu); + +declare global { + interface HTMLElementTagNameMap { + 'sp-menu': Menu; + } +} diff --git a/1st-gen/packages/menu/src/Menu.ts b/1st-gen/packages/menu/src/Menu.ts new file mode 100644 index 00000000000..28cbfb6f743 --- /dev/null +++ b/1st-gen/packages/menu/src/Menu.ts @@ -0,0 +1,1108 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; + +import { MenuItem } from './MenuItem.js'; +import type { + MenuItemAddedOrUpdatedEvent, + MenuItemKeydownEvent, +} from './MenuItem.js'; +import type { Overlay } from '@spectrum-web-components/overlay'; +import menuStyles from './menu.css.js'; +import { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js'; + +export interface MenuChildItem { + menuItem: MenuItem; + managed: boolean; + active: boolean; + focusable: boolean; + focusRoot: Menu; +} + +type SelectsType = 'none' | 'ignore' | 'inherit' | 'multiple' | 'single'; +type RoleType = 'group' | 'menu' | 'listbox' | 'none'; + +/** + * Spectrum Menu Component + * @element sp-menu + * + * @slot - menu items to be listed in the menu + * @fires change - Announces that the `value` of the element has changed + * @attr selects - whether the element has a specific selection algorithm that it applies + * to its item descendants. `single` allows only one descendent to be selected at a time. + * `multiple` allows many descendants to be selected. `inherit` will be applied dynamically + * when an ancestor of this element is actively managing the selection of its descendents. + * When the `selects` attribute is not present a `value` will not be maintained and the Menu + * Item children of this Menu will not have their `selected` state managed. + */ +export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) { + public static override get styles(): CSSResultArray { + return [menuStyles]; + } + + static override shadowRootOptions = { + ...SpectrumElement.shadowRootOptions, + delegatesFocus: true, + }; + + private get isSubmenu(): boolean { + return this.slot === 'submenu'; + } + + protected rovingTabindexController?: RovingTabindexController; + + /** + * iPad scroll detection properties + * + * This feature prevents menu item selection during iPad scrolling to avoid + * accidental selections when users are trying to scroll through a long menu. + * + * How it works: + * 1. On touchstart: Record initial Y position and timestamp + * 2. On touchmove: Calculate vertical movement and time elapsed + * 3. If movement > threshold AND time < threshold: Mark as scrolling + * 4. On touchend: Reset scrolling state after a delay + * 5. During selection: Prevent selection if scrolling is detected + * + * This prevents the common iPad issue where users accidentally select menu + * items while trying to scroll through the menu content. + * + * Threshold Values: + * - Movement threshold: 10px (consistent with Card component click vs. drag detection) + * - Time threshold: 300ms (consistent with longpress duration across the design system) + * - Reset delay: 100ms (allows final touch events to be processed) + * + * These values are carefully chosen to balance preventing accidental triggers + * while allowing intentional scroll gestures. They represent a common UX pattern + * in mobile interfaces and are consistent with other components in the design system. + */ + private touchStartY: number | undefined = undefined; + private touchStartTime: number | undefined = undefined; + private isCurrentlyScrolling = false; + + /** + * Minimum vertical movement (in pixels) required to trigger scrolling detection. + * + * This threshold is consistent with other components in the design system: + * - Card component uses 10px for click vs. drag detection + * - Menu component uses 10px for scroll vs. selection detection + * + * The 10px threshold is carefully chosen to: + * - Allow for natural finger tremor and accidental touches + * - Distinguish between intentional scroll gestures and taps + * - Provide consistent behavior across the platform + * + * @see {@link packages/card/src/Card.ts} for similar threshold usage + */ + private scrollThreshold = 10; // pixels + + /** + * Maximum time (in milliseconds) for a movement to be considered scrolling. + * + * This threshold is consistent with other timing values in the design system: + * - Longpress duration: 300ms (ActionButton, LongpressController) + * - Scroll detection: 300ms (Menu component) + * + * Quick movements within this timeframe are likely intentional scrolls, + * while slower movements are more likely taps or selections. + * + * @see {@link packages/action-button/src/ActionButton.ts} for longpress duration + * @see {@link packages/overlay/src/LongpressController.ts} for longpress duration + */ + private scrollTimeThreshold = 300; // milliseconds + + /** + * Public getter for scrolling state + * Returns true if the component is currently in a scrolling state + */ + public get isScrolling(): boolean { + return this.isCurrentlyScrolling; + } + + public set isScrolling(value: boolean) { + // For testing purposes, allow setting the scrolling state + this.isCurrentlyScrolling = value; + } + + /** + * label of the menu + */ + @property({ type: String, reflect: true }) + public label = ''; + + /** + * whether menu should be ignored by roving tabindex controller + */ + @property({ type: Boolean, reflect: true }) + public ignore = false; + + /** + * how the menu allows selection of its items: + * - `undefined` (default): no selection is allowed + * - `"inherit"`: the selection behavior is managed from an ancestor + * - `"single"`: only one item can be selected at a time + * - `"multiple"`: multiple items can be selected + */ + @property({ type: String, reflect: true }) + public selects: undefined | 'inherit' | 'single' | 'multiple'; + + /** + * value of the selected item(s) + */ + @property({ type: String }) + public value = ''; + + // For the multiple select case, we'll join the value strings together + // for the value property with this separator + @property({ type: String, attribute: 'value-separator' }) + public valueSeparator = ','; + + /** + * selected items values as string + */ + @property({ attribute: false }) + public get selected(): string[] { + return !this.selects ? [] : this._selected; + } + + public set selected(selected: string[]) { + if (selected === this.selected) { + return; + } + const old = this.selected; + this._selected = selected; + this.selectedItems = []; + this.selectedItemsMap.clear(); + this.childItems.forEach((item) => { + if (this !== item.menuData.selectionRoot) { + return; + } + item.selected = this.selected.includes(item.value); + if (item.selected) { + this.selectedItems.push(item); + this.selectedItemsMap.set(item, true); + } + }); + this.requestUpdate('selected', old); + } + + protected _selected = [] as string[]; + + /** + * array of selected menu items + */ + @property({ attribute: false }) + public selectedItems = [] as MenuItem[]; + + @query('slot:not([name])') + public menuSlot!: HTMLSlotElement; + + private childItemSet = new Set(); + public focusedItemIndex = 0; + public focusInItemIndex = 0; + + /** + * Whether to support the pointerdown-drag-pointerup selection strategy. + * Defaults to false to prevent click/touch events from being captured + * behind the menu tray in mobile environments (since the menu closes + * immediately on pointerup). + */ + + public shouldSupportDragAndSelect = false; + + public get focusInItem(): MenuItem | undefined { + return this.rovingTabindexController?.focusInElement; + } + + protected get controlsRovingTabindex(): boolean { + return true; + } + + private selectedItemsMap = new Map(); + + /** + * child items managed by menu + */ + public get childItems(): MenuItem[] { + if (!this.cachedChildItems) { + this.cachedChildItems = this.updateCachedMenuItems(); + } + return this.cachedChildItems; + } + + private cachedChildItems: MenuItem[] | undefined; + + private updateCachedMenuItems(): MenuItem[] { + if (!this.menuSlot) { + return []; + } + const itemsList = []; + const slottedElements = this.menuSlot.assignedElements({ + flatten: true, + }) as HTMLElement[]; + // Recursively flatten and non- elements assigned to the menu into a single array. + for (const [i, slottedElement] of slottedElements.entries()) { + if (this.childItemSet.has(slottedElement as MenuItem)) { + // Assign members of the array that are in this.childItemSet to this.chachedChildItems. + itemsList.push(slottedElement as MenuItem); + continue; + } + const isHTMLSlotElement = slottedElement.localName === 'slot'; + const flattenedChildren = isHTMLSlotElement + ? (slottedElement as HTMLSlotElement).assignedElements({ + flatten: true, + }) + : [...slottedElement.querySelectorAll(`:scope > *`)]; + slottedElements.splice( + i, + 1, + slottedElement, + ...(flattenedChildren as HTMLElement[]) + ); + } + + this.cachedChildItems = [...itemsList]; + this.rovingTabindexController?.clearElementCache(); + + return this.cachedChildItems; + } + + /** + * Hide this getter from web-component-analyzer until + * https://github.com/runem/web-component-analyzer/issues/131 + * has been addressed. + * + * @private + */ + public get childRole(): string { + if (this.resolvedRole === 'listbox') { + return 'option'; + } + switch (this.resolvedSelects) { + case 'single': + return 'menuitemradio'; + case 'multiple': + return 'menuitemcheckbox'; + default: + return 'menuitem'; + } + } + + protected get ownRole(): string { + return 'menu'; + } + + /** + * menuitem role based on selection type + */ + private resolvedSelects?: SelectsType; + + /** + * menu role based on selection type + */ + private resolvedRole?: RoleType; + + /** + * When a descendant `` element is added or updated it will dispatch + * this event to announce its presence in the DOM. During the CAPTURE phase the first + * Menu based element that the event encounters will manage the focus state of the + * dispatching `` element. + * @param event + */ + private onFocusableItemAddedOrUpdated( + event: MenuItemAddedOrUpdatedEvent + ): void { + event.menuCascade.set(this, { + hadFocusRoot: !!event.item.menuData.focusRoot, + ancestorWithSelects: event.currentAncestorWithSelects, + }); + if (this.selects) { + event.currentAncestorWithSelects = this; + } + event.item.menuData.focusRoot = event.item.menuData.focusRoot || this; + } + + /** + * When a descendant `` element is added or updated it will dispatch + * this event to announce its presence in the DOM. During the BUBBLE phase the first + * Menu based element that the event encounters that does not inherit selection will + * manage the selection state of the dispatching `` element. + * @param event + */ + private onSelectableItemAddedOrUpdated( + event: MenuItemAddedOrUpdatedEvent + ): void { + const cascadeData = event.menuCascade.get(this); + /* c8 ignore next 1 */ + if (!cascadeData) return; + + event.item.menuData.parentMenu = event.item.menuData.parentMenu || this; + this.addChildItem(event.item); + + if (this.selects === 'inherit') { + this.resolvedSelects = 'inherit'; + const ignoreMenu = event.currentAncestorWithSelects?.ignore; + this.resolvedRole = ignoreMenu + ? 'none' + : ((event.currentAncestorWithSelects?.getAttribute('role') || + this.getAttribute('role') || + undefined) as RoleType); + } else if (this.selects) { + this.resolvedRole = this.ignore + ? 'none' + : ((this.getAttribute('role') || undefined) as RoleType); + this.resolvedSelects = this.selects; + } else { + this.resolvedRole = this.ignore + ? 'none' + : ((this.getAttribute('role') || undefined) as RoleType); + this.resolvedSelects = + this.resolvedRole === 'none' ? 'ignore' : 'none'; + } + + if (this.resolvedRole === 'none') { + return; + } + + const selects = + this.resolvedSelects === 'single' || + this.resolvedSelects === 'multiple'; + event.item.menuData.cleanupSteps.push((item: MenuItem) => + this.removeChildItem(item) + ); + if ( + (selects || (!this.selects && this.resolvedSelects !== 'ignore')) && + !event.item.menuData.selectionRoot + ) { + event.item.setRole(this.childRole); + event.item.menuData.selectionRoot = + event.item.menuData.selectionRoot || this; + if (event.item.selected) { + this.selectedItemsMap.set(event.item, true); + this.selectedItems = [...this.selectedItems, event.item]; + this._selected = [...this.selected, event.item.value]; + this.value = this.selected.join(this.valueSeparator); + } + } + } + + private addChildItem(item: MenuItem): void { + this.childItemSet.add(item); + this.handleItemsChanged(); + } + + private async removeChildItem(item: MenuItem): Promise { + if (item.focused || item.hasAttribute('focused') || item.active) { + this._updateFocus = this.getNeighboringFocusableElement(item); + } + this.childItemSet.delete(item); + this.cachedChildItems = undefined; + } + + public constructor() { + super(); + + /** + * only create an RTI if menu controls keyboard navigation and one does not already exist + */ + if (!this.rovingTabindexController && this.controlsRovingTabindex) { + this.rovingTabindexController = + new RovingTabindexController(this, { + direction: 'vertical', + focusInIndex: (elements: MenuItem[] | undefined) => { + let firstEnabledIndex = -1; + const firstSelectedIndex = elements?.findIndex( + (el, index) => { + if ( + !elements[firstEnabledIndex] && + !el.disabled + ) { + firstEnabledIndex = index; + } + return el.selected && !el.disabled; + } + ); + return elements && + firstSelectedIndex && + elements[firstSelectedIndex] + ? firstSelectedIndex + : firstEnabledIndex; + }, + elements: () => this.childItems, + isFocusableElement: this.isFocusableElement.bind(this), + hostDelegatesFocus: true, + }); + } + + this.addEventListener( + 'sp-menu-item-added-or-updated', + this.onSelectableItemAddedOrUpdated + ); + this.addEventListener( + 'sp-menu-item-added-or-updated', + this.onFocusableItemAddedOrUpdated, + { + capture: true, + } + ); + this.addEventListener('click', this.handleClick); + this.addEventListener('touchend', this.handlePointerup); + this.addEventListener('focusout', this.handleFocusout); + this.addEventListener('sp-menu-item-keydown', this.handleKeydown); + this.addEventListener('pointerup', this.handlePointerup); + this.addEventListener('sp-opened', this.handleSubmenuOpened); + this.addEventListener('sp-closed', this.handleSubmenuClosed); + + // Add touch event listeners for iPad scroll detection + this.addEventListener('touchstart', this.handleTouchStart, { + passive: true, + }); + this.addEventListener('touchmove', this.handleTouchMove, { + passive: true, + }); + } + + /** + * for picker elements, will set focus on first selected item + */ + public focusOnFirstSelectedItem({ + preventScroll, + }: FocusOptions = {}): void { + if (!this.rovingTabindexController) return; + const selectedItem = this.selectedItems.find((el) => + this.isFocusableElement(el) + ); + if (!selectedItem) { + this.focus({ preventScroll }); + return; + } + + if (selectedItem && !preventScroll) { + selectedItem.scrollIntoView({ block: 'nearest' }); + } + this.rovingTabindexController?.focusOnItem(selectedItem); + } + + public override focus({ preventScroll }: FocusOptions = {}): void { + if (this.rovingTabindexController) { + if ( + !this.childItems.length || + this.childItems.every((childItem) => childItem.disabled) + ) { + return; + } + if ( + this.childItems.some( + (childItem) => childItem.menuData.focusRoot !== this + ) + ) { + super.focus({ preventScroll }); + return; + } + this.rovingTabindexController.focus({ preventScroll }); + } + } + + /** + * Handles touchstart events for iPad scroll detection. + * + * Records the initial touch position and timestamp to establish a baseline + * for detecting scroll gestures. Only processes single-touch events to + * avoid interference with multi-touch gestures. + * + * @param event - The TouchEvent from the touchstart event + */ + private handleTouchStart(event: TouchEvent): void { + if (event.touches.length === 1) { + this.touchStartY = event.touches[0].clientY; + this.touchStartTime = Date.now(); + this.isCurrentlyScrolling = false; + } + } + + /** + * Handles touchmove events for iPad scroll detection. + * + * Calculates the vertical movement distance and time elapsed since touchstart. + * If the movement exceeds the threshold (10px) and happens within the time + * threshold (300ms), it marks the interaction as scrolling. This helps + * distinguish between intentional scroll gestures and accidental touches. + * + * @param event - The TouchEvent from the touchmove event + */ + private handleTouchMove(event: TouchEvent): void { + if ( + event.touches.length === 1 && + this.touchStartY !== undefined && + this.touchStartTime !== undefined + ) { + const currentY = event.touches[0].clientY; + const deltaY = Math.abs(currentY - this.touchStartY); + const deltaTime = Date.now() - this.touchStartTime; + + if ( + deltaY > this.scrollThreshold && + deltaTime < this.scrollTimeThreshold + ) { + this.isCurrentlyScrolling = true; + } + } + } + + /** + * Handles touchend events for iPad scroll detection. + * + * Resets the scrolling state after a short delay (100ms) to allow for + * any final touch events to be processed. This delay prevents immediate + * state changes that could interfere with the selection logic. + * + * The 100ms delay is consistent with the design system's approach to + * touch event handling and ensures that any final touch events or + * gesture recognition can complete before the scrolling state is reset. + */ + private handleTouchEnd(): void { + // Reset scrolling state after a short delay + setTimeout(() => { + this.isCurrentlyScrolling = false; + this.touchStartY = undefined; + this.touchStartTime = undefined; + }, 100); + } + + // if the click and pointerup events are on the same target, we should not + // handle the click event. + private pointerUpTarget = null as EventTarget | null; + + private handleFocusout(): void { + if (!this.matches(':focus-within')) + this.rovingTabindexController?.reset(); + } + + private handleClick(event: Event): void { + if (this.pointerUpTarget === event.target) { + this.pointerUpTarget = null; + return; + } + this.handlePointerBasedSelection(event); + } + + private handlePointerup(event: Event): void { + // Reset scrolling state for iPad scroll detection + // This ensures the scrolling state is properly reset for both touch + // and pointer events, maintaining consistency across different input methods. + this.handleTouchEnd(); + + /* + * early return if drag and select is not supported + * in this case, selection will be handled by the click event + */ + if (!this.shouldSupportDragAndSelect) { + return; + } + this.pointerUpTarget = event.target; + this.handlePointerBasedSelection(event); + } + + private async handlePointerBasedSelection(event: Event): Promise { + // Only handle left clicks + if (event instanceof MouseEvent && event.button !== 0) { + return; + } + + // Prevent selection if we're currently scrolling (iPad fix) + // This prevents accidental menu item selection when users are trying + // to scroll through a long menu on iPad devices. + if (this.isScrolling) { + return; + } + + const path = event.composedPath(); + const target = path.find((el) => { + /* c8 ignore next 3 */ + if (!(el instanceof Element)) { + return false; + } + return el.getAttribute('role') === this.childRole; + }) as MenuItem; + if (event.defaultPrevented) { + const index = this.childItems.indexOf(target); + if (target?.menuData?.focusRoot === this && index > -1) { + this.focusedItemIndex = index; + } + return; + } + if (target?.href && target.href.length) { + // This event will NOT ALLOW CANCELATION as link action + // cancelation should occur on the `` itself. + this.dispatchEvent( + new Event('change', { + bubbles: true, + composed: true, + }) + ); + return; + } else if ( + target?.menuData?.selectionRoot === this && + this.childItems.length + ) { + event.preventDefault(); + if (target.hasSubmenu || target.open) { + return; + } + this.selectOrToggleItem(target); + } else { + return; + } + this.prepareToCleanUp(); + } + + private descendentOverlays = new Map(); + + protected handleDescendentOverlayOpened(event: Event): void { + const target = event.composedPath()[0] as MenuItem; + /* c8 ignore next 1 */ + if (!target.overlayElement) return; + this.descendentOverlays.set( + target.overlayElement, + target.overlayElement + ); + } + + protected handleDescendentOverlayClosed(event: Event): void { + const target = event.composedPath()[0] as MenuItem; + /* c8 ignore next 1 */ + if (!target.overlayElement) return; + this.descendentOverlays.delete(target.overlayElement); + } + + public handleSubmenuClosed = (event: Event): void => { + event.stopPropagation(); + const target = event.composedPath()[0] as Overlay; + target.dispatchEvent( + new Event('sp-menu-submenu-closed', { + bubbles: true, + composed: true, + }) + ); + }; + + /** + * given a menu item, returns the next focusable menu item before or after it; + * if no menu item is provided, returns the first focusable menu item + * @param menuItem {MenuItem} + * @param before {boolean} return the item before; default is false + * @returns {MenuItem} + */ + public getNeighboringFocusableElement( + menuItem?: MenuItem, + before = false + ): MenuItem { + const diff = before ? -1 : 1; + const elements = this.rovingTabindexController?.elements || []; + const index = !!menuItem ? elements.indexOf(menuItem) : -1; + let newIndex = Math.min(Math.max(0, index + diff), elements.length - 1); + while ( + !this.isFocusableElement(elements[newIndex]) && + 0 < newIndex && + newIndex < elements.length - 1 + ) { + newIndex += diff; + } + return !!this.isFocusableElement(elements[newIndex]) + ? (elements[newIndex] as MenuItem) + : menuItem || elements[0]; + } + + public handleSubmenuOpened = (event: Event): void => { + event.stopPropagation(); + const target = event.composedPath()[0] as Overlay; + target.dispatchEvent( + new Event('sp-menu-submenu-opened', { + bubbles: true, + composed: true, + }) + ); + + const openedItem = event + .composedPath() + .find((el) => this.childItemSet.has(el as MenuItem)); + /* c8 ignore next 1 */ + if (!openedItem) return; + }; + + public async selectOrToggleItem(targetItem: MenuItem): Promise { + const resolvedSelects = this.resolvedSelects; + const oldSelectedItemsMap = new Map(this.selectedItemsMap); + const oldSelected = this.selected.slice(); + const oldSelectedItems = this.selectedItems.slice(); + const oldValue = this.value; + + if (targetItem.menuData.selectionRoot !== this) { + return; + } + + if (resolvedSelects === 'multiple') { + if (this.selectedItemsMap.has(targetItem)) { + this.selectedItemsMap.delete(targetItem); + } else { + this.selectedItemsMap.set(targetItem, true); + } + + // Match HTML select and set the first selected + // item as the value. Also set the selected array + // in the order of the menu items. + const selected: string[] = []; + const selectedItems: MenuItem[] = []; + + this.childItemSet.forEach((childItem) => { + if (childItem.menuData.selectionRoot !== this) return; + + if (this.selectedItemsMap.has(childItem)) { + selected.push(childItem.value); + selectedItems.push(childItem); + } + }); + this._selected = selected; + this.selectedItems = selectedItems; + this.value = this.selected.join(this.valueSeparator); + } else { + this.selectedItemsMap.clear(); + this.selectedItemsMap.set(targetItem, true); + this.value = targetItem.value; + this._selected = [targetItem.value]; + this.selectedItems = [targetItem]; + } + + const applyDefault = this.dispatchEvent( + new Event('change', { + cancelable: true, + bubbles: true, + composed: true, + }) + ); + + if (!applyDefault) { + // Cancel the event & don't apply the selection + this._selected = oldSelected; + this.selectedItems = oldSelectedItems; + this.selectedItemsMap = oldSelectedItemsMap; + this.value = oldValue; + return; + } + // Apply the selection changes to the menu items + if (resolvedSelects === 'single') { + for (const oldItem of oldSelectedItemsMap.keys()) { + if (oldItem !== targetItem) { + oldItem.selected = false; + } + } + targetItem.selected = true; + } else if (resolvedSelects === 'multiple') { + targetItem.selected = !targetItem.selected; + } else if ( + !targetItem.hasSubmenu && + targetItem?.menuData?.focusRoot === this + ) { + this.dispatchEvent(new Event('close', { bubbles: true })); + } + } + + protected navigateBetweenRelatedMenus(event: MenuItemKeydownEvent): void { + const { key, root } = event; + const shouldOpenSubmenu = + (this.isLTR && key === 'ArrowRight') || + (!this.isLTR && key === 'ArrowLeft'); + const shouldCloseSelfAsSubmenu = + (this.isLTR && key === 'ArrowLeft') || + (!this.isLTR && key === 'ArrowRight') || + key === 'Escape'; + const lastFocusedItem = root as MenuItem; + if (shouldOpenSubmenu) { + if (lastFocusedItem?.hasSubmenu) { + //open submenu and set focus + event.stopPropagation(); + lastFocusedItem.openOverlay(true); + } + } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) { + event.stopPropagation(); + this.dispatchEvent(new Event('close', { bubbles: true })); + this.updateSelectedItemIndex(); + } + } + + public handleKeydown(event: Event): void { + if (event.defaultPrevented || !this.rovingTabindexController) { + return; + } + const { key, root, shiftKey, target } = event as MenuItemKeydownEvent; + const openSubmenuKey = ['Enter', ' '].includes(key); + if (shiftKey && target !== this && this.hasAttribute('tabindex')) { + this.removeAttribute('tabindex'); + const replaceTabindex = ( + event: FocusEvent | KeyboardEvent + ): void => { + if ( + !(event as KeyboardEvent).shiftKey && + !this.hasAttribute('tabindex') + ) { + document.removeEventListener('keyup', replaceTabindex); + this.removeEventListener('focusout', replaceTabindex); + } + }; + document.addEventListener('keyup', replaceTabindex); + this.addEventListener('focusout', replaceTabindex); + } + if (key === 'Tab') { + this.closeDescendentOverlays(); + return; + } + if (openSubmenuKey && root?.hasSubmenu && !root.open) { + // Remove focus while opening overlay from keyboard or the visible focus + // will slip back to the first item in the menu. + event.preventDefault(); + root.openOverlay(true); + return; + } + if (key === ' ' || key === 'Enter') { + event.preventDefault(); + root?.focusElement?.click(); + if (root) this.selectOrToggleItem(root); + return; + } + this.navigateBetweenRelatedMenus(event as MenuItemKeydownEvent); + } + + private _hasUpdatedSelectedItemIndex = false; + + /** + * on focus, removes focus from focus styling item, and updates the selected item index + */ + private prepareToCleanUp(): void { + document.addEventListener( + 'focusout', + () => { + requestAnimationFrame(() => { + const focusedItem = this.focusInItem; + if (focusedItem) { + focusedItem.focused = false; + } + }); + }, + { once: true } + ); + } + + public updateSelectedItemIndex(): void { + let firstOrFirstSelectedIndex = 0; + const selectedItemsMap = new Map(); + const selected: string[] = []; + const selectedItems: MenuItem[] = []; + let itemIndex = this.childItems.length; + while (itemIndex) { + itemIndex -= 1; + const childItem = this.childItems[itemIndex]; + if (childItem.menuData.selectionRoot === this) { + if ( + childItem.selected || + (!this._hasUpdatedSelectedItemIndex && + this.selected.includes(childItem.value)) + ) { + firstOrFirstSelectedIndex = itemIndex; + selectedItemsMap.set(childItem, true); + selected.unshift(childItem.value); + selectedItems.unshift(childItem); + } + // Remove "focused" from non-"selected" items ONLY + // Preserve "focused" on index===0 when no selection + if (itemIndex !== firstOrFirstSelectedIndex) { + childItem.focused = false; + } + } + } + + this.selectedItemsMap = selectedItemsMap; + this._selected = selected; + this.selectedItems = selectedItems; + this.value = this.selected.join(this.valueSeparator); + this.focusedItemIndex = firstOrFirstSelectedIndex; + this.focusInItemIndex = firstOrFirstSelectedIndex; + } + + private _willUpdateItems = false; + private _updateFocus?: MenuItem; + + private handleItemsChanged(): void { + this.cachedChildItems = undefined; + if (!this._willUpdateItems) { + this._willUpdateItems = true; + this.cacheUpdated = this.updateCache(); + } + } + + private async updateCache(): Promise { + if (!this.hasUpdated) { + await Promise.all([ + new Promise((res) => requestAnimationFrame(() => res(true))), + this.updateComplete, + ]); + } else { + await new Promise((res) => requestAnimationFrame(() => res(true))); + } + if (this.cachedChildItems === undefined) { + this.updateSelectedItemIndex(); + this.updateItemFocus(); + } + + this._willUpdateItems = false; + } + + private updateItemFocus(): void { + this.focusInItem?.setAttribute('tabindex', '0'); + if (this.childItems.length == 0) { + return; + } + } + + public closeDescendentOverlays(): void { + this.descendentOverlays.forEach((overlay) => { + overlay.open = false; + }); + this.descendentOverlays = new Map(); + } + + private handleSlotchange({ + target, + }: Event & { target: HTMLSlotElement }): void { + const assignedElements = target.assignedElements({ + flatten: true, + }) as MenuItem[]; + if (this.childItems.length !== assignedElements.length) { + assignedElements.forEach((item) => { + if (typeof item.triggerUpdate !== 'undefined') { + item.triggerUpdate(); + } else if ( + typeof (item as unknown as Menu).childItems !== 'undefined' + ) { + (item as unknown as Menu).childItems.forEach((child) => { + child.triggerUpdate(); + }); + } + }); + } + if (!!this._updateFocus) { + this.rovingTabindexController?.focusOnItem(this._updateFocus); + this._updateFocus = undefined; + } + } + + protected renderMenuItemSlot(): TemplateResult { + return html` + + `; + } + + public override render(): TemplateResult { + return this.renderMenuItemSlot(); + } + + protected override firstUpdated(changed: PropertyValues): void { + super.firstUpdated(changed); + const updates: Promise[] = [ + new Promise((res) => requestAnimationFrame(() => res(true))), + ]; + [...this.children].forEach((item) => { + if ((item as MenuItem).localName === 'sp-menu-item') { + updates.push((item as MenuItem).updateComplete); + } + }); + this.childItemsUpdated = Promise.all(updates); + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if (changes.has('selects') && this.hasUpdated) { + this.selectsChanged(); + } + if ( + changes.has('label') && + (this.label || typeof changes.get('label') !== 'undefined') + ) { + if (this.label) { + this.setAttribute('aria-label', this.label); + /* c8 ignore next 3 */ + } else { + this.removeAttribute('aria-label'); + } + } + } + + protected selectsChanged(): void { + const updates: Promise[] = [ + new Promise((res) => requestAnimationFrame(() => res(true))), + ]; + this.childItemSet.forEach((childItem) => { + updates.push(childItem.triggerUpdate()); + }); + this.childItemsUpdated = Promise.all(updates); + } + + public override connectedCallback(): void { + super.connectedCallback(); + if (!this.hasAttribute('role') && !this.ignore) { + this.setAttribute('role', this.ownRole); + } + this.updateComplete.then(() => this.updateItemFocus()); + } + + private isFocusableElement(el: MenuItem): boolean { + return el ? !el.disabled : false; + } + + public override disconnectedCallback(): void { + this.cachedChildItems = undefined; + this.selectedItems = []; + this.selectedItemsMap.clear(); + this.childItemSet.clear(); + this.descendentOverlays = new Map(); + super.disconnectedCallback(); + } + + protected childItemsUpdated!: Promise; + protected cacheUpdated = Promise.resolve(); + /* c8 ignore next 3 */ + protected resolveCacheUpdated = (): void => { + return; + }; + + protected override async getUpdateComplete(): Promise { + const complete = (await super.getUpdateComplete()) as boolean; + await this.childItemsUpdated; + await this.cacheUpdated; + return complete; + } +} diff --git a/1st-gen/packages/menu/src/MenuDivider.ts b/1st-gen/packages/menu/src/MenuDivider.ts new file mode 100644 index 00000000000..33fcb02db8b --- /dev/null +++ b/1st-gen/packages/menu/src/MenuDivider.ts @@ -0,0 +1,37 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + PropertyValues, + SizedMixin, + SpectrumElement, +} from '@spectrum-web-components/base'; + +import menuDividerStyles from './menu-divider.css.js'; +import dividerStyles from '@spectrum-web-components/divider/src/divider.css.js'; + +/** + * @element sp-menu-divider + */ +export class MenuDivider extends SizedMixin(SpectrumElement, { + validSizes: ['s', 'm', 'l'], +}) { + public static override get styles(): CSSResultArray { + return [dividerStyles, menuDividerStyles]; + } + + protected override firstUpdated(changed: PropertyValues): void { + super.firstUpdated(changed); + this.setAttribute('role', 'separator'); + } +} diff --git a/1st-gen/packages/menu/src/MenuGroup.ts b/1st-gen/packages/menu/src/MenuGroup.ts new file mode 100644 index 00000000000..0e8c9d23309 --- /dev/null +++ b/1st-gen/packages/menu/src/MenuGroup.ts @@ -0,0 +1,98 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + queryAssignedNodes, + state, +} from '@spectrum-web-components/base/src/decorators.js'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; + +import { Menu } from './Menu.js'; +// Leveraged in build systems that use aliasing to prevent multiple registrations: https://github.com/adobe/spectrum-web-components/pull/3225 +import '@spectrum-web-components/menu/sp-menu.js'; +import menuGroupStyles from './menu-group.css.js'; + +/** + * @element sp-menu-group + * + * @slot header - headline of the menu group + * @slot - menu items to be listed in the group + */ +export class MenuGroup extends Menu { + public static override get styles(): CSSResultArray { + return [...super.styles, menuGroupStyles]; + } + + private headerId = ''; + + @queryAssignedNodes({ + slot: 'header', + flatten: true, + }) + private headerElements!: NodeListOf; + + @state() + private headerElement?: HTMLElement; + + /** + * a menu group must have the role `group` + * and should never function as a menu + */ + protected override get ownRole(): string { + return 'group'; + } + + /** + * only a menu controls roving tabindex; + * groups should defer navigation to parent menu + */ + protected override get controlsRovingTabindex(): boolean { + return false; + } + + protected updateLabel(): void { + const headerElement = this.headerElements.length + ? this.headerElements[0] + : undefined; + if (headerElement !== this.headerElement) { + if (this.headerElement && this.headerElement.id === this.headerId) { + this.headerElement.removeAttribute('id'); + } + if (headerElement) { + this.headerId = + this.headerId || `sp-menu-group-label-${randomID()}`; + const headerId = headerElement.id || this.headerId; + if (!headerElement.id) { + headerElement.id = headerId; + } + this.setAttribute('aria-labelledby', headerId); + } else { + this.removeAttribute('aria-labelledby'); + } + } + this.headerElement = headerElement; + } + + public override render(): TemplateResult { + return html` + + + + ${this.renderMenuItemSlot()} + `; + } +} diff --git a/1st-gen/packages/menu/src/MenuItem.ts b/1st-gen/packages/menu/src/MenuItem.ts new file mode 100644 index 00000000000..75de1e0de3d --- /dev/null +++ b/1st-gen/packages/menu/src/MenuItem.ts @@ -0,0 +1,877 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + INPUT_COMPONENT_PATTERN, + nothing, + PropertyValues, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + ObserveSlotPresence, + ObserveSlotText, + randomID, +} from '@spectrum-web-components/shared'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; + +import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js'; +import { LikeAnchor } from '@spectrum-web-components/shared/src/like-anchor.js'; +import { Focusable } from '@spectrum-web-components/shared/src/focusable.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js'; +import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js'; +import { DependencyManagerController } from '@spectrum-web-components/reactive-controllers/src/DependencyManger.js'; + +import menuItemStyles from './menu-item.css.js'; +import checkmarkStyles from '@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js'; +import type { Menu } from './Menu.js'; +import { MutationController } from '@lit-labs/observers/mutation-controller.js'; +import type { Overlay } from '@spectrum-web-components/overlay'; +import { SlottableRequestEvent } from '@spectrum-web-components/overlay/src/slottable-request-event.js'; + +/** + * Duration during which a pointing device can leave an `` element + * and return to it or to the submenu opened from it before closing that submenu. + **/ +const POINTERLEAVE_TIMEOUT = 100; + +type MenuCascadeItem = { + hadFocusRoot: boolean; + ancestorWithSelects?: HTMLElement; +}; + +/** + * Fires when a menu item is added or updated so that a parent menu can track it. + */ +export class MenuItemAddedOrUpdatedEvent extends Event { + constructor(item: MenuItem) { + super('sp-menu-item-added-or-updated', { + bubbles: true, + composed: true, + }); + this.clear(item); + } + clear(item: MenuItem): void { + this._item = item; + this.currentAncestorWithSelects = undefined; + item.menuData = { + cleanupSteps: [], + focusRoot: undefined, + selectionRoot: undefined, + parentMenu: undefined, + }; + this.menuCascade = new WeakMap(); + } + menuCascade = new WeakMap(); + get item(): MenuItem { + return this._item; + } + private _item!: MenuItem; + currentAncestorWithSelects?: Menu; +} + +/** + * Fires to forward keyboard event information to parent menu. + */ +export class MenuItemKeydownEvent extends KeyboardEvent { + root?: MenuItem; + private _event?: KeyboardEvent; + constructor({ root, event }: { root?: MenuItem; event?: KeyboardEvent }) { + super('sp-menu-item-keydown', { bubbles: true, composed: true }); + this.root = root; + this._event = event; + } + + public override get altKey(): boolean { + return this._event?.altKey || false; + } + + public override get code(): string { + return this._event?.code || ''; + } + + public override get ctrlKey(): boolean { + return this._event?.ctrlKey || false; + } + + public override get isComposing(): boolean { + return this._event?.isComposing || false; + } + + public override get key(): string { + return this._event?.key || ''; + } + + public override get location(): number { + return this._event?.location || 0; + } + + public override get metaKey(): boolean { + return this._event?.metaKey || false; + } + + public override get repeat(): boolean { + return this._event?.repeat || false; + } + + public override get shiftKey(): boolean { + return this._event?.shiftKey || false; + } +} + +export type MenuItemChildren = { icon: Element[]; content: Node[] }; + +/** + * @element sp-menu-item + * + * @slot - text content to display within the Menu Item + * @slot description - description to be placed below the label of the Menu Item + * @slot icon - icon element to be placed at the start of the Menu Item + * @slot value - content placed at the end of the Menu Item like values, keyboard shortcuts, etc. + * @slot submenu - content placed in a submenu + * @fires sp-menu-item-added - announces the item has been added so a parent menu can take ownerships + */ +export class MenuItem extends LikeAnchor( + ObserveSlotText(ObserveSlotPresence(Focusable, '[slot="icon"]')) +) { + public static override get styles(): CSSResultArray { + return [menuItemStyles, checkmarkStyles, chevronStyles]; + } + + abortControllerSubmenu!: AbortController; + + /** + * whether the menu item is active or has an active descendant + */ + @property({ type: Boolean, reflect: true }) + public active = false; + + private dependencyManager = new DependencyManagerController(this); + + /** + * whether the menu item has keyboard focus + */ + @property({ type: Boolean, reflect: true }) + public focused = false; + + /** + * whether the menu item is selected + */ + @property({ type: Boolean, reflect: true }) + public selected = false; + + /** + * value of the menu item which is used for selection + */ + @property({ type: String }) + public get value(): string { + return this._value || this.itemText; + } + + public set value(value: string) { + if (value === this._value) { + return; + } + this._value = value || ''; + if (this._value) { + this.setAttribute('value', this._value); + } else { + this.removeAttribute('value'); + } + } + + private _value = ''; + + /** + * @private + * text content of the menu item minus whitespace + */ + public get itemText(): string { + return this.itemChildren.content.reduce( + (acc, node) => acc + (node.textContent || '').trim(), + '' + ); + } + + /** + * whether the menu item has a submenu + */ + @property({ type: Boolean, reflect: true, attribute: 'has-submenu' }) + public hasSubmenu = false; + + @query('slot:not([name])') + contentSlot!: HTMLSlotElement; + + @query('slot[name="icon"]') + iconSlot!: HTMLSlotElement; + + /** + * whether menu item text content should not wrap + */ + @property({ + type: Boolean, + reflect: true, + attribute: 'no-wrap', + hasChanged() { + return false; + }, + }) + public noWrap = false; + + @query('.anchor') + private anchorElement!: HTMLAnchorElement; + + @query('sp-overlay') + public overlayElement!: Overlay; + + private submenuElement?: HTMLElement; + + /** + * the focusable element of the menu item + */ + public override get focusElement(): HTMLElement { + return this; + } + + protected get hasIcon(): boolean { + return this.slotContentIsPresent; + } + + public get itemChildren(): MenuItemChildren { + if (!this.iconSlot || !this.contentSlot) { + return { + icon: [], + content: [], + }; + } + if (this._itemChildren) { + return this._itemChildren; + } + const icon = this.iconSlot.assignedElements().map((element) => { + const newElement = element.cloneNode(true) as HTMLElement; + newElement.removeAttribute('slot'); + newElement.classList.toggle('icon'); + return newElement; + }); + const content = this.contentSlot + .assignedNodes() + .map((node) => node.cloneNode(true)); + this._itemChildren = { icon, content }; + + return this._itemChildren; + } + + private _itemChildren?: MenuItemChildren; + + constructor() { + super(); + this.addEventListener('click', this.handleClickCapture, { + capture: true, + }); + this.addEventListener('focus', this.handleFocus); + this.addEventListener('blur', this.handleBlur); + + new MutationController(this, { + config: { + characterData: true, + childList: true, + subtree: true, + attributeFilter: ['src'], + }, + callback: (mutations) => { + const isSubmenu = mutations.every( + (mutation) => + (mutation.target as HTMLElement).slot === 'submenu' + ); + if (isSubmenu) { + return; + } + this.breakItemChildrenCache(); + }, + }); + } + + /** + * whether submenu is open + */ + @property({ type: Boolean, reflect: true }) + public open = false; + + /** + * whether menu item's submenu is opened via keyboard + */ + private _openedViaKeyboard = false; + + /** + * whether menu item's submenu is closed via pointer leave + */ + private _closedViaPointer = false; + + private handleClickCapture(event: Event): void | boolean { + if (this.disabled) { + event.preventDefault(); + event.stopImmediatePropagation(); + event.stopPropagation(); + return false; + } + + if (this.shouldProxyClick()) { + return; + } + } + + private handleSlottableRequest = (event: SlottableRequestEvent): void => { + this.submenuElement?.dispatchEvent( + new SlottableRequestEvent(event.name, event.data) + ); + }; + + private proxyFocus = (): void => { + this.focus(); + }; + + private shouldProxyClick(): boolean { + let handled = false; + if (this.anchorElement) { + this.anchorElement.click(); + handled = true; + } + return handled; + } + + protected breakItemChildrenCache(): void { + this._itemChildren = undefined; + this.triggerUpdate(); + } + + protected renderSubmenu(): TemplateResult { + const slot = html` + { + event.clear(event.item); + }, + capture: true, + }} + @focusin=${(event: Event) => event.stopPropagation()} + > + `; + if (!this.hasSubmenu) { + return slot; + } + this.dependencyManager.add('sp-overlay'); + this.dependencyManager.add('sp-popover'); + import('@spectrum-web-components/overlay/sp-overlay.js'); + import('@spectrum-web-components/popover/sp-popover.js'); + return html` + event.stopPropagation()} + @slottable-request=${this.handleSlottableRequest} + > + { + this.handleSubmenuChange(event); + this.open = false; + }} + @pointerenter=${this.handleSubmenuPointerenter} + @pointerleave=${this.handleSubmenuPointerleave} + @sp-menu-item-added-or-updated=${(event: Event) => + event.stopPropagation()} + > + ${slot} + + + + `; + } + + protected override render(): TemplateResult { + return html` + ${this.selected + ? html` + + ` + : nothing} + +
+ +
+ + + ${this.href && this.href.length > 0 + ? super.renderAnchor({ + id: 'button', + ariaHidden: true, + className: 'button anchor hidden', + }) + : nothing} + ${this.renderSubmenu()} + `; + } + + /** + * determines if item has a submenu and updates the `aria-haspopup` attribute + */ + protected manageSubmenu(event: Event & { target: HTMLSlotElement }): void { + this.submenuElement = event.target.assignedElements({ + flatten: true, + })[0] as HTMLElement; + this.hasSubmenu = !!this.submenuElement; + if (this.hasSubmenu) { + this.setAttribute('aria-haspopup', 'true'); + } + } + + private handlePointerdown(event: PointerEvent): void { + if (event.target === this && this.hasSubmenu && this.open) { + this.addEventListener('focus', this.handleSubmenuFocus, { + once: true, + }); + this.overlayElement.addEventListener( + 'beforetoggle', + this.handleBeforetoggle + ); + } + } + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + this.setAttribute('tabindex', '-1'); + this.addEventListener('keydown', this.handleKeydown); + this.addEventListener('mouseover', this.handleMouseover); + this.addEventListener('pointerdown', this.handlePointerdown); + this.addEventListener('pointerenter', this.closeOverlaysForRoot); + if (!this.hasAttribute('id')) { + this.id = `sp-menu-item-${randomID()}`; + } + } + + private getActiveElementSafely(): HTMLElement | null { + let root = this.getRootNode() as Document | ShadowRoot; + let activeElement = root.activeElement as HTMLElement; + + // If no active element in current context and we're in shadow DOM, + // traverse up to find the document-level active element + if (!activeElement && root !== document) { + while (root && root !== document && 'host' in root) { + root = (root as ShadowRoot).host.getRootNode() as + | Document + | ShadowRoot; + activeElement = root.activeElement as HTMLElement; + if (activeElement) break; + } + } + + return activeElement; + } + + handleMouseover(event: MouseEvent): void { + const target = event.target as HTMLElement; + if (target === this) { + // Check for active input elements across shadow boundaries + const activeElement = this.getActiveElementSafely(); + + // Only focus this menu item if no input element is currently active + // This prevents interrupting user input in search boxes, text fields, etc. + if (!activeElement || !this.isInputElement(activeElement)) { + this.focus(); + } + this.focused = false; + } + } + + /** + * Determines if an element is an input field that should retain focus. + * Uses multiple detection strategies to identify input elements generically. + */ + private isInputElement(element: HTMLElement): boolean { + // Check for native HTML input elements + if (this.isNativeInputElement(element)) { + return true; + } + + // Check for contenteditable elements (rich text editors) + if (element.contentEditable === 'true') { + return true; + } + + // Check for Spectrum Web Components with input-like behavior + if (this.isSpectrumInputComponent(element)) { + return true; + } + + return false; + } + + /** + * Checks if an element is a native HTML input element. + */ + private isNativeInputElement(element: HTMLElement): boolean { + return ( + element instanceof HTMLInputElement || + element instanceof HTMLTextAreaElement || + element instanceof HTMLSelectElement + ); + } + + /** + * Checks if an element is a Spectrum Web Component with input behavior. + * Uses ARIA roles and component patterns for generic detection. + */ + private isSpectrumInputComponent(element: HTMLElement): boolean { + // Check if it's a Spectrum Web Component + if (!element.tagName.startsWith('SP-')) { + return false; + } + + // Check ARIA role for input-like behavior + const role = element.getAttribute('role'); + const inputRoles = ['textbox', 'searchbox', 'combobox', 'slider']; + if (role && inputRoles.includes(role)) { + return true; + } + + // Check for components that typically contain input elements + // This covers components like sp-search, sp-textfield, sp-number-field, etc. + const inputComponentPattern = INPUT_COMPONENT_PATTERN; + if (inputComponentPattern.test(element.tagName)) { + return true; + } + + return false; + } + /** + * forward key info from keydown event to parent menu + */ + handleKeydown = (event: KeyboardEvent): void => { + const { target, key } = event; + const openSubmenuKey = + this.hasSubmenu && !this.open && [' ', 'Enter'].includes(key); + if (target === this) { + if ( + ['ArrowLeft', 'ArrowRight', 'Escape'].includes(key) || + openSubmenuKey + ) + event.preventDefault(); + this.dispatchEvent( + new MenuItemKeydownEvent({ root: this, event: event }) + ); + } + }; + + protected closeOverlaysForRoot(): void { + if (this.open) return; + this.menuData.parentMenu?.closeDescendentOverlays(); + } + + protected handleFocus(event: FocusEvent): void { + const { target } = event; + if (target === this) { + this.focused = true; + } + } + + protected handleBlur(event: FocusEvent): void { + const { target } = event; + if (target === this) { + this.focused = false; + } + } + + protected handleSubmenuClick(event: Event): void { + if (event.composedPath().includes(this.overlayElement)) { + return; + } + this.openOverlay(true); + } + + protected handleSubmenuFocus(): void { + requestAnimationFrame(() => { + // Wait till after `closeDescendentOverlays` has happened in Menu + // to reopen (keep open) the direct descendent of this Menu Item + this.overlayElement.open = this.open; + this.focused = false; + }); + } + + protected handleBeforetoggle = (event: Event): void => { + if ((event as Event & { newState: string }).newState === 'closed') { + this.open = true; + this.overlayElement.manuallyKeepOpen(); + this.overlayElement.removeEventListener( + 'beforetoggle', + this.handleBeforetoggle + ); + } + }; + + protected handlePointerenter(): void { + if (this.leaveTimeout) { + clearTimeout(this.leaveTimeout); + delete this.leaveTimeout; + this.recentlyLeftChild = false; + return; + } + this.focus(); + this.openOverlay(); + } + + protected leaveTimeout?: ReturnType; + protected recentlyLeftChild = false; + + protected handlePointerleave(): void { + this._closedViaPointer = true; + if (this.open && !this.recentlyLeftChild) { + this.leaveTimeout = setTimeout(() => { + delete this.leaveTimeout; + this.open = false; + }, POINTERLEAVE_TIMEOUT); + } + } + + /** + * When there is a `change` event in the submenu for this item + * then we "click" this item to cascade the selection up the + * menu tree allowing all submenus between the initial selection + * and the root of the tree to have their selection changes and + * be closed. + */ + protected handleSubmenuChange(event: Event): void { + event.stopPropagation(); + this.menuData.selectionRoot?.selectOrToggleItem(this); + } + + protected handleSubmenuPointerenter(): void { + this.recentlyLeftChild = true; + } + + protected async handleSubmenuPointerleave(): Promise { + this.recentlyLeftChild = false; + } + + protected handleSubmenuOpen(event: Event): void { + const parentOverlay = event.composedPath().find((el) => { + return ( + el !== this.overlayElement && + (el as HTMLElement).localName === 'sp-overlay' + ); + }) as Overlay; + if (this._openedViaKeyboard) { + this.submenuElement?.focus(); + } + this.overlayElement.parentOverlayToForceClose = parentOverlay; + } + + protected cleanup(): void { + this._closedViaPointer = false; + this.setAttribute('aria-expanded', 'false'); + this.open = false; + this.active = false; + } + + public async openOverlay(shouldFocus: boolean = false): Promise { + if (!this.hasSubmenu || this.open || this.disabled) { + return; + } + this.open = true; + this.active = true; + this.setAttribute('aria-expanded', 'true'); + this._openedViaKeyboard = shouldFocus; + this.addEventListener('sp-closed', this.cleanup, { + once: true, + }); + } + + updateAriaSelected(): void { + const role = this.getAttribute('role'); + if (role === 'option') { + this.setAttribute( + 'aria-selected', + this.selected ? 'true' : 'false' + ); + } else if (role === 'menuitemcheckbox' || role === 'menuitemradio') { + this.setAttribute('aria-checked', this.selected ? 'true' : 'false'); + } + } + + public setRole(role: string): void { + this.setAttribute('role', role); + this.updateAriaSelected(); + } + + protected override willUpdate(changes: PropertyValues): void { + super.updated(changes); + + // make sure focus returns to the anchor element when submenu is closed + if ( + changes.has('open') && + !this.open && + this.hasSubmenu && + !this._closedViaPointer && + this.matches(':focus-within') + ) { + this.focus(); + } + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if ( + changes.has('label') && + (this.label || typeof changes.get('label') !== 'undefined') + ) { + this.setAttribute('aria-label', this.label || ''); + } + if ( + changes.has('active') && + (this.active || typeof changes.get('active') !== 'undefined') + ) { + if (this.active) { + this.menuData.selectionRoot?.closeDescendentOverlays(); + } + } + if (this.anchorElement) { + this.anchorElement.addEventListener('focus', this.proxyFocus); + this.anchorElement.tabIndex = -1; + } + if (changes.has('selected')) { + this.updateAriaSelected(); + } + if ( + changes.has('hasSubmenu') && + (this.hasSubmenu || + typeof changes.get('hasSubmenu') !== 'undefined') + ) { + if (this.hasSubmenu) { + this.abortControllerSubmenu = new AbortController(); + const options = { signal: this.abortControllerSubmenu.signal }; + this.addEventListener( + 'click', + this.handleSubmenuClick, + options + ); + this.addEventListener( + 'pointerenter', + this.handlePointerenter, + options + ); + this.addEventListener( + 'pointerleave', + this.handlePointerleave, + options + ); + this.addEventListener( + 'sp-opened', + this.handleSubmenuOpen, + options + ); + } else { + this.abortControllerSubmenu?.abort(); + } + } + } + + public override connectedCallback(): void { + super.connectedCallback(); + this.triggerUpdate(); + } + + _parentElement!: HTMLElement; + + public override disconnectedCallback(): void { + this.menuData.cleanupSteps.forEach((removal) => removal(this)); + this.menuData = { + focusRoot: undefined, + parentMenu: undefined, + selectionRoot: undefined, + cleanupSteps: [], + }; + super.disconnectedCallback(); + } + + private willDispatchUpdate = false; + + public async triggerUpdate(): Promise { + if (this.willDispatchUpdate) { + return; + } + this.willDispatchUpdate = true; + await new Promise((ready) => requestAnimationFrame(ready)); + this.dispatchUpdate(); + } + + public override focus(): void { + super.focus(); + // ensure focus event fires in Chromium for tests + this.dispatchEvent(new FocusEvent('focus')); + } + + public override blur(): void { + // ensure focus event fires in Chromium for tests + this.dispatchEvent(new FocusEvent('blur')); + super.blur(); + } + + public dispatchUpdate(): void { + if (!this.isConnected) { + return; + } + this.dispatchEvent(new MenuItemAddedOrUpdatedEvent(this)); + this.willDispatchUpdate = false; + } + + public menuData: { + focusRoot?: Menu; + parentMenu?: Menu; + selectionRoot?: Menu; + cleanupSteps: ((item: MenuItem) => void)[]; + } = { + // menu that controls ArrowUp/ArrowDown navigation + focusRoot: undefined, + parentMenu: undefined, + // menu or menu group that controls selection + selectionRoot: undefined, + cleanupSteps: [], + }; +} + +declare global { + interface GlobalEventHandlersEventMap { + 'sp-menu-item-added-or-updated': MenuItemAddedOrUpdatedEvent; + } +} diff --git a/1st-gen/packages/menu/src/checkmark-overrides.css b/1st-gen/packages/menu/src/checkmark-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/menu/src/checkmark-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/menu/src/chevron-overrides.css b/1st-gen/packages/menu/src/chevron-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/menu/src/chevron-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/menu/src/index.ts b/1st-gen/packages/menu/src/index.ts new file mode 100644 index 00000000000..68449400c03 --- /dev/null +++ b/1st-gen/packages/menu/src/index.ts @@ -0,0 +1,15 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Menu.js'; +export * from './MenuDivider.js'; +export * from './MenuGroup.js'; +export * from './MenuItem.js'; diff --git a/1st-gen/packages/menu/src/menu-divider-overrides.css b/1st-gen/packages/menu/src/menu-divider-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/menu/src/menu-divider-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/menu/src/menu-divider.css b/1st-gen/packages/menu/src/menu-divider.css new file mode 100644 index 00000000000..c0ab861847b --- /dev/null +++ b/1st-gen/packages/menu/src/menu-divider.css @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-menu-divider.css"); +@import url("./menu-divider-overrides.css"); + +:host { + display: block; + flex-shrink: 0; +} diff --git a/1st-gen/packages/menu/src/menu-group.css b/1st-gen/packages/menu/src/menu-group.css new file mode 100644 index 00000000000..fba9b26d121 --- /dev/null +++ b/1st-gen/packages/menu/src/menu-group.css @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-menu-sectionHeading.css"); + +:host { + margin: 0; + display: flex; + overflow: visible; + flex-direction: column; +} + +[hidden] { + display: none !important; +} diff --git a/1st-gen/packages/menu/src/menu-item-overrides.css b/1st-gen/packages/menu/src/menu-item-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/menu/src/menu-item-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/menu/src/menu-item.css b/1st-gen/packages/menu/src/menu-item.css new file mode 100644 index 00000000000..d6c82a5b689 --- /dev/null +++ b/1st-gen/packages/menu/src/menu-item.css @@ -0,0 +1,75 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-checkmark.css"); +@import url("./spectrum-chevron.css"); +@import url("./spectrum-menu-item.css"); +@import url("./menu-item-overrides.css"); + +:host { + text-align: initial; +} + +:host([hidden]) { + display: none; +} + +:host([disabled]) { + pointer-events: none; +} + +:host([disabled]) [name="value"]::slotted(*) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); +} + +:host([has-submenu][disabled]) .chevron { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); +} + +#button { + position: absolute; + inset: 0; +} + +:host([dir="ltr"]) [icon-only]::slotted(:last-of-type) { + margin-right: auto; +} + +:host([dir="rtl"]) [icon-only]::slotted(:last-of-type) { + margin-left: auto; +} + +/* N: Manually adding this selector because I can't use this selector in +** spectrum-menu.css without touching all the other `.spectrum-Menu-item`s in +** that file which I don't want to surface +*/ +@media (forced-colors: active) { + :host { + forced-color-adjust: none; + } +} + +::slotted([slot="submenu"]) { + width: max-content; + max-width: 100%; + overflow-y: auto; +} + +:host([no-wrap]) #label { + display: block; +} + +/** Host is :focus bt not :focus-visible so we remove the outline */ +:host([focused]:not(:focus-visible)) { + outline: none; + box-shadow: none; +} diff --git a/1st-gen/packages/menu/src/menu-overrides.css b/1st-gen/packages/menu/src/menu-overrides.css new file mode 100644 index 00000000000..5e107c13229 --- /dev/null +++ b/1st-gen/packages/menu/src/menu-overrides.css @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-menu-item-background-color-hover: var(--system-menu-item-background-color-hover); + --spectrum-menu-item-background-color-down: var(--system-menu-item-background-color-down); + --spectrum-menu-item-background-color-key-focus: var(--system-menu-item-background-color-key-focus); + --spectrum-menu-item-corner-radius: var(--system-menu-item-corner-radius); + --spectrum-menu-item-focus-indicator-shadow: var(--system-menu-item-focus-indicator-shadow); + --spectrum-menu-item-focus-indicator-offset: var(--system-menu-item-focus-indicator-offset); + --spectrum-menu-item-spacing-multiplier: var(--system-menu-item-spacing-multiplier); + --spectrum-menu-item-focus-indicator-outline-style: var(--system-menu-item-focus-indicator-outline-style); +} diff --git a/1st-gen/packages/menu/src/menu-sectionHeading-overrides.css b/1st-gen/packages/menu/src/menu-sectionHeading-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/menu/src/menu-sectionHeading-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/menu/src/menu.css b/1st-gen/packages/menu/src/menu.css new file mode 100644 index 00000000000..e582664b6d5 --- /dev/null +++ b/1st-gen/packages/menu/src/menu.css @@ -0,0 +1,34 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./menu-overrides.css"); +@import url("./spectrum-menu.css"); + +:host { + flex-direction: column; + + /** + * Allow menu elements to be foreced to width 100% when placed inside of a Tray + **/ + width: var(--swc-menu-width); +} + +:host(:focus) { + outline: none; +} + +::slotted(*) { + /** + * Remove when Spectrum CSS supports this correctly + */ + flex-shrink: 0; +} diff --git a/1st-gen/packages/menu/src/spectrum-checkmark.css b/1st-gen/packages/menu/src/spectrum-checkmark.css new file mode 100644 index 00000000000..0302d8ed77f --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-checkmark.css @@ -0,0 +1,61 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.checkmark { + display: var(--mod-menu-checkmark-display, var(--spectrum-menu-checkmark-display)); + block-size: var(--mod-menu-item-checkmark-height, var(--spectrum-menu-item-checkmark-height)); + inline-size: var(--mod-menu-item-checkmark-width, var(--spectrum-menu-item-checkmark-width)); + fill: var(--highcontrast-menu-checkmark-icon-color-default, var(--mod-menu-checkmark-icon-color-default, var(--spectrum-menu-checkmark-icon-color-default))); + color: var(--highcontrast-menu-checkmark-icon-color-default, var(--mod-menu-checkmark-icon-color-default, var(--spectrum-menu-checkmark-icon-color-default))); + opacity: 1; + grid-area: checkmarkArea; + align-self: start; + margin-block-start: calc(var(--mod-menu-item-top-to-checkmark, var(--spectrum-menu-item-top-to-checkmark)) - var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); + margin-inline-end: var(--mod-menu-item-text-to-control, var(--spectrum-menu-item-text-to-control)); +} + +.spectrum-Menu-back:focus-visible { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +.spectrum-Menu-backButton:focus-visible { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/src/spectrum-chevron.css b/1st-gen/packages/menu/src/spectrum-chevron.css new file mode 100644 index 00000000000..0fd7b436df6 --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-chevron.css @@ -0,0 +1,56 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.chevron { + block-size: var(--spectrum-menu-item-checkmark-height); + inline-size: var(--spectrum-menu-item-checkmark-width); + grid-area: chevronArea; + align-self: center; + margin-inline-end: var(--mod-menu-item-text-to-control, var(--spectrum-menu-item-text-to-control)); +} + +.spectrum-Menu-back:focus-visible { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +.spectrum-Menu-backButton:focus-visible { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/src/spectrum-menu-divider.css b/1st-gen/packages/menu/src/spectrum-menu-divider.css new file mode 100644 index 00000000000..b22773195d2 --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-menu-divider.css @@ -0,0 +1,56 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-menu-divider-thickness: var(--spectrum-divider-thickness-medium); + inline-size: auto; + margin-block: var(--mod-menu-section-divider-margin-block, max(0px, (var(--spectrum-menu-item-section-divider-height) - var(--spectrum-menu-divider-thickness)) / 2)); + margin-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); + overflow: visible; +} + +.spectrum-Menu-back:focus-visible { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +.spectrum-Menu-backButton:focus-visible { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/src/spectrum-menu-item.css b/1st-gen/packages/menu/src/spectrum-menu-item.css new file mode 100644 index 00000000000..8a07e4c96c1 --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-menu-item.css @@ -0,0 +1,384 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +::slotted([slot="icon"]) { + fill: var(--highcontrast-menu-item-color-default, var(--mod-menu-item-label-icon-color-default, var(--spectrum-menu-item-label-icon-color-default))); + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-item-label-icon-color-default, var(--spectrum-menu-item-label-icon-color-default))); + grid-area: iconArea; + align-self: start; +} + +::slotted([slot="icon"]) { + margin-inline-end: var(--mod-menu-item-label-text-to-visual, var(--spectrum-menu-item-label-text-to-visual)); +} + +:host { + cursor: pointer; + border-radius: var(--spectrum-menu-item-corner-radius); + box-sizing: border-box; + background-color: var(--highcontrast-menu-item-background-color-default, var(--mod-menu-item-background-color-default, var(--spectrum-menu-item-background-color-default))); + line-height: var(--mod-menu-item-label-line-height, var(--spectrum-menu-item-label-line-height)); + min-block-size: var(--mod-menu-item-min-height, var(--spectrum-menu-item-min-height)); + padding-block-start: var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text)); + padding-block-end: var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text)); + padding-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); + margin: calc((var(--spectrum-menu-item-focus-indicator-offset) + var(--spectrum-menu-item-focus-indicator-width)) * var(--spectrum-menu-item-spacing-multiplier)); + grid-template: + ". chevronAreaCollapsible . headingIconArea sectionHeadingArea . . ." 1fr + "selectedArea chevronAreaCollapsible checkmarkArea iconArea labelArea valueArea actionsArea chevronAreaDrillIn" + ". . . . descriptionArea . . ." + ". . . . submenuArea . . ." + / auto auto auto auto 1fr auto auto auto; + align-items: center; + -webkit-text-decoration: none; + text-decoration: none; + display: grid; + position: relative; +} + +.spectrum-Menu-itemCheckbox { + --mod-checkbox-top-to-text: 0; + --mod-checkbox-text-to-control: 0; + min-block-size: 0; +} + +.spectrum-Menu-itemCheckbox .spectrum-Checkbox-box { + margin-block-start: var(--mod-menu-item-top-to-checkbox, var(--spectrum-menu-item-top-to-checkbox)); + margin-block-end: 0; + margin-inline-end: var(--mod-menu-item-text-to-control, var(--spectrum-menu-item-text-to-control)); +} + +.spectrum-Menu-itemSwitch { + min-block-size: 0; +} + +.spectrum-Menu-itemSwitch .spectrum-Switch-switch { + margin-block-start: var(--mod-menu-item-top-to-action, var(--spectrum-menu-item-top-to-action)); + margin-block-end: 0; +} + +#label { + grid-area: submenuItemLabelArea; +} + +::slotted([slot="value"]) { + grid-area: submenuItemValueArea; +} + +:host([focused]), +:host(:focus) { + background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-key-focus, var(--spectrum-menu-item-background-color-key-focus))); + outline: none; +} + +:host([focused]) > #label, +:host(:focus) > #label { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-content-color-focus, var(--spectrum-menu-item-label-content-color-focus))); +} + +:host([focused]) > [name="description"]::slotted(*), +:host(:focus) > [name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-description-color-focus, var(--spectrum-menu-item-description-color-focus))); +} + +:host([focused]) > ::slotted([slot="value"]), +:host(:focus) > ::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-focus, var(--spectrum-menu-item-value-color-focus))); +} + +:host([focused]) > .icon:not(.chevron, .checkmark), +:host(:focus) > .icon:not(.chevron, .checkmark) { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-focus, var(--spectrum-menu-item-label-icon-color-focus))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-focus, var(--spectrum-menu-item-label-icon-color-focus))); +} + +:host([focused]) > .chevron, +:host(:focus) > .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); +} + +:host([focused]) > .checkmark, +:host(:focus) > .checkmark { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-focus, var(--spectrum-menu-checkmark-icon-color-focus))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-focus, var(--spectrum-menu-checkmark-icon-color-focus))); +} + +:host(:is(:active, [active])) { + background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-down, var(--spectrum-menu-item-background-color-down))); +} + +:host(:is(:active, [active])) > #label { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-content-color-down, var(--spectrum-menu-item-label-content-color-down))); +} + +:host(:is(:active, [active])) > [name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-description-color-down, var(--spectrum-menu-item-description-color-down))); +} + +:host(:is(:active, [active])) > ::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-down, var(--spectrum-menu-item-value-color-down))); +} + +:host(:is(:active, [active])) > .icon:not(.chevron, .checkmark) { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-down, var(--spectrum-menu-item-label-icon-color-down))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-down, var(--spectrum-menu-item-label-icon-color-down))); +} + +:host(:is(:active, [active])) > .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); +} + +:host(:is(:active, [active])) > .checkmark { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-down, var(--spectrum-menu-checkmark-icon-color-down))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-down, var(--spectrum-menu-checkmark-icon-color-down))); +} + +:host([disabled]), +:host([aria-disabled="true"]) { + background-color: initial; +} + +:host([disabled]) #label, +:host([disabled]) ::slotted([slot="value"]), +:host([aria-disabled="true"]) #label, +:host([aria-disabled="true"]) ::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-content-color-disabled, var(--spectrum-menu-item-label-content-color-disabled))); +} + +:host([disabled]) [name="description"]::slotted(*), +:host([aria-disabled="true"]) [name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-description-color-disabled, var(--spectrum-menu-item-description-color-disabled))); +} + +:host([disabled]) ::slotted([slot="icon"]), +:host([aria-disabled="true"]) ::slotted([slot="icon"]) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); + fill: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); +} + +:host([focused]) .spectrum-Menu-back, +:host([focused]) { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.spectrum-Menu-itemSelection { + grid-area: selectedArea; +} + +#label { + --mod-switch-control-label-spacing: 0; + --mod-switch-spacing-top-to-label: 0; + font-size: var(--mod-menu-item-label-font-size, var(--spectrum-menu-item-label-font-size)); + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-item-label-content-color-default, var(--spectrum-menu-item-label-content-color-default))); + hyphens: auto; + overflow-wrap: break-word; + grid-area: labelArea; +} + +::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-item-value-color-default, var(--spectrum-menu-item-value-color-default))); + font-size: var(--mod-menu-item-label-font-size, var(--spectrum-menu-item-label-font-size)); + grid-area: valueArea; + justify-self: end; +} + +.spectrum-Menu-itemActions, +::slotted([slot="value"]) { + align-self: start; + margin-inline-start: var(--mod-menu-item-label-to-value-area-min-spacing, var(--spectrum-menu-item-label-to-value-area-min-spacing)); +} + +.spectrum-Menu-itemActions { + grid-area: actionsArea; +} + +[name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-item-description-color-default, var(--spectrum-menu-item-description-color-default))); + font-size: var(--mod-menu-item-description-font-size, var(--spectrum-menu-item-description-font-size)); + hyphens: auto; + overflow-wrap: break-word; + line-height: var(--mod-menu-item-description-line-height, var(--spectrum-menu-item-description-line-height)); + grid-area: descriptionArea; + margin-block-start: var(--mod-menu-item-label-to-description-spacing, var(--spectrum-menu-item-label-to-description-spacing)); +} + +:host([no-wrap]) #label { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.spectrum-Menu-item--collapsible.is-open { + padding-block-end: 0; +} + +.spectrum-Menu-item--collapsible.is-open .chevron { + transform: rotate(90deg); +} + +:host([focused]) .spectrum-Menu-item--collapsible.is-open, +:host(:is(:active, [active])) .spectrum-Menu-item--collapsible.is-open, +.spectrum-Menu-item--collapsible.is-open:focus { + background-color: var(--highcontrast-menu-item-background-color-default, var(--mod-menu-item-background-color-default, var(--spectrum-menu-item-background-color-default))); +} + +.spectrum-Menu-item--collapsible ::slotted([slot="icon"]) { + grid-area: headingIconArea; +} + +.spectrum-Menu-item--collapsible > ::slotted([slot="icon"]) { + padding-block-start: var(--mod-menu-section-header-top-edge-to-text, var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); + padding-block-end: var(--mod-menu-section-header-bottom-edge-to-text, var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text))); +} + +.spectrum-Menu-item--collapsible .chevron { + grid-area: chevronAreaCollapsible; +} + +:host([has-submenu]) .chevron { + fill: var(--highcontrast-menu-item-color-default, var(--mod-menu-drillin-icon-color-default, var(--spectrum-menu-drillin-icon-color-default))); + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-drillin-icon-color-default, var(--spectrum-menu-drillin-icon-color-default))); + grid-area: chevronAreaDrillIn; + margin-inline-start: var(--mod-menu-item-label-to-value-area-min-spacing, var(--spectrum-menu-item-label-to-value-area-min-spacing)); + margin-inline-end: 0; +} + +:host([has-submenu]) .is-open { + --spectrum-menu-item-background-color-default: var(--highcontrast-menu-item-selected-background-color, var(--mod-menu-item-background-color-hover, var(--spectrum-menu-item-background-color-hover))); +} + +:host([has-submenu]) .is-open .icon:not(.chevron, .checkmark) { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); +} + +:host([has-submenu]) .is-open .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover))); +} + +:host([has-submenu]) .is-open .checkmark { + fill: var(--highcontrast-menu-checkmark-icon-color-default, var(--mod-menu-checkmark-icon-color-hover, var(--spectrum-menu-checkmark-icon-color-hover))); + color: var(--highcontrast-menu-checkmark-icon-color-default, var(--mod-menu-checkmark-icon-color-hover, var(--spectrum-menu-checkmark-icon-color-hover))); +} + +@media (hover: hover) { + :host(:hover) { + background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-hover, var(--spectrum-menu-item-background-color-hover))); + } + + :host(:hover) > #label { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-content-color-hover, var(--spectrum-menu-item-label-content-color-hover))); + } + + :host(:hover) > [name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-description-color-hover, var(--spectrum-menu-item-description-color-hover))); + } + + :host(:hover) > ::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-hover, var(--spectrum-menu-item-value-color-hover))); + } + + :host(:hover) > .icon:not(.chevron, .checkmark) { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); + } + + :host(:hover) > .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-collapsible-icon-color, var(--spectrum-menu-collapsible-icon-color))); + } + + :host(:hover) > .checkmark { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-hover, var(--spectrum-menu-checkmark-icon-color-hover))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-checkmark-icon-color-hover, var(--spectrum-menu-checkmark-icon-color-hover))); + } + + :host([disabled]:hover), + :host([aria-disabled="true"]:hover) { + cursor: default; + background-color: initial; + } + + :host([disabled]:hover) #label, + :host([disabled]:hover) ::slotted([slot="value"]), + :host([aria-disabled="true"]:hover) #label, + :host([aria-disabled="true"]:hover) ::slotted([slot="value"]) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-content-color-disabled, var(--spectrum-menu-item-label-content-color-disabled))); + } + + :host([disabled]:hover) [name="description"]::slotted(*), + :host([aria-disabled="true"]:hover) [name="description"]::slotted(*) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-description-color-disabled, var(--spectrum-menu-item-description-color-disabled))); + } + + :host([disabled]:hover) ::slotted([slot="icon"]), + :host([aria-disabled="true"]:hover) ::slotted([slot="icon"]) { + color: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); + fill: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); + } + + .spectrum-Menu-item--collapsible.is-open:hover { + background-color: var(--highcontrast-menu-item-background-color-default, var(--mod-menu-item-background-color-default, var(--spectrum-menu-item-background-color-default))); + } + + :host([has-submenu]:hover) .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover))); + } +} + +:host([has-submenu][focused]) .chevron, +:host([has-submenu]:focus) .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus))); +} + +:host([has-submenu]:is(:active, [active])) .chevron { + fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down))); + color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down))); +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +:host([focused]) .spectrum-Menu-backButton { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/src/spectrum-menu-sectionHeading.css b/1st-gen/packages/menu/src/spectrum-menu-sectionHeading.css new file mode 100644 index 00000000000..119def21c19 --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-menu-sectionHeading.css @@ -0,0 +1,65 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.spectrum-Menu-back:focus-visible { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.header { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-section-header-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + min-inline-size: var(--mod-menu-section-header-min-width, var(--spectrum-menu-section-header-min-width)); + padding-block-start: var(--mod-menu-section-header-top-edge-to-text, var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); + padding-block-end: var(--mod-menu-section-header-bottom-edge-to-text, var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text))); + padding-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); + grid-area: sectionHeadingArea / 1 / sectionHeadingArea / -1; + display: block; +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-back .header { + padding: 0; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +.spectrum-Menu-backButton:focus-visible { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/src/spectrum-menu.css b/1st-gen/packages/menu/src/spectrum-menu.css new file mode 100644 index 00000000000..66df013a67e --- /dev/null +++ b/1st-gen/packages/menu/src/spectrum-menu.css @@ -0,0 +1,254 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-menu-item-background-color-default: ButtonFace; + --highcontrast-menu-item-color-default: ButtonText; + --highcontrast-menu-item-background-color-focus: Highlight; + --highcontrast-menu-item-color-focus: HighlightText; + --highcontrast-menu-checkmark-icon-color-default: Highlight; + --highcontrast-menu-item-color-disabled: GrayText; + --highcontrast-menu-item-focus-indicator-color: Highlight; + --highcontrast-menu-item-selected-background-color: Highlight; + --highcontrast-menu-item-selected-color: HighlightText; + } + + @supports (color: SelectedItem) { + :host { + --highcontrast-menu-item-selected-background-color: SelectedItem; + --highcontrast-menu-item-selected-color: SelectedItemText; + } + } +} + +:host { + --spectrum-menu-item-top-to-action: var(--spectrum-spacing-50); + --spectrum-menu-item-top-to-checkbox: var(--spectrum-spacing-50); + --spectrum-menu-item-label-line-height: var(--spectrum-line-height-100); + --spectrum-menu-item-label-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-menu-item-label-to-description-spacing: var(--spectrum-menu-item-label-to-description); + --spectrum-menu-item-focus-indicator-width: var(--mod-menu-item-focus-indicator-width, var(--spectrum-border-width-200)); + --spectrum-menu-item-focus-indicator-color: var(--spectrum-blue-800); + --spectrum-menu-item-label-to-value-area-min-spacing: var(--spectrum-spacing-100); + --spectrum-menu-item-label-content-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-menu-item-label-content-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-menu-item-label-content-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-menu-item-label-content-color-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-menu-item-label-icon-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-menu-item-label-icon-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-menu-item-label-icon-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-menu-item-label-icon-color-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-menu-item-label-content-color-disabled: var(--spectrum-disabled-content-color); + --spectrum-menu-item-label-icon-color-disabled: var(--spectrum-disabled-content-color); + --spectrum-menu-item-description-line-height: var(--spectrum-line-height-100); + --spectrum-menu-item-description-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-menu-item-description-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-menu-item-description-color-hover: var(--spectrum-neutral-subdued-content-color-hover); + --spectrum-menu-item-description-color-down: var(--spectrum-neutral-subdued-content-color-down); + --spectrum-menu-item-description-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-menu-item-description-color-disabled: var(--spectrum-disabled-content-color); + --spectrum-menu-section-header-line-height: var(--spectrum-line-height-100); + --spectrum-menu-section-header-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-menu-section-header-font-weight: var(--spectrum-bold-font-weight); + --spectrum-menu-section-header-color: var(--spectrum-gray-900); + --spectrum-menu-collapsible-icon-color: var(--spectrum-gray-900); + --spectrum-menu-checkmark-icon-color-default: var(--spectrum-accent-color-900); + --spectrum-menu-checkmark-icon-color-hover: var(--spectrum-accent-color-1000); + --spectrum-menu-checkmark-icon-color-down: var(--spectrum-accent-color-1100); + --spectrum-menu-checkmark-icon-color-focus: var(--spectrum-accent-color-1000); + --spectrum-menu-drillin-icon-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-menu-drillin-icon-color-hover: var(--spectrum-neutral-subdued-content-color-hover); + --spectrum-menu-drillin-icon-color-down: var(--spectrum-neutral-subdued-content-color-down); + --spectrum-menu-drillin-icon-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-menu-item-value-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-menu-item-value-color-hover: var(--spectrum-neutral-subdued-content-color-hover); + --spectrum-menu-item-value-color-down: var(--spectrum-neutral-subdued-content-color-down); + --spectrum-menu-item-value-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-menu-checkmark-display-hidden: none; + --spectrum-menu-checkmark-display-shown: block; + --spectrum-menu-checkmark-display: var(--spectrum-menu-checkmark-display-shown); + --spectrum-menu-item-min-height: var(--spectrum-component-height-100); + --spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-100); + --spectrum-menu-item-icon-width: var(--spectrum-workflow-icon-size-100); + --spectrum-menu-item-label-font-size: var(--spectrum-font-size-100); + --spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-100); + --spectrum-menu-item-label-inline-edge-to-content: var(--spectrum-component-edge-to-text-100); + --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-100); + --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-100); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-100); + --spectrum-menu-item-description-font-size: var(--spectrum-font-size-75); + --spectrum-menu-section-header-font-size: var(--spectrum-font-size-100); + --spectrum-menu-section-header-min-width: var(--spectrum-component-height-100); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-medium); + --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-medium); + --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-medium); + --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-medium); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-medium); + --spectrum-menu-item-collapsible-no-icon-submenu-item-padding-x-start: calc(var(--spectrum-menu-item-label-inline-edge-to-content) + var(--spectrum-menu-item-checkmark-width) + var(--spectrum-menu-item-label-text-to-visual) + var(--spectrum-menu-item-focus-indicator-width)); + --spectrum-menu-item-focus-indicator-color-default: var(--highcontrast-menu-item-focus-indicator-color, var(--mod-menu-item-focus-indicator-color, var(--spectrum-menu-item-focus-indicator-color))); + --spectrum-menu-item-focus-indicator-border-width: calc(var(--spectrum-menu-item-focus-indicator-width) * var(--spectrum-menu-item-focus-indicator-direction-scalar, 1)); +} + +:host([size="s"]) { + --spectrum-menu-item-min-height: var(--spectrum-component-height-75); + --spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-75); + --spectrum-menu-item-icon-width: var(--spectrum-workflow-icon-size-75); + --spectrum-menu-item-label-font-size: var(--spectrum-font-size-75); + --spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-75); + --spectrum-menu-item-label-inline-edge-to-content: var(--spectrum-component-edge-to-text-75); + --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-75); + --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-75); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-75); + --spectrum-menu-item-description-font-size: var(--spectrum-font-size-50); + --spectrum-menu-section-header-font-size: var(--spectrum-font-size-75); + --spectrum-menu-section-header-min-width: var(--spectrum-component-height-75); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-small); + --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-small); + --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-small); + --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-small); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-small); +} + +:host([size="l"]) { + --spectrum-menu-item-min-height: var(--spectrum-component-height-200); + --spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-200); + --spectrum-menu-item-icon-width: var(--spectrum-workflow-icon-size-200); + --spectrum-menu-item-label-font-size: var(--spectrum-font-size-200); + --spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-200); + --spectrum-menu-item-label-inline-edge-to-content: var(--spectrum-component-edge-to-text-200); + --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-200); + --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-200); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-200); + --spectrum-menu-item-description-font-size: var(--spectrum-font-size-100); + --spectrum-menu-section-header-font-size: var(--spectrum-font-size-200); + --spectrum-menu-section-header-min-width: var(--spectrum-component-height-200); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-large); + --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-large); + --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-large); + --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-large); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-large); +} + +:host([size="xl"]) { + --spectrum-menu-item-min-height: var(--spectrum-component-height-300); + --spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-300); + --spectrum-menu-item-icon-width: var(--spectrum-workflow-icon-size-300); + --spectrum-menu-item-label-font-size: var(--spectrum-font-size-300); + --spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-300); + --spectrum-menu-item-label-inline-edge-to-content: var(--spectrum-component-edge-to-text-300); + --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-300); + --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-300); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-300); + --spectrum-menu-item-description-font-size: var(--spectrum-font-size-200); + --spectrum-menu-section-header-font-size: var(--spectrum-font-size-300); + --spectrum-menu-section-header-min-width: var(--spectrum-component-height-300); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-extra-large); + --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-extra-large); + --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-extra-large); + --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-extra-large); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-extra-large); +} + +:host:dir(rtl), +:host([dir="rtl"]) { + --spectrum-menu-item-focus-indicator-direction-scalar: -1; +} + +:host { + inline-size: var(--mod-menu-inline-size, auto); + box-sizing: border-box; + margin: 0; + padding: 0; + list-style-type: none; + display: inline-block; + overflow: auto; +} + +:host:lang(ja), +:host:lang(ko), +:host:lang(zh) { + --spectrum-menu-item-label-line-height: var(--mod-menu-item-label-line-height-cjk, var(--spectrum-menu-item-label-line-height-cjk)); + --spectrum-menu-item-description-line-height: var(--mod-menu-item-description-line-height-cjk, var(--spectrum-menu-item-description-line-height-cjk)); + --spectrum-menu-section-header-line-height: var(--mod-menu-section-header-line-height-cjk, var(--spectrum-menu-section-header-line-height-cjk)); +} + +:host([selects]) ::slotted(sp-menu-item) { + --spectrum-menu-checkmark-display: var(--spectrum-menu-checkmark-display-hidden); + padding-inline-start: var(--mod-menu-item-selectable-edge-to-text-not-selected, var(--spectrum-menu-item-selectable-edge-to-text-not-selected)); +} + +:host([selects]) ::slotted(sp-menu-item[selected]) { + --spectrum-menu-checkmark-display: var(--spectrum-menu-checkmark-display-shown); + padding-inline-start: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); +} + +.spectrum-Menu-backIcon { + margin-block: var(--mod-menu-back-icon-margin-block, var(--spectrum-menu-back-icon-margin)); + margin-inline: var(--mod-menu-back-icon-margin-inline, var(--spectrum-menu-back-icon-margin)); + fill: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-icon-color-default, var(--spectrum-menu-section-header-color))); + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-icon-color-default, var(--spectrum-menu-section-header-color))); +} + +.spectrum-Menu-back:focus-visible { + box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); + outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); + outline-offset: var(--spectrum-menu-item-focus-indicator-offset); + border-radius: var(--spectrum-menu-item-corner-radius); +} + +.spectrum-Menu-sectionHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-section-header-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + min-inline-size: var(--mod-menu-section-header-min-width, var(--spectrum-menu-section-header-min-width)); + padding-block-start: var(--mod-menu-section-header-top-edge-to-text, var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); + padding-block-end: var(--mod-menu-section-header-bottom-edge-to-text, var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text))); + padding-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); + grid-area: sectionHeadingArea / 1 / sectionHeadingArea / -1; + display: block; +} + +.spectrum-Menu-back { + padding-inline: var(--mod-menu-back-padding-inline-start, 0) var(--mod-menu-back-padding-inline-end, var(--spectrum-menu-item-label-inline-edge-to-content)); + padding-block: var(--mod-menu-back-padding-block-start, 0) var(--mod-menu-back-padding-block-end, 0); + flex-flow: wrap; + align-items: center; + display: flex; +} + +.spectrum-Menu-back .spectrum-Menu-sectionHeading { + padding: 0; +} + +.spectrum-Menu-backButton { + cursor: pointer; + background: none; + border: 0; + margin: 0; + padding: 0; + display: inline-flex; +} + +.spectrum-Menu-backButton:focus-visible { + outline: var(--spectrum-focus-indicator-thickness) solid var(--spectrum-focus-indicator-color); + outline-offset: calc((var(--spectrum-focus-indicator-thickness) + 1px) * -1); +} + +.spectrum-Menu-backHeading { + color: var(--highcontrast-menu-item-color-default, var(--mod-menu-back-heading-color, var(--spectrum-menu-section-header-color))); + font-size: var(--mod-menu-section-header-font-size, var(--spectrum-menu-section-header-font-size)); + font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); + line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); + display: block; +} diff --git a/1st-gen/packages/menu/stories/index.ts b/1st-gen/packages/menu/stories/index.ts new file mode 100644 index 00000000000..a0e0331cdf6 --- /dev/null +++ b/1st-gen/packages/menu/stories/index.ts @@ -0,0 +1,113 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import { Menu } from '@spectrum-web-components/menu'; + +export const MenuMarkup = ({ + size = 'm' as 's' | 'm' | 'l' | 'xl', +} = {}): TemplateResult => { + return html` + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + `; +}; + +export class ComplexSlottedGroup extends LitElement { + get menu(): Menu { + return this.renderRoot.querySelector('sp-menu') as Menu; + } + + static override shadowRootOptions = { + ...LitElement.shadowRootOptions, + delegatesFocus: true, + }; + + protected override render(): TemplateResult { + return html` + + + Before First + + + + Sibling 1 + + Sibling 2 + + + After 1 + After 2 + + + `; + } +} + +customElements.define('complex-slotted-group', ComplexSlottedGroup); + +export class ComplexSlottedMenu extends LitElement { + get menu(): Menu { + return ( + this.renderRoot.querySelector( + 'complex-slotted-group' + ) as ComplexSlottedGroup + ).menu; + } + + static override shadowRootOptions = { + ...LitElement.shadowRootOptions, + delegatesFocus: true, + }; + + protected override render(): TemplateResult { + return html` + + Middle 1 + Middle 2 + Middle 3 + + + Before Last + + `; + } +} + +customElements.define('complex-slotted-menu', ComplexSlottedMenu); diff --git a/1st-gen/packages/menu/stories/menu-divider.stories.ts b/1st-gen/packages/menu/stories/menu-divider.stories.ts new file mode 100644 index 00000000000..75dfc00b2dd --- /dev/null +++ b/1st-gen/packages/menu/stories/menu-divider.stories.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/popover/sp-popover.js'; + +export default { + component: 'sp-menu-divider', + title: 'Menu Divider', +}; + +const Template = (size: string): TemplateResult => { + return html` + + + Deselect + Select Inverse + Feather... + + Select and Mask... + Make Work Path + + Save Selection + + Create group + + + `; +}; + +export const sizeS = (): TemplateResult => Template('s'); + +export const sizeM = (): TemplateResult => Template('m'); + +export const sizeL = (): TemplateResult => Template('l'); diff --git a/1st-gen/packages/menu/stories/menu-group.stories.ts b/1st-gen/packages/menu/stories/menu-group.stories.ts new file mode 100644 index 00000000000..5bbbf5aeb69 --- /dev/null +++ b/1st-gen/packages/menu/stories/menu-group.stories.ts @@ -0,0 +1,166 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import { MenuGroup } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; + +import './index.js'; + +export default { + component: 'sp-menu', + title: 'Menu Group', +}; + +export const complexSlotted = (): TemplateResult => { + return html` + + External A + External 1 + External 2 + + `; +}; + +export const mixed = (): TemplateResult => { + let style = 'italic'; + let weight = '700'; + let color = 'blue'; + let decoration = 'overline'; + const styleRules = ({ + style, + weight, + color, + decoration, + }: { + style: string; + weight: string; + color: string; + decoration: string; + }): string => { + return ` + .style-rule { + font-weight: ${weight}; + font-style: ${style}; + color: ${color}; + text-decoration: ${decoration}; + } + `; + }; + const update = (event: Event): void => { + const { value, id } = event.target as MenuGroup; + switch (id) { + case 'font': + const values = value.split(','); + style = values.indexOf('italic') > -1 ? 'italic' : 'normal'; + weight = values.indexOf('bold') > -1 ? '700' : '400'; + break; + case 'color': + color = value; + break; + case 'decoration': + decoration = value; + break; + } + (document.querySelector('#output') as HTMLElement).textContent = + styleRules({ + style, + weight, + color, + decoration, + }); + }; + return html` + + + + + Bold + Italic + + + + Black + Blue + Red + Green + + + + None + + Overline + + + Line-through + + Underline + + + +
+            ${styleRules({ style, weight, color, decoration })}
+        
+ `; +}; + +export const inherit = (): TemplateResult => { + return html` + + + + + Orange + Apple + Grape + + + + Carrots + Summer Squash + Zuccini + + + + Ceral + Flour + Salt + Sugar + + + + `; +}; diff --git a/1st-gen/packages/menu/stories/menu-item.disconnected.stories.ts b/1st-gen/packages/menu/stories/menu-item.disconnected.stories.ts new file mode 100644 index 00000000000..c99b69b9be2 --- /dev/null +++ b/1st-gen/packages/menu/stories/menu-item.disconnected.stories.ts @@ -0,0 +1,191 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, LitElement, TemplateResult } from 'lit'; +import { property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { when } from 'lit/directives/when.js'; + +import '@spectrum-web-components/picker/sp-picker.js'; +import '@spectrum-web-components/button/sp-button.js'; +import { SpectrumMixin } from '@spectrum-web-components/base'; + +enum BlendModeValue { + normal = 2, + multiply = 3, + screen = 7, +} + +interface BlendModeOption { + value: BlendModeValue; + title: string; + subtitle: string; + thumbnail: string; +} + +const XElement = SpectrumMixin(LitElement); + +class MyContainer extends XElement { + @state() + private _counter = 0; + + private _handleClick(): void { + this._counter += 1; + } + + protected override render(): TemplateResult { + return html` +
+ ${when( + this._counter % 2 === 0, + () => html` + + `, + () => html` + + ` + )} + + Switch views + +
+ `; + } +} + +customElements.define('my-container', MyContainer); + +class MyView1 extends XElement { + protected override render(): TemplateResult { + const blendModeOptions = [ + { + value: BlendModeValue.normal, + title: 'Normal 1', + subtitle: 'No effect applied', + }, + { + value: BlendModeValue.multiply, + title: 'Multiply', + subtitle: 'Darken shadows with contrast and details', + }, + { + value: BlendModeValue.screen, + title: 'Screen', + subtitle: 'Brighten highlights with contrast and details', + }, + ]; + return html` + View 1 + + `; + } +} + +customElements.define('my-view1', MyView1); + +class MyView2 extends XElement { + protected override render(): TemplateResult { + const blendModeOptions = [ + { + value: BlendModeValue.normal, + title: 'Normal 2', + subtitle: 'No effect applied', + }, + { + value: BlendModeValue.multiply, + title: 'Multiply', + subtitle: 'Darken shadows with contrast and details', + }, + { + value: BlendModeValue.screen, + title: 'Screen', + subtitle: 'Brighten highlights with contrast and details', + }, + ]; + return html` + View 2 + + `; + } +} + +customElements.define('my-view2', MyView2); + +class MyPicker extends XElement { + @property({ type: Array }) + public blendModeOptions: BlendModeOption[] = []; + + @property() + public blendMode: number = BlendModeValue.normal; + + private _renderBlendOptions(): TemplateResult { + return html` + ${repeat( + this.blendModeOptions, + // This is intentional so that repeat directive will add instead of + // update existing DOM which will then trigger error in + // MenuItem.childrenItem + // Using .value for the key will workaround the issue + (blendModeOption) => blendModeOption, + (blendModeOption: BlendModeOption) => html` + + ${blendModeOption.title} + ${blendModeOption.subtitle} + + ` + )} + `; + } + protected override render(): TemplateResult { + return html` + + ${this._renderBlendOptions()} + + `; + } +} + +customElements.define('my-picker', MyPicker); + +export default { + component: 'sp-menu-item', + title: 'Menu Item/Disconnected', +}; + +export const disconnectedChildItems = (): TemplateResult => html` + +`; + +disconnectedChildItems.swc_vrt = { + skip: true, +}; + +disconnectedChildItems.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; diff --git a/1st-gen/packages/menu/stories/menu-item.stories.ts b/1st-gen/packages/menu/stories/menu-item.stories.ts new file mode 100644 index 00000000000..6fe3bc6c0be --- /dev/null +++ b/1st-gen/packages/menu/stories/menu-item.stories.ts @@ -0,0 +1,160 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { when } from '@spectrum-web-components/base/src/directives.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-edit.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/checkbox/sp-checkbox.js'; + +export default { + component: 'sp-menu-item', + title: 'Menu Item', +}; + +export const Default = (): TemplateResult => { + return html` + + Menu Item + + `; +}; + +class CheckBoxBehindMenuItem extends LitElement { + private _renderMenu = true; + + private _onMenuChange(_event: Event): void { + this._renderMenu = false; + this.requestUpdate(); + console.log('On menu change, renderMenu: ', this._renderMenu); + } + + private _onCheckboxChange(_event: Event): void { + console.log('On checkbox change'); + } + + private _handleReset(): void { + this._renderMenu = true; + this.requestUpdate(); + } + + protected override render(): TemplateResult { + return html` + + Reset + + ${when( + this._renderMenu, + () => html` + + + Click left margin! + + + ` + )} + ${when( + !this._renderMenu, + () => html` + + Should not be checked + + ` + )} + `; + } +} + +customElements.define('checkbox-behind-menu-item', CheckBoxBehindMenuItem); + +export const MenuItemWithCheckbox = (): TemplateResult => { + return html` + + `; +}; + +MenuItemWithCheckbox.swc_vrt = { + skip: true, +}; + +export const noWrap = (): TemplateResult => { + return html` + + + Select a Country with a very long label, too long, in fact + + + `; +}; + +export const descriptionSlot = (): TemplateResult => { + return html` + + + Quick export + Share a snapshot + + + `; +}; + +export const valueSlot = (): TemplateResult => { + /** + * This story featurs zero width spaces between the characters in the `` element. + * While their absence has not caused issues in the local Storybook, the visual regression + * suite was causig the `⌘​` character to display different between the various Menu Items + * without the intevening zero width space character. When reviewing in the future, + * `font-variant-ligatures: none` was also not enough to address this situation. + */ + // + // + return html` + + + + Save + ⌘​S + + + Save As... + ⇧​⌘​S + + + Save All + ⌥​⌘​S + + + `; +}; + +export const href = (): TemplateResult => { + return html` + + + + Edit the Documentation Site + + + `; +}; diff --git a/1st-gen/packages/menu/stories/menu-sizes.stories.ts b/1st-gen/packages/menu/stories/menu-sizes.stories.ts new file mode 100644 index 00000000000..7ce5eca4459 --- /dev/null +++ b/1st-gen/packages/menu/stories/menu-sizes.stories.ts @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; +import { MenuMarkup } from './'; + +export default { + component: 'sp-menu', + title: 'Menu/Sizes', +}; + +export const S = (): TemplateResult => MenuMarkup({ size: 's' }); +export const M = (): TemplateResult => MenuMarkup({ size: 'm' }); +export const L = (): TemplateResult => MenuMarkup({ size: 'l' }); +export const XL = (): TemplateResult => MenuMarkup({ size: 'xl' }); diff --git a/1st-gen/packages/menu/stories/menu.stories.ts b/1st-gen/packages/menu/stories/menu.stories.ts new file mode 100644 index 00000000000..992d1a1d1ad --- /dev/null +++ b/1st-gen/packages/menu/stories/menu.stories.ts @@ -0,0 +1,593 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; + +import type { Menu, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/icon/sp-icon.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark-circle.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-export.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-folder-open.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-share.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js'; +import '@spectrum-web-components/search/sp-search.js'; +import '@spectrum-web-components/textfield/sp-textfield.js'; +import '@spectrum-web-components/number-field/sp-number-field.js'; +import '@spectrum-web-components/combobox/sp-combobox.js'; +import '@spectrum-web-components/color-field/sp-color-field.js'; + +export default { + component: 'sp-menu', + title: 'Menu', +}; + +export const Default = (): TemplateResult => { + return html` + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + `; +}; + +export const singleSelect = (): TemplateResult => { + return html` + { + navigator.clipboard.writeText(value); + }} + > + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + + { + navigator.clipboard.writeText(value); + }} + > + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + `; +}; + +export const multipleSelect = (): TemplateResult => { + return html` + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + + `; +}; + +export const controlled = (): TemplateResult => { + const forceSelection = (event: Event & { target: Menu }): void => { + event.target.updateComplete.then(() => { + event.target.selected = ['Select and Mask...']; + }); + }; + return html` +

+ This Menu will default to a + selected + value of + [ 'Feather...', 'Save Selection' ] + but then on any subsequent interaction be forced to a + selected + value of + [ 'Select and Mask...' ] + . +

+ + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + `; +}; +controlled.swc_vrt = { + skip: true, +}; + +controlled.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +class MenuItemWithDescription extends LitElement { + public overriderender(): TemplateResult { + return html` + + + + Quick export + Share a snapshot + + + + Open a copy + Illustrator for iPad + + + + Share link + Enable comments and download + + + + + + Deselect + + Select Inverse + Enable inverse selection + + Feather... + Select and Mask... + + Save Selection + + Make Work Path + + Create a reusable work path + + + + + `; + } +} + +customElements.define('menu-item-with-description', MenuItemWithDescription); + +export const menuItemWithDescription = (): TemplateResult => html` + +`; + +class WithIcons extends LitElement { + public override render(): TemplateResult { + return html` + + + + + Quick export + + + + Open a copy + + + + Share link + + Enable comments and download + + + + + `; + } +} + +customElements.define('menu-with-icons', WithIcons); + +export const SelectsWithIcons = (): TemplateResult => html` + +`; + +class HeadersAndIcons extends LitElement { + public override render(): TemplateResult { + return html` + + + + Section Heading + Action 1 + Action 2 + Action 3 + + + + Section Heading + + + Save + + + + Download + + + + Share link + Enable comments + + + + + `; + } +} + +customElements.define('headers-and-icons', HeadersAndIcons); + +export const headersAndIcons = (): TemplateResult => html` + +`; + +headersAndIcons.storyName = 'Headers and Icons'; + +export const Selected = (): TemplateResult => { + return html` + + + + San Francisco + Financial District + South of Market + North Beach + + + + Oakland + City Center + Jack London Square + + My best friend's mom's house in the burbs just off + Silverado street + + + + + `; +}; + +export const MenuGroupSelects = (): TemplateResult => { + return html` + + + + One of these + Camden + Cedar Riverside + Downtown + Northeast Arts District + Uptown + + + Or of these + Lowertown + Grand Ave + + + Many of these + Financial District + South of Market + North Beach + + + + One of these + City Center + Jack London Square + + My best friend's mom's house in the burbs just off + Silverado street + + + + + `; +}; + +export const selectedOffPage = (): TemplateResult => { + return html` +

+ In this example the \`<sp-menu-item selected>\` element is off + the visible page by default, but does not alter the page scroll on + load. +

+ + + My best friend's mom's house in the burbs just off Silverado + street + + + `; +}; + +export const MenuGroupSelectsMultiple = (): TemplateResult => { + return html` + + + + Many of these + Camden + Cedar Riverside + Downtown + Northeast Arts District + Uptown + + + And these, too + Lowertown + Grand Ave + + + None of these + Financial District + South of Market + North Beach + + + + One of these + City Center + Jack London Square + + My best friend's mom's house in the burbs just off + Silverado street + + + + + `; +}; + +export const menuWithValueSlots = (): TemplateResult => { + return html` + + + Undo + ⌘​Z + + + Redo + ⇧⌘​Z + + + + Cut + ⌘​X + + + Copy + ⌘​S + + + Paste + ⌘​P + + + + + + Undo + ⌘​Z + + + Redo + ⇧⌘​Z + + + + Cut + ⌘​X + + + Copy + ⌘​S + + + Paste + ⌘​P + + + + `; +}; + +headersAndIcons.storyName = 'Dynamic MenuItems'; + +export const dynamicRemoval = (): TemplateResult => { + const removeItem = async function (event: FocusEvent) { + await (event.target as MenuItem)?.updateComplete; + (event.target as MenuItem)?.remove(); + }; + return html` + + Deselect + Select Inverse + + Feather... + + Select and Mask... + Save Selection + Make Work Path + + `; +}; + +export const InputsWithMenu = (): TemplateResult => { + return html` +
+

Input Focus Demo

+

+ Try typing in any input field below, then hover over the menu + items. The input should maintain focus and not be interrupted. + This demonstrates the fix for focus stealing from all supported + input types. +

+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+ + + + Search Results + Recent Searches + Saved Searches + Advanced Search + Search Settings + Clear History + + +
+ `; +}; + +InputsWithMenu.parameters = { + tags: ['!dev'], +}; + +InputsWithMenu.swc_vrt = { + skip: true, +}; + +InputsWithMenu.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; diff --git a/1st-gen/packages/menu/stories/submenu.stories.ts b/1st-gen/packages/menu/stories/submenu.stories.ts new file mode 100644 index 00000000000..b307a532546 --- /dev/null +++ b/1st-gen/packages/menu/stories/submenu.stories.ts @@ -0,0 +1,485 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import { Overlay, VirtualTrigger } from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js'; +import type { ActionMenu } from '@spectrum-web-components/action-menu'; +import type { Menu, MenuItem } from '@spectrum-web-components/menu'; + +export default { + component: 'sp-menu', + title: 'Menu/Submenu', +}; + +function nextFrame(): Promise { + return new Promise((res) => requestAnimationFrame(() => res())); +} + +class SubmenuReady extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + constructor() { + super(); + this.readyPromise = new Promise((res) => { + this.ready = res; + this.setup(); + }); + } + + menu!: ActionMenu; + submenu!: MenuItem; + submenuChild!: MenuItem; + + async setup(): Promise { + await nextFrame(); + + this.menu = document.querySelector(`sp-action-menu`) as ActionMenu; + this.menu.addEventListener('sp-opened', this.handleMenuOpened); + this.menu.addEventListener( + 'sp-closed', + () => { + this.menu.removeEventListener( + 'sp-opened', + this.handleMenuOpened + ); + }, + { once: true } + ); + this.menu.open = true; + } + + handleMenuOpened = async (event: Event): Promise => { + this.menu.removeEventListener('sp-opened', this.handleMenuOpened); + await nextFrame(); + await (event.target as ActionMenu).updateComplete; + + this.submenu = document.querySelector('#submenu-item-1') as MenuItem; + if (!this.submenu) { + return; + } + + this.submenu.addEventListener('sp-opened', this.handleSubmenuOpened); + this.submenu.click(); + }; + + handleSubmenuOpened = async (event: Event): Promise => { + this.submenu.removeEventListener('sp-opened', this.handleSubmenuOpened); + await nextFrame(); + await (event.target as MenuItem).updateComplete; + + this.submenuChild = document.querySelector( + '#submenu-item-2' + ) as MenuItem; + if (!this.submenuChild) { + return; + } + this.submenuChild.addEventListener( + 'sp-opened', + this.handleSubmenuChildOpened + ); + this.submenuChild.click(); + }; + + handleSubmenuChildOpened = async (event: Event): Promise => { + this.submenuChild.removeEventListener( + 'sp-opened', + this.handleSubmenuChildOpened + ); + await nextFrame(); + await (event.target as MenuItem).updateComplete; + + this.ready(true); + }; + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } +} + +customElements.define('submenu-ready', SubmenuReady); + +const submenuDecorator = (story: () => TemplateResult): TemplateResult => { + return html` + ${story()} + + `; +}; + +export const submenu = (): TemplateResult => { + const getValueEls = (): { + root: HTMLElement; + first: HTMLElement; + second: HTMLElement; + } => { + return { + root: document.querySelector('#root-value') as HTMLElement, + first: document.querySelector('#first-value') as HTMLElement, + second: document.querySelector('#second-value') as HTMLElement, + }; + }; + const clearValues = (): void => { + const valueEls = getValueEls(); + valueEls.root.textContent = ''; + valueEls.first.textContent = ''; + valueEls.second.textContent = ''; + }; + const handleRootChange = (event: Event & { target: ActionMenu }): void => { + const valueEls = getValueEls(); + valueEls.root.textContent = event.target.value; + }; + const handleFirstDescendantChange = ( + event: Event & { target: Menu } + ): void => { + const valueEls = getValueEls(); + valueEls.first.textContent = event.target.selected[0] || ''; + }; + const handleSecondDescendantChange = ( + event: Event & { target: Menu } + ): void => { + const valueEls = getValueEls(); + valueEls.second.textContent = event.target.selected[0] || ''; + }; + return html` + + + console.log('group change')} + role="none" + > + New York + Bronx + + Brooklyn + + + Ft. Greene + + S. Oxford St + S. Portland Ave + S. Elliot Pl + + + Park Slope + Williamsburg + + + + Manhattan + + SoHo + + Union Square + + 14th St + Broadway + Park Ave + + + Upper East Side + + + + Queens + + + You shouldn't be able to see this! + + Forest Hills + Jamaica + + + + +
+ Root value: + +
+ First descendant value: + +
+ Second descendant value: + +
+
+ `; +}; + +submenu.decorators = [submenuDecorator]; + +export const contextMenu = (): TemplateResult => { + const contextmenu = async (event: PointerEvent): Promise => { + event.preventDefault(); + const virtualTrigger = new VirtualTrigger(event.clientX, event.clientY); + const overlay = document.querySelector('sp-overlay') as Overlay; + clearValues(); + overlay.triggerElement = virtualTrigger; + overlay.willPreventClose = true; + overlay.type = 'auto'; + overlay.placement = 'right-start'; + overlay.open = true; + }; + const getValueEls = (): { root: HTMLElement; first: HTMLElement } => { + return { + root: document.querySelector('#root-value') as HTMLElement, + first: document.querySelector('#first-value') as HTMLElement, + }; + }; + const clearValues = (): void => { + const valueEls = getValueEls(); + valueEls.root.textContent = ''; + valueEls.first.textContent = ''; + }; + const handleRootChange = (event: Event & { target: ActionMenu }): void => { + const valueEls = getValueEls(); + valueEls.root.textContent = event.target.value; + event.target.parentElement?.dispatchEvent( + new Event('close', { bubbles: true }) + ); + }; + const handleFirstDescendantChange = ( + event: Event & { target: Menu } + ): void => { + const valueEls = getValueEls(); + valueEls.first.textContent = event.target.selected[0] || ''; + }; + return html` + +
+
+ Root value: + +
+ First descendant value: + +
+
+
+ + + event.target?.dispatchEvent( + new Event('close', { bubbles: true }) + )} + > + + + Options + + Copy + ⌘​S + + + Paste + ⌘​P + + + Cut + ⌘​X + + + + Select layer + + Ellipse 1 + Rectangle + + + + Group + ⌘​G + + + Unlock + ⌘​L + + + + Bring to front + ⇧​⌘​​] + + + Bring forward + ⌘​​] + + + Send backward + ⌘​​[ + + + Send to back + ⇧​⌘​​[ + + + + Delete + DEL + + + + + + `; +}; + +export const customRootSubmenu = (): TemplateResult => { + return html` + + Bronx + + Brooklyn +
+ Kitten +

I am an arbitrary content in submenu

+
+
+
+ `; +}; + +export const customRootSubmenuWithScroll = (): TemplateResult => { + return html` + + Bronx + + Brooklyn +
+ Additional options + Available on request + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection + Deselect + Select inverse + Feather... + + Select and mask... + + Save selection +
+
+
+ `; +}; + +customRootSubmenu.swc_vrt = { + skip: true, +}; diff --git a/1st-gen/packages/menu/test/benchmark/test-basic.ts b/1st-gen/packages/menu/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..946e7874cd1 --- /dev/null +++ b/1st-gen/packages/menu/test/benchmark/test-basic.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + + Section Heading + Action 1 + Action 2 + Action 3 + + + + Section Heading + Save + Download + + +`); diff --git a/1st-gen/packages/menu/test/menu-group.test.ts b/1st-gen/packages/menu/test/menu-group.test.ts new file mode 100644 index 00000000000..d12a984f04c --- /dev/null +++ b/1st-gen/packages/menu/test/menu-group.test.ts @@ -0,0 +1,454 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + elementUpdated, + expect, + fixture, + html, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { Menu, MenuGroup, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { + mouseClickOn, + testForLitDevWarnings, +} from '../../../test/testing-helpers.js'; +import { ComplexSlottedGroup, ComplexSlottedMenu } from '../stories/index.js'; +import { complexSlotted } from '../stories/menu-group.stories.js'; + +const managedItems = (menu: Menu | MenuGroup): MenuItem[] => { + return menu.childItems.filter( + (item: MenuItem) => item.menuData.selectionRoot === menu + ); +}; + +const focusableItems = (menu: Menu | MenuGroup): MenuItem[] => { + return menu.childItems.filter( + (item: MenuItem) => item.menuData.focusRoot === menu + ); +}; + +describe('Menu group', () => { + testForLitDevWarnings( + async () => + await fixture
(html` + + + Section Heading + Action 1 + Action 2 + Action 3 + + + + Section Heading + Save + Download + + + `) + ); + it('renders', async () => { + const el = await fixture(html` + + + Section Heading + Action 1 + Action 2 + Action 3 + + + + Section Heading + Save + Download + + + `); + + await waitUntil( + () => { + return managedItems(el).length === 5; + }, + `expected menu group to manage 5 children, received ${managedItems(el).length} of ${el.childItems.length}` + ); + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('manages [slot="header"] content', async () => { + const el = await fixture(html` + + `); + await elementUpdated(el); + const slot = el.shadowRoot.querySelector( + '[name="header"' + ) as HTMLSlotElement; + const header = document.createElement('span'); + header.textContent = 'Header'; + header.slot = 'header'; + expect(header.id).to.equal(''); + let slotchanged = oneEvent(slot, 'slotchange'); + el.append(header); + await slotchanged; + expect(header.id).to.equal( + (el as unknown as { headerId: string }).headerId + ); + + slotchanged = oneEvent(slot, 'slotchange'); + header.remove(); + await slotchanged; + expect(header.id).to.equal(''); + }); + it('handles selects for nested menu groups', async () => { + const el = await fixture(html` + + First + + Second + + + Multi1 + + Multi2 + + + SubInherit1 + + SubInherit2 + + + + + Single1 + + Single2 + + + + Inherit1 + + Inherit2 + + + + Inherit1 + + Inherit2 + + + + `); + + // 1 & 3 should be menuitemradio + // 2 shouwl menuitemcheckbox + + await waitUntil( + () => managedItems(el).length === 4, + `expected outer menu to manage 4 items (2 are inherited), got ${ + managedItems(el).length + }, with ${el.childItems.length} total` + ); + await waitUntil( + () => el.selectedItems.length === 1, + 'expected 1 selected item' + ); + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + const multiGroup = el.querySelector( + 'sp-menu-group#mg-multi' + ) as MenuGroup; + const multiItem1 = multiGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const multiItem2 = multiGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + await waitUntil( + () => managedItems(multiGroup).length === 4, + `selects="#mg-multi should manage 4 items (2 are inherited), received ${ + managedItems(multiGroup).length + }` + ); + + const singleGroup = el.querySelector( + 'sp-menu-group#mg-single' + ) as MenuGroup; + + const singleItem1 = singleGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const singleItem2 = singleGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + await waitUntil( + () => managedItems(singleGroup).length === 2, + 'selects="#mg-none should manage 4 items (2 are inherited)' + ); + + const noneGroup = el.querySelector( + 'sp-menu-group#mg-none' + ) as MenuGroup; + const noneItem1 = noneGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const noneItem2 = noneGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + await waitUntil( + () => managedItems(noneGroup).length === 2, + `selects="#mg-none" should manage 2 items, received ${ + managedItems(noneGroup).length + }` + ); + + const inheritGroup = el.querySelector( + 'sp-menu-group#mg-inherit' + ) as MenuGroup; + const inheritItem1 = inheritGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const inheritItem2 = inheritGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + expect(firstItem.getAttribute('role')).to.equal('menuitemradio'); + expect(secondItem.getAttribute('role')).to.equal('menuitemradio'); + expect(multiItem1.getAttribute('role')).to.equal('menuitemcheckbox'); + expect(multiItem2.getAttribute('role')).to.equal('menuitemcheckbox'); + expect(singleItem1.getAttribute('role')).to.equal('menuitemradio'); + expect(singleItem2.getAttribute('role')).to.equal('menuitemradio'); + expect(noneItem1.getAttribute('role')).to.equal('menuitem'); + expect(noneItem2.getAttribute('role')).to.equal('menuitem'); + expect(inheritItem1.getAttribute('role')).to.equal('menuitemradio'); + expect(inheritItem2.getAttribute('role')).to.equal('menuitemradio'); + + await elementUpdated(firstItem); + expect(singleItem1.selected).to.be.true; + expect(firstItem.selected).to.be.true; + expect(secondItem.selected, 'second item not selected').to.be.false; + expect(el.value).to.equal('First'); + expect(el.selectedItems.length).to.equal(1); + + expect(firstItem.getAttribute('aria-checked')).to.equal('true'); + expect(secondItem.getAttribute('aria-checked')).to.equal('false'); + let change = oneEvent(el, 'change'); + secondItem.click(); + await change; + await elementUpdated(el); + await elementUpdated(firstItem); + await elementUpdated(secondItem); + expect(firstItem.selected, 'first item not selected').to.be.false; + expect(secondItem.selected).to.be.true; + expect(firstItem.getAttribute('aria-checked')).to.equal('false'); + expect(secondItem.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('Second'); + expect(el.selectedItems.length).to.equal(1); + change = oneEvent(el, 'change'); + inheritItem1.click(); + await change; + await elementUpdated(el); + await elementUpdated(inheritItem1); + await elementUpdated(secondItem); + expect(secondItem.selected, 'second item not selected again').to.be + .false; + expect(inheritItem1.selected).to.be.true; + expect(secondItem.getAttribute('aria-checked')).to.equal('false'); + expect(inheritItem1.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('Inherit1'); + expect(el.selectedItems.length).to.equal(1); + change = oneEvent(el, 'change'); + noneItem2.click(); + await change; + await elementUpdated(el); + await elementUpdated(noneGroup); + await elementUpdated(noneItem2); + expect(inheritItem1.selected).to.be.true; + expect(noneItem2.selected, 'none item not selected').to.be.false; + expect(el.value).to.equal('Inherit1'); + expect(el.selectedItems.length).to.equal(1); + change = oneEvent(el, 'change'); + singleItem2.click(); + await change; + await elementUpdated(singleGroup); + await elementUpdated(singleItem1); + await elementUpdated(singleItem2); + expect(singleItem2.selected).to.be.true; + expect(singleItem1.selected, 'first item not selected').to.be.false; + expect(inheritItem1.selected).to.be.true; + expect(singleItem1.getAttribute('aria-checked')).to.equal('false'); + expect(singleItem2.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('Inherit1'); + expect(el.selectedItems.length).to.equal(1); + //expect(singleGroup.value).to.equal('Inherit1') + expect(singleGroup.selectedItems.length).to.equal(1); + change = oneEvent(el, 'change'); + multiItem2.click(); + await change; + await elementUpdated(el); + await elementUpdated(multiItem2); + expect(multiItem1.selected).to.be.true; + expect(multiItem2.selected).to.be.true; + expect(inheritItem1.selected).to.be.true; + expect(multiItem1.getAttribute('aria-checked')).to.equal('true'); + expect(multiItem2.getAttribute('aria-checked')).to.equal('true'); + //expect(multiGroup.value).to.equal('Inherit1') + expect(multiGroup.selectedItems.length).to.equal(2); + }); + + it('handles changing managed items for selects changes', async () => { + const el = await fixture(html` + + First + Second + + Inherit1 + Inherit2 + + SubInherit1 + SubInherit2 + + + + `); + + await waitUntil( + () => managedItems(el).length == 6, + `expected outer menu to manage 6 items, manages ${ + managedItems(el).length + }` + ); + await waitUntil( + () => el.selectedItems.length == 2, + 'expected 2 selected item' + ); + await elementUpdated(el); + + const inheritGroup = el.querySelector( + 'sp-menu-group#mg-inherit' + ) as MenuGroup; + const inheritItem1 = inheritGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const inheritItem2 = inheritGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + const subInheritGroup = el.querySelector( + 'sp-menu-group#mg-sub-inherit' + ) as MenuGroup; + const subInheritItem1 = subInheritGroup.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const subInheritItem2 = subInheritGroup.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + expect(inheritItem1.getAttribute('role')).to.equal('menuitemcheckbox'); + expect(inheritItem2.getAttribute('role')).to.equal('menuitemcheckbox'); + expect(subInheritItem1.getAttribute('role')).to.equal( + 'menuitemcheckbox' + ); + expect(subInheritItem2.getAttribute('role')).to.equal( + 'menuitemcheckbox' + ); + expect(el.value).to.equal('First--SubInherit2'); + expect(el.selectedItems.length).to.equal(2); + inheritGroup.setAttribute('selects', 'single'); + + await elementUpdated(inheritGroup); + await elementUpdated(el); + + await waitUntil( + () => { + return managedItems(inheritGroup).length === 4; + }, + `expected new single sub-group to manage 4 items, received ${managedItems(inheritGroup).length} because "selects === ${inheritGroup.selects}` + ); + + await waitUntil( + () => managedItems(el).length === 2, + `expected outer menu to manage 2 items with none inherited, received ${ + managedItems(el).length + }` + ); + expect(inheritGroup.value).to.equal('SubInherit2'); + expect(inheritGroup.selectedItems.length).to.equal(1); + expect(el.value).to.equal('First'); + expect(inheritItem1.getAttribute('role')).to.equal('menuitemradio'); + expect(inheritItem2.getAttribute('role')).to.equal('menuitemradio'); + expect(subInheritItem1.getAttribute('role')).to.equal('menuitemradio'); + expect(subInheritItem2.getAttribute('role')).to.equal('menuitemradio'); + }); + it('manages complex slotted menu items', async function () { + const el = await fixture(complexSlotted()); + + await waitUntil( + () => focusableItems(el.menu).length == 12, + `expected outer menu to manage 12 items, ${ + el.menu.localName + } manages ${focusableItems(el.menu).length}` + ); + + const menu = el.menu; + const items: Record = {}; + items.i2 = el.querySelector('#i-2') as MenuItem; + items.i8 = el.querySelector('#i-8') as MenuItem; + items.i9 = el.querySelector('#i-9') as MenuItem; + items.i3 = el.renderRoot.querySelector('#i-3') as MenuItem; + items.i5 = el.renderRoot.querySelector('#i-5') as MenuItem; + items.i6 = el.renderRoot.querySelector('#i-6') as MenuItem; + items.i7 = el.renderRoot.querySelector('#i-7') as MenuItem; + const group = el.renderRoot.querySelector( + '#complex-slotted-group' + ) as ComplexSlottedGroup; + items.i1 = group?.renderRoot.querySelector('#i-1') as MenuItem; + items.i4 = group?.renderRoot.querySelector('#i-4') as MenuItem; + items.i10 = group?.renderRoot.querySelector('#i-10') as MenuItem; + items.i11 = group?.renderRoot.querySelector('#i-11') as MenuItem; + items.i12 = group?.renderRoot.querySelector('#i-12') as MenuItem; + + await mouseClickOn(items.i9); + await elementUpdated(items.i9); + + await sendKeys({ press: 'ArrowDown' }); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(items.i9); + expect(items.i9.focused).to.be.true; + await sendKeys({ press: 'ArrowDown' }); + let i = 9; + const count = Object.keys(items).length + 1; + while (!items.i9.focused) { + i = Math.max(1, (i + 1 + count) % count); + await elementUpdated(menu); + await elementUpdated(items[`i${i}`]); + expect(items[`i${i}`].focused, `i${i} should be focused`).to.be + .true; + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(menu); + await elementUpdated(items[`i${i}`]); + } + }); +}); diff --git a/1st-gen/packages/menu/test/menu-item.test.ts b/1st-gen/packages/menu/test/menu-item.test.ts new file mode 100644 index 00000000000..99b5c3f9c2c --- /dev/null +++ b/1st-gen/packages/menu/test/menu-item.test.ts @@ -0,0 +1,259 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + elementUpdated, + expect, + fixture, + html, + waitUntil, +} from '@open-wc/testing'; +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import { Menu, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import { spy } from 'sinon'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { mouseClickOn } from '../../../test/testing-helpers.js'; + +describe('Menu item', () => { + it('renders', async () => { + const el = await fixture(html` + + Selected + + `); + await waitUntil( + () => el.childItems.length == 1, + 'expected menu group to manage 1 child' + ); + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('can be disabled', async () => { + const el = await fixture(html` + + + Selected + + Disabled + + `); + await elementUpdated(el); + expect(el.value).to.equal('Selected'); + + const disabled = el.querySelector('[disabled]') as MenuItem; + + await sendMouse([ + { + type: 'move', + position: [disabled], + }, + { + type: 'down', + }, + { + type: 'up', + }, + ]); + await elementUpdated(el); + expect(el.value).to.equal('Selected'); + + disabled.click(); + await elementUpdated(el); + expect(el.value).to.equal('Selected'); + + disabled.dispatchEvent( + new Event('click', { + bubbles: true, + composed: true, + }) + ); + await elementUpdated(el); + expect(el.value).to.equal('Selected'); + }); + it('proxies `click()`', async () => { + const clickTargetSpy = spy(); + const el = await fixture(html` + { + clickTargetSpy( + event.composedPath()[0] as HTMLAnchorElement + ); + event.stopPropagation(); + event.preventDefault(); + }} + > + + Selected Text + + + `); + + await elementUpdated(el); + + const item = el.querySelector('sp-menu-item') as MenuItem; + const { anchorElement } = item as unknown as { + anchorElement: HTMLAnchorElement; + }; + ( + item as unknown as { anchorElement: HTMLAnchorElement } + ).anchorElement.dispatchEvent(new FocusEvent('focus')); + + await elementUpdated(item); + + expect(item === document.activeElement).to.be.true; + item.click(); + + expect(clickTargetSpy.calledWith(anchorElement)).to.be.true; + }); + it('allows link click', async () => { + const clickTargetSpy = spy(); + const el = await fixture(html` + { + clickTargetSpy( + event.composedPath()[0] as HTMLAnchorElement + ); + event.stopPropagation(); + event.preventDefault(); + }} + > + + Selected Text + + + `); + + const item = el.querySelector('sp-menu-item') as MenuItem; + const { anchorElement } = item as unknown as { + anchorElement: HTMLAnchorElement; + }; + ( + item as unknown as { anchorElement: HTMLAnchorElement } + ).anchorElement.dispatchEvent(new FocusEvent('focus')); + + await elementUpdated(item); + expect(item === document.activeElement).to.be.true; + + // tests mouse click events, and by extension VoiceOver CRTL+Option+Space click + await mouseClickOn(el); + + expect(clickTargetSpy.calledWith(anchorElement)).to.be.true; + }); + it('value attribute', async () => { + const el = await fixture(html` + Selected Text + `); + expect(el.itemText).to.equal('Selected Text'); + expect(el.value).to.equal('selected'); + }); + it('no value attribute', async () => { + const el = await fixture(html` + Selected Text + `); + expect(el.itemText).to.equal('Selected Text'); + expect(el.value).to.equal('Selected Text'); + }); + it('value property', async () => { + const el = await fixture(html` + Selected Text + `); + expect(el.itemText).to.equal('Selected Text'); + expect(el.value).to.equal('Selected Text'); + expect(el.hasAttribute('value')).to.be.false; + + el.value = 'Selected Text'; + await elementUpdated(el); + + expect(el.value).to.equal('Selected Text'); + expect(el.getAttribute('value')).to.equal('Selected Text'); + + el.value = ''; + await elementUpdated(el); + + expect(el.value).to.equal('Selected Text'); + expect(el.hasAttribute('value')).to.be.false; + }); + it('assigns content to the description slot', async () => { + const el = await fixture(html` + + Menu Item Text + Description for the Menu-Item + + `); + const descriptionElement = el.querySelector('span') as HTMLElement; + expect(descriptionElement.assignedSlot).to.not.be.null; + }); + it('acualizes a submenu', async () => { + const test = await fixture(html` + + Selected + + `); + + const el = test.querySelector('sp-menu-item') as MenuItem; + + expect(el.hasSubmenu).to.be.false; + + const submenuItem = document.createElement('sp-menu-item'); + const submenu = document.createElement('sp-menu'); + submenuItem.textContent = 'Test Submenu Item'; + submenu.slot = 'submenu'; + submenu.append(submenuItem); + + el.append(submenu); + await elementUpdated(el); + + expect(el.hasSubmenu).to.be.true; + + submenu.remove(); + await elementUpdated(el); + + expect(el.hasSubmenu).to.be.false; + }); + it('should not allow text-align to cascade when used inside an overlay', async () => { + const element = await fixture(html` +
+

+ The paragraph and the button are centered. Menu items are + not. +

+ + One + Two + This is a long option + + More options + + Three + Four + Another long option + + + +
+ `); + + const menuItems = element.querySelectorAll( + 'sp-menu-item' + ) as NodeListOf; + + for (const menuItem of menuItems) + expect(getComputedStyle(menuItem).textAlign).to.equal('start'); + }); +}); diff --git a/1st-gen/packages/menu/test/menu-memory.test.ts b/1st-gen/packages/menu/test/menu-memory.test.ts new file mode 100644 index 00000000000..966f155ca80 --- /dev/null +++ b/1st-gen/packages/menu/test/menu-memory.test.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { singleSelect } from '../stories/menu.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(singleSelect()); diff --git a/1st-gen/packages/menu/test/menu-selects.test.ts b/1st-gen/packages/menu/test/menu-selects.test.ts new file mode 100644 index 00000000000..45cab0e005c --- /dev/null +++ b/1st-gen/packages/menu/test/menu-selects.test.ts @@ -0,0 +1,602 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + elementUpdated, + expect, + html, + nextFrame, + oneEvent, +} from '@open-wc/testing'; +import { Menu, MenuGroup, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { spy } from 'sinon'; +import { + fixture, + mouseClickOn, + sendShiftTabKey, +} from '../../../test/testing-helpers.js'; + +describe('Menu [selects]', () => { + let el!: Menu; + let options!: MenuItem[]; + beforeEach(async () => { + el = await fixture
(html` + + Option 1 + Option 2 + Option 3 + + `); + options = [...el.querySelectorAll('sp-menu-item')] as MenuItem[]; + await Promise.all(options.map((option) => option.updateComplete)); + await nextFrame(); + await nextFrame(); + }); + describe('fires `change` events', async () => { + it('on browser clicks', async () => { + const item1 = options[0]; + const change = oneEvent(el, 'change'); + await mouseClickOn(item1); + await change; + expect(el.value).to.equal('1'); + }); + it('on JS clicks', async () => { + const item1 = options[0]; + const change = oneEvent(el, 'change'); + item1.click(); + await change; + expect(el.value).to.equal('1'); + }); + }); + it('manages a single selection when [selects="single"]', async () => { + expect(el.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(el.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('3'); + }); + it('manages multiple selections when [selects="multiple"]', async () => { + el.selects = 'multiple'; + + await elementUpdated(el); + + expect(el.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + expect(el.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('1,2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('1,2,3'); + + change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(el.value).to.equal('2,3'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('3'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal(''); + }); +}); + +describe('Menu [selects] w/ group', () => { + let el!: Menu; + let options!: MenuItem[]; + beforeEach(async () => { + el = await fixture(html` + + + Option 1 + Option 2 + Option 3 + + + `); + options = [...el.querySelectorAll('sp-menu-item')] as MenuItem[]; + await Promise.all(options.map((option) => option.updateComplete)); + await nextFrame(); + await nextFrame(); + }); + describe('fires `change` events', async () => { + it('on browser clicks', async () => { + const item1 = options[0]; + const change = oneEvent(el, 'change'); + await mouseClickOn(item1); + await change; + expect(el.value).to.equal('1'); + }); + it('on JS clicks', async () => { + const item1 = options[0]; + const change = oneEvent(el, 'change'); + item1.click(); + await change; + expect(el.value).to.equal('1'); + }); + }); + it('manages a single selection when [selects="single"]', async () => { + expect(el.value).to.equal(''); + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(el.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('3'); + }); + it('manages multiple selections when [selects="multiple"]', async () => { + el.selects = 'multiple'; + + await elementUpdated(el); + + expect(el.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + expect(el.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('1,2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('1,2,3'); + + change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(el.value).to.equal('2,3'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal('3'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(el.value).to.equal(''); + }); +}); + +describe('Menu w/ group [selects]', () => { + let el!: Menu; + let group!: MenuGroup; + let options!: MenuItem[]; + beforeEach(async () => { + el = await fixture(html` + + + Option 1 + Option 2 + Option 3 + + + `); + group = el.querySelector('sp-menu-group') as MenuGroup; + options = [...el.querySelectorAll('sp-menu-item')] as MenuItem[]; + await Promise.all(options.map((option) => option.updateComplete)); + await nextFrame(); + await nextFrame(); + }); + describe('fires `change` events', async () => { + it('on browser clicks', async () => { + const item1 = options[0]; + const change = oneEvent(group, 'change'); + await mouseClickOn(item1); + await change; + expect(group.value).to.equal('1'); + }); + it('on JS clicks', async () => { + const item1 = options[0]; + const change = oneEvent(group, 'change'); + item1.click(); + await change; + expect(group.value).to.equal('1'); + }); + }); + + it('manages a single selection when [selects="single"]', async () => { + expect(group.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(group.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal('2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal('3'); + }); + it('manages multiple selections when [selects="multiple"]', async () => { + group.selects = 'multiple'; + + await elementUpdated(group); + + expect(group.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + expect(group.value).to.equal('1'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal('1,2'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal('1,2,3'); + + change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(group.value).to.equal('2,3'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal('3'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + await elementUpdated(el); + + expect(group.value).to.equal(''); + }); +}); + +describe('Menu w/ groups [selects]', () => { + let el!: Menu; + let groupA!: MenuGroup; + let groupB!: MenuGroup; + let options!: MenuItem[]; + beforeEach(async () => { + el = await fixture(html` + + + Option 1a + Option 2a + Option 3a + + + Option 1b + Option 2b + Option 3b + + + `); + groupA = el.querySelector('sp-menu-group:first-child') as MenuGroup; + groupB = el.querySelector('sp-menu-group:last-child') as MenuGroup; + options = [...el.querySelectorAll('sp-menu-item')] as MenuItem[]; + await Promise.all(options.map((option) => option.updateComplete)); + await nextFrame(); + await nextFrame(); + }); + describe('fires `change` events', async () => { + it('on browser clicks', async () => { + const item1a = options[0]; + const item1b = options[3]; + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal(''); + let change = oneEvent(el, 'change'); + await mouseClickOn(item1a); + await change; + await elementUpdated(item1a); + expect(groupA.value).to.equal('1a'); + expect(groupB.value).to.equal(''); + change = oneEvent(el, 'change'); + await mouseClickOn(item1b); + await change; + expect(groupA.value).to.equal('1a'); + expect(groupB.value).to.equal('1b'); + }); + it('on JS clicks', async () => { + const item1a = options[0]; + const item1b = options[3]; + let change = oneEvent(el, 'change'); + item1a.click(); + await change; + expect(groupA.value).to.equal('1a'); + change = oneEvent(el, 'change'); + item1b.click(); + await change; + expect(groupB.value).to.equal('1b'); + }); + it('can have them `preventDefault()`ed', async () => { + const preventSpy = spy(); + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal(''); + const item1a = options[0]; + const item1b = options[3]; + groupA.addEventListener('change', (event: Event) => { + event.preventDefault(); + preventSpy(); + }); + let change = oneEvent(el, 'change'); + item1a.click(); + await change; + change = oneEvent(el, 'change'); + item1b.click(); + await change; + expect(preventSpy.callCount).to.equal(1); + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal('1b'); + }); + }); + + it('manages a single selection when [selects="single"]', async () => { + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(groupA.value).to.equal('1a'); + + change = oneEvent(el, 'change'); + options[3].click(); + await change; + + expect(groupB.value).to.equal('1b'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + expect(groupA.value).to.equal('2a'); + + change = oneEvent(el, 'change'); + options[4].click(); + await change; + + expect(groupB.value).to.equal('2b'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + expect(groupA.value).to.equal('3a'); + + change = oneEvent(el, 'change'); + options[5].click(); + await change; + + expect(groupB.value).to.equal('3b'); + }); + it('manages multiple selections when [selects="multiple"]', async () => { + groupA.selects = 'multiple'; + groupB.selects = 'multiple'; + + await elementUpdated(groupA); + await elementUpdated(groupB); + + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal(''); + + let change = oneEvent(el, 'change'); + options[0].click(); + await change; + expect(groupA.value).to.equal('1a'); + expect(groupB.value).to.equal(''); + + change = oneEvent(el, 'change'); + options[3].click(); + await change; + expect(groupA.value).to.equal('1a'); + expect(groupB.value).to.equal('1b'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + expect(groupA.value).to.equal('1a,2a'); + expect(groupB.value).to.equal('1b'); + + change = oneEvent(el, 'change'); + options[4].click(); + await change; + + expect(groupA.value).to.equal('1a,2a'); + expect(groupB.value).to.equal('1b,2b'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + expect(groupA.value).to.equal('1a,2a,3a'); + expect(groupB.value).to.equal('1b,2b'); + + change = oneEvent(el, 'change'); + options[5].click(); + await change; + + expect(groupA.value).to.equal('1a,2a,3a'); + expect(groupB.value).to.equal('1b,2b,3b'); + + change = oneEvent(el, 'change'); + options[0].click(); + await change; + + expect(groupA.value).to.equal('2a,3a'); + expect(groupB.value).to.equal('1b,2b,3b'); + + change = oneEvent(el, 'change'); + options[3].click(); + await change; + + expect(groupA.value).to.equal('2a,3a'); + expect(groupB.value).to.equal('2b,3b'); + + change = oneEvent(el, 'change'); + options[1].click(); + await change; + + expect(groupA.value).to.equal('3a'); + expect(groupB.value).to.equal('2b,3b'); + + change = oneEvent(el, 'change'); + options[4].click(); + await change; + + expect(groupA.value).to.equal('3a'); + expect(groupB.value).to.equal('3b'); + + change = oneEvent(el, 'change'); + options[2].click(); + await change; + + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal('3b'); + + change = oneEvent(el, 'change'); + options[5].click(); + await change; + + expect(groupA.value).to.equal(''); + expect(groupB.value).to.equal(''); + }); + it('manages focus', async function () { + await elementUpdated(groupA); + await elementUpdated(groupB); + const input = document.createElement('input'); + el.insertAdjacentElement('afterend', input); + input.focus(); + expect(document.activeElement === input).to.be.true; + await sendShiftTabKey(); + expect(document.activeElement === options[0]).to.be.true; + await sendKeys({ press: 'ArrowDown' }); + expect(document.activeElement === options[1]).to.be.true; + await sendKeys({ press: 'ArrowUp' }); + + await elementUpdated(el); + let optionCount = 0; + for (const option of options) { + const parentElement = option.parentElement as Menu; + expect(document.activeElement === option, 'option focused').to.be + .true; + expect(option.focused, `option ${optionCount} visually focused`).to + .be.true; + await sendKeys({ press: 'Space' }); + expect(parentElement.value).to.equal(option.value); + await sendKeys({ press: 'ArrowDown' }); + optionCount += 1; + } + }); +}); diff --git a/1st-gen/packages/menu/test/menu.test.ts b/1st-gen/packages/menu/test/menu.test.ts new file mode 100644 index 00000000000..62b523c7822 --- /dev/null +++ b/1st-gen/packages/menu/test/menu.test.ts @@ -0,0 +1,981 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + aTimeout, + elementUpdated, + expect, + html, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { Menu, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/search/sp-search.js'; +import '@spectrum-web-components/textfield/sp-textfield.js'; +import '@spectrum-web-components/number-field/sp-number-field.js'; +import '@spectrum-web-components/combobox/sp-combobox.js'; +import '@spectrum-web-components/color-field/sp-color-field.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import { isFirefox, isWebKit } from '@spectrum-web-components/shared'; +import { sendKeys } from '@web/test-runner-commands'; +import { spy } from 'sinon'; +import { + arrowDownEvent, + arrowUpEvent, + fixture, + mouseClickOn, + mouseMoveOver, + tabEvent, + testForLitDevWarnings, + tEvent, +} from '../../../test/testing-helpers.js'; + +describe('Menu', () => { + it('renders empty', async () => { + const el = await fixture(html` + Test + `); + + const anchor = el.querySelector('a') as HTMLAnchorElement; + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + expect(document.activeElement).to.not.equal(anchor); + + expect(el.getAttribute('role')).to.equal('menu'); + + el.focus(); + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + expect(document.activeElement).to.not.equal(anchor); + + anchor.focus(); + expect(document.activeElement).to.not.equal(el); + expect(document.activeElement).to.equal(anchor); + }); + it('renders w/ [disabled] menu items', async () => { + const focusinSpy = spy(); + const el = await fixture(html` + focusinSpy()}> + Disabled item + + `); + + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + + el.focus(); + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + expect(focusinSpy.callCount).to.equal(0); + }); + it('renders w/ all [disabled] menu items', async () => { + const focusinSpy = spy(); + const el = await fixture(html` + focusinSpy()}> + Disabled item 1 + Disabled item 2 + + `); + const firstItem = el.querySelector('sp-menu-item') as MenuItem; + + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + + el.focus(); + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + expect(focusinSpy.callCount).to.equal(0); + firstItem.focus(); + await elementUpdated(el); + expect(document.activeElement).to.not.equal(el); + expect(focusinSpy.callCount).to.equal(0); + expect(el.matches(':focus-within')).to.be.false; + }); + it('renders w/ menu items', async () => { + const el = await fixture(html` + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + `); + + await elementUpdated(el); + + expect(el.childItems.length).to.equal(6); + await expect(el).to.be.accessible(); + }); + + testForLitDevWarnings( + async () => + await fixture(html` + + Not Selected + Selected + Other + + `) + ); + + it('renders w/ selected', async () => { + const el = await fixture(html` + + Not Selected + Selected + Other + + `); + + await elementUpdated(el); + + const selectedItem = el.querySelector( + 'sp-menu-item[selected]' + ) as MenuItem; + + expect(selectedItem.selected).to.be.true; + await expect(el).to.be.accessible(); + }); + + it('has a "value" that can be copied during "change" events', async function () { + // @TODO: skipping this test because it's flaky in WebKit and Firefox in CI. Will review in the migration to Spectrum 2. + if (isWebKit() || isFirefox()) { + this.skip(); + } + const el = await fixture(html` + { + navigator.clipboard.writeText(value); + }} + > + Not Selected + Selected + Other + + `); + + await elementUpdated(el); + + const selectedItem = el.querySelector( + 'sp-menu-item[selected]' + ) as MenuItem; + + selectedItem.focus(); + + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + + const clipboardText = await navigator.clipboard.readText(); + await elementUpdated(el); + + expect(clipboardText).to.equal('Other'); + }); + + it('accepts Numpad keys', async function () { + // @TODO: skipping this test because it's flaky in WebKit and Firefox in CI. Will review in the migration to Spectrum 2. + if (isWebKit() || isFirefox()) { + this.skip(); + } + const el = await fixture(html` + { + navigator.clipboard.writeText(value); + }} + > + Not Selected + Selected + Other + + `); + + await elementUpdated(el); + const selectedItem = el.querySelector( + 'sp-menu-item[selected]' + ) as MenuItem; + selectedItem.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + await sendKeys({ press: 'NumpadEnter' }); + + await elementUpdated(el); + + const clipboardText = await navigator.clipboard.readText(); + expect(clipboardText).to.equal('Other'); + }); + + it('renders w/ hrefs', async () => { + const el = await fixture(html` + + + Not Selected + + Selected + Other + + `); + + await waitUntil( + () => el.childItems.length == 3, + 'expected menu to manage 3 items' + ); + await elementUpdated(el); + + await expect(el).to.be.accessible(); + + expect(el.getAttribute('role')).to.equal('menu'); + }); + + it('handle focus and keyboard input', async () => { + const el = await fixture(html` + + Deselect + Select Inverse + Feather... + Select and Mask... + + Save Selection + Make Work Path + + `); + + await waitUntil( + () => el.childItems.length == 6, + 'expected menu to manage 6 items' + ); + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const thirdToLastItem = el.querySelector( + 'sp-menu-item:nth-last-of-type(3)' + ) as MenuItem; + const secondToLastItem = el.querySelector( + 'sp-menu-item:nth-last-of-type(2)' + ) as MenuItem; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement).to.equal(firstItem); + expect(firstItem.focused, 'first item focused').to.be.true; + expect(firstItem.textContent, 'focused item text').to.equal('Deselect'); + + el.dispatchEvent(arrowUpEvent()); + el.dispatchEvent(arrowUpEvent()); + el.dispatchEvent(tEvent()); + + expect( + document.activeElement === thirdToLastItem, + 'active element after arrow up' + ).to.be.true; + expect(thirdToLastItem.focused, 'third to last item focused').to.be + .true; + expect(thirdToLastItem.textContent, 'focused item text').to.equal( + 'Select and Mask...' + ); + + el.dispatchEvent(arrowDownEvent()); + + expect( + document.activeElement === secondToLastItem, + 'active element after arrow down' + ).to.be.true; + expect(secondToLastItem.focused, 'second to last item focused').to.be + .true; + expect(secondToLastItem.textContent, 'focused item text').to.equal( + 'Save Selection' + ); + }); + + it('handles hover and keyboard input', async () => { + const el = await fixture(html` + + Deselect + Select Inverse + + `); + + await waitUntil( + () => el.childItems.length == 2, + 'expected menu to manage 2 items' + ); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement).to.equal(firstItem); + expect(firstItem.focused, 'first item focused').to.be.true; + + await mouseMoveOver(secondItem); + + expect(document.activeElement, 'active element after hover').to.equal( + secondItem + ); + expect(document.activeElement).to.equal(secondItem); + expect( + secondItem.focused, + 'second item should not have focus styling on hover' + ).to.be.false; + + await sendKeys({ press: 'ArrowUp' }); + + expect(document.activeElement).to.equal(firstItem); + expect( + firstItem.focused, + 'first item should have focus styling after keyboard' + ).to.be.true; + }); + + it('handle focus and late descendant additions', async () => { + const el = await fixture(html` + + + Options + Deselect + + + `); + + await waitUntil( + () => el.childItems.length == 1, + 'expected menu to manage 1 item' + ); + await elementUpdated(el); + + const initialLoadedItem = el.querySelector('#deselect') as MenuItem; + + el.focus(); + + await elementUpdated(el); + + expect(document.activeElement).to.equal(initialLoadedItem); + expect(initialLoadedItem.focused, 'visually focused').to.be.true; + expect(initialLoadedItem.textContent, 'focused item text').to.equal( + 'Deselect' + ); + + el.blur(); + + const group = el.querySelector('sp-menu-group') as HTMLElement; + + const prependedItem = document.createElement('sp-menu-item'); + prependedItem.textContent = 'Prepended Item'; + + const appendedItem = document.createElement('sp-menu-item'); + appendedItem.textContent = 'Appended Item'; + + group.prepend(prependedItem); + group.append(appendedItem); + await elementUpdated(el); + + await waitUntil(() => { + return el.childItems.length == 3; + }, 'expected menu to manage 3 items'); + + await elementUpdated(el); + + expect(el.childItems.length).to.equal(3); + el.focus(); + + expect( + document.activeElement === prependedItem, + 'prepended item is active element?' + ).to.be.true; + expect(prependedItem.focused, 'prepended item visibly focused').to.be + .true; + + await sendKeys({ press: 'ArrowUp' }); + + expect( + document.activeElement === appendedItem, + 'appended item is active element' + ).to.be.true; + expect(appendedItem.focused, 'appended visibly focused').to.be.true; + }); + + it('cleans up when tabbing away', async () => { + const el = await fixture(html` + + Deselect + Select Inverse + Third Item + + `); + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const thirdItem = el.querySelector( + 'sp-menu-item:nth-of-type(3)' + ) as MenuItem; + + el.focus(); + + expect( + document.activeElement === firstItem, + 'first item is active element' + ).to.be.true; + expect(firstItem.focused, 'first item focused').to.be.true; + el.dispatchEvent(arrowDownEvent()); + el.dispatchEvent(arrowDownEvent()); + expect(thirdItem.focused, 'third item focused').to.be.true; + // imitate tabbing away + thirdItem.dispatchEvent(tabEvent()); + el.dispatchEvent( + new CustomEvent('focusout', { + composed: true, + bubbles: true, + }) + ); + await elementUpdated(el); + + el.focus(); + // focus management should start again from the first item. + await sendKeys({ press: 'ArrowDown' }); + expect(firstItem.focused, 'first item focused again').to.be.true; + }); + + it('handles focus across focused MenuItem removals', async () => { + const el = await fixture(html` + + Deselect + Select Inverse + Third Item + + `); + await waitUntil( + () => el.childItems.length == 3, + 'expected menu to manage 3 items', + { timeout: 2000 } // Increase timeout for CI environment stability + ); + + expect(el.children.length).to.equal(el.childItems.length); + + el.focus(); + + const children = [...el.children]; + + expect(children[1], 'selected element is focused').to.equal( + document.activeElement + ); + + await sendKeys({ press: 'ArrowUp' }); + + expect(children[0], 'first element is focused').to.equal( + document.activeElement + ); + // @TODO: skipping the remaining assertions because it fails on Chromium. Will review in the migration to Spectrum 2. + if (isFirefox() || isWebKit()) { + children[0].remove(); + await elementUpdated(el); + expect(children[1], 'selected element is focused').to.equal( + document.activeElement + ); + + await sendKeys({ press: 'ArrowUp' }); + expect(children[2], 'last element is focused').to.equal( + document.activeElement + ); + } + }); + + it('handles single selection', async () => { + const el = await fixture(html` + + First + Second + Third + + `); + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + expect(firstItem.getAttribute('role')).to.equal('menuitemradio'); + expect(secondItem.getAttribute('role')).to.equal('menuitemradio'); + + expect(firstItem.selected).to.be.true; + expect(secondItem.selected).to.be.false; + expect(firstItem.getAttribute('aria-checked')).to.equal('true'); + expect(secondItem.getAttribute('aria-checked')).to.equal('false'); + expect(el.value).to.equal('First'); + + const change = oneEvent(el, 'change'); + secondItem.click(); + await change; + + await elementUpdated(el); + await elementUpdated(firstItem); + await elementUpdated(secondItem); + + expect(firstItem.selected).to.be.false; + expect(secondItem.selected).to.be.true; + expect(firstItem.getAttribute('aria-checked')).to.equal('false'); + expect(secondItem.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('Second'); + }); + it('does not make a selection on a right/middle mouse click', async () => { + const changeSpy = spy(); + const el = await fixture(html` + { + changeSpy(); + }} + > + First + Second + Third + + `); + + await waitUntil( + () => el.childItems.length == 3, + 'expected menu to manage 3 items' + ); + await elementUpdated(el); + + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + //@TODO: this tests opens a context menu outside of the test runner and that should be fixed. + // send right mouse click to the secondItem + await mouseClickOn(secondItem, 'center', { button: 'right' }); + await elementUpdated(el); + await elementUpdated(secondItem); + await aTimeout(150); + expect(changeSpy.callCount, 'no change').to.equal(0); + + // send middle mouse click to the secondItem + await mouseClickOn(secondItem, 'center', { button: 'middle' }); + await elementUpdated(el); + await elementUpdated(secondItem); + await aTimeout(150); + expect(changeSpy.callCount, 'no change').to.equal(0); + }); + it('handles multiple selection', async () => { + const changeSpy = spy(); + const el = await fixture(html` + changeSpy()}> + First + Second + Third + + `); + + await waitUntil( + () => el.childItems.length == 3, + 'expected menu to manage 3 items' + ); + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + + expect(firstItem.getAttribute('role')).to.equal('menuitemcheckbox'); + expect(secondItem.getAttribute('role')).to.equal('menuitemcheckbox'); + + expect(firstItem.selected).to.be.true; + expect(secondItem.selected).to.be.false; + expect(firstItem.getAttribute('aria-checked')).to.equal('true'); + expect(secondItem.getAttribute('aria-checked')).to.equal('false'); + expect(el.value).to.equal('First'); + expect(el.selectedItems.length).to.equal(1); + + let change = oneEvent(el, 'change'); + secondItem.click(); + await change; + + await elementUpdated(el); + await elementUpdated(firstItem); + await elementUpdated(secondItem); + + expect(changeSpy.callCount, 'one change').to.equal(1); + expect(firstItem.selected).to.be.true; + expect(secondItem.selected).to.be.true; + expect(firstItem.getAttribute('aria-checked')).to.equal('true'); + expect(secondItem.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('First,Second'); + expect(el.selectedItems.length).to.equal(2); + + change = oneEvent(el, 'change'); + firstItem.click(); + await change; + + await elementUpdated(el); + await elementUpdated(firstItem); + await elementUpdated(secondItem); + + expect(changeSpy.callCount, 'two changes').to.equal(2); + expect(firstItem.selected).to.be.false; + expect(secondItem.selected).to.be.true; + expect(firstItem.getAttribute('aria-checked')).to.equal('false'); + expect(secondItem.getAttribute('aria-checked')).to.equal('true'); + expect(el.value).to.equal('Second'); + expect(el.selectedItems.length).to.equal(1); + }); + it('can be controlled to manage a single togglable selection', async () => { + const toggleSingleSelected = ( + event: Event & { target: Menu } + ): void => { + event.preventDefault(); + const selected: string[] = []; + if (event.target.selected.length) { + selected.push(event.target.selected.at(-1) as string); + } + event.target.updateComplete.then(() => { + event.target.selected = selected; + }); + }; + const el = await fixture(html` + + First + Second + Third + + `); + await elementUpdated(el); + expect(el.selected).to.deep.equal([]); + + const items = [...el.children] as MenuItem[]; + await Promise.all(items.map((child) => child.updateComplete)); + + items[0].click(); + await elementUpdated(el); + expect(el.selected).to.deep.equal(['1']); + + items[0].click(); + await elementUpdated(el); + expect(el.selected).to.deep.equal([]); + + items[1].click(); + await elementUpdated(el); + expect(el.selected).to.deep.equal(['2']); + + items[2].click(); + await elementUpdated(el); + expect(el.selected).to.deep.equal(['3']); + }); + + it('handles long menu with basic selection', async () => { + const menuItems = Array.from( + { length: 30 }, + (_, i) => html` + Item ${i + 1} + ` + ); + + const el = await fixture(html` + + ${menuItems} + + `); + await elementUpdated(el); + + // Wait for all menu items to be properly rendered + await waitUntil( + () => el.childItems.length === 30, + 'expected menu to manage 30 items' + ); + + const firstItem = el.querySelector('sp-menu-item') as MenuItem; + const middleItem = el.querySelector( + 'sp-menu-item:nth-child(15)' + ) as MenuItem; + const lastItem = el.querySelector( + 'sp-menu-item:nth-child(30)' + ) as MenuItem; + + // Test scrolling state management + expect(el.isScrolling).to.be.false; + el.isScrolling = true; + expect(el.isScrolling).to.be.true; + el.isScrolling = false; + expect(el.isScrolling).to.be.false; + + // Test normal selection when not scrolling + firstItem.click(); + await elementUpdated(el); + await elementUpdated(firstItem); + expect(firstItem.selected).to.be.true; + expect(el.value).to.equal('1'); + + // Test selection of middle item when not scrolling + middleItem.click(); + await elementUpdated(el); + await elementUpdated(middleItem); + expect(middleItem.selected).to.be.true; + expect(el.value).to.equal('15'); + expect(firstItem.selected).to.be.false; + + // Test selection of last item when not scrolling + lastItem.click(); + await elementUpdated(el); + await elementUpdated(lastItem); + expect(lastItem.selected).to.be.true; + expect(el.value).to.equal('30'); + expect(middleItem.selected).to.be.false; + + // Test that the component can be disconnected without errors + el.remove(); + }); + + it('prevents selection during iPad scroll detection', async () => { + const menuItems = Array.from( + { length: 30 }, + (_, i) => html` + Item ${i + 1} + ` + ); + + const el = await fixture(html` + + ${menuItems} + + `); + await elementUpdated(el); + + // Wait for all menu items to be properly rendered + await waitUntil( + () => el.childItems.length === 30, + 'expected menu to manage 30 items' + ); + + const middleItem = el.querySelector( + 'sp-menu-item:nth-child(15)' + ) as MenuItem; + const firstItem = el.querySelector('sp-menu-item') as MenuItem; + + // Test normal selection first (no scrolling) + middleItem.click(); + await elementUpdated(el); + await elementUpdated(middleItem); + expect(middleItem.selected).to.be.true; + expect(el.value).to.equal('15'); + + // Reset selection + firstItem.click(); + await elementUpdated(el); + await elementUpdated(firstItem); + expect(firstItem.selected).to.be.true; + expect(el.value).to.equal('1'); + + // Manually set scrolling state to simulate iPad scroll detection + el.isScrolling = true; + expect(el.isScrolling).to.be.true; + + // Try to select an item while scrolling is detected + middleItem.click(); + await elementUpdated(el); + await elementUpdated(middleItem); + + // Verify that selection is prevented during scroll + expect(middleItem.selected).to.be.false; + expect(el.value).to.equal('1'); // Should still be the first item + + // Reset scrolling state + el.isScrolling = false; + expect(el.isScrolling).to.be.false; + + // Now try to select the item again (should work since scrolling is reset) + middleItem.click(); + await elementUpdated(el); + await elementUpdated(middleItem); + expect(middleItem.selected).to.be.true; + expect(el.value).to.equal('15'); + + // Test that the component can be disconnected without errors + el.remove(); + }); + + it('does not steal focus from input elements on mouseover', async () => { + const el = await fixture(html` +
+ + + + + + + + + + + Menu Item 1 + + + Menu Item 2 + + + Menu Item 3 + + + +
+ `); + + await elementUpdated(el); + + const searchInput = el.querySelector('#test-search') as HTMLElement; + const textfieldInput = el.querySelector( + '#test-textfield' + ) as HTMLElement; + const numberInput = el.querySelector('#test-number') as HTMLElement; + const comboboxInput = el.querySelector('#test-combobox') as HTMLElement; + const colorInput = el.querySelector('#test-color') as HTMLElement; + const nativeInput = el.querySelector( + '#test-native' + ) as HTMLInputElement; + + const menuItem1 = el.querySelector('#menu-item-1') as MenuItem; + const menuItem2 = el.querySelector('#menu-item-2') as MenuItem; + const menuItem3 = el.querySelector('#menu-item-3') as MenuItem; + + // Test with sp-search + searchInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(searchInput); + + await mouseMoveOver(menuItem1); + await elementUpdated(el); + expect(document.activeElement).to.equal( + searchInput, + 'sp-search should retain focus on mouseover' + ); + + await mouseMoveOver(menuItem2); + await elementUpdated(el); + expect(document.activeElement).to.equal( + searchInput, + 'sp-search should retain focus on mouseover' + ); + + // Test with sp-textfield + textfieldInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(textfieldInput); + + await mouseMoveOver(menuItem1); + await elementUpdated(el); + expect(document.activeElement).to.equal( + textfieldInput, + 'sp-textfield should retain focus on mouseover' + ); + + // Test with sp-number-field + numberInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(numberInput); + + await mouseMoveOver(menuItem2); + await elementUpdated(el); + expect(document.activeElement).to.equal( + numberInput, + 'sp-number-field should retain focus on mouseover' + ); + + // Test with sp-combobox + comboboxInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(comboboxInput); + + await mouseMoveOver(menuItem3); + await elementUpdated(el); + expect(document.activeElement).to.equal( + comboboxInput, + 'sp-combobox should retain focus on mouseover' + ); + + // Test with sp-color-field + colorInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(colorInput); + + await mouseMoveOver(menuItem1); + await elementUpdated(el); + expect(document.activeElement).to.equal( + colorInput, + 'sp-color-field should retain focus on mouseover' + ); + + // Test with native input + nativeInput.focus(); + await elementUpdated(el); + expect(document.activeElement).to.equal(nativeInput); + + await mouseMoveOver(menuItem2); + await elementUpdated(el); + expect(document.activeElement).to.equal( + nativeInput, + 'native input should retain focus on mouseover' + ); + }); +}); diff --git a/1st-gen/packages/menu/test/submenu.test.ts b/1st-gen/packages/menu/test/submenu.test.ts new file mode 100644 index 00000000000..e3dde7ef127 --- /dev/null +++ b/1st-gen/packages/menu/test/submenu.test.ts @@ -0,0 +1,890 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + aTimeout, + elementUpdated, + expect, + html, + nextFrame, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { ActionMenu } from '@spectrum-web-components/action-menu'; +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js'; +import { Menu, MenuItem } from '@spectrum-web-components/menu'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; +import { slottableRequest } from '@spectrum-web-components/overlay/src/slottable-request-directive.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { TemplateResult } from 'lit-html'; +import { spy } from 'sinon'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { + fixture, + mouseClickOn, + mouseMoveAway, + mouseMoveOver, + sendTabKey, +} from '../../../test/testing-helpers.js'; + +type SelectsWithKeyboardTest = { + dir: 'ltr' | 'rtl' | 'auto'; + openKey: 'ArrowRight' | 'ArrowLeft'; + closeKey: 'ArrowRight' | 'ArrowLeft'; +}; + +const selectsWithKeyboardData = [ + { + dir: 'ltr', + openKey: 'ArrowRight', + closeKey: 'ArrowLeft', + }, + { + dir: 'rtl', + openKey: 'ArrowLeft', + closeKey: 'ArrowRight', + }, +] as SelectsWithKeyboardTest[]; + +describe('Submenu', () => { + function selectWithPointer(): void { + it('with pointer', async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + await opened; + + expect(this.rootItem.open).to.be.true; + + const item2 = document.querySelector('.submenu-item-2') as MenuItem; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseClickOn(item2); + await closed; + + expect( + this.submenuChanged.withArgs('Two').calledOnce, + `submenu changed ${this.submenuChanged.callCount} times` + ).to.be.true; + expect( + this.rootChanged.withArgs('Has submenu').calledOnce, + 'root changed' + ).to.be.true; + }); + } + function selectsWithBoth(testData: SelectsWithKeyboardTest): void { + it(`with pointer and keyboard: ${testData.dir}`, async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + await opened; + const item1 = document.querySelector('.submenu-item-1') as MenuItem; + const item2 = document.querySelector('.submenu-item-2') as MenuItem; + + expect(this.rootItem.open, `submenu should open`).to.be.true; + expect(document.activeElement).not.to.equal(item1); + + const prev = this.rootItem.previousElementSibling as MenuItem; + + // arrow up should move focus away from the submenu + // but submenu stays open while pointer is over it + await sendKeys({ press: 'ArrowUp' }); + expect(document.activeElement).to.equal(prev); + expect(prev.focused, `focus is on previous item`).to.be.true; + expect(this.rootItem.open, `submenu should stay open`).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseClickOn(item2); + await closed; + + expect( + this.submenuChanged.withArgs('Two').calledOnce, + `submenu changed ${this.submenuChanged.callCount} times` + ).to.be.true; + expect( + this.rootChanged.withArgs('Has submenu').calledOnce, + `root changed ${this.submenuChanged.callCount} times` + ).to.be.true; + }); + } + function selectsWithKeyboard(testData: SelectsWithKeyboardTest): void { + it(`with keyboard: ${testData.dir}`, async function () { + this.el.parentElement.dir = testData.dir; + + await elementUpdated(this.el); + expect( + this.rootItem.open, + `rootItem open before ${testData.openKey}` + ).to.be.false; + const input = document.createElement('input'); + this.el.insertAdjacentElement('beforebegin', input); + await elementUpdated(input); + await sendTabKey(); + await elementUpdated(input); + + expect(document.activeElement).to.equal(input); + await sendTabKey(); + await elementUpdated(this.el); + await waitUntil( + () => document.activeElement === this.el.children[0], + 'focuses first menu item after tab' + ); + + expect(document.activeElement).to.equal(this.el.children[0]); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(this.rootItem); + + expect( + this.rootItem.focused, + `rootItem focused before ${testData.openKey}` + ).to.be.true; + + let opened = oneEvent(this.rootItem, 'sp-opened'); + await sendKeys({ press: testData.openKey }); + await opened; + + const rootItem = this.el.querySelector('.root') as MenuItem; + let submenu = this.el.querySelector('[slot="submenu"]') as Menu; + let submenuItem = this.el.querySelector( + '.submenu-item-1' + ) as MenuItem; + + expect( + this.rootItem.open, + `rootItem open after ${testData.openKey}` + ).to.be.true; + + //opening a menu via keyboard should set focus on first item + expect(document.activeElement).to.equal(submenuItem); + + let closed = oneEvent(this.rootItem, 'sp-closed'); + await sendKeys({ press: testData.closeKey }); + await closed; + + expect( + this.rootItem.open, + `rootItem open after ${testData.closeKey}` + ).to.be.false; + + //closing a submenu via keyboard should set focus on its parent menuitem + expect(document.activeElement).to.equal(rootItem); + + opened = oneEvent(this.rootItem, 'sp-opened'); + await sendKeys({ press: testData.openKey }); + await opened; + await elementUpdated(this.rootItem); + + submenu = this.el.querySelector('[slot="submenu"]') as Menu; + await elementUpdated(submenu); + + expect(this.rootItem.open, 'rootItem.open').to.be.true; + expect(submenuItem.focused, 'submenuItem.focused').to.be.true; + expect(document.activeElement).to.equal(submenuItem); + + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(submenu); + await elementUpdated(submenuItem); + + submenuItem = this.el.querySelector('.submenu-item-2') as MenuItem; + expect(submenuItem.focused, `submenu focused`).to.be.true; + expect(document.activeElement === submenuItem, `submenu active`).to + .be.true; + + closed = oneEvent(this.rootItem, 'sp-closed'); + await sendKeys({ press: 'Enter' }); + await closed; + + expect(this.submenuChanged.calledWith('Two'), 'submenu changed').to + .be.true; + expect(this.rootChanged.called, 'root has changed').to.be.true; + expect( + this.rootChanged.calledWith('Has submenu'), + 'root specifically changed' + ).to.be.true; + }); + } + function returnsFocusToRootWhenClosingSubmenu(): void { + it('returns visible focus when submenu closed', async function () { + const input = document.createElement('input'); + this.el.insertAdjacentElement('beforebegin', input); + + await sendTabKey(); + await elementUpdated(input); + expect(document.activeElement, 'focuses input').to.equal(input); + await sendTabKey(); + await waitUntil( + () => document.activeElement === this.el.children[0], + 'focuses first menu item after tab' + ); + expect(document.activeElement, 'focuses first menu item').to.equal( + this.el.children[0] + ); + + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(this.el); + await nextFrame(); + await nextFrame(); + expect(this.rootItem.active, 'menu with submenu is not active').to + .be.false; + expect( + this.rootItem.focused, + `focused: ${document.activeElement?.localName}` + ).to.be.true; + expect(this.rootItem.open, 'menu with submenu is not open').to.be + .false; + expect( + document.activeElement, + 'focuses menu with submenu' + ).to.equal(this.rootItem); + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await sendKeys({ press: 'ArrowRight' }); + await opened; + + expect(this.rootItem.active).to.be.true; + expect(this.rootItem.focused).to.be.false; + expect(this.rootItem.open).to.be.true; + + await sendKeys({ press: 'ArrowDown' }); + + expect(this.rootItem.active).to.be.true; + expect(this.rootItem.focused).to.be.false; + expect(this.rootItem.open).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await sendKeys({ press: 'ArrowLeft' }); + await closed; + + expect(this.rootItem.active).to.be.false; + expect(this.rootItem.focused).to.be.true; + expect(this.rootItem.open).to.be.false; + }); + } + function closesOnPointerLeave(): void { + it('closes on `pointerleave`', async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + await opened; + + expect(this.rootItem.open).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseMoveAway(this.rootItem); + await closed; + + expect(this.rootItem.open).to.be.false; + }); + } + function persistsThroughMouseLeaveAndReturn(): void { + it('stays open when mousing off menu item and back again', async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + await mouseMoveAway(this.rootItem); + await mouseMoveOver(this.rootItem); + await opened; + expect(this.rootItem.open).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseMoveAway(this.rootItem); + + await closed; + }); + } + function doesNotOpenWhenDisabled(): void { + it('does not open when disabled', async function () { + this.rootItem.disabled = true; + await elementUpdated(this.rootItem); + + expect(this.rootItem.open).to.be.false; + + await mouseMoveOver(this.rootItem); + + // wait 200ms for open + await new Promise((r) => setTimeout(r, 200)); + + expect(this.rootItem.open).to.be.false; + }); + } + function persistsWhenMovingBetweenItemAndSubmenu(): void { + it('stays open when mousing between menu item and submenu', async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + await opened; + await nextFrame(); + await nextFrame(); + + const subItem = this.el.querySelector( + '.submenu-item-2' + ) as MenuItem; + const clickSpy = spy(); + subItem.addEventListener('click', () => clickSpy()); + expect(this.rootItem.open).to.be.true; + + await mouseMoveOver(subItem); + expect(this.rootItem.open).to.be.true; + // Ensure it _doesn't_ get closed. + await aTimeout(150); + + expect(this.rootItem.open).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseClickOn(subItem); + await closed; + + expect(clickSpy.callCount).to.equal(1); + }); + } + function continuesToOpenWhenMovingBetweenItemAndSubmenu(): void { + it('continues to open when mousing between menu item and submenu', async function () { + expect(this.rootItem.open).to.be.false; + + const opened = oneEvent(this.rootItem, 'sp-opened'); + await mouseMoveOver(this.rootItem); + // Wait for the overlay system to position the submenu before measuring it's position and moving to it. + await aTimeout(200); // Replace 8 nextFrame() calls with single timeout for CI stability + const subItem = this.el.querySelector( + '.submenu-item-2' + ) as MenuItem; + const clickSpy = spy(); + subItem.addEventListener('click', () => clickSpy()); + await mouseMoveOver(subItem); + await opened; + expect(this.rootItem.open).to.be.true; + // Ensure it _doesn't_ get closed. + await aTimeout(150); + + expect(this.rootItem.open).to.be.true; + + const closed = oneEvent(this.rootItem, 'sp-closed'); + await mouseClickOn(subItem); + await closed; + + expect(clickSpy.callCount).to.equal(1); + }); + } + const renderSubmenu = (): TemplateResult => html` + One + Two + Three + `; + describe('static DOM', () => { + beforeEach(async function () { + this.rootChanged = spy(); + this.submenuChanged = spy(); + this.el = await fixture
(html` + { + this.rootChanged(event.target.value); + }} + > + No submenu + + Has submenu + { + this.submenuChanged(event.target.value); + }} + > + ${renderSubmenu()} + + + + `); + await elementUpdated(this.el); + this.rootItem = this.el.querySelector('.root') as MenuItem; + await elementUpdated(this.rootItem); + }); + describe('selects', () => { + selectWithPointer(); + selectsWithKeyboardData.map((testData) => { + selectsWithKeyboard(testData); + selectsWithBoth(testData); + }); + }); + closesOnPointerLeave(); + returnsFocusToRootWhenClosingSubmenu(); + persistsThroughMouseLeaveAndReturn(); + doesNotOpenWhenDisabled(); + persistsWhenMovingBetweenItemAndSubmenu(); + continuesToOpenWhenMovingBetweenItemAndSubmenu(); + }); + describe('directive', () => { + beforeEach(async function () { + this.rootChanged = spy(); + this.submenuChanged = spy(); + this.el = await fixture(html` + { + this.rootChanged(event.target.value); + }} + > + No submenu + + Has submenu + { + this.submenuChanged(event.target.value); + }} + ${slottableRequest(renderSubmenu)} + > + + + `); + await elementUpdated(this.el); + this.rootItem = this.el.querySelector('.root') as MenuItem; + await elementUpdated(this.rootItem); + }); + describe('selects', () => { + selectWithPointer(); + selectsWithKeyboardData.map((testData) => { + selectsWithKeyboard(testData); + selectsWithBoth(testData); + }); + }); + closesOnPointerLeave(); + returnsFocusToRootWhenClosingSubmenu(); + persistsThroughMouseLeaveAndReturn(); + doesNotOpenWhenDisabled(); + persistsWhenMovingBetweenItemAndSubmenu(); + continuesToOpenWhenMovingBetweenItemAndSubmenu(); + }); + it('closes deep tree on selection', async function () { + const rootChanged = spy(); + const submenuChanged = spy(); + const subSubmenuChanged = spy(); + const el = await fixture(html` + { + rootChanged(event.target.value); + }} + > + + Has submenu + { + submenuChanged(event.target.value); + }} + > + One + + Two + { + subSubmenuChanged(event.target.value); + }} + > + + A + + + B + + + C + + + + + Three + + + + + `); + const rootItem = el.querySelector('.root') as MenuItem; + const item2 = document.querySelector('.submenu-item-2') as MenuItem; + const itemC = document.querySelector('.sub-submenu-item-3') as MenuItem; + expect(rootItem.open).to.be.false; + + let opened = oneEvent(rootItem, 'sp-opened'); + // Hover the root menu item to open a submenu + await mouseMoveOver(rootItem); + await opened; + + expect(rootItem.open).to.be.true; + + opened = oneEvent(item2, 'sp-opened'); + // Move to the submenu item to open a submenu + await mouseMoveOver(item2); + await opened; + + expect(item2.open).to.be.true; + + const closed = oneEvent(rootItem, 'sp-closed'); + // click to select and close + await mouseClickOn(itemC); + await closed; + + expect(rootChanged.calledWith('Has submenu'), 'root changed').to.be + .true; + expect(submenuChanged.calledWith('Two'), 'submenu changed').to.be.true; + expect(subSubmenuChanged.calledWith('C'), 'sub submenu changed').to.be + .true; + }); + it('closes all descendant submenus when closing a ancestor menu', async () => { + const el = await fixture(html` + + + + New York + Bronx + + Brooklyn + + + Ft. Greene + + S. Oxford St + S. Portland Ave + S. Elliot Pl + + + Park Slope + Williamsburg + + + + Manhattan + + SoHo + + Union Square + + 14th St + Broadway + Park Ave + + + Upper East Side + + + + + `); + + const rootMenu1 = el.querySelector('#submenu-item-1') as MenuItem; + const rootMenu2 = el.querySelector('#submenu-item-3') as MenuItem; + const childMenu2 = el.querySelector('#submenu-item-2') as MenuItem; + + expect(el.open).to.be.false; + let opened = oneEvent(el, 'sp-opened'); + el.click(); + await opened; + expect(el.open).to.be.true; + + opened = oneEvent(rootMenu1, 'sp-opened'); + await mouseMoveOver(rootMenu1); + await opened; + expect(rootMenu1.open).to.be.true; + + opened = oneEvent(childMenu2, 'sp-opened'); + await mouseMoveOver(childMenu2); + await opened; + expect(childMenu2.open).to.be.true; + + const childMenu2Closed = oneEvent(childMenu2, 'sp-closed'); + const rootMenu1Closed = oneEvent(rootMenu1, 'sp-closed'); + const rootMenu2Opened = oneEvent(rootMenu2, 'sp-opened'); + rootMenu2.dispatchEvent( + new PointerEvent('pointerenter', { bubbles: true }) + ); + await childMenu2Closed; + await rootMenu1Closed; + await rootMenu2Opened; + }); + describe('deep tree', () => { + beforeEach(async function () { + this.el = await fixture(html` + + + + New York + Bronx + + Brooklyn + + + Ft. Greene + + + S. Oxford St + + + S. Portland Ave + + + S. Elliot Pl + + + + Park Slope + + Williamsburg + + + + + Manhattan + + SoHo + + Union Square + + 14th St + Broadway + Park Ave + + + Upper East Side + + + + + `); + await nextFrame(); + await nextFrame(); + }); + it('closes back to the first overlay without a `root` when clicking away', async function () { + const rootMenu1 = this.el.querySelector('#submenu-item-1') as Menu; + const childMenu2 = this.el.querySelector('#submenu-item-2') as Menu; + document.body.style.setProperty('padding', '50px'); + + expect(this.el.open).to.be.false; + let opened = oneEvent(this.el, 'sp-opened'); + this.el.click(); + await opened; + expect(this.el.open).to.be.true; + + opened = oneEvent(rootMenu1, 'sp-opened'); + await mouseMoveOver(rootMenu1); + await opened; + + opened = oneEvent(childMenu2, 'sp-opened'); + await mouseMoveOver(childMenu2); + await opened; + const closed = Promise.all([ + oneEvent(childMenu2, 'sp-closed'), + oneEvent(rootMenu1, 'sp-closed'), + ]); + await mouseMoveAway(this.el); + await closed; + }); + it('closes descendant menus when Menu Item in ancestor without a submenu is pointerentered', async function () { + const rootMenu = this.el.querySelector( + '#submenu-item-1' + ) as MenuItem; + const noSubmenu = this.el.querySelector('#no-submenu') as MenuItem; + + expect(this.el.open).to.be.false; + let opened = oneEvent(this.el, 'sp-opened'); + this.el.click(); + await opened; + expect(this.el.open).to.be.true; + + opened = oneEvent(rootMenu, 'sp-opened'); + rootMenu.dispatchEvent( + new PointerEvent('pointerenter', { bubbles: true }) + ); + await opened; + + const closed = oneEvent(rootMenu, 'sp-closed'); + noSubmenu.dispatchEvent( + new PointerEvent('pointerenter', { bubbles: true }) + ); + await closed; + }); + it('closes descendant menus when Menu Item in ancestor is clicked', async function () { + const rootMenu1 = this.el.querySelector( + '#submenu-item-1' + ) as MenuItem; + const childMenu2 = this.el.querySelector( + '#submenu-item-2' + ) as MenuItem; + const ancestorItem = this.el.querySelector( + '#ancestor-item' + ) as MenuItem; + + expect(this.el.open).to.be.false; + let opened = oneEvent(this.el, 'sp-opened'); + this.el.click(); + await opened; + expect(this.el.open).to.be.true; + + opened = oneEvent(rootMenu1, 'sp-opened'); + await mouseMoveOver(rootMenu1); + await opened; + + opened = oneEvent(childMenu2, 'sp-opened'); + await mouseMoveOver(childMenu2); + await opened; + + const closed = Promise.all([ + oneEvent(childMenu2, 'sp-closed'), + oneEvent(rootMenu1, 'sp-closed'), + ]); + await mouseClickOn(ancestorItem); + await closed; + }); + }); + it('cleans up submenus that close before they are "open"', async () => { + if ('showPopover' in document.createElement('div')) { + return; + } + await sendMouse({ + type: 'move', + position: [1, 1], + }); + const el = await fixture(html` + + + Has submenu + ${renderSubmenu()} + + + Has submenu + ${renderSubmenu()} + + + `); + + await elementUpdated(el); + const rootItem1 = el.querySelector('.root-1') as MenuItem; + const rootItem2 = el.querySelector('.root-2') as MenuItem; + expect(rootItem1.open, 'initially closed 1').to.be.false; + expect(rootItem2.open, 'initially closed 2').to.be.false; + + // Open the first submenu + await mouseMoveOver(rootItem1); + // Open the second submenu, closing the first + await mouseMoveOver(rootItem2); + // Open the first submenu, closing the second + await mouseMoveOver(rootItem1); + // Open the second submenu, closing the first + await mouseMoveOver(rootItem2); + await elementUpdated(rootItem1); + await elementUpdated(rootItem2); + const closed = oneEvent(rootItem2, 'sp-closed'); + // Close the second submenu + await mouseClickOn(rootItem2); + await elementUpdated(rootItem2); + await closed; + + expect(rootItem1.open, 'finally closed 1').to.be.false; + expect(rootItem2.open, 'finally closed 2').to.be.false; + }); + it('allows using non-menu-item elements as the root of a submenu', async () => { + const el = await fixture(html` + + + Has submenu +
+ One + Two + Three +
+
+
+ `); + await elementUpdated(el); + const rootItem = el.querySelector('.root') as MenuItem; + + // Open the first submenu + await mouseMoveOver(rootItem); + + expect(rootItem.open).to.be.true; + + const firstSubMenuItemRect = el + .querySelector('.submenu-1') + ?.getBoundingClientRect(); + + if (!firstSubMenuItemRect) { + throw new Error('Submenu item not found'); + } + + // click to select + await mouseMoveOver(firstSubMenuItemRect); + + // This test will fail if the click event throws an error + // because the submenu root is not a menu-item + }); + it('should make submenu scrollable when content exceeds max height', async () => { + const el = await fixture
(html` + + + Parent Item +
+ ${Array(20) + .fill(0) + .map( + (_, i) => html` + + Submenu Item ${i + 1} + + ` + )} +
+
+
+ `); + + await elementUpdated(el); + + const menuItem = el.querySelector('sp-menu-item') as MenuItem; + const submenu = menuItem.querySelector( + '[slot="submenu"]' + ) as HTMLElement; + + // Open the submenu + const opened = oneEvent(menuItem, 'sp-opened'); + menuItem.dispatchEvent( + new PointerEvent('pointerenter', { bubbles: true }) + ); + await opened; + + // Force a specific max-height to ensure scrolling + submenu.style.maxHeight = '200px'; + await elementUpdated(submenu); + + // Get computed styles + const computedStyle = window.getComputedStyle(submenu); + + // Verify overflow-y is set to auto + expect(computedStyle.overflowY).to.equal('auto'); + + // Verify that the content is actually overflowing + expect(submenu.scrollHeight).to.be.greaterThan(submenu.clientHeight); + + // Verify that the submenu is scrollable + const initialScrollTop = submenu.scrollTop; + submenu.scrollTop = 50; + await elementUpdated(submenu); + expect(submenu.scrollTop).to.equal(50); + expect(submenu.scrollTop).to.not.equal(initialScrollTop); + }); +}); diff --git a/1st-gen/packages/menu/tsconfig.json b/1st-gen/packages/menu/tsconfig.json new file mode 100644 index 00000000000..27f2b070813 --- /dev/null +++ b/1st-gen/packages/menu/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../../tools/base" }, + { "path": "../action-button" }, + { "path": "../overlay" } + ] +} diff --git a/1st-gen/packages/meter/.npmrc b/1st-gen/packages/meter/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/meter/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/meter/CHANGELOG.md b/1st-gen/packages/meter/CHANGELOG.md new file mode 100644 index 00000000000..5cc3dedcc34 --- /dev/null +++ b/1st-gen/packages/meter/CHANGELOG.md @@ -0,0 +1,565 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/field-label@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/field-label@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/field-label@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/field-label@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies [[`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0)]: + - @spectrum-web-components/field-label@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/field-label@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/field-label@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +### BREAKING CHANGES + +- remove deprecated 'static' references ([#4818](https://github.com/adobe/spectrum-web-components/issues/4818)) + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Features + +- add `static-color` to replace `static` ([#4808](https://github.com/adobe/spectrum-web-components/issues/4808)) ([43cf086](https://github.com/adobe/spectrum-web-components/commit/43cf0865d902346568c755650f53410c7788f2a1)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **styles, theme:** surface exports that omit Spectrum Vars proactively ([#4142](https://github.com/adobe/spectrum-web-components/issues/4142)) ([5b524c1](https://github.com/adobe/spectrum-web-components/commit/5b524c1d54a64225cb3b2f71b92f581695985519)) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +### Bug Fixes + +- **button:** adds pending button, fixes [#3162](https://github.com/adobe/spectrum-web-components/issues/3162) ([#3163](https://github.com/adobe/spectrum-web-components/issues/3163)) ([71254ec](https://github.com/adobe/spectrum-web-components/commit/71254ec2b29f18e62a9a2e5285ca8c35273d8d43)) + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +### Bug Fixes + +- update deps graph, update link docs ([#3709](https://github.com/adobe/spectrum-web-components/issues/3709)) ([2deb284](https://github.com/adobe/spectrum-web-components/commit/2deb2847e6ad458c3cbaec02732fffde133e0c54)) + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Features + +- **meter:** add "variant" (coalescing various boolean attributes) and remove "over-background" attributes ([#3514](https://github.com/adobe/spectrum-web-components/issues/3514)) ([40e5f8a](https://github.com/adobe/spectrum-web-components/commit/40e5f8ae476a590bb3df52d7281f76f5908b8672)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Bug Fixes + +- **meter, progress-bar, progress-circle:** use innerText when label is not provided ([#3483](https://github.com/adobe/spectrum-web-components/issues/3483)) ([59358c7](https://github.com/adobe/spectrum-web-components/commit/59358c7ada3283e2fdb08793d4c4160dcfe7aee2)) +- **meter:** added role meter progressbar in meter component ([#3459](https://github.com/adobe/spectrum-web-components/issues/3459)) ([d2eccef](https://github.com/adobe/spectrum-web-components/commit/d2eccef6de8a1c7a0f09bcae9618b4aff2109edd)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +### Bug Fixes + +- **meter,progress-bar:** add i18n to progress delivery ([c7e4020](https://github.com/adobe/spectrum-web-components/commit/c7e4020dc3120f7e6e366bcc89dd523dea3ba821)) + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- **meter:** remove comment ([27687ec](https://github.com/adobe/spectrum-web-components/commit/27687eca42f37cd06f3ae5a18910b632215a5c6a)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use ObserveSlotText mixin to prevent white space from overriding label attribute ([610fb4b](https://github.com/adobe/spectrum-web-components/commit/610fb4b5b392b7e3673c7d46bf8f9f5f79f27ca9)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- **meter:** add meter pattern ([fa092ba](https://github.com/adobe/spectrum-web-components/commit/fa092ba915a2fe6320cd9bdbe33055a9e41eee87)) +- **meter:** update spectrum css input ([683bb1a](https://github.com/adobe/spectrum-web-components/commit/683bb1a769483c50eeceb245730e8efbf2ec7442)) +- **progress-bar:** use core tokens ([540552e](https://github.com/adobe/spectrum-web-components/commit/540552ecda4cfab4f26045a6ef2ed58457190ab9)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.8.3...@spectrum-web-components/meter@0.8.4) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.8.2...@spectrum-web-components/meter@0.8.3) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.8.1...@spectrum-web-components/meter@0.8.2) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.8.0...@spectrum-web-components/meter@0.8.1) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.8...@spectrum-web-components/meter@0.8.0) (2023-02-08) + +### Features + +- **progress-bar:** use core tokens ([540552e](https://github.com/adobe/spectrum-web-components/commit/540552ecda4cfab4f26045a6ef2ed58457190ab9)) + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.7...@spectrum-web-components/meter@0.7.8) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.6...@spectrum-web-components/meter@0.7.7) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.5...@spectrum-web-components/meter@0.7.6) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.4...@spectrum-web-components/meter@0.7.5) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.3...@spectrum-web-components/meter@0.7.4) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.2...@spectrum-web-components/meter@0.7.3) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.1...@spectrum-web-components/meter@0.7.2) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.7.0...@spectrum-web-components/meter@0.7.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.14...@spectrum-web-components/meter@0.7.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.6.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.13...@spectrum-web-components/meter@0.6.14) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.12...@spectrum-web-components/meter@0.6.13) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.11...@spectrum-web-components/meter@0.6.12) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.10...@spectrum-web-components/meter@0.6.11) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.9...@spectrum-web-components/meter@0.6.10) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.8...@spectrum-web-components/meter@0.6.9) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.7...@spectrum-web-components/meter@0.6.8) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.6...@spectrum-web-components/meter@0.6.7) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.5...@spectrum-web-components/meter@0.6.6) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.4...@spectrum-web-components/meter@0.6.5) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.3...@spectrum-web-components/meter@0.6.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.2...@spectrum-web-components/meter@0.6.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.1...@spectrum-web-components/meter@0.6.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.6.0...@spectrum-web-components/meter@0.6.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.5.1...@spectrum-web-components/meter@0.6.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.5.0...@spectrum-web-components/meter@0.5.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.10...@spectrum-web-components/meter@0.5.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.4.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.9...@spectrum-web-components/meter@0.4.10) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.8...@spectrum-web-components/meter@0.4.9) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.7...@spectrum-web-components/meter@0.4.8) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.6...@spectrum-web-components/meter@0.4.7) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.5...@spectrum-web-components/meter@0.4.6) (2021-08-17) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.4...@spectrum-web-components/meter@0.4.5) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.3...@spectrum-web-components/meter@0.4.4) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.2...@spectrum-web-components/meter@0.4.3) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.1...@spectrum-web-components/meter@0.4.2) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.4.0...@spectrum-web-components/meter@0.4.1) (2021-06-07) + +### Bug Fixes + +- use ObserveSlotText mixin to prevent white space from overriding label attribute ([610fb4b](https://github.com/adobe/spectrum-web-components/commit/610fb4b5b392b7e3673c7d46bf8f9f5f79f27ca9)) + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.7...@spectrum-web-components/meter@0.4.0) (2021-05-24) + +### Features + +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.6...@spectrum-web-components/meter@0.3.7) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.5...@spectrum-web-components/meter@0.3.6) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.4...@spectrum-web-components/meter@0.3.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.3...@spectrum-web-components/meter@0.3.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.2...@spectrum-web-components/meter@0.3.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.1...@spectrum-web-components/meter@0.3.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.3.0...@spectrum-web-components/meter@0.3.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.2.3...@spectrum-web-components/meter@0.3.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.2.2...@spectrum-web-components/meter@0.2.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.2.1...@spectrum-web-components/meter@0.2.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/meter + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/meter@0.2.0...@spectrum-web-components/meter@0.2.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/meter + +# 0.2.0 (2021-01-21) + +### Bug Fixes + +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- **meter:** remove comment ([27687ec](https://github.com/adobe/spectrum-web-components/commit/27687eca42f37cd06f3ae5a18910b632215a5c6a)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **meter:** add meter pattern ([fa092ba](https://github.com/adobe/spectrum-web-components/commit/fa092ba915a2fe6320cd9bdbe33055a9e41eee87)) +- **meter:** update spectrum css input ([683bb1a](https://github.com/adobe/spectrum-web-components/commit/683bb1a769483c50eeceb245730e8efbf2ec7442)) + +# 0.1.0 (2021-01-13) + +### Bug Fixes + +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- **meter:** remove comment ([27687ec](https://github.com/adobe/spectrum-web-components/commit/27687eca42f37cd06f3ae5a18910b632215a5c6a)) + +### Features + +- apply sizedMixin for t-shirt sizing ([d7b63fb](https://github.com/adobe/spectrum-web-components/commit/d7b63fb0db06b5a8a412fea8370964f4db9d18ae)) +- use SixedMixin to manage "size" property ([8819821](https://github.com/adobe/spectrum-web-components/commit/88198212cb495833ed2e7644f95b43dca915318d)) +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **meter:** add meter pattern ([fa092ba](https://github.com/adobe/spectrum-web-components/commit/fa092ba915a2fe6320cd9bdbe33055a9e41eee87)) +- **meter:** update spectrum css input ([683bb1a](https://github.com/adobe/spectrum-web-components/commit/683bb1a769483c50eeceb245730e8efbf2ec7442)) diff --git a/1st-gen/packages/meter/README.md b/1st-gen/packages/meter/README.md new file mode 100644 index 00000000000..9be4d197fa5 --- /dev/null +++ b/1st-gen/packages/meter/README.md @@ -0,0 +1,161 @@ +## Overview + +An `` is a visual representation of a quantity or achievement. The meter's progress is determined by user actions, rather than system actions. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/meter?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/meter) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/meter?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/meter) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-bccezzju) + +```bash +yarn add @spectrum-web-components/meter +``` + +Import the side-effectful registration of `` via: + +```javascript +import '@spectrum-web-components/meter/sp-meter.js'; +``` + +When looking to leverage the `Meter` base class as a type and/or for extension purposes, do so via: + +```javascript +import { Meter } from '@spectrum-web-components/meter'; +``` + +### Anatomy + +The meter consists of several key parts: + +- A label that describes what is being measured +- A progress track showing the total possible range +- A fill bar indicating the current progress +- A percentage value showing the numeric progress + +```html +Tasks Completed +``` + +#### Label + +The label is the text that describes what is being measured. It can be provided either through the default slot or the `label` attribute. + +```html +Course Progress +
+ +``` + +### Options + +#### Sizes + + +Small + + +```html +Tasks Completed +``` + + +Medium + + +```html +Tasks Completed +``` + + +Large + + +```html +Tasks Completed +``` + + +Extra Large + + +```html +Tasks Completed +``` + + + + +#### Variants + +The meter supports several variants to convey different semantic meanings: + + +Informative + + +By default, the informative variant can be used to represent a neutral or non-semantic value, such as the number of tutorials completed. + +```html +Storage Space +``` + + +Positive + + +The positive variant can be used to represent a positive semantic value, such as when there's a lot of space remaining. +Use value `variant="positive"` to define a positive variant. + +```html +Storage Space +``` + + +Notice + + +The notice variant can be used to warn users about a situation that may need to be addressed soon, such as when space remaining is becoming limited. +Use value `variant="notice"` to define a notice variant. + +```html +Storage Space +``` + + +Negative + + +The negative variant can be used to warn users about a critical situation that needs their urgent attention, such as when space remaining is becoming very limited. +Use value `variant="negative"` to define a negative variant. + +```html +Storage Space +``` + + + + +#### Label Position + +A meter can be delivered with its labeling displayed above its visual indicator or to either side. Use the boolean `side-label` attribute to define where this content should appear. + +```html +Side Label +``` + +### Accessibility + +The `` element is rendered with `role="meter progressbar"` to ensure proper semantics for assistive technologies. The current progress value is set as a percentager via the `progress` attribute and is exposed to assistive technology via `aria-valuenow`. + +```html +Download Progress +``` + +#### Include a label + +A meter is required to have either a visible text label or a `label` attribute. + +#### Don't override color + +The meter's variants provide semantic meaning through both color and ARIA attributes, ensuring that information is not conveyed through color alone. The progress track and fill maintain sufficient contrast for visibility. diff --git a/1st-gen/packages/meter/package.json b/1st-gen/packages/meter/package.json new file mode 100644 index 00000000000..27bbdc31330 --- /dev/null +++ b/1st-gen/packages/meter/package.json @@ -0,0 +1,79 @@ +{ + "name": "@spectrum-web-components/meter", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/meter" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/meter", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Meter.js": { + "development": "./src/Meter.dev.js", + "default": "./src/Meter.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/meter-overrides.css.js": "./src/meter-overrides.css.js", + "./src/meter.css.js": "./src/meter.css.js", + "./src/progress-bar-overrides.css.js": "./src/progress-bar-overrides.css.js", + "./sp-meter.js": { + "development": "./sp-meter.dev.js", + "default": "./sp-meter.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/field-label": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/meter/sp-meter.ts b/1st-gen/packages/meter/sp-meter.ts new file mode 100644 index 00000000000..5bfb26e5db7 --- /dev/null +++ b/1st-gen/packages/meter/sp-meter.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Meter } from './src/Meter.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-meter', Meter); + +declare global { + interface HTMLElementTagNameMap { + 'sp-meter': Meter; + } +} diff --git a/1st-gen/packages/meter/src/Meter.ts b/1st-gen/packages/meter/src/Meter.ts new file mode 100644 index 00000000000..39b9f36645c --- /dev/null +++ b/1st-gen/packages/meter/src/Meter.ts @@ -0,0 +1,141 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + nothing, + PropertyValues, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; + +import { getLabelFromSlot } from '@spectrum-web-components/shared/src/get-label-from-slot.js'; +import { ObserveSlotText } from '@spectrum-web-components/shared/src/observe-slot-text.js'; +import { LanguageResolutionController } from '@spectrum-web-components/reactive-controllers/src/LanguageResolution.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import styles from './meter.css.js'; + +export const meterVariants = ['positive', 'notice', 'negative']; + +export type MeterVariants = (typeof meterVariants)[number]; + +/** + * @element sp-meter + * + * @slot - text labeling the Meter + */ +export class Meter extends SizedMixin(ObserveSlotText(SpectrumElement, ''), { + noDefaultSize: true, +}) { + public static override get styles(): CSSResultArray { + return [styles]; + } + + @property({ type: Number }) + public progress = 0; + + /** + * The variant applies specific styling when set to `negative`, `positive`, `notice` + * `variant` attribute is removed when not matching one of the above. + * + * @param {String} variant + */ + @property({ type: String }) + public set variant(variant: MeterVariants) { + if (variant === this.variant) { + return; + } + const oldValue = this.variant; + if (meterVariants.includes(variant)) { + this.setAttribute('variant', variant); + this._variant = variant; + } else { + this.removeAttribute('variant'); + this._variant = ''; + } + this.requestUpdate('variant', oldValue); + } + + public get variant(): MeterVariants { + return this._variant; + } + + private _variant: MeterVariants = ''; + + @property({ type: String, reflect: true }) + public label = ''; + + @query('slot') + private slotEl!: HTMLSlotElement; + + private languageResolver = new LanguageResolutionController(this); + + @property({ type: Boolean, reflect: true, attribute: 'side-label' }) + // called sideLabel + public sideLabel = false; + + @property({ reflect: true, attribute: 'static-color' }) + public staticColor?: 'white'; + + protected override render(): TemplateResult { + return html` + + ${this.slotHasContent ? nothing : this.label} + ${this.label} + + + ${new Intl.NumberFormat(this.languageResolver.language, { + style: 'percent', + unitDisplay: 'narrow', + }).format(this.progress / 100)} + +
+
+
+ `; + } + + protected handleSlotchange(): void { + const labelFromSlot = getLabelFromSlot(this.label, this.slotEl); + if (labelFromSlot) { + this.label = labelFromSlot; + } + } + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + this.setAttribute('role', 'meter progressbar'); + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if (changes.has('progress')) { + this.setAttribute('aria-valuenow', '' + this.progress); + } + if (changes.has('label')) { + if (this.label.length) { + this.setAttribute('aria-label', this.label); + } else { + this.removeAttribute('aria-label'); + } + } + } +} diff --git a/1st-gen/packages/meter/src/index.ts b/1st-gen/packages/meter/src/index.ts new file mode 100644 index 00000000000..f87d4d3814f --- /dev/null +++ b/1st-gen/packages/meter/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './Meter.js'; diff --git a/1st-gen/packages/meter/src/meter-overrides.css b/1st-gen/packages/meter/src/meter-overrides.css new file mode 100644 index 00000000000..609762307c2 --- /dev/null +++ b/1st-gen/packages/meter/src/meter-overrides.css @@ -0,0 +1,37 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-meter-min-width: var(--system-meter-min-width); + --spectrum-meter-max-width: var(--system-meter-max-width); + --spectrum-meter-inline-size: var(--system-meter-inline-size); + --spectrum-meter-top-to-text: var(--system-meter-top-to-text); + --spectrum-meter-fill-color-positive: var(--system-meter-fill-color-positive); + --spectrum-meter-fill-color-notice: var(--system-meter-fill-color-notice); + --spectrum-meter-fill-color-negative: var(--system-meter-fill-color-negative); + --spectrum-meter-thickness: var(--system-meter-thickness); + --spectrum-meter-font-size: var(--system-meter-font-size); +} + +:host([size="s"]) { + --spectrum-meter-thickness: var(--system-meter-size-s-thickness); + --spectrum-meter-inline-size: var(--system-meter-size-s-inline-size); + --spectrum-meter-font-size: var(--system-meter-size-s-font-size); + --spectrum-meter-top-to-text: var(--system-meter-size-s-top-to-text); +} + +:host([size="l"]) { + --spectrum-meter-thickness: var(--system-meter-size-l-thickness); + --spectrum-meter-inline-size: var(--system-meter-size-l-inline-size); + --spectrum-meter-font-size: var(--system-meter-size-l-font-size); + --spectrum-meter-top-to-text: var(--system-meter-size-l-top-to-text); +} diff --git a/1st-gen/packages/meter/src/meter.css b/1st-gen/packages/meter/src/meter.css new file mode 100644 index 00000000000..e65ef9785fd --- /dev/null +++ b/1st-gen/packages/meter/src/meter.css @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-progress-bar.css"); +@import url("./progress-bar-overrides.css"); +@import url("./spectrum-meter.css"); +@import url("./meter-overrides.css"); + +.fill { + transform-origin: left; +} + +:host([dir="rtl"]) .fill { + transform-origin: right; +} diff --git a/1st-gen/packages/meter/src/progress-bar-overrides.css b/1st-gen/packages/meter/src/progress-bar-overrides.css new file mode 100644 index 00000000000..722272bc7c0 --- /dev/null +++ b/1st-gen/packages/meter/src/progress-bar-overrides.css @@ -0,0 +1,65 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-progressbar-animation-ease-in-out-indeterminate: var(--system-progress-bar-animation-ease-in-out-indeterminate); + --spectrum-progressbar-animation-duration-indeterminate: var(--system-progress-bar-animation-duration-indeterminate); + --spectrum-progressbar-corner-radius: var(--system-progress-bar-corner-radius); + --spectrum-progressbar-fill-size-indeterminate: var(--system-progress-bar-fill-size-indeterminate); + --spectrum-progressbar-size-2400: var(--system-progress-bar-size-2400); + --spectrum-progressbar-size-2500: var(--system-progress-bar-size-2500); + --spectrum-progressbar-size-2800: var(--system-progress-bar-size-2800); + --spectrum-progressbar-line-height-cjk: var(--system-progress-bar-line-height-cjk); + --spectrum-progressbar-min-size: var(--system-progress-bar-min-size); + --spectrum-progressbar-max-size: var(--system-progress-bar-max-size); + --spectrum-progressbar-line-height: var(--system-progress-bar-line-height); + --spectrum-progressbar-spacing-label-to-progressbar: var(--system-progress-bar-spacing-label-to); + --spectrum-progressbar-spacing-label-to-text: var(--system-progress-bar-spacing-label-to-text); + --spectrum-progressbar-text-color: var(--system-progress-bar-text-color); + --spectrum-progressbar-track-color: var(--system-progress-bar-track-color); + --spectrum-progressbar-fill-color: var(--system-progress-bar-fill-color); + --spectrum-progressbar-label-and-value-white: var(--system-progress-bar-label-and-value-white); + --spectrum-progressbar-track-color-white: var(--system-progress-bar-track-color-white); + --spectrum-progressbar-fill-color-white: var(--system-progress-bar-fill-color-white); + --spectrum-progressbar-size-default: var(--system-progress-bar-size-default); + --spectrum-progressbar-font-size: var(--system-progress-bar-font-size); + --spectrum-progressbar-thickness: var(--system-progress-bar-thickness); + --spectrum-progressbar-spacing-top-to-text: var(--system-progress-bar-spacing-top-to-text); +} + +.spectrum-ProgressBar--sizeM { + --spectrum-progressbar-size-default: var(--system-progress-bar-size-m-size-default); + --spectrum-progressbar-font-size: var(--system-progress-bar-size-m-font-size); + --spectrum-progressbar-thickness: var(--system-progress-bar-size-m-thickness); + --spectrum-progressbar-spacing-top-to-text: var(--system-progress-bar-size-m-spacing-top-to-text); +} + +.spectrum-ProgressBar--sizeS { + --spectrum-progressbar-size-default: var(--system-progress-bar-size-s-size-default); + --spectrum-progressbar-font-size: var(--system-progress-bar-size-s-font-size); + --spectrum-progressbar-thickness: var(--system-progress-bar-size-s-thickness); + --spectrum-progressbar-spacing-top-to-text: var(--system-progress-bar-size-s-spacing-top-to-text); +} + +.spectrum-ProgressBar--sizeL { + --spectrum-progressbar-size-default: var(--system-progress-bar-size-l-size-default); + --spectrum-progressbar-font-size: var(--system-progress-bar-size-l-font-size); + --spectrum-progressbar-thickness: var(--system-progress-bar-size-l-thickness); + --spectrum-progressbar-spacing-top-to-text: var(--system-progress-bar-size-l-spacing-top-to-text); +} + +.spectrum-ProgressBar--sizeXL { + --spectrum-progressbar-size-default: var(--system-progress-bar-size-xl-size-default); + --spectrum-progressbar-font-size: var(--system-progress-bar-size-xl-font-size); + --spectrum-progressbar-thickness: var(--system-progress-bar-size-xl-thickness); + --spectrum-progressbar-spacing-top-to-text: var(--system-progress-bar-size-xl-spacing-top-to-text); +} diff --git a/1st-gen/packages/meter/src/spectrum-meter.css b/1st-gen/packages/meter/src/spectrum-meter.css new file mode 100644 index 00000000000..5fad393467e --- /dev/null +++ b/1st-gen/packages/meter/src/spectrum-meter.css @@ -0,0 +1,32 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --mod-progressbar-size-default: var(--mod-meter-inline-size, var(--spectrum-meter-inline-size)); + --mod-progressbar-max-size: var(--mod-meter-max-width, var(--spectrum-meter-max-width)); + --mod-progressbar-min-size: var(--mod-meter-min-width, var(--spectrum-meter-min-width)); + --mod-progressbar-thickness: var(--spectrum-meter-thickness); + --mod-progressbar-font-size: var(--spectrum-meter-font-size); + --mod-progressbar-spacing-top-to-text: var(--spectrum-meter-top-to-text); +} + +:host([variant="positive"]) { + --mod-progressbar-fill-color: var(--mod-meter-fill-color-positive, var(--spectrum-meter-fill-color-positive)); +} + +:host([variant="notice"]) { + --mod-progressbar-fill-color: var(--mod-meter-fill-color-notice, var(--spectrum-meter-fill-color-notice)); +} + +:host([variant="negative"]) { + --mod-progressbar-fill-color: var(--mod-meter-fill-color-negative, var(--spectrum-meter-fill-color-negative)); +} diff --git a/1st-gen/packages/meter/src/spectrum-progress-bar.css b/1st-gen/packages/meter/src/spectrum-progress-bar.css new file mode 100644 index 00000000000..6ce38cc4e67 --- /dev/null +++ b/1st-gen/packages/meter/src/spectrum-progress-bar.css @@ -0,0 +1,147 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + font-size: var(--mod-progressbar-font-size, var(--spectrum-progressbar-font-size)); + vertical-align: top; + inline-size: var(--mod-progressbar-size-default, var(--spectrum-progressbar-size-default)); + max-inline-size: var(--mod-progressbar-max-size, var(--spectrum-progressbar-max-size)); + min-inline-size: var(--mod-progressbar-min-size, var(--spectrum-progressbar-min-size)); + flex-flow: wrap; + justify-content: space-between; + align-items: center; + display: inline-flex; + position: relative; +} + +.label, +.percentage { + text-align: start; + line-height: var(--mod-progressbar-line-height, var(--spectrum-progressbar-line-height)); + color: var(--mod-progressbar-text-color, var(--spectrum-progressbar-text-color)); + margin-block-start: var(--mod-progressbar-spacing-top-to-text, var(--spectrum-progressbar-spacing-top-to-text)); + margin-block-end: var(--mod-progressbar-spacing-label-to-progressbar, var(--spectrum-progressbar-spacing-label-to-progressbar)); +} + +.label:lang(ja), +.label:lang(ko), +.label:lang(zh), +.percentage:lang(ja), +.percentage:lang(ko), +.percentage:lang(zh) { + line-height: var(--mod-progressbar-line-height-cjk, var(--spectrum-progressbar-line-height-cjk)); +} + +.label { + flex: 1; +} + +.percentage { + align-self: flex-start; + margin-inline-start: var(--mod-progressbar-spacing-label-to-text, var(--spectrum-progressbar-spacing-label-to-text)); +} + +.track { + inline-size: 100%; + block-size: var(--mod-progressbar-thickness, var(--spectrum-progressbar-thickness)); + border-radius: var(--spectrum-progressbar-corner-radius); + background: var(--highcontrast-progressbar-track-color, var(--mod-progressbar-track-color, var(--spectrum-progressbar-track-color))); + overflow: hidden; +} + +.fill { + block-size: var(--mod-progressbar-thickness, var(--spectrum-progressbar-thickness)); + background: var(--highcontrast-progressbar-fill-color, var(--mod-progressbar-fill-color, var(--spectrum-progressbar-fill-color))); + border: none; + transition: width 1s; +} + +:host([indeterminate]) .fill { + inline-size: var(--mod-progressbar-fill-size-indeterminate, var(--spectrum-progressbar-fill-size-indeterminate)); + animation-timing-function: var(--mod-progressbar-animation-ease-in-out-indeterminate, var(--spectrum-progressbar-animation-ease-in-out-indeterminate)); + will-change: transform; + animation-name: indeterminate-loop-ltr; + animation-duration: var(--mod-progressbar-animation-duration-indeterminate, var(--spectrum-progressbar-animation-duration-indeterminate)); + animation-iteration-count: infinite; + position: relative; +} + +:host([indeterminate]) .fill:dir(rtl), +:host([dir="rtl"][indeterminate]) .fill { + animation-name: indeterminate-loop-rtl; +} + +:host([side-label]) { + flex-flow: row; + justify-content: space-between; + display: inline-flex; +} + +:host([side-label]) .track { + flex: 1 1 var(--mod-progressbar-size-default, var(--spectrum-progressbar-size-default)); +} + +:host([side-label]) .label { + flex-grow: 0; + margin-block-end: 0; + margin-inline-end: var(--mod-progressbar-spacing-label-to-text, var(--spectrum-progressbar-spacing-label-to-text)); +} + +:host([side-label]) .percentage { + text-align: end; + order: 3; + margin-block-end: 0; + margin-inline-start: var(--mod-spacing-progressbar-label-to-text, var(--spectrum-progressbar-spacing-label-to-text)); +} + +:host([static-color="white"]) .fill { + background: var(--mod-progressbar-fill-color-white, var(--spectrum-progressbar-fill-color-white)); +} + +:host([static-color="white"]) .fill, +:host([static-color="white"]) .label, +:host([static-color="white"]) .percentage { + color: var(--mod-progressbar-label-and-value-white, var(--spectrum-progressbar-label-and-value-white)); +} + +:host([static-color="white"]) .track { + background: var(--spectrum-progressbar-track-color-white); +} + +@keyframes indeterminate-loop-ltr { + 0% { + transform: translate(calc(var(--mod-progressbar-fill-size-indeterminate, var(--spectrum-progressbar-fill-size-indeterminate)) * -1)); + } + + to { + transform: translate(var(--mod-progressbar-size-default, var(--spectrum-progressbar-size-default))); + } +} + +@keyframes indeterminate-loop-rtl { + 0% { + transform: translate(var(--mod-progressbar-size-default, var(--spectrum-progressbar-fill-size-indeterminate))); + } + + to { + transform: translate(calc(var(--mod-progressbar-size-default, var(--spectrum-progressbar-size-default)) * -1)); + } +} + +@media (forced-colors: active) { + .track { + --highcontrast-progressbar-fill-color: ButtonText; + --highcontrast-progressbar-track-color: ButtonFace; + forced-color-adjust: none; + border: 1px solid ButtonText; + } +} diff --git a/1st-gen/packages/meter/stories/meter-sizes.stories.ts b/1st-gen/packages/meter/stories/meter-sizes.stories.ts new file mode 100644 index 00000000000..a1fcf843b21 --- /dev/null +++ b/1st-gen/packages/meter/stories/meter-sizes.stories.ts @@ -0,0 +1,32 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/meter/sp-meter.js'; + +export default { + title: 'Meter/Sizes', + component: 'sp-meter', +}; + +export const s = (): TemplateResult => { + return html` + Storage Space + `; +}; + +export const l = (): TemplateResult => { + return html` + Storage Space + `; +}; diff --git a/1st-gen/packages/meter/stories/meter.stories.ts b/1st-gen/packages/meter/stories/meter.stories.ts new file mode 100644 index 00000000000..70c6e4d7522 --- /dev/null +++ b/1st-gen/packages/meter/stories/meter.stories.ts @@ -0,0 +1,77 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/meter/sp-meter.js'; + +export default { + title: 'Meter', + component: 'sp-meter', +}; + +const makeOverBackground = + (variant?: 'white' | 'black') => + (story: () => TemplateResult): TemplateResult => { + const color = + variant === 'black' + ? 'rgb(181, 209, 211)' + : 'var(--spectrum-seafoam-900)'; + return html` +
+ ${story()} +
+ `; + }; + +export const sideLabel = (): TemplateResult => { + return html` + Storage Space + `; +}; + +export const negative = (): TemplateResult => { + return html` + Storage Space + `; +}; + +export const notice = (): TemplateResult => { + return html` + Storage Space + `; +}; + +export const positive = (): TemplateResult => { + return html` + Storage Space + `; +}; + +export const staticWhite = (): TemplateResult => { + return makeOverBackground('white')( + (): TemplateResult => html` + + Storage Space + + ` + ); +}; diff --git a/1st-gen/packages/meter/test/benchmark/basic-test.ts b/1st-gen/packages/meter/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..974c3be16ed --- /dev/null +++ b/1st-gen/packages/meter/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/meter/sp-meter.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/meter/test/meter-memory.test.ts b/1st-gen/packages/meter/test/meter-memory.test.ts new file mode 100644 index 00000000000..42d9f8052dd --- /dev/null +++ b/1st-gen/packages/meter/test/meter-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/meter/sp-meter.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/meter/test/meter.test.ts b/1st-gen/packages/meter/test/meter.test.ts new file mode 100644 index 00000000000..92f9d31db2d --- /dev/null +++ b/1st-gen/packages/meter/test/meter.test.ts @@ -0,0 +1,157 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +import '@spectrum-web-components/meter/sp-meter.js'; +import { Meter, meterVariants } from '@spectrum-web-components/meter'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; +import { createLanguageContext } from '../../../tools/reactive-controllers/test/helpers.js'; + +describe('Meter', () => { + testForLitDevWarnings( + async () => + await fixture(html` + + `) + ); + it('loads default meter accessibly', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + + await expect(el).to.be.accessible(); + }); + meterVariants.map((variant) => { + it(`loads - [variant="${variant}"]`, async () => { + const el = await fixture(html` + + This meter is of the \`${variant}\` variant. + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + }); + it('accepts a changing process w/ [label]', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('0'); + + el.progress = 50; + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('50'); + + el.progress = 100; + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('100'); + }); + + it('accepts label from `slot`', async () => { + const el = await fixture(html` + Label From Slot + `); + + await elementUpdated(el); + + expect(el.getAttribute('label')).to.equal('Label From Slot'); + }); + it('accepts a changing process', async () => { + const el = await fixture(html` + Changing Value + `); + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('0'); + + el.progress = 50; + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('50'); + + el.progress = 100; + + await elementUpdated(el); + + expect(el.hasAttribute('aria-valuenow')).to.be.true; + expect(el.getAttribute('aria-valuenow')).to.equal('100'); + }); + + it('resolves a language (en-US)', async () => { + const [languageContext] = createLanguageContext('en-US'); + const test = await fixture(html` +
+ +
+ `); + const el = test.querySelector('sp-meter') as Meter; + const percentage = el.shadowRoot.querySelector( + '.percentage' + ) as HTMLElement; + expect(percentage.textContent?.search('%')).to.not.equal(-1); + }); + + it('resolves a language (ar-sa)', async () => { + const [languageContext] = createLanguageContext('ar-sa'); + const test = await fixture(html` +
+ +
+ `); + const el = test.querySelector('sp-meter') as Meter; + const percentage = el.shadowRoot.querySelector( + '.percentage' + ) as HTMLElement; + expect(percentage.textContent?.search('٪')).to.not.equal(-1); + }); + + it('validates variants', async () => { + const el = await fixture(html` + + This meter validates variants. + + `); + + await elementUpdated(el); + expect(el.variant).to.equal(''); + + el.variant = meterVariants[0]; + + await elementUpdated(el); + expect(el.variant).to.equal(meterVariants[0]); + + el.variant = meterVariants[0]; + + await elementUpdated(el); + expect(el.variant).to.equal(meterVariants[0]); + }); +}); diff --git a/1st-gen/packages/meter/tsconfig.json b/1st-gen/packages/meter/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/meter/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/modal/.npmrc b/1st-gen/packages/modal/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/modal/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/modal/CHANGELOG.md b/1st-gen/packages/modal/CHANGELOG.md new file mode 100644 index 00000000000..4680fb5b8ce --- /dev/null +++ b/1st-gen/packages/modal/CHANGELOG.md @@ -0,0 +1,455 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +### Features + +- **picker,action-group,split-button:** leverage Overlay v2 ([170a223](https://github.com/adobe/spectrum-web-components/commit/170a223d74870ed3eda452285943716f8cbf4b7c)) + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) +- **overlay:** correct overlay content sizing ([d9bcd6f](https://github.com/adobe/spectrum-web-components/commit/d9bcd6fd6b4eecae297c6e5cc5330e79a9e198ff)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- **modal:** add modal CSS only pattern ([44c7655](https://github.com/adobe/spectrum-web-components/commit/44c765582baba6f751602f7b37a083dd5234e4df)) +- **modal:** update spectrum css input ([bbcfc2a](https://github.com/adobe/spectrum-web-components/commit/bbcfc2a35a42fc3b81d3de17f216e4c872d3ac07)) +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.7.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.9...@spectrum-web-components/modal@0.7.10) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.8...@spectrum-web-components/modal@0.7.9) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.7...@spectrum-web-components/modal@0.7.8) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.6...@spectrum-web-components/modal@0.7.7) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.5...@spectrum-web-components/modal@0.7.6) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.4...@spectrum-web-components/modal@0.7.5) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.3...@spectrum-web-components/modal@0.7.4) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.2...@spectrum-web-components/modal@0.7.3) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.1...@spectrum-web-components/modal@0.7.2) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.7.0...@spectrum-web-components/modal@0.7.1) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.10...@spectrum-web-components/modal@0.7.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.6.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.9...@spectrum-web-components/modal@0.6.10) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.8...@spectrum-web-components/modal@0.6.9) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.7...@spectrum-web-components/modal@0.6.8) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.6...@spectrum-web-components/modal@0.6.7) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.5...@spectrum-web-components/modal@0.6.6) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.4...@spectrum-web-components/modal@0.6.5) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.3...@spectrum-web-components/modal@0.6.4) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.2...@spectrum-web-components/modal@0.6.3) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.1...@spectrum-web-components/modal@0.6.2) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.6.0...@spectrum-web-components/modal@0.6.1) (2022-02-22) + +### Bug Fixes + +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.5.2...@spectrum-web-components/modal@0.6.0) (2022-02-02) + +### Features + +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.5.1...@spectrum-web-components/modal@0.5.2) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.5.0...@spectrum-web-components/modal@0.5.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.4.1...@spectrum-web-components/modal@0.5.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.4.0...@spectrum-web-components/modal@0.4.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.8...@spectrum-web-components/modal@0.4.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.3.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.7...@spectrum-web-components/modal@0.3.8) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.6...@spectrum-web-components/modal@0.3.7) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.5...@spectrum-web-components/modal@0.3.6) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.4...@spectrum-web-components/modal@0.3.5) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.3...@spectrum-web-components/modal@0.3.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.2...@spectrum-web-components/modal@0.3.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.1...@spectrum-web-components/modal@0.3.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/modal + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.3.0...@spectrum-web-components/modal@0.3.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/modal + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.2.1...@spectrum-web-components/modal@0.3.0) (2021-03-04) + +### Bug Fixes + +- **overlay:** correct overlay content sizing ([d9bcd6f](https://github.com/adobe/spectrum-web-components/commit/d9bcd6fd6b4eecae297c6e5cc5330e79a9e198ff)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/modal@0.2.0...@spectrum-web-components/modal@0.2.1) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# 0.2.0 (2021-01-21) + +### Bug Fixes + +- address a11y issues raised by updating our dependencies ([4f06477](https://github.com/adobe/spectrum-web-components/commit/4f0647782eea7fdd85560e1bcb2f8b892f30bc33)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use the "browsers" listing in postcss-preset-env ([4eaf6a2](https://github.com/adobe/spectrum-web-components/commit/4eaf6a28f7b5eaf60487841d264d6d804ae675ce)) + +### Features + +- **modal:** add modal CSS only pattern ([44c7655](https://github.com/adobe/spectrum-web-components/commit/44c765582baba6f751602f7b37a083dd5234e4df)) +- **modal:** update spectrum css input ([bbcfc2a](https://github.com/adobe/spectrum-web-components/commit/bbcfc2a35a42fc3b81d3de17f216e4c872d3ac07)) + +# 0.1.0 (2021-01-13) + +### Bug Fixes + +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update export patterns ([b2da444](https://github.com/adobe/spectrum-web-components/commit/b2da444359b4022ed3f61dedf563b5bacba42103)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) + +### Features + +- **modal:** add modal CSS only pattern ([44c7655](https://github.com/adobe/spectrum-web-components/commit/44c765582baba6f751602f7b37a083dd5234e4df)) +- **modal:** update spectrum css input ([bbcfc2a](https://github.com/adobe/spectrum-web-components/commit/bbcfc2a35a42fc3b81d3de17f216e4c872d3ac07)) diff --git a/1st-gen/packages/modal/package.json b/1st-gen/packages/modal/package.json new file mode 100644 index 00000000000..36848ec8770 --- /dev/null +++ b/1st-gen/packages/modal/package.json @@ -0,0 +1,61 @@ +{ + "name": "@spectrum-web-components/modal", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/modal" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/modal", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/modal.css.js", + "module": "./src/modal.css.js", + "type": "module", + "exports": { + ".": "./src/modal-wrapper.css.js", + "./package.json": "./package.json", + "./src/modal-overrides.css.js": "./src/modal-overrides.css.js", + "./src/modal-wrapper.css.js": "./src/modal-wrapper.css.js", + "./src/modal.css.js": "./src/modal.css.js" + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/modal/src/modal-overrides.css b/1st-gen/packages/modal/src/modal-overrides.css new file mode 100644 index 00000000000..731ba78ae42 --- /dev/null +++ b/1st-gen/packages/modal/src/modal-overrides.css @@ -0,0 +1,15 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-modal-background-color: var(--system-modal-background-color); +} diff --git a/1st-gen/packages/modal/src/modal-wrapper-overrides.css b/1st-gen/packages/modal/src/modal-wrapper-overrides.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/modal/src/modal-wrapper-overrides.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/modal/src/modal-wrapper.css b/1st-gen/packages/modal/src/modal-wrapper.css new file mode 100644 index 00000000000..31656321a0c --- /dev/null +++ b/1st-gen/packages/modal/src/modal-wrapper.css @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-modal-wrapper.css"); diff --git a/1st-gen/packages/modal/src/modal.css b/1st-gen/packages/modal/src/modal.css new file mode 100644 index 00000000000..996d22d3d6d --- /dev/null +++ b/1st-gen/packages/modal/src/modal.css @@ -0,0 +1,26 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-modal.css"); +@import url("./modal-overrides.css"); + +:host { + --spectrum-dialog-confirm-exit-animation-duration: var(--swc-test-duration); + --spectrum-dialog-confirm-entry-animation-duration: var(--swc-test-duration); + --spectrum-modal-confirm-entry-animation-distance: var(--spectrum-dialog-confirm-entry-animation-distance); + + height: 100dvh; +} + +.modal { + overflow: visible; +} diff --git a/1st-gen/packages/modal/src/spectrum-modal-wrapper.css b/1st-gen/packages/modal/src/spectrum-modal-wrapper.css new file mode 100644 index 00000000000..4d2e343bfba --- /dev/null +++ b/1st-gen/packages/modal/src/spectrum-modal-wrapper.css @@ -0,0 +1,47 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + box-sizing: border-box; + inline-size: 100vw; + block-size: 100vh; + block-size: -webkit-fill-available; + block-size: stretch; + visibility: hidden; + pointer-events: none; + z-index: 1; + transition: visibility 0s linear var(--mod-modal-transition-animation-duration, var(--spectrum-animation-duration-100)); + justify-content: center; + align-items: center; + display: flex; + position: fixed; + inset-block-start: 0; + inset-inline-start: 0; +} + +:host([open]) { + visibility: visible; +} + +@media only screen and (device-height <= 350px), only screen and (device-width <= 400px) { + :host([responsive]) { + inline-size: 100%; + block-size: 100%; + max-inline-size: 100%; + max-block-size: 100%; + border-radius: 0; + } + + :host([responsive]) { + margin-block-start: 0; + } +} diff --git a/1st-gen/packages/modal/src/spectrum-modal.css b/1st-gen/packages/modal/src/spectrum-modal.css new file mode 100644 index 00000000000..96a29482e2f --- /dev/null +++ b/1st-gen/packages/modal/src/spectrum-modal.css @@ -0,0 +1,84 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-modal-confirm-entry-animation-duration: var(--mod-modal-confirm-entry-animation-duration, var(--spectrum-animation-duration-500)); + --spectrum-modal-confirm-entry-animation-delay: var(--mod-overlay-animation-duration-opened, var(--mod-modal-confirm-entry-animation-delay, var(--spectrum-animation-duration-200))); + --spectrum-modal-confirm-exit-animation-duration: var(--mod-overlay-animation-duration, var(--mod-modal-confirm-exit-animation-duration, var(--spectrum-animation-duration-100))); + --spectrum-modal-confirm-exit-animation-delay: var(--mod-modal-confirm-exit-animation-delay, var(--spectrum-animation-duration-0)); + --spectrum-modal-fullscreen-margin: var(--mod-modal-fullscreen-margin, 32px); +} + +.modal { + visibility: hidden; + opacity: 0; + transform: translateY(var(--mod-modal-confirm-entry-animation-distance, var(--spectrum-dialog-confirm-entry-animation-distance))); + z-index: 1; + max-block-size: 90vh; + max-block-size: var(--mod-modal-max-height, 90vh); + max-inline-size: 90%; + max-inline-size: var(--mod-modal-max-width, 90%); + background: var(--mod-modal-background-color, var(--spectrum-modal-background-color)); + border-radius: var(--mod-modal-confirm-border-radius, var(--spectrum-corner-radius-100)); + pointer-events: auto; + transition: + opacity var(--spectrum-modal-confirm-exit-animation-duration) var(--spectrum-animation-ease-in) var(--spectrum-modal-confirm-exit-animation-delay), + visibility var(--spectrum-animation-duration-0) var(--spectrum-animation-linear) calc(var(--spectrum-modal-confirm-exit-animation-delay) + var(--spectrum-modal-confirm-exit-animation-duration)), + transform var(--spectrum-animation-duration-0) var(--spectrum-animation-linear) calc(var(--spectrum-modal-confirm-exit-animation-delay) + var(--spectrum-modal-confirm-exit-animation-duration)); + outline: none; + overflow: hidden; +} + +:host([open]) .modal { + pointer-events: auto; + visibility: visible; + opacity: 1; + transition: + transform var(--spectrum-modal-confirm-entry-animation-duration) var(--spectrum-animation-ease-out) var(--spectrum-modal-confirm-entry-animation-delay), + opacity var(--spectrum-modal-confirm-entry-animation-duration) var(--spectrum-animation-ease-out) var(--spectrum-modal-confirm-entry-animation-delay); + transform: translateY(0); +} + +@media only screen and (device-height <= 350px), only screen and (device-width <= 400px) { + :host([responsive]) .modal { + inline-size: 100%; + block-size: 100%; + max-inline-size: 100%; + max-block-size: 100%; + border-radius: 0; + } +} + +.fullscreen { + max-inline-size: none; + max-block-size: none; + position: fixed; + inset-block-start: var(--spectrum-modal-fullscreen-margin); + inset-block-end: var(--spectrum-modal-fullscreen-margin); + inset-inline-start: var(--spectrum-modal-fullscreen-margin); + inset-inline-end: var(--spectrum-modal-fullscreen-margin); +} + +.fullscreenTakeover { + max-inline-size: none; + max-block-size: none; + box-sizing: border-box; + border: none; + border-radius: 0; + position: fixed; + inset: 0; +} + +.fullscreenTakeover, +:host([open]) .fullscreenTakeover { + transform: none; +} diff --git a/1st-gen/packages/modal/tsconfig.json b/1st-gen/packages/modal/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/modal/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/number-field/.npmrc b/1st-gen/packages/number-field/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/number-field/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/number-field/CHANGELOG.md b/1st-gen/packages/number-field/CHANGELOG.md new file mode 100644 index 00000000000..c34ef38e911 --- /dev/null +++ b/1st-gen/packages/number-field/CHANGELOG.md @@ -0,0 +1,740 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c), [`14ebeb9`](https://github.com/adobe/spectrum-web-components/commit/14ebeb9e8a24de9c9a80e7f3f0babd19a34e8179), [`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/textfield@1.9.0 + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/infield-button@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/infield-button@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/textfield@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies [[`cde976d`](https://github.com/adobe/spectrum-web-components/commit/cde976ddfa71f898e2d0404ecc53150db149a861)]: + - @spectrum-web-components/textfield@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/infield-button@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5408](https://github.com/adobe/spectrum-web-components/pull/5408) [`74386e8`](https://github.com/adobe/spectrum-web-components/commit/74386e8c5b4717270fcccd9ebb72dab8cf757515) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! - The changes included resolve UI issues with number-field by proxy of textfield. The validation icons in number-field no longer overlap the infield buttons. The width of the number-field now calculates accurately and can be modified via `--mod-stepper-width` token as it was before. + +- [#5157](https://github.com/adobe/spectrum-web-components/pull/5157) [`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - # Release Note + + ## Infield Button + + ### 6.1.2 + - [#3615](https://github.com/adobe/spectrum-css/pull/3615) [`f09c84a`](https://github.com/adobe/spectrum-css/commit/f09c84ae9922d67b6fe237d693afee0fab53fa67) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - ### Infield button fast follows + - Updated infield button disabled border color to use `-spectrum-gray-300` for spectrum-two theme and `-spectrum-gray-200` for other themes. + + ### 6.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 6.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/icon@9.1.0 + - @spectrum-css/tokens@16.0.1 + + ## Number Field + + Bump @spectrum-css/stepper to 7.1.3 + + ### 7.1.3 + - [#3621](https://github.com/adobe/spectrum-css/pull/3621) [`3aec28a`](https://github.com/adobe/spectrum-css/commit/3aec28aac60bdf32a585fa8ff38559d80b57ff86) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - Updates `-spectrum-stepper-buttons-border-color-keyboard-focus` from `gray-900` to `gray-800` to match the rest of the border color on keyboardFocus. + + ### 7.1.2 + + 📝 [#3594](https://github.com/adobe/spectrum-css/pull/3594) [`6200a63`](https://github.com/adobe/spectrum-css/commit/6200a63f2c7dc1d2b0481c33b17c86427726c0bd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updates Stepper's key-focus border color (`-spectrum-stepper-border-color-keyboard-focus`) to `-spectrum-gray-800`. + + ### 7.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 7.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/actionbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/infieldbutton@7.0.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Textfield + + ### 8.1.1 + + 📝 [#3575](https://github.com/adobe/spectrum-css/pull/3575) [`2e17d10`](https://github.com/adobe/spectrum-css/commit/2e17d109ebec3c2745c32a15840af5c636c8dc5d) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updated border color on keyboard focus state for textfield in spectrum-two theme. + + ### 8.1.0 + + 📝 [#3539](https://github.com/adobe/spectrum-css/pull/3539) [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! + - Updates invalid icon spacing to be vertically centered for S2. + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + - Dependency alignment across the project. + + Set component peerDependencies as optional to reduce console warnings on downstream projects. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/helptext@8.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Search + + ### 8.1.2 + - [#3658](https://github.com/adobe/spectrum-css/pull/3658) [`e9fde67`](https://github.com/adobe/spectrum-css/commit/e9fde67bf341798a6ab34f227b2e7a417d1e5da7) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! - Change S2 theme border color to gray-800 on keyfocus per design request in order to align with text field. + + ### 8.1.1 + + 📝 [#3593](https://github.com/adobe/spectrum-css/pull/3593) [`d829abb`](https://github.com/adobe/spectrum-css/commit/d829abb44f1eaa1874090e52caee553d776684e7) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + + Updated `--spectrum-search-background-color-disabled` to `--spectrum-gray-25` and `--spectrum-search-border-color-disabled` to `--spectrum-gray-300` for the S2 foundations contexts. + + Also defines disabled quiet border and background colors (`--system-search-quiet-background-color-disabled` and `--system-search-quiet-border-color-disabled`) in order to maintain disabled quiet styling. + + ### 8.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/clearbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + +- Updated dependencies [[`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd)]: + - @spectrum-web-components/infield-button@1.6.0 + - @spectrum-web-components/textfield@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Minor Changes + +- [#5284](https://github.com/adobe/spectrum-web-components/pull/5284) [`5a3bc6d`](https://github.com/adobe/spectrum-web-components/commit/5a3bc6d24ea95f6dd5b5ead9d7eb45c393324ee9) Thanks [@blunteshwar](https://github.com/blunteshwar)! - Fixed keyboard flickering on mobile devices when using NumberField's increment/decrement buttons + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/textfield@1.5.0 + - @spectrum-web-components/infield-button@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/infield-button@1.4.0 + - @spectrum-web-components/textfield@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/infield-button@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/textfield@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +### Bug Fixes + +- **number-field:** added aria-hidden attribute for inc/dec buttons ([#4933](https://github.com/adobe/spectrum-web-components/issues/4933)) ([b16a839](https://github.com/adobe/spectrum-web-components/commit/b16a839b33cc7d02b42e012afaa6327972eb0c6b)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **number-field, slider:** ensure cached value is cleared when toggling between different steps ([#4846](https://github.com/adobe/spectrum-web-components/issues/4846)) ([1c84c96](https://github.com/adobe/spectrum-web-components/commit/1c84c968f55cde28d0144a78153c9a33a078c726)) +- **number-field:** allow only numeric characters for Japanese/Chinese IME ([#4817](https://github.com/adobe/spectrum-web-components/issues/4817)) ([a791bd1](https://github.com/adobe/spectrum-web-components/commit/a791bd1c027ede4c88e8c066ef97610409a0f2c4)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +### Bug Fixes + +- **number-field:** show decimal on iPad minimized keyboard ([#4784](https://github.com/adobe/spectrum-web-components/issues/4784)) ([deb7a1c](https://github.com/adobe/spectrum-web-components/commit/deb7a1cce452f120a9c2c96d73b0d03132c02565)) + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +### Bug Fixes + +- add null check in updated method of sp-number-field ([#4709](https://github.com/adobe/spectrum-web-components/issues/4709)) ([7b1eeab](https://github.com/adobe/spectrum-web-components/commit/7b1eeab613fffe833ea0f57a23d2cc11bef71ea7)) + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +### Bug Fixes + +- **number-field:** update IME change detection ([#4672](https://github.com/adobe/spectrum-web-components/issues/4672)) ([de05aee](https://github.com/adobe/spectrum-web-components/commit/de05aee7c414e6cfcd27a12f129b03886311d3bf)) + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +### Bug Fixes + +- **number-field:** multiple separators use-cases in decimal inputs in iOS devices ([#4571](https://github.com/adobe/spectrum-web-components/issues/4571)) ([6319da8](https://github.com/adobe/spectrum-web-components/commit/6319da80a21511735d9e9518125dbc2a24364f88)) + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +### Bug Fixes + +- **number-field:** updated number field to respect all locales ([#4508](https://github.com/adobe/spectrum-web-components/issues/4508)) ([cc6e928](https://github.com/adobe/spectrum-web-components/commit/cc6e928bc6797280f119994b1908f17bbcb574e3)) + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +### Bug Fixes + +- **number-field:** select full value when using Tab to enter a field with a unit ([#4340](https://github.com/adobe/spectrum-web-components/issues/4340)) ([a9d5cef](https://github.com/adobe/spectrum-web-components/commit/a9d5cef4a69af4f3f357bacbfdae9465d3e80fa5)) + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **number-field, slider:** floating point roundoff precision bug ([#4263](https://github.com/adobe/spectrum-web-components/issues/4263)) ([74480ef](https://github.com/adobe/spectrum-web-components/commit/74480efd47305a7d41d0e20682d8dcba1c129f2f)) +- **number-field:** handles values greater than 1000 ([#4417](https://github.com/adobe/spectrum-web-components/issues/4417)) ([45d69d0](https://github.com/adobe/spectrum-web-components/commit/45d69d0bb927bd18c3d58c757c40c14768b70a82)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +### Bug Fixes + +- **number-field, slider:** floating point roundoff precision bug ([#4263](https://github.com/adobe/spectrum-web-components/issues/4263)) ([74480ef](https://github.com/adobe/spectrum-web-components/commit/74480efd47305a7d41d0e20682d8dcba1c129f2f)) + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **styles, theme:** surface exports that omit Spectrum Vars proactively ([#4142](https://github.com/adobe/spectrum-web-components/issues/4142)) ([5b524c1](https://github.com/adobe/spectrum-web-components/commit/5b524c1d54a64225cb3b2f71b92f581695985519)) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +### Bug Fixes + +- **combobox:** add combobox pattern ([#3894](https://github.com/adobe/spectrum-web-components/issues/3894)) ([47d7d71](https://github.com/adobe/spectrum-web-components/commit/47d7d71bc9e17b67452d45b9495c970dac15ff89)), closes [#3887](https://github.com/adobe/spectrum-web-components/issues/3887) + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +### Bug Fixes + +- **number-field:** validate min/max in more contexts ([2328a62](https://github.com/adobe/spectrum-web-components/commit/2328a62daaf9491cdc5de4f46ab422e54c57bc3f)) + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +### Bug Fixes + +- **number-field:** update display value on scroll and arrow up/down ([fc59a18](https://github.com/adobe/spectrum-web-components/commit/fc59a18c73bb9b63f319d006713a5b5d15778cca)) + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **infield-button:** add infield-button package ([057b885](https://github.com/adobe/spectrum-web-components/commit/057b885276f3d5dcbe32bab5ab36a2bb82334bc3)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +### Bug Fixes + +- **number-field:** prevent over excited "change" events ([7b93724](https://github.com/adobe/spectrum-web-components/commit/7b937241151cad5cfc9e5a03fa70c4b70ac0cbea)) + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +### Bug Fixes + +- **number-field:** handle negative numbers ([#3673](https://github.com/adobe/spectrum-web-components/issues/3673)) ([62553dd](https://github.com/adobe/spectrum-web-components/commit/62553dd437efb89b42372553adfdf95fc0be7496)) +- **number-field:** update number-field value on pressing "enter" ([#3638](https://github.com/adobe/spectrum-web-components/issues/3638)) ([649eb2f](https://github.com/adobe/spectrum-web-components/commit/649eb2f5dd9e0d08bb18f640565b34e908c5b518)) + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- correct composition entry of multi-byte numbers ([#3610](https://github.com/adobe/spectrum-web-components/issues/3610)) ([5e11934](https://github.com/adobe/spectrum-web-components/commit/5e1193455dd876a45648b3040688a3bc389819a1)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +### Bug Fixes + +- **number-field:** update button label to use number-field-labels as part of the text ([#3474](https://github.com/adobe/spectrum-web-components/issues/3474)) ([b92daf2](https://github.com/adobe/spectrum-web-components/commit/b92daf2f50224a362215477341d7d10a4eb39734)) + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **number-field,search,textfield:** add t-shirt sizes ([fda8f96](https://github.com/adobe/spectrum-web-components/commit/fda8f96b71b1447a8281f73d885c1c33ae74cfec)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +### Bug Fixes + +- **number-field:** simplify width management ([ef4765a](https://github.com/adobe/spectrum-web-components/commit/ef4765a33f81d19229d13ea418aa625f5e1e693a)) + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Features + +- **number-field:** use core tokens ([23a924e](https://github.com/adobe/spectrum-web-components/commit/23a924ef24ea5adfa0472e8e424bfeec1d184603)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- add "editable" option to "sp-slider" ([e86d7fa](https://github.com/adobe/spectrum-web-components/commit/e86d7fa84491b41a39dbab9c8d85eec42df320cd)) +- add input validation to Number Field ([b1dd5ea](https://github.com/adobe/spectrum-web-components/commit/b1dd5ea79b079e7ff9a3f850c8589f4295878941)) +- allow user input of extemely large number when a max is applied ([0644b7f](https://github.com/adobe/spectrum-web-components/commit/0644b7f5e0d5cbbf27e241d730aaec8c991ff97c)) +- allow value when step=0 ([41de75a](https://github.com/adobe/spectrum-web-components/commit/41de75a6cc2c1dd982b30a8281f4a9166e4cd87a)) +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) +- convert the langage resolution workflow to a Reactive Controller ([b7781db](https://github.com/adobe/spectrum-web-components/commit/b7781db820620688f97a40225fb17a10e7881178)) +- correct the origin on "maximumFractionDigits" when deciding "inputMode" ([e2fe9c8](https://github.com/adobe/spectrum-web-components/commit/e2fe9c8f71f3cac07905c6e1549594a8f64c8df4)) +- ensure "wheel" interactions lead to a "change" event ([3be87cd](https://github.com/adobe/spectrum-web-components/commit/3be87cd0e606a3e96f163e3e14da3ab455bc588d)) +- ensure dependencies included in package.json ([eb77858](https://github.com/adobe/spectrum-web-components/commit/eb778588c8bd75a9801d568c348096aecb74614a)) +- ensure reactivity of resolved language ([5863a15](https://github.com/adobe/spectrum-web-components/commit/5863a155262d6ba6898f82bff49aed55a6eae4f4)) +- ensure streamingListener ends even if pointercancel not fired ([74105f2](https://github.com/adobe/spectrum-web-components/commit/74105f23d30f549f18040cc7d05b99c9b746871a)) +- explicitly setting NumberField wheel event handler as not passive ([fad1496](https://github.com/adobe/spectrum-web-components/commit/fad1496b0cfab5c35b2de7447f2f0bee5325dfc2)) +- manage "lang" via context provided by "sp-theme" ([b1e3457](https://github.com/adobe/spectrum-web-components/commit/b1e3457ae447427c54f8645c478866340329750c)) +- move hover/focus hoisting into conditioning ([15ac2f7](https://github.com/adobe/spectrum-web-components/commit/15ac2f7f561b3cb5b865d1539fbd753999f25119)) +- normalize wheel input directionally for more predictable input ([e4383a8](https://github.com/adobe/spectrum-web-components/commit/e4383a82a5c287e45ea1b22e592ce5e022125739)) +- **number-field:** add an "indeterminate" state ([8bde8a1](https://github.com/adobe/spectrum-web-components/commit/8bde8a1ce54e4966736da6676424db8080c81861)) +- **number-field:** add support for modified stepping ([#1534](https://github.com/adobe/spectrum-web-components/issues/1534)) ([f8ec763](https://github.com/adobe/spectrum-web-components/commit/f8ec7635e0771097df592df9f60d042113533c4a)) +- **number-field:** added flag to scroll event to allow slider component to update on scroll ([4199eb0](https://github.com/adobe/spectrum-web-components/commit/4199eb0084dcaa9da77f3ff3880dd93f24f72b1d)) +- **number-field:** clean up delivery of quiet variant ([cd93964](https://github.com/adobe/spectrum-web-components/commit/cd9396494b838a584e939a573e8baec6ef7c8a4c)) +- **number-field:** dispatch input/change events as expected ([4a457ee](https://github.com/adobe/spectrum-web-components/commit/4a457ee4eb9e0056ea25b30796b34fb32ebdf29f)) +- **number-field:** ensure "quiet" Number Field is sized correctly in the DOM ([3ea2c8f](https://github.com/adobe/spectrum-web-components/commit/3ea2c8f9f336e9199d184b48c521dd30f833145d)) +- **number-field:** include dependancy listings ([5c9031d](https://github.com/adobe/spectrum-web-components/commit/5c9031da3694bfe516d020922b0a2d70660e6cf1)) +- **number-field:** prevent changes by user when readonly ([64a7e93](https://github.com/adobe/spectrum-web-components/commit/64a7e93ea81177a545983fdf88a9162ab3bf1ee6)) +- **number-field:** prevent interactin with stepper buttons when disabled ([ae20343](https://github.com/adobe/spectrum-web-components/commit/ae2034357fb97314e0f93df1294a6a0273fccd75)) +- **number-field:** process 2 byte characters as their single byte cousins ([f424c0a](https://github.com/adobe/spectrum-web-components/commit/f424c0aa9e04baf24aa3f6c23dd4697ab0699fc0)) +- **number-field:** readonly - no pointer events for stepper buttons ([05364fb](https://github.com/adobe/spectrum-web-components/commit/05364fb491b381d5ed1be60dc63b9c4158bfbe87)) +- **number-field:** support non-supported units in "Intl.numberFormat" ([d846c0b](https://github.com/adobe/spectrum-web-components/commit/d846c0bc75c538b008d6a7f50dc9aecc06a9b606)) +- **number-field:** validate value before dispatching "change" event ([8c2ad89](https://github.com/adobe/spectrum-web-components/commit/8c2ad89521b8bc39c3c1a29f6e46e8e2414dcd06)) +- prevent console.log in source and test files ([3ee082c](https://github.com/adobe/spectrum-web-components/commit/3ee082ceadd9eeef167bb8ac6241fe1501e4426c)) +- **theme:** stop language resolution propagation and demo using local languages ([6b81391](https://github.com/adobe/spectrum-web-components/commit/6b81391c3e4416889daa5627526dc0194f2f5f56)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- **number-field:** add number field pattern ([384ab34](https://github.com/adobe/spectrum-web-components/commit/384ab34d5aafe54e3206ff6802eb642c4df556c6)) +- **number-field:** use new config ([8d42d69](https://github.com/adobe/spectrum-web-components/commit/8d42d693363e69362e18c49f1d7a5c91262f4c38)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- support Spectrum Token consumption and update Action Button to use them ([743ab16](https://github.com/adobe/spectrum-web-components/commit/743ab16d8f05335d320440effbdcb8cd4bffc97d)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.6.1...@spectrum-web-components/number-field@0.6.2) (2023-04-24) + +### Bug Fixes + +- ensure streamingListener ends even if pointercancel not fired ([74105f2](https://github.com/adobe/spectrum-web-components/commit/74105f23d30f549f18040cc7d05b99c9b746871a)) + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.6.0...@spectrum-web-components/number-field@0.6.1) (2023-04-05) + +### Bug Fixes + +- **theme:** stop language resolution propagation and demo using local languages ([6b81391](https://github.com/adobe/spectrum-web-components/commit/6b81391c3e4416889daa5627526dc0194f2f5f56)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.13...@spectrum-web-components/number-field@0.6.0) (2023-03-22) + +### Bug Fixes + +- move hover/focus hoisting into conditioning ([15ac2f7](https://github.com/adobe/spectrum-web-components/commit/15ac2f7f561b3cb5b865d1539fbd753999f25119)) + +### Features + +- **number-field:** use new config ([8d42d69](https://github.com/adobe/spectrum-web-components/commit/8d42d693363e69362e18c49f1d7a5c91262f4c38)) + +## [0.5.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.12...@spectrum-web-components/number-field@0.5.13) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.11...@spectrum-web-components/number-field@0.5.12) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.10...@spectrum-web-components/number-field@0.5.11) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.9...@spectrum-web-components/number-field@0.5.10) (2023-01-23) + +### Bug Fixes + +- ensure "wheel" interactions lead to a "change" event ([3be87cd](https://github.com/adobe/spectrum-web-components/commit/3be87cd0e606a3e96f163e3e14da3ab455bc588d)) + +## [0.5.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.8...@spectrum-web-components/number-field@0.5.9) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.7...@spectrum-web-components/number-field@0.5.8) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.6...@spectrum-web-components/number-field@0.5.7) (2022-11-21) + +### Bug Fixes + +- ensure dependencies included in package.json ([eb77858](https://github.com/adobe/spectrum-web-components/commit/eb778588c8bd75a9801d568c348096aecb74614a)) + +## [0.5.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.5...@spectrum-web-components/number-field@0.5.6) (2022-11-14) + +### Bug Fixes + +- correct the origin on "maximumFractionDigits" when deciding "inputMode" ([e2fe9c8](https://github.com/adobe/spectrum-web-components/commit/e2fe9c8f71f3cac07905c6e1549594a8f64c8df4)) +- ensure reactivity of resolved language ([5863a15](https://github.com/adobe/spectrum-web-components/commit/5863a155262d6ba6898f82bff49aed55a6eae4f4)) + +## [0.5.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.4...@spectrum-web-components/number-field@0.5.5) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.3...@spectrum-web-components/number-field@0.5.4) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.2...@spectrum-web-components/number-field@0.5.3) (2022-10-10) + +### Bug Fixes + +- convert the langage resolution workflow to a Reactive Controller ([b7781db](https://github.com/adobe/spectrum-web-components/commit/b7781db820620688f97a40225fb17a10e7881178)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.1...@spectrum-web-components/number-field@0.5.2) (2022-09-14) + +### Bug Fixes + +- **number-field:** added flag to scroll event to allow slider component to update on scroll ([4199eb0](https://github.com/adobe/spectrum-web-components/commit/4199eb0084dcaa9da77f3ff3880dd93f24f72b1d)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.5.0...@spectrum-web-components/number-field@0.5.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.4.1...@spectrum-web-components/number-field@0.5.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.4.0...@spectrum-web-components/number-field@0.4.1) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.13...@spectrum-web-components/number-field@0.4.0) (2022-07-18) + +### Bug Fixes + +- **number-field:** ensure "quiet" Number Field is sized correctly in the DOM ([3ea2c8f](https://github.com/adobe/spectrum-web-components/commit/3ea2c8f9f336e9199d184b48c521dd30f833145d)) + +### Features + +- support Spectrum Token consumption and update Action Button to use them ([743ab16](https://github.com/adobe/spectrum-web-components/commit/743ab16d8f05335d320440effbdcb8cd4bffc97d)) + +## [0.3.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.12...@spectrum-web-components/number-field@0.3.13) (2022-06-29) + +### Bug Fixes + +- explicitly setting NumberField wheel event handler as not passive ([fad1496](https://github.com/adobe/spectrum-web-components/commit/fad1496b0cfab5c35b2de7447f2f0bee5325dfc2)) + +## [0.3.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.11...@spectrum-web-components/number-field@0.3.12) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.10...@spectrum-web-components/number-field@0.3.11) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.9...@spectrum-web-components/number-field@0.3.10) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.8...@spectrum-web-components/number-field@0.3.9) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.7...@spectrum-web-components/number-field@0.3.8) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.6...@spectrum-web-components/number-field@0.3.7) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.5...@spectrum-web-components/number-field@0.3.6) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.4...@spectrum-web-components/number-field@0.3.5) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.3...@spectrum-web-components/number-field@0.3.4) (2022-02-02) + +### Bug Fixes + +- **number-field:** validate value before dispatching "change" event ([8c2ad89](https://github.com/adobe/spectrum-web-components/commit/8c2ad89521b8bc39c3c1a29f6e46e8e2414dcd06)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.2...@spectrum-web-components/number-field@0.3.3) (2022-01-26) + +### Bug Fixes + +- **number-field:** process 2 byte characters as their single byte cousins ([f424c0a](https://github.com/adobe/spectrum-web-components/commit/f424c0aa9e04baf24aa3f6c23dd4697ab0699fc0)) + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.1...@spectrum-web-components/number-field@0.3.2) (2022-01-07) + +### Bug Fixes + +- **number-field:** clean up delivery of quiet variant ([cd93964](https://github.com/adobe/spectrum-web-components/commit/cd9396494b838a584e939a573e8baec6ef7c8a4c)) +- allow user input of extemely large number when a max is applied ([0644b7f](https://github.com/adobe/spectrum-web-components/commit/0644b7f5e0d5cbbf27e241d730aaec8c991ff97c)) +- allow value when step=0 ([41de75a](https://github.com/adobe/spectrum-web-components/commit/41de75a6cc2c1dd982b30a8281f4a9166e4cd87a)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.3.0...@spectrum-web-components/number-field@0.3.1) (2021-12-13) + +### Bug Fixes + +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) +- **number-field:** prevent interactin with stepper buttons when disabled ([ae20343](https://github.com/adobe/spectrum-web-components/commit/ae2034357fb97314e0f93df1294a6a0273fccd75)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.2.1...@spectrum-web-components/number-field@0.3.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.2.0...@spectrum-web-components/number-field@0.2.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.10...@spectrum-web-components/number-field@0.2.0) (2021-11-02) + +### Bug Fixes + +- **number-field:** prevent changes by user when readonly ([64a7e93](https://github.com/adobe/spectrum-web-components/commit/64a7e93ea81177a545983fdf88a9162ab3bf1ee6)) +- **number-field:** readonly - no pointer events for stepper buttons ([05364fb](https://github.com/adobe/spectrum-web-components/commit/05364fb491b381d5ed1be60dc63b9c4158bfbe87)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.1.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.9...@spectrum-web-components/number-field@0.1.10) (2021-10-12) + +### Bug Fixes + +- **number-field:** add an "indeterminate" state ([8bde8a1](https://github.com/adobe/spectrum-web-components/commit/8bde8a1ce54e4966736da6676424db8080c81861)) + +## [0.1.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.8...@spectrum-web-components/number-field@0.1.9) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.1.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.7...@spectrum-web-components/number-field@0.1.8) (2021-09-13) + +### Bug Fixes + +- **number-field:** support non-supported units in "Intl.numberFormat" ([d846c0b](https://github.com/adobe/spectrum-web-components/commit/d846c0bc75c538b008d6a7f50dc9aecc06a9b606)) +- add input validation to Number Field ([b1dd5ea](https://github.com/adobe/spectrum-web-components/commit/b1dd5ea79b079e7ff9a3f850c8589f4295878941)) + +## [0.1.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.6...@spectrum-web-components/number-field@0.1.7) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.1.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.5...@spectrum-web-components/number-field@0.1.6) (2021-08-17) + +### Bug Fixes + +- add "editable" option to "sp-slider" ([e86d7fa](https://github.com/adobe/spectrum-web-components/commit/e86d7fa84491b41a39dbab9c8d85eec42df320cd)) + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.4...@spectrum-web-components/number-field@0.1.5) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.3...@spectrum-web-components/number-field@0.1.4) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/number-field + +## [0.1.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.2...@spectrum-web-components/number-field@0.1.3) (2021-07-01) + +### Bug Fixes + +- **number-field:** add support for modified stepping ([#1534](https://github.com/adobe/spectrum-web-components/issues/1534)) ([f8ec763](https://github.com/adobe/spectrum-web-components/commit/f8ec7635e0771097df592df9f60d042113533c4a)) +- manage "lang" via context provided by "sp-theme" ([b1e3457](https://github.com/adobe/spectrum-web-components/commit/b1e3457ae447427c54f8645c478866340329750c)) +- normalize wheel input directionally for more predictable input ([e4383a8](https://github.com/adobe/spectrum-web-components/commit/e4383a82a5c287e45ea1b22e592ce5e022125739)) + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.1...@spectrum-web-components/number-field@0.1.2) (2021-06-16) + +### Bug Fixes + +- prevent console.log in source and test files ([3ee082c](https://github.com/adobe/spectrum-web-components/commit/3ee082ceadd9eeef167bb8ac6241fe1501e4426c)) + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/number-field@0.1.0...@spectrum-web-components/number-field@0.1.1) (2021-06-07) + +### Bug Fixes + +- **number-field:** dispatch input/change events as expected ([4a457ee](https://github.com/adobe/spectrum-web-components/commit/4a457ee4eb9e0056ea25b30796b34fb32ebdf29f)) +- **number-field:** include dependancy listings ([5c9031d](https://github.com/adobe/spectrum-web-components/commit/5c9031da3694bfe516d020922b0a2d70660e6cf1)) + +# 0.1.0 (2021-05-24) + +### Features + +- **number-field:** add number field pattern ([384ab34](https://github.com/adobe/spectrum-web-components/commit/384ab34d5aafe54e3206ff6802eb642c4df556c6)) diff --git a/1st-gen/packages/number-field/README.md b/1st-gen/packages/number-field/README.md new file mode 100644 index 00000000000..87b56d1c206 --- /dev/null +++ b/1st-gen/packages/number-field/README.md @@ -0,0 +1,402 @@ +## Overview + +`` elements are used for numeric inputs. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/number-field?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/number-field) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/number-field?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/number-field) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-drmcfxlv) + +``` +yarn add @spectrum-web-components/number-field +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/number-field/sp-number-field.js'; +``` + +When looking to leverage the `NumberField` base class as a type and/or for extension purposes, do so via: + +``` +import { NumberField } from '@spectrum-web-components/number-field'; +``` + +### Anatomy + +A number field consists of an input field for numeric values and optional stepper buttons for incrementing and decrementing the value. The stepper UI can be hidden using the `hide-stepper` attribute. + +```html + + What is the air-speed velocity of an unladen swallow? + + +``` + +### Options + +#### Sizes + + +Small + + +```html + +``` + + +Medium + + +```html + +``` + + +Large + + +```html + +``` + + +Extra Large + + +```html + +``` + + + + +#### Formatting + +An `` element will process its numeric value with `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.value)` in order to prepare it for visual delivery in the input. In order to customize this processing supply your own `Intl.NumberFormatOptions` via the `formatOptions` property, or `format-options` attribute as seen below. + +`this.resolvedLanguage` represents the language in which the `` element is currently being delivered. By default, this value will represent the language established by the `lang` attribute on the root `` element while falling back to `navigator.language` when that is not present. This value can be customized via a language context provided by a parent element that listens for the `sp-language-context` event and supplies update language settings to the `callback` function contained therein. Applications leveraging the [``](./components/theme) element to manage the visual delivery or text direction of their content will be also be provided a reactive context for supplying language information to its descendants. + + +Decimals + + +The following example uses the `signDisplay` option to include the plus sign for positive numbers, for example to display an offset from some value. In addition, it always displays a minimum of 1 digit after the decimal point, and allows up to 2 fraction digits. If the user enters more than 2 fraction digits, the result will be rounded. + +```html +Adjust exposure + +``` + + +Percentages + + +The `style: 'percent'` option can be passed to the `formatOptions` property to treat the value as a percentage. In this mode, the value is multiplied by 100 before it is displayed, i.e. `0.45` is displayed as "45%". The reverse is also true: when the user enters a value, the `change` event will be triggered with the entered value divided by 100. When the percent option is enabled, the default step automatically changes to 0.01 such that incrementing and decrementing occurs by 1%. This can be overridden with the step property. + +```html +Sales tax + +``` + + +Currency values + + +The `style: 'currency'` option can be passed to the `formatOptions` property to treat the value as a currency value. The `currency` option must also be passed to set the currency code (e.g. `USD`) to use. In addition, the `currencyDisplay` option can be used to choose whether to display the currency `symbol`, currency `code`, or currency `name`. Finally, the `currencySign` option can be set to `accounting` to use accounting notation for negative numbers, which uses parentheses rather than a minus sign in some locales. + +If you need to allow the user to change the currency, you should include a separate dropdown next to the `sp-number-field`. The `sp-number-field` itself will not determine the currency from the user input. + +```html +Transaction amount + +``` + + +Units + + +The `style: 'unit'` option can be passed to the `formatOptions` property to format the value with a unit of measurement. The `unit` option must also be passed to set which unit to use (e.g. `inch`). In addition, the `unitDisplay` option can be used to choose whether to display the unit in `long`, `short`, or `narrow` format. + +If you need to allow the user to change the unit, you should include a separate dropdown next to the number field. The number field itself will not determine the unit from the user input. + +Note: The unit style is not currently supported in Safari. A [polyfill](https://formatjs.io/docs/polyfills/intl-numberformat/) may be necessary. + +```html +Package width + +``` + + +Custom Units + + +While `Intl.NumberFormatOptions` does support a [wide range of units](https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier), it is possible to encounter units (e.g. the graphics units of `pixel`, `pixels`, `points`, etc.) that are not supported therein. When this occurs, an `` element will attempt to polyfill support for this unit. See the following example delivering `{ style: "unit", unit: "px" }` below: + +```html +Document width in pixels + +``` + +Note: the polyfilling done here is very simplistic and is triggered by supplying options that would otherwise cause the `Intl.NumberFormat()` call to throw an error. Once the unsupporting unit of `px` causes the construction of the object to throw, a back up formatter/parser pair will be created without the supplied unit data. When the `style` is set to `unit`, the `unit` value of will be adopted as the _static_ unit display. This means that neither pluralization or translation will be handled within the `` element itself. If pluralization or translation is important to the delivered interface, please be sure to handle passing those strings into to element via the `formatOptions` property reactively to the value of the element or locale of that page in question. + + +Minimum and maximum values + + +The `min` and `max` properties can be used to limit the entered value to a specific range. The value will be clamped when the user commits the value to the `` element. In addition, the increment and decrement buttons will be disabled when the value is within one step value from the bounds. Ranges can be open ended by only providing a value for either `min` or `max` rather than both. + +If a valid range is known ahead of time, it is a good idea to provide it to `` so it can optimize the experience. For example, when the minimum value is greater than or equal to zero, it is possible to use a numeric keyboard on iOS rather than a full text keyboard (necessary to enter a minus sign). + +```html +Red value + +``` + + +Step values + + +The step prop can be used to snap the value to certain increments. If there is a `min` defined, the steps are calculated starting from that minimum value. For example, if `min === 2`, and `step === 3`, the valid step values would be 2, 5, 8, 11, etc. If no `min` is defined, the steps are calculated starting from zero and extending in both directions. In other words, such that the values are evenly divisible by the step. A step can be any positive decimal. If no step is defined, any decimal value may be typed, but incrementing and decrementing snaps the value to an integer. + +If the user types a value that is between two steps and blurs the input, the value will be snapped to the nearest step. When incrementing or decrementing, the value is snapped to the nearest step that is higher or lower, respectively. When incrementing or decrementing from an empty field, the value starts at the minValue or maxValue, respectively, if defined. Otherwise, the value starts from 0. + + +```html +Step + + +Step + min + + +Step + min + max + +``` + + + + +### States + +#### Invalid + +The `invalid` attribute indicates that the number field's value is invalid. When set, appropriate ARIA attributes will be automatically applied. + +```html + + It's one banana, Michael, how much could it cost? + + + + Value should be between $0 and $0.3. + +``` + +#### Valid + +The `valid` attribute indicates that the number field's value is valid. + +```html + + It's one banana, Michael, how much could it cost? + + +``` + +#### Required + +Use the `required` attribute to indicate a number field value is required. Dictate the validity or invalidity state of the text entry with the `valid` or `invalid` attributes. + +```html +Count + +Size + +``` + +#### Disabled + +The `disabled` attribute prevents the number field from receiving focus or events. The number field will appear faded. + +```html +Number of tickets + +``` + +#### Read-only + +Number fields have a `readonly` attribute for when they’re in the disabled state but still need their labels to be shown. This allows for content to be copied, but not interacted with or changed. + +```html +Number of tickets + +``` + +### Behaviors + +The number field works with the following interactions: + +- the input field, +- ArrowUp or ArrowDown keys, +- the scroll wheel, or +- the stepper UI, when not hidden by the `hide-stepper` attribute. + +The input value incrementally increases or decreases by the value of the `step` attribute. The shift key can be used to apply steps at 10 times (or the value of the `step-modifier` attribute times) their normal rate. + +#### Default value + +The `` component doesn't manage a default value by itself. This means that consumers can set the value of the number-field as an empty string by clearing the input. If we want the number-field to reset to a `default-value` when the user clears the input, we can listen for the `change` event on the number-field component and set its value to the desired `default-value` if the input is empty. + +```html + + Default value of this number field is 42 + + + + +``` + +### Accessibility + +#### Labels + +Every number field must have a label that clearly describes its purpose. The label can be provided either via the `label` attribute or with an associated `` element. + +#### Keyboard Navigation + +Number fields support the following keyboard interactions: + +- ArrowUp and ArrowDown keys increment and decrement the value +- Shift + ArrowUp or ArrowDown applies steps at 10 times (or the value of `step-modifier`) the normal rate +- The scroll wheel can be used to increment and decrement the value when focused + +#### Help Text + +Consider providing help text to explain: + +- The expected format of the input +- Any minimum or maximum values +- The meaning of units or special formatting (e.g., currency, percentages) +- Step increments if they differ from the default + + diff --git a/1st-gen/packages/number-field/package.json b/1st-gen/packages/number-field/package.json new file mode 100644 index 00000000000..0107bbba818 --- /dev/null +++ b/1st-gen/packages/number-field/package.json @@ -0,0 +1,85 @@ +{ + "name": "@spectrum-web-components/number-field", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "Web component implementation of a Spectrum design NumberField", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/number-field" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/number-field", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/NumberField.js": { + "development": "./src/NumberField.dev.js", + "default": "./src/NumberField.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/number-field-overrides.css.js": "./src/number-field-overrides.css.js", + "./src/number-field.css.js": "./src/number-field.css.js", + "./sp-number-field.js": { + "development": "./sp-number-field.dev.js", + "default": "./sp-number-field.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@internationalized/number": "3.6.5", + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-ui": "1.9.0", + "@spectrum-web-components/infield-button": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0", + "@spectrum-web-components/textfield": "1.9.0" + }, + "devDependencies": { + "@formatjs/intl-numberformat": "8.15.4" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/number-field/sp-number-field.ts b/1st-gen/packages/number-field/sp-number-field.ts new file mode 100644 index 00000000000..a16494f2b60 --- /dev/null +++ b/1st-gen/packages/number-field/sp-number-field.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { NumberField } from './src/NumberField.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-number-field', NumberField); + +declare global { + interface HTMLElementTagNameMap { + 'sp-number-field': NumberField; + } +} diff --git a/1st-gen/packages/number-field/src/NumberField.ts b/1st-gen/packages/number-field/src/NumberField.ts new file mode 100644 index 00000000000..ff82ffb7b19 --- /dev/null +++ b/1st-gen/packages/number-field/src/NumberField.ts @@ -0,0 +1,855 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { NumberFormatter, NumberParser } from '@internationalized/number'; +import { + CSSResultArray, + html, + nothing, + PropertyValues, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; +import { streamingListener } from '@spectrum-web-components/base/src/streaming-listener.js'; +import { + LanguageResolutionController, + languageResolverUpdatedSymbol, +} from '@spectrum-web-components/reactive-controllers/src/LanguageResolution.js'; + +import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron200.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron50.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron75.js'; +import '@spectrum-web-components/infield-button/sp-infield-button.js'; +import { TextfieldBase } from '@spectrum-web-components/textfield'; +import styles from './number-field.css.js'; +import { isAndroid, isIOS, isIPhone } from '@spectrum-web-components/shared'; + +export const FRAMES_PER_CHANGE = 5; +// Debounce duration for inserting a `change` event after a batch of `wheel` originating `input` events. +export const CHANGE_DEBOUNCE_MS = 100; +export const indeterminatePlaceholder = '-'; +export const remapMultiByteCharacters: Record = { + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '0': '0', + '、': ',', + ',': ',', + '。': '.', + '.': '.', + '%': '%', + '+': '+', + ー: '-', + 一: '1', + 二: '2', + 三: '3', + 四: '4', + 五: '5', + 六: '6', + 七: '7', + 八: '8', + 九: '9', + 零: '0', +}; +const chevronIcon: Record TemplateResult> = { + s: (dir) => html` + + `, + m: (dir) => html` + + `, + l: (dir) => html` + + `, + xl: (dir) => html` + + `, +}; + +/** + * @element sp-number-field + * @slot help-text - default or non-negative help text to associate to your form element + * @slot negative-help-text - negative help text to associate to your form element when `invalid` + */ +export class NumberField extends TextfieldBase { + public static override get styles(): CSSResultArray { + return [...super.styles, styles, chevronStyles]; + } + + @query('.buttons') + private buttons!: HTMLDivElement; + + @property({ type: Boolean, reflect: true }) + public override focused = false; + + _forcedUnit = ''; + + /** + * An `<sp-number-field>` element will process its numeric value with + * `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.valueAsNumber)` + * in order to prepare it for visual delivery in the input. In order to customize this + * processing supply your own `Intl.NumberFormatOptions` object here. + * + * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat + */ + @property({ type: Object, attribute: 'format-options' }) + public formatOptions: Intl.NumberFormatOptions = {}; + + /** + * Whether the stepper UI is hidden or not. + */ + @property({ type: Boolean, reflect: true, attribute: 'hide-stepper' }) + public hideStepper = false; + + @property({ type: Boolean, reflect: true }) + public indeterminate = false; + + @property({ type: Boolean, reflect: true, attribute: 'keyboard-focused' }) + public keyboardFocused = false; + + @property({ type: Number }) + public max?: number; + + @property({ type: Number }) + public min?: number; + + /** + * The distance by which to alter the value of the element when taking a "step". + * + * When `this.formatOptions.style === 'percentage'` the default step will be + * set to 0.01 unless otherwise supplied to the element. + */ + @property({ type: Number }) + public step?: number; + + public managedInput = false; + + @property({ type: Number, reflect: true, attribute: 'step-modifier' }) + public stepModifier = 10; + + @property({ type: Number }) + public override set value(rawValue: number) { + const value = this.validateInput(rawValue); + if (value === this.value) { + return; + } + this.lastCommitedValue = value; + const oldValue = this._value; + this._value = value; + this.requestUpdate('value', oldValue); + } + + public override get value(): number { + return this._value; + } + + private get inputValue(): string { + return this.indeterminate + ? this.formattedValue + : this.inputElement.value; + } + + public override _value = NaN; + private _trackingValue = ''; + private lastCommitedValue?: number; + + private setValue(newValue: number = this.value): void { + // Capture previous value for accurate IME change detection + const previousValue = this.lastCommitedValue; + + this.value = newValue; + + if ( + typeof previousValue === 'undefined' || + previousValue === this.value + ) { + // Do not announce when the value is unchanged. + return; + } + + this.lastCommitedValue = this.value; + + this.dispatchEvent( + new Event('change', { bubbles: true, composed: true }) + ); + } + + /** + * Retreive the value of the element parsed to a Number. + */ + public get valueAsString(): string { + return this._value.toString(); + } + + public set valueAsString(value: string) { + this.value = this.numberParser.parse(value); + } + + public get formattedValue(): string { + if (isNaN(this.value)) return ''; + return ( + this.numberFormatter.format(this.value) + + (this.focused ? '' : this._forcedUnit) + ); + } + + private decimalsChars = new Set(['.', ',']); + private valueBeforeFocus: string = ''; + private isIntentDecimal: boolean = false; + + private convertValueToNumber(inputValue: string): number { + // Normalize full-width characters to their ASCII equivalents + let normalizedValue = inputValue + .split('') + .map((char) => remapMultiByteCharacters[char] || char) + .join(''); + + const separators = this.valueBeforeFocus + .split('') + .filter((char) => this.decimalsChars.has(char)); + const uniqueSeparators = new Set(separators); + + if ( + isIOS() && + this.inputElement.inputMode === 'decimal' && + normalizedValue !== this.valueBeforeFocus + ) { + const parts = this.numberFormatter.formatToParts(1000.1); + + const replacementDecimal = parts.find( + (part) => part.type === 'decimal' + )!.value; + + for (const separator of uniqueSeparators) { + const isDecimalSeparator = separator === replacementDecimal; + if (!isDecimalSeparator && !this.isIntentDecimal) { + normalizedValue = normalizedValue.replace( + new RegExp(separator, 'g'), + '' + ); + } + } + + let hasReplacedDecimal = false; + const valueChars = normalizedValue.split(''); + for (let index = valueChars.length - 1; index >= 0; index--) { + const char = valueChars[index]; + if (this.decimalsChars.has(char)) { + if (!hasReplacedDecimal) { + valueChars[index] = replacementDecimal; + hasReplacedDecimal = true; + } else valueChars[index] = ''; + } + } + normalizedValue = valueChars.join(''); + } + return this.numberParser.parse(normalizedValue); + } + private get _step(): number { + if (typeof this.step !== 'undefined') { + return this.step; + } + if (this.formatOptions?.style === 'percent') { + return 0.01; + } + return 1; + } + + private nextChange!: number; + private changeCount = 0; + private findChange!: (event: PointerEvent) => void; + private change!: (event: PointerEvent) => void; + private safty!: number; + private languageResolver = new LanguageResolutionController(this); + + private handlePointerdown(event: PointerEvent): void { + if (event.button !== 0) { + event.preventDefault(); + return; + } + this.managedInput = true; + this.buttons.setPointerCapture(event.pointerId); + const stepUpRect = this.buttons.children[0].getBoundingClientRect(); + const stepDownRect = this.buttons.children[1].getBoundingClientRect(); + this.findChange = (event: PointerEvent) => { + if ( + event.clientX >= stepUpRect.x && + event.clientY >= stepUpRect.y && + event.clientX <= stepUpRect.x + stepUpRect.width && + event.clientY <= stepUpRect.y + stepUpRect.height + ) { + this.change = (event: PointerEvent) => + this.increment(event.shiftKey ? this.stepModifier : 1); + } else if ( + event.clientX >= stepDownRect.x && + event.clientY >= stepDownRect.y && + event.clientX <= stepDownRect.x + stepDownRect.width && + event.clientY <= stepDownRect.y + stepDownRect.height + ) { + this.change = (event: PointerEvent) => + this.decrement(event.shiftKey ? this.stepModifier : 1); + } + }; + this.findChange(event); + this.startChange(event); + } + + private startChange(event: PointerEvent): void { + this.changeCount = 0; + this.doChange(event); + this.safty = setTimeout(() => { + this.doNextChange(event); + }, 400) as unknown as number; + } + + private doChange(event: PointerEvent): void { + this.change(event); + } + + private handlePointermove(event: PointerEvent): void { + this.findChange(event); + } + + private handlePointerup(event: PointerEvent): void { + this.buttons.releasePointerCapture(event.pointerId); + cancelAnimationFrame(this.nextChange); + clearTimeout(this.safty); + this.managedInput = false; + this.setValue(); + } + + private doNextChange(event: PointerEvent): number { + this.changeCount += 1; + if (this.changeCount % FRAMES_PER_CHANGE === 0) { + this.doChange(event); + } + return requestAnimationFrame(() => { + this.nextChange = this.doNextChange(event); + }); + } + + private stepBy(count: number): void { + if (this.disabled || this.readonly) { + return; + } + const min = typeof this.min !== 'undefined' ? this.min : 0; + let value = this.value; + value += count * this._step; + if (isNaN(this.value)) { + value = min; + } + value = this.valueWithLimits(value); + + this.requestUpdate(); + this._value = this.validateInput(value); + this.inputElement.value = this.numberFormatter.format(value); + + const inputEvent = new Event('input', { + bubbles: true, + composed: true, + }); + this.inputElement.readOnly = true; + this.inputElement.dispatchEvent(inputEvent); + this.indeterminate = false; + this.focus(); + this.inputElement.readOnly = false; + } + + private increment(factor = 1): void { + this.stepBy(1 * factor); + } + + private decrement(factor = 1): void { + this.stepBy(-1 * factor); + } + + private handleKeydown(event: KeyboardEvent): void { + if (this.isComposing) return; + switch (event.code) { + case 'ArrowUp': + event.preventDefault(); + this.increment(event.shiftKey ? this.stepModifier : 1); + this.setValue(); + break; + case 'ArrowDown': + event.preventDefault(); + this.decrement(event.shiftKey ? this.stepModifier : 1); + this.setValue(); + break; + } + } + + private queuedChangeEvent!: number; + + protected onScroll(event: WheelEvent): void { + event.preventDefault(); + this.managedInput = true; + const direction = event.shiftKey + ? event.deltaX / Math.abs(event.deltaX) + : event.deltaY / Math.abs(event.deltaY); + if (direction !== 0 && !isNaN(direction)) { + this.stepBy(direction * (event.shiftKey ? this.stepModifier : 1)); + clearTimeout(this.queuedChangeEvent); + this.queuedChangeEvent = setTimeout(() => { + this.setValue(); + }, CHANGE_DEBOUNCE_MS) as unknown as number; + } + this.managedInput = false; + } + + protected override onFocus(): void { + super.onFocus(); + this._trackingValue = this.inputValue; + this.keyboardFocused = !this.readonly && true; + this.addEventListener('wheel', this.onScroll, { passive: false }); + this.valueBeforeFocus = this.inputElement.value; + } + + protected override onBlur(_event: FocusEvent): void { + super.onBlur(_event); + this.keyboardFocused = !this.readonly && false; + this.removeEventListener('wheel', this.onScroll); + this.isIntentDecimal = false; + } + + private handleFocusin(): void { + this.focused = !this.readonly && true; + this.keyboardFocused = !this.readonly && true; + } + + private handleFocusout(): void { + this.focused = !this.readonly && false; + this.keyboardFocused = !this.readonly && false; + } + + private wasIndeterminate = false; + private indeterminateValue?: number; + + protected override handleChange(): void { + const value = this.convertValueToNumber(this.inputValue); + if (this.wasIndeterminate) { + this.wasIndeterminate = false; + this.indeterminateValue = undefined; + if (isNaN(value)) { + this.indeterminate = true; + return; + } + } + this.setValue(value); + this.inputElement.value = this.formattedValue; + } + + protected handleCompositionStart(): void { + this.isComposing = true; + } + + protected handleCompositionEnd(): void { + this.isComposing = false; + requestAnimationFrame(() => { + this.inputElement.dispatchEvent( + new Event('input', { + composed: true, + bubbles: true, + }) + ); + }); + } + + private hasRecentlyReceivedPointerDown = false; + + protected override handleInputElementPointerdown(): void { + this.hasRecentlyReceivedPointerDown = true; + this.updateComplete.then(() => { + requestAnimationFrame(() => { + this.hasRecentlyReceivedPointerDown = false; + }); + }); + } + + protected override handleInput(event: InputEvent): void { + if (this.isComposing) { + // If user actually types a new character. + if (event.data) { + // Don't allow non-numeric characters even in composing mode. + const partialValue = this.convertValueToNumber(event.data); + + if (Number.isNaN(partialValue)) { + this.inputElement.value = this.indeterminate + ? indeterminatePlaceholder + : this._trackingValue; + + this.isComposing = false; + } + } + + event.stopPropagation(); + return; + } + if (this.indeterminate) { + this.wasIndeterminate = true; + this.indeterminateValue = this.value; + this.inputElement.value = this.inputElement.value.replace( + indeterminatePlaceholder, + '' + ); + } + if (event.data && this.decimalsChars.has(event.data)) + this.isIntentDecimal = true; + + const { value: originalValue, selectionStart } = this.inputElement; + const value = originalValue + .split('') + .map((char) => remapMultiByteCharacters[char] || char) + .join(''); + + if (this.numberParser.isValidPartialNumber(value)) { + // Use starting value as this.value is the `input` value. + this.lastCommitedValue = this.lastCommitedValue ?? this.value; + const valueAsNumber = this.convertValueToNumber(value); + if (!value && this.indeterminateValue) { + this.indeterminate = true; + this._value = this.indeterminateValue; + } else { + this.indeterminate = false; + this._value = this.validateInput(valueAsNumber); + } + this._trackingValue = value; + this.inputElement.value = value; + this.inputElement.setSelectionRange(selectionStart, selectionStart); + return; + } else { + this.inputElement.value = this.indeterminate + ? indeterminatePlaceholder + : this._trackingValue; + + // Don't emit input event when the character is invalid. + event.stopPropagation(); + } + const currentLength = value.length; + const previousLength = this._trackingValue.length; + const nextSelectStart = + (selectionStart || currentLength) - + (currentLength - previousLength); + this.inputElement.setSelectionRange(nextSelectStart, nextSelectStart); + } + + private valueWithLimits(nextValue: number): number { + let value = nextValue; + if (typeof this.min !== 'undefined') { + value = Math.max(this.min, value); + } + if (typeof this.max !== 'undefined') { + value = Math.min(this.max, value); + } + return value; + } + + private validateInput(value: number): number { + value = this.valueWithLimits(value); + const signMultiplier = value < 0 ? -1 : 1; // 'signMultiplier' adjusts 'value' for 'validateInput' and reverts it before returning. + value *= signMultiplier; + + // Step shouldn't validate when 0... + if (this.step) { + const min = typeof this.min !== 'undefined' ? this.min : 0; + const moduloStep = parseFloat( + this.valueFormatter.format((value - min) % this.step) + ); + const fallsOnStep = moduloStep === 0; + if (!fallsOnStep) { + const overUnder = Math.round(moduloStep / this.step); + if (overUnder === 1) { + value += this.step - moduloStep; + } else { + value -= moduloStep; + } + } + if (typeof this.max !== 'undefined') { + while (value > this.max) { + value -= this.step; + } + } + value = parseFloat(this.valueFormatter.format(value)); + } + value *= signMultiplier; + return value; + } + + protected override get displayValue(): string { + const indeterminateValue = this.focused ? '' : indeterminatePlaceholder; + return this.indeterminate ? indeterminateValue : this.formattedValue; + } + + protected clearNumberFormatterCache(): void { + this._numberFormatter = undefined; + this._numberParser = undefined; + } + + protected get numberFormatter(): NumberFormatter { + if (!this._numberFormatter || !this._numberFormatterFocused) { + const { + style, + unit, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + unitDisplay, + ...formatOptionsNoUnit + } = this.formatOptions; + if (style !== 'unit') { + (formatOptionsNoUnit as Intl.NumberFormatOptions).style = style; + } + this._numberFormatterFocused = new NumberFormatter( + this.languageResolver.language, + formatOptionsNoUnit + ); + try { + this._numberFormatter = new NumberFormatter( + this.languageResolver.language, + this.formatOptions + ); + this._forcedUnit = ''; + this._numberFormatter.format(1); + } catch (error) { + if (style === 'unit') { + this._forcedUnit = unit as string; + } + this._numberFormatter = this._numberFormatterFocused; + } + } + return this.focused + ? this._numberFormatterFocused + : this._numberFormatter; + } + + protected clearValueFormatterCache(): void { + this._valueFormatter = undefined; + } + protected get valueFormatter(): NumberFormatter { + if (!this._valueFormatter) { + const digitsAfterDecimal = this.step + ? this.step != Math.floor(this.step) + ? this.step.toString().split('.')[1].length + : 0 + : 0; + this._valueFormatter = new NumberFormatter('en', { + useGrouping: false, + maximumFractionDigits: digitsAfterDecimal, + }); + } + + return this._valueFormatter; + } + private _numberFormatter?: NumberFormatter; + private _numberFormatterFocused?: NumberFormatter; + private _valueFormatter?: NumberFormatter; + protected get numberParser(): NumberParser { + if (!this._numberParser || !this._numberParserFocused) { + const { + style, + unit, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + unitDisplay, + ...formatOptionsNoUnit + } = this.formatOptions; + if (style !== 'unit') { + (formatOptionsNoUnit as Intl.NumberFormatOptions).style = style; + } + this._numberParserFocused = new NumberParser( + this.languageResolver.language, + formatOptionsNoUnit + ); + try { + this._numberParser = new NumberParser( + this.languageResolver.language, + this.formatOptions + ); + this._forcedUnit = ''; + this._numberParser.parse('0'); + } catch (error) { + if (style === 'unit') { + this._forcedUnit = unit as string; + } + this._numberParser = this._numberParserFocused; + } + } + return this.focused ? this._numberParserFocused : this._numberParser; + } + + applyFocusElementLabel = (value?: string): void => { + this.appliedLabel = value; + }; + + private _numberParser?: NumberParser; + private _numberParserFocused?: NumberParser; + + protected override renderField(): TemplateResult { + this.autocomplete = 'off'; + return html` + ${super.renderField()} + ${this.hideStepper + ? nothing + : html` + + + + + `} + `; + } + + protected override update(changes: PropertyValues): void { + if (changes.has('formatOptions') || changes.has('resolvedLanguage')) { + this.clearNumberFormatterCache(); + } + if ( + changes.has('value') || + changes.has('max') || + changes.has('min') || + changes.has('step') + ) { + const value = this.numberParser.parse( + this.formattedValue.replace(this._forcedUnit, '') + ); + this.value = value; + this.clearValueFormatterCache(); + } + super.update(changes); + } + + public override willUpdate(changes: PropertyValues): void { + this.multiline = false; + if (changes.has(languageResolverUpdatedSymbol)) { + this.clearNumberFormatterCache(); + } + } + + private isComposing = false; + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + this.addEventListener('keydown', this.handleKeydown); + this.addEventListener('compositionstart', this.handleCompositionStart); + this.addEventListener('compositionend', this.handleCompositionEnd); + } + + protected override updated(changes: PropertyValues): void { + if (!this.inputElement || !this.isConnected) { + // Prevent race conditions if inputElement is removed from DOM while a queued update is still running. + return; + } + + if (changes.has('min') || changes.has('formatOptions')) { + const hasOnlyPositives = + typeof this.min !== 'undefined' && this.min >= 0; + + const { maximumFractionDigits } = + this.numberFormatter.resolvedOptions(); + const hasDecimals = + maximumFractionDigits && maximumFractionDigits > 0; + + let inputMode = 'numeric'; + /* c8 ignore next 5 */ + // iPhone doesn't have a minus sign in either numeric or decimal. + if (isIPhone() && !hasOnlyPositives) inputMode = 'text'; + else if (isIOS() && hasDecimals) inputMode = 'decimal'; + // Android numeric has both a decimal point and minus key. Decimal does not have a minus key. + else if (isAndroid() && hasDecimals && hasOnlyPositives) + inputMode = 'decimal'; + + this.inputElement.inputMode = inputMode; + } + if ( + changes.has('focused') && + this.focused && + !this.hasRecentlyReceivedPointerDown && + !!this.formatOptions.unit + ) { + // Normalize keyboard focus entry between unit and non-unit bearing Number Fields + this.setSelectionRange(0, this.displayValue.length); + } + } +} diff --git a/1st-gen/packages/number-field/src/index.ts b/1st-gen/packages/number-field/src/index.ts new file mode 100644 index 00000000000..d8843d86e82 --- /dev/null +++ b/1st-gen/packages/number-field/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export * from './NumberField.js'; diff --git a/1st-gen/packages/number-field/src/number-field-overrides.css b/1st-gen/packages/number-field/src/number-field-overrides.css new file mode 100644 index 00000000000..86806b44807 --- /dev/null +++ b/1st-gen/packages/number-field/src/number-field-overrides.css @@ -0,0 +1,40 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-stepper-border-width: var(--system-stepper-border-width); + --spectrum-stepper-border-color-default: var(--system-stepper-border-color-default); + --spectrum-stepper-border-color-hover: var(--system-stepper-border-color-hover); + --spectrum-stepper-border-color-focus: var(--system-stepper-border-color-focus); + --spectrum-stepper-border-color-focus-hover: var(--system-stepper-border-color-focus-hover); + --spectrum-stepper-border-color-keyboard-focus: var(--system-stepper-border-color-keyboard-focus); + --spectrum-stepper-buttons-border-style: var(--system-stepper-buttons-border-style); + --spectrum-stepper-buttons-border-width: var(--system-stepper-buttons-border-width); + --spectrum-stepper-buttons-border-color: var(--system-stepper-buttons-border-color); + --spectrum-stepper-buttons-background-color: var(--system-stepper-buttons-background-color); + --spectrum-stepper-buttons-border-color-hover: var(--system-stepper-buttons-border-color-hover); + --spectrum-stepper-buttons-border-color-focus: var(--system-stepper-buttons-border-color-focus); + --spectrum-stepper-buttons-border-color-keyboard-focus: var(--system-stepper-buttons-border-color-keyboard-focus); + --spectrum-stepper-button-border-width: var(--system-stepper-button-border-width); + --spectrum-stepper-border-color-invalid: var(--system-stepper-border-color-invalid); + --spectrum-stepper-border-color-focus-invalid: var(--system-stepper-border-color-focus-invalid); + --spectrum-stepper-border-color-focus-hover-invalid: var(--system-stepper-border-color-focus-hover-invalid); + --spectrum-stepper-border-color-keyboard-focus-invalid: var(--system-stepper-border-color-keyboard-focus-invalid); + --spectrum-stepper-border-color-disabled: var(--system-stepper-border-color-disabled); + --spectrum-stepper-button-border-width-disabled: var(--system-stepper-button-border-width-disabled); + --spectrum-stepper-buttons-background-color-disabled: var(--system-stepper-buttons-background-color-disabled); +} + +:host([quiet]) #textfield { + --spectrum-stepper-buttons-border-style: var(--system-stepper-quiet-buttons-border-style); + --spectrum-stepper-button-edge-to-fill: var(--system-stepper-quiet-button-edge-to-fill); +} diff --git a/1st-gen/packages/number-field/src/number-field.css b/1st-gen/packages/number-field/src/number-field.css new file mode 100644 index 00000000000..9d0dd9e3aa7 --- /dev/null +++ b/1st-gen/packages/number-field/src/number-field.css @@ -0,0 +1,93 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-number-field.css"); +@import url("./number-field-overrides.css"); + +/* sets the missing variables for the width calcs for each size- found in spectrum-number-field.css */ +:host, +:host([size="m"]) { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-medium)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-100)); +} + +:host([size="s"]) { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-small)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-75)); +} + +:host([size="l"]) { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-large)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-200)); +} + +:host([size="xl"]) { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-extra-large)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-300)); +} + +:host { + /* TODO: added stepper-button-width multiplied by 2 just to give extra space to the input field. + That "2" is a magic number and should be removed when we are able (possibly after S2 migration). */ + --spectrum-stepper-width: calc(var(--mod-stepper-height, var(--spectrum-stepper-height)) * var(--mod-stepper-min-width-multiplier, var(--spectrum-text-field-minimum-width-multiplier)) + var(--mod-stepper-button-width, var(--spectrum-stepper-button-width)) * 2 + var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)) * 2); + + /* resets the inline-size of sp-number-field to the newly defined stepper-width */ + inline-size: var(--mod-stepper-width, var(--spectrum-stepper-width)); +} + +:host([hide-stepper]) { + --spectrum-stepper-width: calc(var(--mod-stepper-height, var(--spectrum-stepper-height)) * var(--mod-stepper-min-width-multiplier, var(--spectrum-text-field-minimum-width-multiplier)) + var(--mod-stepper-button-width, var(--spectrum-stepper-button-width)) + var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)) * 2); +} + +/* keeps the textfield 100% of the width of the sp-number-field so there isn't a gap between the containers */ +#textfield { + inline-size: 100%; +} + +.input { + font-variant-numeric: tabular-nums; +} + +:host([readonly]) .buttons { + pointer-events: none; + visibility: hidden; +} + +:host([readonly]:not([disabled], [invalid], [focused], [keyboard-focused])) #textfield:hover .input { + border-color: transparent; +} + +:host([hide-stepper]:not([quiet])) #textfield input { + border: var(--mod-textfield-border-width, var(--spectrum-textfield-border-width)) solid var(--mod-textfield-border-color, var(--spectrum-textfield-border-color)); + border-radius: var(--spectrum-textfield-corner-radius); +} + +:host([quiet]) #textfield .button { + --mod-infield-button-border-color: var(--mod-infield-border-color-quiet, transparent); + --mod-infield-button-edge-to-fill: 0; + --mod-infield-button-border-width: var(--mod-infield-button-border-width-quiet, 0); +} + +:host([focused]:not([disabled])) #textfield:hover { + --mod-stepper-buttons-border-color-focus-hover: var(--mod-stepper-border-color-focus-hover, var(--spectrum-stepper-border-color-focus-hover)); +} + +/* visually places the validation icon inside the input field */ +:host([invalid]:not([hide-stepper])) #textfield .icon, +:host([valid]:not([hide-stepper])) #textfield .icon { + inset-inline-end: calc(var(--spectrum-stepper-button-width) + var(--spectrum-textfield-icon-spacing-inline-end-invalid)); +} + +/* includes the alert icon size in the input's padding similar to the valid variant */ +:host([invalid]) .input { + padding-inline-end: calc(var(--mod-textfield-icon-spacing-inline-start-valid, var(--spectrum-textfield-icon-spacing-inline-start-valid)) + var(--mod-textfield-icon-size-valid, var(--spectrum-textfield-icon-size-valid)) + var(--mod-textfield-icon-spacing-inline-end-valid, var(--spectrum-textfield-icon-spacing-inline-end-valid)) - var(--mod-textfield-border-width, var(--spectrum-textfield-border-width))); +} diff --git a/1st-gen/packages/number-field/src/spectrum-number-field.css b/1st-gen/packages/number-field/src/spectrum-number-field.css new file mode 100644 index 00000000000..dd420075632 --- /dev/null +++ b/1st-gen/packages/number-field/src/spectrum-number-field.css @@ -0,0 +1,321 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-stepper-border-color: CanvasText; + --highcontrast-stepper-border-color-hover: Highlight; + --highcontrast-stepper-border-color-focus: Highlight; + --highcontrast-stepper-border-color-focus-hover: Highlight; + --highcontrast-stepper-border-color-keyboard-focus: CanvasText; + --highcontrast-stepper-focus-indicator-color: Highlight; + } + + :host([invalid]) #textfield { + --highcontrast-stepper-border-color: Highlight; + --highcontrast-stepper-border-color-hover: Highlight; + --highcontrast-stepper-border-color-focus: Highlight; + --highcontrast-stepper-border-color-focus-hover: Highlight; + --highcontrast-stepper-border-color-keyboard-focus: Highlight; + } + + :host([disabled]) #textfield { + --highcontrast-stepper-border-color: GrayText; + --highcontrast-stepper-buttons-border-width: var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)); + } + + :host([focused]:not([disabled])) #textfield, + :host(:not([disabled])) #textfield:focus { + --highcontrast-stepper-border-color: var(--highcontrast-stepper-border-color-focus); + } + + @media (hover: hover) { + :host(:not([disabled]):hover) #textfield { + --highcontrast-stepper-border-color: var(--highcontrast-stepper-border-color-hover); + } + + :host([focused]:not([disabled]):hover) #textfield, + :host(:not([disabled]):hover) #textfield:focus { + --highcontrast-stepper-border-color: var(--highcontrast-stepper-border-color-focus-hover); + } + } + + :host([keyboard-focused]:not([disabled])) #textfield, + :host(:not([disabled])) #textfield:focus-visible { + --highcontrast-stepper-border-color: var(--highcontrast-stepper-border-color-keyboard-focus); + } + + .input { + --highcontrast-textfield-border-color: var(--highcontrast-stepper-border-color); + } + + .button { + --highcontrast-infield-button-border-color: var(--highcontrast-stepper-border-color); + --highcontrast-infield-button-border-color-active: var(--highcontrast-stepper-border-color); + } +} + +:host { + --spectrum-stepper-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color, var(--spectrum-stepper-border-color-default))); + --spectrum-stepper-border-radius: var(--mod-stepper-border-radius, var(--spectrum-corner-radius-100)); + --spectrum-stepper-focus-indicator-width: var(--mod-stepper-focus-indicator-width, var(--spectrum-focus-indicator-thickness)); + --spectrum-stepper-focus-indicator-gap: var(--mod-stepper-focus-indicator-gap, var(--spectrum-focus-indicator-gap)); + --spectrum-stepper-focus-indicator-color: var(--highcontrast-stepper-focus-indicator-color, var(--mod-stepper-focus-indicator-color, var(--spectrum-focus-indicator-color))); + --spectrum-stepper-animation-duration: var(--mod-stepper-animation-duration, var(--spectrum-animation-duration-100)); +} + +#textfield, +:host([size="m"]) #textfield { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-medium)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-100)); +} + +:host([size="s"]) #textfield { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-small)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-75)); +} + +:host([size="l"]) #textfield { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-large)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-200)); +} + +:host([size="xl"]) #textfield { + --spectrum-stepper-button-width: var(--mod-stepper-button-width, var(--spectrum-in-field-button-width-stacked-extra-large)); + --spectrum-stepper-height: var(--mod-stepper-height, var(--spectrum-component-height-300)); +} + +:host([disabled]) #textfield { + --spectrum-stepper-buttons-border-width: var(--spectrum-stepper-button-border-width-disabled); + --spectrum-stepper-buttons-background-color: var(--spectrum-stepper-buttons-background-color-disabled); +} + +:host([invalid]) #textfield { + --mod-stepper-border-color: var(--mod-stepper-border-color-invalid, var(--spectrum-negative-border-color-default)); + --mod-stepper-border-color-hover: var(--mod-stepper-border-color-hover-invalid, var(--spectrum-negative-border-color-hover)); + --mod-stepper-border-color-focus: var(--mod-stepper-border-color-focus-invalid, var(--spectrum-negative-border-color-focus)); + --mod-stepper-border-color-focus-hover: var(--mod-stepper-border-color-focus-hover-invalid, var(--spectrum-negative-border-color-focus-hover)); + --mod-stepper-border-color-keyboard-focus: var(--mod-stepper-border-color-keyboard-focus-invalid, var(--spectrum-negative-border-color-key-focus)); +} + +:host([focused]:not([disabled])) #textfield, +:host(:not([disabled])) #textfield:focus { + --mod-stepper-border-color: var(--highcontrast-stepper-border-color-focus, var(--mod-stepper-border-color-focus, var(--spectrum-stepper-border-color-focus))); + --mod-stepper-buttons-border-color: var(--highcontrast-stepper-border-color-focus, var(--mod-stepper-border-color-focus, var(--spectrum-stepper-border-color-focus))); +} + +:host([keyboard-focused]:not([disabled])) #textfield { + --mod-stepper-border-color: var(--highcontrast-stepper-border-color-focus, var(--mod-stepper-border-color-focus, var(--spectrum-stepper-border-color-keyboard-focus))); +} + +:host([quiet]) #textfield { + --mod-stepper-buttons-background-color: transparent; +} + +:host([quiet][keyboard-focused]:not([disabled])) #textfield { + --mod-stepper-focus-indicator-visibility: visible; +} + +:host([quiet][invalid]) #textfield { + --mod-stepper-border-color: var(--mod-stepper-border-color-invalid, var(--spectrum-negative-border-color-default)); +} + +:host { + --mod-infield-button-border-color: var(--mod-stepper-buttons-border-color, var(--spectrum-stepper-buttons-border-color)); + --mod-infield-button-border-color-quiet-disabled: var(--spectrum-disabled-border-color); + --mod-infield-button-border-width: var(--mod-stepper-button-border-width, var(--spectrum-stepper-button-border-width)); + --mod-textfield-border-width: var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)); + --mod-textfield-border-color: var(--spectrum-stepper-border-color); +} + +#textfield:not(.spectrum-Stepper--quiet) { + --mod-textfield-border-color-disabled: var(--spectrum-stepper-border-color-disabled); +} + +:host(:not([disabled])[focused]) #textfield, +:host(:not([disabled])) #textfield:focus { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color-focus, var(--mod-stepper-buttons-border-color-focus, var(--spectrum-stepper-buttons-border-color-focus))); + --mod-textfield-focus-indicator-width: 0; +} + +:host([keyboard-focused]:not([disabled])) #textfield, +:host(:not([disabled])) #textfield:focus-visible { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color-keyboard-focus, var(--mod-stepper-buttons-border-color-keyboard-focus, var(--spectrum-stepper-buttons-border-color-keyboard-focus))); + --mod-textfield-focus-indicator-width: 0; + --mod-textfield-border-color: var(--highcontrast-stepper-border-color-keyboard-focus, var(--mod-stepper-border-color-keyboard-focus, var(--spectrum-stepper-border-color-keyboard-focus))); + outline: var(--spectrum-stepper-focus-indicator-width) solid; + outline-color: var(--spectrum-stepper-focus-indicator-color); + outline-offset: var(--spectrum-stepper-focus-indicator-gap); +} + +:host([invalid]) #textfield { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-invalid, var(--spectrum-stepper-border-color-invalid))); + --mod-textfield-icon-spacing-inline-start-invalid: 0; +} + +:host([invalid][focused]) #textfield, +:host([invalid]) #textfield:focus { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-focus-invalid, var(--spectrum-stepper-border-color-focus-invalid))); +} + +:host([invalid][keyboard-focused]) #textfield, +:host([invalid]) #textfield:focus-visible { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-keyboard-focus-invalid, var(--spectrum-stepper-border-color-keyboard-focus-invalid))); +} + +:host([quiet]) #textfield { + --mod-infield-button-width-stacked: var(--mod-stepper-button-width-quiet, var(--spectrum-stepper-button-width)); + --mod-infield-button-border-color: var(--spectrum-stepper-border-color); + --mod-infield-button-border-color-quiet: var(--spectrum-stepper-border-color); + --mod-infield-button-border-block-end-width: var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)); + --mod-infield-button-stacked-bottom-border-block-end-width: var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)); + --mod-infield-button-stacked-bottom-border-radius-end-end: 0; + --mod-infield-button-stacked-bottom-border-radius-end-start: 0; + --mod-infield-button-fill-justify-content: flex-end; + --mod-infield-button-inner-edge-to-fill: var(--spectrum-stepper-button-edge-to-fill); + --mod-infield-button-edge-to-fill: var(--spectrum-stepper-button-edge-to-fill); + --mod-textfield-focus-indicator-color: transparent; + --mod-textfield-background-color: transparent; + --mod-textfield-border-color-hover: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-hover, var(--spectrum-stepper-border-color-hover))); +} + +:host([quiet][focused]:not([disabled])) #textfield, +:host([quiet]:not([disabled])) #textfield:focus { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-focus, var(--spectrum-stepper-border-color-focus))); +} + +:host([quiet][keyboard-focused]:not([disabled])) #textfield { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-keyboard-focus, var(--spectrum-stepper-border-color-keyboard-focus))); +} + +@media (hover: hover) { + :host(:not([disabled]):hover) #textfield { + --mod-stepper-border-color: var(--highcontrast-stepper-border-color-hover, var(--mod-stepper-border-color-hover, var(--spectrum-stepper-border-color-hover))); + } + + :host([focused]:not([disabled]):hover) #textfield, + :host(:not([disabled]):hover) #textfield:focus { + --mod-stepper-border-color: var(--highcontrast-stepper-border-color-focus-hover, var(--mod-stepper-border-color-focus-hover, var(--spectrum-stepper-border-color-focus-hover))); + --mod-stepper-buttons-border-color: var(--highcontrast-stepper-border-color-focus-hover, var(--mod-stepper-border-color-focus-hover, var(--spectrum-stepper-border-color-focus-hover))); + } + + :host([quiet]:not([disabled]):hover) #textfield { + --mod-stepper-buttons-background-color: transparent; + } + + :host(:hover) #textfield:not(.is-invalid, .is-disabled, .is-focused) { + --mod-infield-button-border-color: var(--mod-stepper-buttons-border-color-hover, var(--spectrum-stepper-buttons-border-color-hover)); + } + + :host(:not([disabled])[focused]:hover) #textfield, + :host(:not([disabled]):hover) #textfield:focus { + --mod-infield-button-border-color: var(--mod-stepper-buttons-border-color-focus-hover, var(--spectrum-stepper-buttons-border-color-focus-hover)); + --mod-textfield-focus-indicator-width: 0; + --mod-textfield-border-color: var(--highcontrast-stepper-border-color-focus-hover, var(--mod-stepper-border-color-focus-hover, var(--spectrum-stepper-border-color-focus-hover))); + } + + :host([invalid]:hover) #textfield { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-hover-invalid, var(--spectrum-negative-border-color-hover))); + } + + :host([invalid][focused]:hover) #textfield, + :host([invalid]:hover) #textfield:focus { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-focus-hover-invalid, var(--spectrum-stepper-border-color-focus-hover-invalid))); + } + + :host([quiet]:not([disabled]):hover) #textfield { + --mod-textfield-border-color-hover: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-hover, var(--spectrum-stepper-border-color-hover))); + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-hover, var(--spectrum-stepper-border-color-hover))); + } + + :host([quiet][focused]:not([disabled]):hover) #textfield, + :host([quiet]:not([disabled]):hover) #textfield:focus { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-focus-hover, var(--spectrum-stepper-border-color-focus-hover))); + } + + :host([quiet][keyboard-focused]:not([disabled]):hover) #textfield { + --mod-infield-button-border-color: var(--highcontrast-stepper-border-color, var(--mod-stepper-border-color-hover, var(--spectrum-stepper-border-color-hover))); + } +} + +#textfield { + --spectrum-stepper-width: var(--mod-stepper-width, calc(var(--spectrum-stepper-height) * var(--mod-stepper-min-width-multiplier, var(--spectrum-text-field-minimum-width-multiplier)) + var(--spectrum-stepper-button-width) + var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)) * 2)); + inline-size: var(--spectrum-stepper-width); + block-size: var(--spectrum-stepper-height); + border-radius: var(--spectrum-stepper-border-radius); + flex-flow: row; + display: inline-flex; + position: relative; +} + +#textfield:before { + content: ""; +} + +.input { + border-inline-end-width: 0; + border-start-end-radius: 0; + border-end-end-radius: 0; +} + +.buttons { + box-sizing: border-box; + block-size: var(--spectrum-stepper-height); + inline-size: var(--spectrum-stepper-button-width); + border-color: var(--spectrum-stepper-border-color); + border-style: var(--mod-stepper-buttons-border-style, var(--spectrum-stepper-buttons-border-style)); + border-width: var(--highcontrast-stepper-buttons-border-width, var(--mod-stepper-buttons-border-width, var(--spectrum-stepper-buttons-border-width))); + background-color: var(--mod-stepper-buttons-background-color, var(--spectrum-stepper-buttons-background-color)); + transition: border-color var(--spectrum-stepper-animation-duration) ease-in-out; + border-inline-start-width: 0; + flex-direction: column; + justify-content: center; + display: flex; +} + +.buttons, +#textfield.hide-stepper .input { + border-start-end-radius: var(--spectrum-stepper-border-radius); + border-end-end-radius: var(--spectrum-stepper-border-radius); +} + +#textfield.hide-stepper .input { + border-inline-end-width: var(--mod-stepper-border-width, var(--spectrum-stepper-border-width)); +} + +:host([quiet]) #textfield { + border-start-start-radius: 0; + border-start-end-radius: 0; + border-end-end-radius: 0; + border-end-start-radius: 0; +} + +:host([quiet]) .hide-stepper .input { + border-inline-end-width: 0; + border-end-end-radius: 0; +} + +:host([quiet]):after { + visibility: hidden; + visibility: var(--mod-stepper-focus-indicator-visibility, hidden); + content: ""; + inline-size: 100%; + block-size: var(--spectrum-stepper-focus-indicator-width); + background-color: var(--spectrum-stepper-focus-indicator-color); + position: absolute; + inset-block-end: calc((var(--spectrum-stepper-focus-indicator-gap) + var(--spectrum-stepper-focus-indicator-width)) * -1); + inset-inline-start: 0; +} + +:host([quiet][keyboard-focused]:not([disabled])) { + outline: none; +} diff --git a/1st-gen/packages/number-field/stories/number-field-sizes.stories.ts b/1st-gen/packages/number-field/stories/number-field-sizes.stories.ts new file mode 100644 index 00000000000..782394b18e0 --- /dev/null +++ b/1st-gen/packages/number-field/stories/number-field-sizes.stories.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/number-field/sp-number-field.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +export default { + component: 'sp-number-field', + title: 'Number Field/Sizes', +}; + +const template = ({ + size, +}: { + size?: 's' | 'm' | 'l' | 'xl'; +} = {}): TemplateResult => { + return html` + + Pick a number + + + `; +}; + +export const s = (): TemplateResult => template({ size: 's' }); +export const noSize = (): TemplateResult => template(); +export const m = (): TemplateResult => template({ size: 'm' }); +export const l = (): TemplateResult => template({ size: 'l' }); +export const XL = (): TemplateResult => template({ size: 'xl' }); diff --git a/1st-gen/packages/number-field/stories/number-field.stories.ts b/1st-gen/packages/number-field/stories/number-field.stories.ts new file mode 100644 index 00000000000..2a8cdfd33ae --- /dev/null +++ b/1st-gen/packages/number-field/stories/number-field.stories.ts @@ -0,0 +1,524 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +import '@spectrum-web-components/number-field/sp-number-field.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import { spreadProps } from '../../../test/lit-helpers.js'; +import { NumberField } from '@spectrum-web-components/number-field/src/NumberField.js'; + +export default { + title: 'Number Field', + component: 'sp-number-field', + args: { + disabled: false, + readonly: false, + quiet: false, + value: undefined, + placeholder: '', + min: undefined, + max: undefined, + step: undefined, + }, + argTypes: { + disabled: { + name: 'disabled', + type: { name: 'boolean', required: false }, + description: + 'Disable this control. It will not receive focus or events.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + indeterminate: { + name: 'indeterminate', + type: { name: 'boolean', required: false }, + description: + 'Whether the value of the Number Field can be determined for display.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + readonly: { + name: 'readonly', + type: { name: 'boolean', required: false }, + description: + 'When this control is read only, you will not be able to input an updated value.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + quiet: { + name: 'quiet', + type: { name: 'boolean', required: false }, + description: + 'An altered delivery with no background and only a bottom border.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + hideStepper: { + name: 'hide stepper', + type: { name: 'boolean', required: false }, + description: 'Whether to remove the stepper UI from the control.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + value: { + name: 'value', + type: { name: 'number', required: false }, + description: 'Value to apply to the control.', + table: { + type: { summary: 'string' }, + defaultValue: { summary: undefined }, + }, + control: { + type: 'number', + }, + }, + step: { + name: 'step', + type: { name: 'number', required: false }, + description: + 'Amount to change the value by when using the stepper or arrow key interactions.', + table: { + type: { summary: 'string' }, + defaultValue: { summary: undefined }, + }, + control: { + type: 'number', + }, + }, + stepModifier: { + name: 'step modifier', + type: { name: 'number', required: false }, + description: + 'Amount to scale the step increment/decrement when holding the shift key', + table: { + type: { summary: 'number' }, + defaultValue: { summary: 10 }, + }, + control: { + type: 'number', + }, + }, + placeholder: { + name: 'placeholder', + type: { name: 'string', required: false }, + description: 'Placeholder to apply to the control.', + table: { + type: { summary: 'string' }, + }, + control: { + type: 'text', + }, + }, + min: { + name: 'min', + type: { name: 'number', required: false }, + description: 'The minimum value the control can be set to.', + table: { + type: { summary: 'number' }, + defaultValue: { summary: undefined }, + }, + control: { + type: 'number', + }, + }, + max: { + name: 'max', + type: { name: 'numer', required: false }, + description: 'The maximum value the control can be set to.', + table: { + type: { summary: 'number' }, + defaultValue: { summary: undefined }, + }, + control: { + type: 'number', + }, + }, + }, +}; + +interface StoryArgs { + disabled?: boolean; + indeterminate?: boolean; + invalid?: boolean; + value?: number; + placeholder?: string; + max?: number; + min?: number; + hideStepper?: boolean; + readonly?: boolean; + step?: number; + onChange?: (value: number) => void; + onInput?: (value: number) => void; + [prop: string]: unknown; +} + +export const Default = (args: StoryArgs = {}): TemplateResult => { + const onChange = + (args.onChange as (value: number) => void) || + (() => { + return; + }); + const onInput = + (args.onInput as (value: number) => void) || + (() => { + return; + }); + return html` + Enter a number + + onInput((event.target as NumberField).value)} + @change=${(event: Event) => + onChange((event.target as NumberField).value)} + style=${ifDefined(args.quiet ? undefined : '')} + > + `; +}; + +Default.args = { + value: 100, +}; + +export const quiet = (args: StoryArgs = {}): TemplateResult => Default(args); + +quiet.args = { + quiet: true, + value: 100, +}; + +export const indeterminate = (args: StoryArgs = {}): TemplateResult => + Default(args); + +indeterminate.args = { + value: 100, + indeterminate: true, +}; + +export const decimals = (args: StoryArgs): TemplateResult => { + return html` + + Enter a number with visible decimals + + + `; +}; + +decimals.args = { + value: 19.274, +}; + +export const germanDecimals = (args: StoryArgs): TemplateResult => { + let currentDir: 'ltr' | 'rtl' | '' = 'ltr'; + let currentSystem: 'spectrum' | 'spectrum-two' | 'express' = 'spectrum-two'; + if (window.__swc_hack_knobs__) { + currentDir = window.__swc_hack_knobs__.defaultDirection; + currentSystem = window.__swc_hack_knobs__.defaultSystemVariant; + } + return html` + + Enter a number with visible decimals + + + + + `; +}; + +germanDecimals.args = { + value: 19.274, +}; + +export const percents = (args: StoryArgs = {}): TemplateResult => { + return html` + Enter a percentage + + `; +}; + +percents.args = { + value: 0.372, +}; + +export const currency = (args: StoryArgs = {}): TemplateResult => { + return html` + Enter a value in Euros + + `; +}; + +currency.args = { + value: 23.19, +}; + +export const units = (args: StoryArgs): TemplateResult => { + return html` + Enter a lengths in inches + + `; +}; + +units.args = { + value: 24, +}; + +export const pixels = (args: StoryArgs): TemplateResult => { + return html` + Enter a lengths in pixels + + `; +}; + +pixels.args = { + value: 800, +}; + +export const minMax = (args: StoryArgs): TemplateResult => html` + + Enter a value between 0 and 255 + + +`; + +minMax.args = { + value: 4, + min: 0, + max: 255, +}; + +export const hideStepper = (args: StoryArgs): TemplateResult => { + return html` + + Enter a number without the stepper UI + + + `; +}; +hideStepper.args = { + hideStepper: true, + value: 67, +}; + +export const hideStepperQuiet = (args: StoryArgs): TemplateResult => { + return html` + + Enter a number without the stepper UI + + + `; +}; +hideStepperQuiet.args = { + hideStepper: true, + value: 67, + quiet: true, +}; + +export const disabled = (args: StoryArgs): TemplateResult => { + return html` + + This Number Field is disabled + + + `; +}; +disabled.args = { + disabled: true, + value: 892, +}; + +export const readOnly = (args: StoryArgs): TemplateResult => { + return html` + + You can only read the following value + + + `; +}; +readOnly.args = { + readonly: true, + value: '15', +}; + +export const validationIcons = (args: StoryArgs): TemplateResult => { + return html` + + Invalid Number Field without Stepper + + + + Valid Number Field with Stepper + + + + Invalid Number Field with Stepper + + + `; +}; +validationIcons.args = { + invalid: true, + value: '15', + hideStepper: true, +}; + +export const ScrollingContainer = (args: StoryArgs = {}): TemplateResult => { + const onChange = + (args.onChange as (value: number) => void) || + (() => { + return; + }); + const onInput = + (args.onInput as (value: number) => void) || + (() => { + return; + }); + return html` + +
+
+ Enter a number + + onInput((event.target as NumberField).value)} + @change=${(event: Event) => + onChange((event.target as NumberField).value)} + > +

+ This box should not scroll when the focus is inside the + number field and field value is changed by using the mouse + wheel. +

+
+
+ `; +}; diff --git a/1st-gen/packages/number-field/test/benchmark/basic-test.ts b/1st-gen/packages/number-field/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..252c2687ca6 --- /dev/null +++ b/1st-gen/packages/number-field/test/benchmark/basic-test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/number-field/sp-number-field.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/number-field/test/helpers.ts b/1st-gen/packages/number-field/test/helpers.ts new file mode 100644 index 00000000000..7284c2d16d0 --- /dev/null +++ b/1st-gen/packages/number-field/test/helpers.ts @@ -0,0 +1,52 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { elementUpdated, fixture, nextFrame } from '@open-wc/testing'; +import { NumberField } from '@spectrum-web-components/number-field'; +import { sendMouse } from '../../../test/plugins/browser.js'; + +export async function getElFrom(test: TemplateResult): Promise { + const wrapped = await fixture(html` +
+ ${test} +
+ `); + const el = wrapped.querySelector('sp-number-field') as NumberField; + await elementUpdated(el); + return el; +} + +export async function clickBySelector( + el: NumberField, + selector: string, + options: { button?: 'left' | 'right' | 'middle' } = {} +): Promise { + const target = el.shadowRoot.querySelector(selector) as HTMLElement; + await sendMouse([ + { + type: 'move', + position: [target], + options, + }, + { + type: 'down', + options, + }, + ]); + await nextFrame(); + await sendMouse({ + type: 'up', + options, + }); + await elementUpdated(el); +} diff --git a/1st-gen/packages/number-field/test/inputs.test.ts b/1st-gen/packages/number-field/test/inputs.test.ts new file mode 100644 index 00000000000..09e9a1bb8bb --- /dev/null +++ b/1st-gen/packages/number-field/test/inputs.test.ts @@ -0,0 +1,435 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { shouldPolyfill } from '@formatjs/intl-numberformat/should-polyfill.js'; +import { elementUpdated, expect, nextFrame } from '@open-wc/testing'; +import { html } from '@spectrum-web-components/base'; +import { createLanguageContext } from '../../../tools/reactive-controllers/test/helpers.js'; +import { getElFrom } from './helpers.js'; + +import { remapMultiByteCharacters } from '@spectrum-web-components/number-field'; +import '@spectrum-web-components/number-field/sp-number-field.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { + currency, + decimals, + Default, + minMax, + percents, +} from '../stories/number-field.stories.js'; +import { sendTabKey } from '../../../test/testing-helpers.js'; + +describe('NumberField - inputs', () => { + before(async () => { + const shouldPolyfillEn = shouldPolyfill('en'); + const shouldPolyfillEs = shouldPolyfill('es'); + const shouldPolyfillFr = shouldPolyfill('fr'); + if (shouldPolyfillEn || shouldPolyfillEs || shouldPolyfillFr) { + await import('@formatjs/intl-numberformat/polyfill-force.js'); + } + if (shouldPolyfillEn) { + await import('@formatjs/intl-numberformat/locale-data/en.js'); + } + if (shouldPolyfillEs) { + await import('@formatjs/intl-numberformat/locale-data/es.js'); + } + if (shouldPolyfillFr) { + await import('@formatjs/intl-numberformat/locale-data/fr.js'); + } + }); + describe('keystroke prevention', () => { + it('converts 2 byte characters, default', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '3、567、890。1' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('3,567,890.1'); + }); + it('converts 2 byte characters, percents', async () => { + const el = await getElFrom(html` + ${percents()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '24%' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('24%'); + }); + it('prevents second "." in EN', async () => { + const el = await getElFrom(html` + ${Default()} + `); + el.formatOptions = { + maximumFractionDigits: 2, + }; + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '1.1.1' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('1.11'); + }); + it('prevents text characters', async () => { + const el = await getElFrom(html` + ${Default()} + `); + el.formatOptions = { + maximumFractionDigits: 1, + }; + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: 'D2.2' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('2.2'); + + el.value = NaN; + + await sendKeys({ type: '8u23.s7' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('823.7'); + }); + it('allows "-" to start', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '-54' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-54'); + }); + it('prevents "-" not at the start', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '54-' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('54'); + + el.value = NaN; + + await sendKeys({ type: '5-4' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('54'); + }); + it('prevent "+" to start, normally', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '+54' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('54'); + }); + it('allow "+" to start when "signDisplay: always"', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + el.formatOptions = { + signDisplay: 'always', + }; + el.focus(); + await sendKeys({ type: '+54' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('+54'); + }); + it('prevents "%" when when not percents', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '63%' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('63'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('63'); + }); + it('allows "%" when percents, and keeps "%" on blur', async () => { + const el = await getElFrom(html` + ${percents()} + `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '63%' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('63%'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('63%'); + }); + it('prevents "Backspace" on curreny value text, and keeps currency value text of blur', async () => { + const el = await getElFrom(html` + ${currency({ value: 234.21 })} + `); + await elementUpdated(el); + expect(el.formattedValue).to.equal('EUR 234.21'); + + el.focus(); + ( + el as unknown as { + inputElement: HTMLInputElement; + } + ).inputElement.setSelectionRange(2, 2); + await sendKeys({ press: 'Backspace' }); + await elementUpdated(el); + expect( + (el as unknown as { inputElement: HTMLInputElement }) + .inputElement.value + ).to.equal('EUR 234.21'); + el.blur(); + await elementUpdated(el); + expect( + (el as unknown as { inputElement: HTMLInputElement }) + .inputElement.value + ).to.equal('EUR 234.21'); + }); + it('prevents "." when `maximumFractionDigits: 0`', async () => { + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + el.formatOptions = { + maximumFractionDigits: 0, + }; + el.focus(); + await elementUpdated(el); + await sendKeys({ type: '5.2' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('52'); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(52); + }); + xit('allow arabic numerals entered', async () => { + // Safari requires more polyfilling for this text + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await elementUpdated(el); + await sendKeys({ type: '٢١' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('21'); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(21); + }); + xit('allow hanidec numerals entered', async () => { + // Safari requires more polyfilling for this text + const el = await getElFrom(html` + ${Default()} + `); + await elementUpdated(el); + + el.focus(); + await elementUpdated(el); + await sendKeys({ type: '二一' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('21'); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(21); + }); + }); + describe('user suplied large numbers', () => { + it('do not crash the Number Field', async () => { + const el = await getElFrom(minMax(minMax.args)); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '12345678901234567890' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('255'); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(255); + }); + }); + describe('with floating point numbers', () => { + it('do not crash the Number Field', async () => { + const el = await getElFrom(minMax(minMax.args)); + el.setAttribute('min', '0.1'); + el.setAttribute('step', '0.01'); + el.setAttribute('value', '0.5'); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '6' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0.56'); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(0.56); + }); + }); + describe('locale specific', () => { + it('can determine the group symbol', async () => { + const [languageContext] = createLanguageContext('es-ES'); + const el = await getElFrom(html` +
${Default()}
+ `); + await elementUpdated(el); + + el.focus(); + await sendKeys({ type: '123.456.789' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('123.456.789'); + await sendTabKey(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('123.456.789'); + }); + }); + describe('2-byte characters', () => { + const numbers = Object.keys(remapMultiByteCharacters); + // only `1`-`0` can be accepted as single key inputs. + numbers.splice(10); + numbers.forEach((input) => { + const actual = remapMultiByteCharacters[input]; + it(`accepts "${input}" as "${actual}"`, async () => { + const el = await getElFrom(Default()); + el.focusElement.value = input; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.formattedValue).to.equal(actual); + expect(el.value).to.equal(Number(actual)); + }); + }); + it('accepts "、" as "," and "。" as "."', async () => { + const el = await getElFrom(Default(Default.args)); + el.focusElement.value = '1、234。56'; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.formattedValue).to.equal('1,234.56'); + expect(el.value).to.equal(Number(1234.56)); + }); + it('accepts misplaced "、" and corrects them', async () => { + const el = await getElFrom(Default(Default.args)); + const nextFocusableElement = document.createElement('input'); + el.insertAdjacentElement('afterend', nextFocusableElement); + el.focus(); + await elementUpdated(el); + + el.focusElement.value = '12、3456、7。89'; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.focusElement.value, 'visible').to.equal('12,3456,7.89'); + expect(el.formattedValue, 'tracked').to.equal('1,234,567.89'); + expect(el.value, 'value').to.equal(Number(1234567.89)); + + await sendTabKey(); + await elementUpdated(el); + expect(el.focusElement.value, 'visible').to.equal('1,234,567.89'); + expect(el.formattedValue, 'tracked').to.equal('1,234,567.89'); + expect(el.value, 'value').to.equal(Number(1234567.89)); + nextFocusableElement.remove(); + }); + it('accepts "+" as "+" and "ー" as "-"', async () => { + const el = await getElFrom(decimals(decimals.args)); + el.focusElement.value = '+9。87'; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.formattedValue).to.equal('+9.87'); + expect(el.value).to.equal(Number(9.87)); + + el.focusElement.value = 'ー9.87'; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.formattedValue).to.equal('-9.87'); + expect(el.value).to.equal(Number(-9.87)); + }); + it('accepts "%" as "%"', async () => { + const el = await getElFrom(percents(percents.args)); + el.focusElement.value = '10%'; + el.focusElement.dispatchEvent( + new Event('input', { + bubbles: true, + cancelable: true, + composed: true, + }) + ); + await elementUpdated(el); + + expect(el.formattedValue).to.equal('10%'); + expect(el.value).to.equal(Number(0.1)); + }); + it('does not accept non-numeric characters', async () => { + const el = await getElFrom(Default(Default.args)); + + el.focusElement.focus(); + el.dispatchEvent(new CompositionEvent('compositionstart')); + await sendKeys({ type: 'あい' }); + + await elementUpdated(el.focusElement); + await nextFrame(); + + expect(el.focusElement.value).to.equal('100'); + el.dispatchEvent(new CompositionEvent('compositionend')); + + await nextFrame(); + expect(el.focusElement.value).to.equal('100'); + }); + }); +}); diff --git a/1st-gen/packages/number-field/test/number-field-memory.test.ts b/1st-gen/packages/number-field/test/number-field-memory.test.ts new file mode 100644 index 00000000000..a02d56da7b8 --- /dev/null +++ b/1st-gen/packages/number-field/test/number-field-memory.test.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Default } from '../stories/number-field.stories.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(Default({})); diff --git a/1st-gen/packages/number-field/test/number-field.test.ts b/1st-gen/packages/number-field/test/number-field.test.ts new file mode 100644 index 00000000000..051db21efeb --- /dev/null +++ b/1st-gen/packages/number-field/test/number-field.test.ts @@ -0,0 +1,1838 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { shouldPolyfill } from '@formatjs/intl-numberformat/should-polyfill.js'; +import { + aTimeout, + elementUpdated, + expect, + fixtureCleanup, + nextFrame, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { html } from '@spectrum-web-components/base'; + +import { + CHANGE_DEBOUNCE_MS, + FRAMES_PER_CHANGE, + indeterminatePlaceholder, + NumberField, +} from '@spectrum-web-components/number-field'; +import '@spectrum-web-components/number-field/sp-number-field.js'; +import { isWebKit } from '@spectrum-web-components/shared'; +import { + a11ySnapshot, + findAccessibilityNode, + resetMouse, + sendKeys, + setUserAgent, +} from '@web/test-runner-commands'; +import { SinonSpy, spy } from 'sinon'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { + fixture, + mouseClickOn, + mouseMoveOver, + sendTabKey, + testForLitDevWarnings, +} from '../../../test/testing-helpers.js'; +import { createLanguageContext } from '../../../tools/reactive-controllers/test/helpers.js'; +import { + currency, + decimals, + Default, + germanDecimals, + indeterminate, + percents, + pixels, + units, +} from '../stories/number-field.stories.js'; +import { clickBySelector, getElFrom } from './helpers.js'; + +// Helper function to set up input and change spies +function setupEventSpies(element: NumberField): { + inputSpy: SinonSpy; + changeSpy: SinonSpy; +} { + const inputSpy = spy(); + const changeSpy = spy(); + element.addEventListener('input', () => inputSpy()); + element.addEventListener('change', () => changeSpy()); + return { inputSpy, changeSpy }; +} + +describe('NumberField', () => { + before(async () => { + const shouldPolyfillEn = shouldPolyfill('en'); + const shouldPolyfillFr = shouldPolyfill('fr'); + if (shouldPolyfillEn || shouldPolyfillFr) { + await import('@formatjs/intl-numberformat/polyfill-force.js'); + } + if (shouldPolyfillEn) { + await import('@formatjs/intl-numberformat/locale-data/en.js'); + } + if (shouldPolyfillFr) { + await import('@formatjs/intl-numberformat/locale-data/fr.js'); + } + }); + testForLitDevWarnings(async () => await getElFrom(Default({}))); + it('loads default number-field accessibly', async () => { + const el = await getElFrom(Default({})); + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + describe('receives input', () => { + it('without language context', async () => { + const el = await getElFrom(Default({ value: 1337 })); + + el.size = 's'; + expect(el.formattedValue).to.equal('1,337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + expect(el.focusElement.value).to.equal('1,337'); + el.focus(); + await sendKeys({ type: '7331' }); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('13,377,331'); + expect(el.valueAsString).to.equal('13377331'); + expect(el.value).to.equal(13377331); + expect(el.focusElement.value).to.equal('13,377,331'); + }); + it('with language context', async () => { + const [languageContext] = createLanguageContext('fr'); + const el = await getElFrom(html` +
+ ${Default({ value: 1337 })} +
+ `); + + el.size = 'l'; + expect(el.formattedValue).to.equal('1 337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + expect(el.focusElement.value).to.equal('1 337'); + el.focus(); + await sendKeys({ type: '7331' }); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('13 377 331'); + expect(el.valueAsString).to.equal('13377331'); + expect(el.value).to.equal(13377331); + expect(el.focusElement.value).to.equal('13 377 331'); + }); + }); + xit('correctly interprets decimal point on iPhone', async () => { + // setUserAgent is not currently supported by Playwright + await setUserAgent( + 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1' + ); + const el = await getElFrom(decimals({ value: 1234 })); + expect(el.formattedValue).to.equal('1,234'); + + el.focus(); + await sendKeys({ press: 'Backspace' }); + el.blur(); + expect(el.formattedValue).to.equal('123'); + + el.focus(); + await sendKeys({ type: '45' }); + el.blur(); + expect(el.formattedValue).to.equal('12,345'); + + el.focus(); + await sendKeys({ type: ',6' }); + el.blur(); + expect(el.formattedValue).to.equal('12,345.6'); + + el.focus(); + await sendKeys({ type: ',7' }); + el.blur(); + expect(el.formattedValue).to.equal('123,456.7'); + + el.focus(); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: 'Backspace' }); + el.blur(); + expect(el.formattedValue).to.equal('123,456'); + }); + describe('Step', () => { + it('can be 0', async () => { + const el = await getElFrom( + Default({ + step: 0, + min: 0, + max: 10, + value: 5, + }) + ); + + el.size = 'xl'; + expect(el.value).to.equal(5); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.focusElement.value).to.equal('5'); + }); + it('respects other locales', async () => { + const el = await getElFrom( + germanDecimals({ + step: 0.01, + }) + ); + el.value = 2.42; + await elementUpdated(el); + el.size = 'xl'; + expect(el.value).to.equal(2.42); + expect(el.formattedValue).to.equal('+2,42'); + expect(el.focusElement.value).to.equal('+2,42'); + + await clickBySelector(el, '.step-up'); + + expect(el.value).to.equal(2.43); + expect(el.formattedValue).to.equal('+2,43'); + expect(el.focusElement.value).to.equal('+2,43'); + }); + it('supports both positive and negative decimal values', async () => { + const el = await getElFrom( + Default({ + step: 0.001, + min: -10, + max: 10, + value: -2.4, + }) + ); + + el.size = 'xl'; + expect(el.value).to.equal(-2.4); + expect(el.valueAsString).to.equal('-2.4'); + expect(el.focusElement.value).to.equal('-2.4'); + }); + it('correctly handles max values greater than 1000 with step=1', async () => { + const el = await getElFrom( + Default({ + step: 1, + min: 0, + max: 200000, + value: 999, + }) + ); + + await clickBySelector(el, '.step-up'); + + expect(el.value).to.equal(1000); + expect(el.valueAsString).to.equal('1000'); + expect(el.formattedValue).to.equal('1,000'); + expect(el.focusElement.value).to.equal('1,000'); + + el.value = 15000; + await elementUpdated(el); + + expect(el.value).to.equal(15000); + expect(el.valueAsString).to.equal('15000'); + expect(el.formattedValue).to.equal('15,000'); + expect(el.focusElement.value).to.equal('15,000'); + }); + }); + describe('Increments', () => { + let el: NumberField; + + beforeEach(async () => { + el = await getElFrom(Default({})); + expect(el.value).to.be.NaN; + expect(el.formattedValue).to.equal(''); + expect(el.valueAsString).to.equal('NaN'); + expect(el.focusElement.value).to.equal(''); + }); + it('via pointer, only "left" button', async () => { + await clickBySelector(el, '.step-up', { button: 'middle' }); + expect(el.formattedValue).to.equal(''); + expect(el.valueAsString).to.equal('NaN'); + expect(el.value).to.be.NaN; + expect(el.focusElement.value).to.equal(''); + }); + + it('via pointer', async () => { + await clickBySelector(el, '.step-up'); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await clickBySelector(el, '.step-up'); + expect(el.formattedValue).to.equal('1'); + expect(el.valueAsString).to.equal('1'); + expect(el.value).to.equal(1); + expect(el.focusElement.value).to.equal('1'); + }); + it('via arrow up', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('1'); + expect(el.valueAsString).to.equal('1'); + expect(el.value).to.equal(1); + expect(el.focusElement.value).to.equal('1'); + }); + it('via arrow up (shift modified)', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'Shift+ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + expect(el.focusElement.value).to.equal('10'); + }); + it('via arrow up (custom shift modified value)', async () => { + el.focus(); + (el as NumberField).stepModifier = 5; + (el as NumberField).step = 3; + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'Shift+ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('15'); + expect(el.valueAsString).to.equal('15'); + expect(el.value).to.equal(15); + expect(el.focusElement.value).to.equal('15'); + }); + it('via scroll', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 1 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 100 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('1'); + expect(el.valueAsString).to.equal('1'); + expect(el.value).to.equal(1); + expect(el.focusElement.value).to.equal('1'); + }); + it('via scroll (shift modified)', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.dispatchEvent( + new WheelEvent('wheel', { + deltaX: 1, + shiftKey: true, + }) + ); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + el.dispatchEvent( + new WheelEvent('wheel', { + deltaX: 100, + shiftKey: true, + }) + ); + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + expect(el.focusElement.value).to.equal('10'); + }); + }); + describe('Decrements', () => { + let el: NumberField; + + beforeEach(async () => { + el = await getElFrom(Default({})); + expect(el.value).to.be.NaN; + expect(el.formattedValue).to.equal(''); + expect(el.valueAsString).to.equal('NaN'); + expect(el.focusElement.value).to.equal(''); + }); + it('via pointer, only "left" button', async () => { + await clickBySelector(el, '.step-down', { button: 'middle' }); + expect(el.formattedValue).to.equal(''); + expect(el.valueAsString).to.equal('NaN'); + expect(el.value).to.be.NaN; + expect(el.focusElement.value).to.equal(''); + }); + it('via pointer', async () => { + await clickBySelector(el, '.step-down'); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await clickBySelector(el, '.step-down'); + expect(el.formattedValue).to.equal('-1'); + expect(el.valueAsString).to.equal('-1'); + expect(el.value).to.equal(-1); + expect(el.focusElement.value).to.equal('-1'); + }); + it('via arrow down', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-1'); + expect(el.valueAsString).to.equal('-1'); + expect(el.value).to.equal(-1); + expect(el.focusElement.value).to.equal('-1'); + }); + it('via arrow down (shift modified)', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'Shift+ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-10'); + expect(el.valueAsString).to.equal('-10'); + expect(el.value).to.equal(-10); + expect(el.focusElement.value).to.equal('-10'); + }); + it('via arrow up (custom shift modified value)', async () => { + el.focus(); + (el as NumberField).stepModifier = 5; + (el as NumberField).step = 3; + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + await sendKeys({ press: 'Shift+ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-15'); + expect(el.valueAsString).to.equal('-15'); + expect(el.value).to.equal(-15); + expect(el.focusElement.value).to.equal('-15'); + }); + it('via scroll', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.dispatchEvent(new WheelEvent('wheel', { deltaY: -1 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + el.dispatchEvent(new WheelEvent('wheel', { deltaY: -100 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-1'); + expect(el.valueAsString).to.equal('-1'); + expect(el.value).to.equal(-1); + expect(el.focusElement.value).to.equal('-1'); + }); + it('via scroll (shift modified)', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.dispatchEvent( + new WheelEvent('wheel', { + deltaX: -1, + shiftKey: true, + }) + ); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + expect(el.focusElement.value).to.equal('0'); + el.dispatchEvent( + new WheelEvent('wheel', { + deltaX: -100, + shiftKey: true, + }) + ); + await elementUpdated(el); + expect(el.formattedValue).to.equal('-10'); + expect(el.valueAsString).to.equal('-10'); + expect(el.value).to.equal(-10); + expect(el.focusElement.value).to.equal('-10'); + }); + }); + describe('dispatched events', () => { + const inputSpy = spy(); + const changeSpy = spy(); + let el: NumberField; + beforeEach(async () => { + inputSpy.resetHistory(); + changeSpy.resetHistory(); + el = await getElFrom(Default({ value: 50 })); + el.addEventListener('input', (event: Event) => { + inputSpy((event.target as NumberField)?.value); + }); + el.addEventListener('change', (event: Event) => { + changeSpy((event.target as NumberField)?.value); + }); + }); + it('except when changing `value` from the outside', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.value = 51; + expect(changeSpy.callCount).to.equal(0); + await elementUpdated(el); + el.value = 52; + expect(changeSpy.callCount).to.equal(0); + }); + it('handles IME input correctly and dispatches change event', async () => { + el.focus(); + el.dispatchEvent(new CompositionEvent('compositionstart')); + // input multibyte characters + await sendKeys({ type: '123' }); + await elementUpdated(el); + el.dispatchEvent(new CompositionEvent('compositionend')); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + expect(el.value).to.equal(50123); + expect(changeSpy.callCount).to.equal(1); + }); + it('via scroll', async () => { + el.focus(); + await elementUpdated(el); + expect(el.focused).to.be.true; + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 1 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('51'); + expect(el.valueAsString).to.equal('51'); + expect(el.value).to.equal(51); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(0); + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 100 })); + await elementUpdated(el); + expect(el.formattedValue).to.equal('52'); + expect(el.valueAsString).to.equal('52'); + expect(el.value).to.equal(52); + expect(inputSpy.callCount).to.equal(2); + expect(changeSpy.callCount).to.equal(0); + await aTimeout(CHANGE_DEBOUNCE_MS + 10); + expect(inputSpy.callCount).to.equal(2); + expect(changeSpy.callCount).to.equal(1); + }); + it('has a useful `value`', async () => { + el.focus(); + await sendKeys({ type: '7' }); + await sendKeys({ press: 'Enter' }); + expect(inputSpy.calledWith(507), 'input').to.be.true; + expect(changeSpy.calledWith(507), 'change').to.be.true; + await sendKeys({ type: ',00' }); + await sendKeys({ press: 'Enter' }); + expect(inputSpy.calledWith(5070), 'input').to.be.true; + expect(inputSpy.calledWith(50700), 'input').to.be.true; + expect(changeSpy.calledWith(50700), 'change').to.be.true; + }); + it('has a useful `value` - percent', async () => { + el.formatOptions = { style: 'percent' }; + el.value = 0.45; + expect(el.value).to.equal(0.45); + el.focus(); + await sendKeys({ type: '7' }); // Visible text: 45%7 + expect(inputSpy.calledWith(4.57), 'first input').to.be.true; + await sendKeys({ press: 'Backspace' }); // Visible text: 45% + await sendKeys({ press: 'Backspace' }); // Visible text: 45 + await sendKeys({ press: 'Backspace' }); // Visible text: 4 + await sendKeys({ press: 'Enter' }); + expect(el.value).to.equal(0.04); + expect(inputSpy.calledWith(0.45), 'second input').to.be.true; + expect(inputSpy.calledWith(0.04), 'third input').to.be.true; + expect(changeSpy.calledWith(0.04), 'change').to.be.true; + }); + it('has a useful `value` - currency', async () => { + el.formatOptions = { + style: 'currency', + currency: 'EUR', + currencyDisplay: 'code', + currencySign: 'accounting', + }; + await elementUpdated(el); + el.value = 45; + expect(el.value).to.equal(45); + el.focus(); + await sendKeys({ type: '7' }); // Visible text: EUR 45.007 + expect(el.value).to.equal(45.007); + expect(inputSpy.calledWith(el.value), 'first input').to.be.true; + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ press: 'ArrowLeft' }); // Visible text: EUR 45.007 + await sendKeys({ type: '1' }); // Visible text: 1EUR 45.007 + await sendKeys({ press: 'Enter' }); // Visible text: EUR 145.01 + expect(el.value).to.equal(145.007); + expect(inputSpy.calledWith(145.007), 'second input').to.be.true; + expect(changeSpy.calledWith(145.007), 'change').to.be.true; + }); + it('one input/one change for each Arrow*', async () => { + el.focus(); + await sendKeys({ press: 'ArrowUp' }); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(1); + expect(el.value).to.equal(51); + await sendKeys({ press: 'ArrowDown' }); + expect(inputSpy.callCount).to.equal(2); + expect(changeSpy.callCount).to.equal(2); + expect(el.value).to.equal(50); + }); + it('one input/one change for each click', async () => { + await clickBySelector(el, '.step-up'); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(1); + expect(el.value).to.equal(51); + await clickBySelector(el, '.step-down'); + expect(inputSpy.callCount).to.equal(2); + expect(changeSpy.callCount).to.equal(2); + expect(el.value).to.equal(50); + }); + it('click with modifier key', async () => { + let target = el.shadowRoot.querySelector('.step-up') as HTMLElement; + const stepUpRect = target.getBoundingClientRect(); + const options = { + bubbles: true, + composed: true, + shiftKey: true, + clientX: stepUpRect.x + 1, + clientY: stepUpRect.y + 1, + }; + ( + el as unknown as { + buttons: HTMLDivElement; + } + ).buttons.setPointerCapture = () => { + return; + }; + ( + el as unknown as { + buttons: HTMLDivElement; + } + ).buttons.releasePointerCapture = () => { + return; + }; + let input = oneEvent(el, 'input'); + target.dispatchEvent(new PointerEvent('pointerdown', options)); + await input; + target.dispatchEvent(new PointerEvent('pointerup', options)); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(1); + expect(el.value).to.equal(60); + target = el.shadowRoot.querySelector('.step-down') as HTMLElement; + const stepDownRect = target.getBoundingClientRect(); + options.clientX = stepDownRect.x + 1; + options.clientY = stepDownRect.y + 1; + input = oneEvent(el, 'input'); + target.dispatchEvent(new PointerEvent('pointerdown', options)); + await input; + target.dispatchEvent(new PointerEvent('pointerup', options)); + expect(inputSpy.callCount).to.equal(2); + expect(changeSpy.callCount).to.equal(2); + expect(el.value).to.equal(50); + }); + it('many input, but one change', async () => { + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + const buttonDown = el.shadowRoot.querySelector( + '.step-down' + ) as HTMLElement; + sendMouse([ + { + type: 'move', + position: [buttonUp], + }, + { + type: 'down', + }, + ]); + await oneEvent(el, 'input'); + expect(el.value, 'initial: el.value').to.be.greaterThanOrEqual(51); + expect( + inputSpy.callCount, + 'initial: inputSpy.callCount' + ).to.be.greaterThanOrEqual(1); + expect( + changeSpy.callCount, + 'initial: no changeSpy.callCount' + ).to.equal(0); + await oneEvent(el, 'input'); + expect(el.value, 'second: el.value').to.be.greaterThanOrEqual(52); + expect( + inputSpy.callCount, + 'second: inputSpy.callCount' + ).to.be.greaterThanOrEqual(2); + expect( + changeSpy.callCount, + 'second: no changeSpy.callCount' + ).to.equal(0); + await oneEvent(el, 'input'); + expect(el.value, 'third: el.value').to.be.greaterThanOrEqual(53); + expect( + inputSpy.callCount, + 'third: inputSpy.callCount' + ).to.be.greaterThanOrEqual(3); + expect( + changeSpy.callCount, + 'third: no changeSpy.callCount' + ).to.equal(0); + await mouseMoveOver(buttonDown); + expect( + inputSpy.callCount, + 'fourth: inputSpy.callCount' + ).to.be.greaterThanOrEqual(5); + expect( + changeSpy.callCount, + 'fourth: no changeSpy.callCount' + ).to.equal(0); + await sendMouse({ type: 'up' }); + expect( + inputSpy.callCount, + 'fifth: inputSpy.callCount' + ).to.be.greaterThanOrEqual(5); + expect( + changeSpy.callCount, + 'fifth: changeSpy.callCount is fired' + ).to.equal(1); + }); + it('no change in committed value - using buttons', async () => { + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + const buttonDown = el.shadowRoot.querySelector( + '.step-down' + ) as HTMLElement; + sendMouse([ + { + type: 'move', + position: [buttonUp], + }, + { + type: 'down', + }, + ]); + await oneEvent(el, 'input'); + expect(el.value, 'first: el.value').to.be.greaterThanOrEqual(51); + expect( + inputSpy.callCount, + 'first: inputSpy.callCount' + ).to.be.greaterThanOrEqual(1); + expect( + changeSpy.callCount, + 'first: no changeSpy.callCount' + ).to.equal(0); + await oneEvent(el, 'input'); + expect(el.value, 'second: el.value').to.be.greaterThanOrEqual(52); + expect( + inputSpy.callCount, + 'second: inputSpy.callCount' + ).to.be.greaterThanOrEqual(2); + expect( + changeSpy.callCount, + 'second: no changeSpy.callCount' + ).to.equal(0); + await mouseMoveOver(buttonDown); + await oneEvent(el, 'input'); + expect( + inputSpy.callCount, + 'third: inputSpy.callCount' + ).to.be.greaterThanOrEqual(4); + expect( + changeSpy.callCount, + 'third: no changeSpy.callCount' + ).to.equal(0); + expect(el.value, 'third: el.value').to.be.lessThanOrEqual(52); + await mouseMoveOver(buttonDown); + await oneEvent(el, 'input'); + expect(el.value, 'fourth: el.value').to.be.lessThanOrEqual(51); + await waitUntil(() => el.value === 50); + await sendMouse({ type: 'up' }); + expect( + inputSpy.callCount, + 'fourth: inputSpy.callCount' + ).to.be.greaterThanOrEqual(4); + expect(el.value, 'final: el.value').to.equal(50); + expect( + changeSpy.callCount, + 'value does not change from initial value so no "change" event is dispatched' + ).to.equal(0); + }); + }); + + describe('Stepper UI interactions', () => { + let el: NumberField; + let inputSpy: SinonSpy; + let changeSpy: SinonSpy; + + beforeEach(async () => { + el = await getElFrom(Default({ value: 50 })); + const spies = setupEventSpies(el); + inputSpy = spies.inputSpy; + changeSpy = spies.changeSpy; + }); + + afterEach(() => { + // Reset spies after each test to ensure isolation + inputSpy?.resetHistory(); + changeSpy?.resetHistory(); + + // Clean up fixtures to prevent test pollution + fixtureCleanup(); + resetMouse(); + }); + + it('increments value with stepper UI click', async () => { + // Initial state + expect(el.value).to.equal(50); + + // Get step-up button position + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + // Click the step-up button + await mouseClickOn(buttonUp); + + await elementUpdated(el); + + // Verify single increment + expect(el.value).to.equal(51); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(1); + }); + + it('decrements value with stepper UI click', async () => { + // Initial state + expect(el.value).to.equal(50); + + // Get step-down button position + const buttonDown = el.shadowRoot.querySelector( + '.step-down' + ) as HTMLElement; + // Click the step-down button + await mouseClickOn(buttonDown); + + await elementUpdated(el); + + // Verify single decrement + expect(el.value).to.equal(49); + expect(inputSpy.callCount).to.equal(1); + expect(changeSpy.callCount).to.equal(1); + }); + + it('continuously increments when holding down step-up button', async () => { + // Initial state + expect(el.value).to.equal(50); + + // Get step-up button position + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + + // Press and hold the step-up button + await sendMouse([ + { + type: 'move', + position: [buttonUp], + }, + { + type: 'down', + }, + ]); + + // Wait for first increment + await oneEvent(el, 'input'); + await elementUpdated(el); + // Note: We use range assertions (to.be.at.least) instead of exact equality here because + // continuous increment timing is non-deterministic and depends on system performance, + // browser event loop, and test environment. We're verifying the behavior works, + // not the exact count of increments. + expect(el.value).to.be.at.least(51); + const firstIncrementValue = el.value; + + // Wait for continuous increments (at least one more) + await oneEvent(el, 'input'); + await elementUpdated(el); + // Verify that holding the button causes multiple increments, not just one + expect(el.value).to.be.greaterThan(firstIncrementValue); + + // Release the button + await sendMouse({ type: 'up' }); + + // Verify no further increments after release + const finalValue = el.value; + // We intentionally use a timeout here to verify the ABSENCE of events. + // After releasing the mouse, we need to ensure no more increments occur. + // Event-based synchronization (oneEvent) can't be used because we're + // testing that NO events should fire. This timeout gives enough time + // for any erroneous delayed increments to occur if the bug exists. + await aTimeout(100); + expect(el.value).to.equal(finalValue); + }); + + it('changes from increment to decrement when dragging between buttons', async () => { + // Get button positions + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + const buttonDown = el.shadowRoot.querySelector( + '.step-down' + ) as HTMLElement; + + // Press and hold the step-up button + await sendMouse([ + { + type: 'move', + position: [buttonUp], + }, + { + type: 'down', + }, + ]); + + // Wait for increment to start + await oneEvent(el, 'input'); + await elementUpdated(el); + // Using range assertions because press-and-hold timing is non-deterministic + expect(el.value).to.be.at.least(51); + + // Wait for another increment + await oneEvent(el, 'input'); + await elementUpdated(el); + const valueBeforeSwitch = el.value; + // Ensure we've had multiple increments before testing direction change + expect(valueBeforeSwitch).to.be.at.least(52); + + // Move to step-down button while still holding + inputSpy.resetHistory(); + await mouseMoveOver(buttonDown); + + // input is only processed onces per FRAMES_PER_CHANGE number of frames so wait for the direction to change + let framesToWait = FRAMES_PER_CHANGE * 2; + while (framesToWait) { + framesToWait -= 1; + await nextFrame(); + } + await elementUpdated(el); + + // Value should have decreased from the peak + // Using lessThan because we can't predict exact decrement count during drag transition + expect(el.value).to.be.lessThan(valueBeforeSwitch); + // At least one decrement should have occurred after moving to step-down button + expect(inputSpy.callCount).to.be.at.least(1); + + // Release the button + await sendMouse({ type: 'up' }); + // Verify no further increments after release + const finalValue = el.value; + // We intentionally use a timeout here to verify the ABSENCE of events. + // After releasing the mouse, we need to ensure no more increments occur. + // Event-based synchronization (oneEvent) can't be used because we're + // testing that NO events should fire. This timeout gives enough time + // for any erroneous delayed increments to occur if the bug exists. + await aTimeout(100); + expect(el.value).to.equal(finalValue); + }); + }); // End of Stepper UI interactions describe block + + it('surfaces `valueAsNumber`', async () => { + const el = await getElFrom(Default({})); + el.value = 1000; + await elementUpdated(el); + expect(el.formattedValue).to.equal('1,000'); + expect(el.valueAsString).to.equal('1000'); + expect(el.value).to.equal(1000); + el.valueAsString = '2222'; + await elementUpdated(el); + expect(el.formattedValue).to.equal('2,222'); + expect(el.valueAsString).to.equal('2222'); + expect(el.value).to.equal(2222); + }); + describe('manages `value` with `formatOptions`', () => { + it('manages decimals', async () => { + const el = await getElFrom(decimals({ value: 1.333333 })); + expect(el.value).to.equal(1.33); + expect(el.formattedValue).to.equal('+1.33'); + expect(el.valueAsString).to.equal('1.33'); + }); + it('manages precents', async () => { + const el = await getElFrom(percents({ value: 0.45 })); + expect(el.formattedValue).to.equal('45%'); + expect(el.valueAsString).to.equal('0.45'); + expect(el.value).to.equal(0.45); + await clickBySelector(el, '.step-down'); + await elementUpdated(el); + expect(el.formattedValue).to.equal('44%'); + expect(el.valueAsString).to.equal('0.44'); + expect(el.value).to.equal(0.44); + await clickBySelector(el, '.step-up'); + await elementUpdated(el); + expect(el.formattedValue).to.equal('45%'); + expect(el.valueAsString).to.equal('0.45'); + expect(el.value).to.equal(0.45); + el.focus(); + el.value = 0; + await sendKeys({ type: '54' }); + await sendKeys({ press: 'Enter' }); + expect(el.formattedValue).to.equal('54%'); + expect(el.valueAsString).to.equal('0.54'); + expect(el.value).to.equal(0.54); + await elementUpdated(el); + expect(el.formattedValue).to.equal('54%'); + expect(el.valueAsString).to.equal('0.54'); + expect(el.value).to.equal(0.54); + }); + it('manages currency', async () => { + const el = await getElFrom(currency({ value: 234.21 })); + expect(el.formattedValue).to.equal('EUR 234.21'); + expect(el.valueAsString).to.equal('234.21'); + expect(el.value).to.equal(234.21); + }); + it('manages units', async () => { + const el = await getElFrom(units({ value: 17 })); + expect(el.formattedValue).to.equal('17 inches'); + expect(el.valueAsString).to.equal('17'); + expect(el.value).to.equal(17); + }); + it('does not select all on click based `focus`', async function () { + const el = await getElFrom(units({ value: 17 })); + expect(el.value).to.equal(17); + + const inputElement = el.shadowRoot?.querySelector( + 'input' + ) as HTMLInputElement; + + await mouseClickOn(el.focusElement); + await elementUpdated(el); + expect(el.focused).to.be.true; + + let length: number | null = null; + await waitUntil( + () => { + if ( + inputElement.selectionStart !== null && + inputElement.selectionEnd !== null + ) { + length = + inputElement.selectionEnd - + inputElement.selectionStart; + return true; + } + return false; + }, + 'selection changed', + { timeout: 400 } + ); + expect(length, `selection length)`).to.equal(0); + }); + it('selects all on `Tab` based `focus`', async function () { + const el = await getElFrom(units({ value: 17 })); + const input = document.createElement('input'); + el.insertAdjacentElement('beforebegin', input); + input.focus(); + + const inputElement = el.shadowRoot?.querySelector( + 'input' + ) as HTMLInputElement; + + await sendTabKey(); + await elementUpdated(el); + expect(el.focused).to.be.true; + + let length: number | null = null; + await waitUntil( + () => { + if ( + inputElement.selectionStart !== null && + inputElement.selectionEnd !== null + ) { + length = + inputElement.selectionEnd - + inputElement.selectionStart; + return true; + } + return false; + }, + 'selection changed', + { timeout: 400 } + ); + + expect(length, `selection length`).to.equal( + el.valueAsString.length + ); + }); + it('manages units not supported by the browser', async () => { + const el = await getElFrom(pixels({ value: 17 })); + expect(el.formattedValue).to.equal('17px'); + expect(el.valueAsString).to.equal('17'); + expect(el.value).to.equal(17); + }); + }); + describe('max', () => { + let el: NumberField; + let lastInputValue = 0; + let lastChangeValue = 0; + const inputSpy = spy(); + const changeSpy = spy(); + beforeEach(async () => { + inputSpy.resetHistory(); + changeSpy.resetHistory(); + el = await getElFrom( + Default({ + max: 10, + value: 10, + onInput: (value: number) => { + inputSpy(value); + lastInputValue = value; + }, + onChange: (value: number) => { + changeSpy(value); + lastChangeValue = value; + }, + }) + ); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('constrains input', async () => { + el.focus(); + await sendKeys({ type: '15' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(lastInputValue, 'last input value').to.equal(10); + expect(lastChangeValue, 'last change value').to.equal( + 0, + 'value does not change from initial value so no "change" event is dispatched' + ); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('constrains `value`', async () => { + el.value = 20; + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('constrains ArrowUp usage', async () => { + expect(el.value).to.equal(10); + el.focus(); + await sendKeys({ press: 'ArrowUp' }); + expect(el.focusElement.value).to.equal('10'); + await sendKeys({ press: 'Shift+ArrowUp' }); + expect(el.focusElement.value).to.equal('10'); + }); + it('constrains pointer usage', async () => { + expect(el.value).to.equal(10); + const buttonUp = el.shadowRoot.querySelector( + '.step-up' + ) as HTMLElement; + await mouseClickOn(buttonUp); + expect(el.value).to.equal(10); + }); + it('validates on commit', async () => { + el.focus(); + await sendKeys({ type: '15' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('disabled `stepUp` button', async () => { + await clickBySelector(el, '.step-up'); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('validates late', async () => { + el.max = 5; + await elementUpdated(el); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.value).to.equal(5); + }); + it('dispatches onchange on setting max value', async () => { + el.value = 5; + await elementUpdated(el); + expect(changeSpy.callCount).to.equal(0); + expect(el.value).to.equal(5); + el.focus(); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: '1' }); + await sendKeys({ press: '5' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(10); + expect(inputSpy.callCount).to.equal(3); + expect(changeSpy.callCount).to.equal(1); + expect(lastChangeValue, 'last change value').to.equal(10); + }); + }); + describe('min', () => { + let el: NumberField; + let lastInputValue = 0; + let lastChangeValue = 0; + const inputSpy = spy(); + const changeSpy = spy(); + beforeEach(async () => { + inputSpy.resetHistory(); + changeSpy.resetHistory(); + el = await getElFrom( + Default({ + min: 10, + value: 10, + onInput: (value: number) => { + inputSpy(value); + lastInputValue = value; + }, + onChange: (value: number) => { + changeSpy(value); + lastChangeValue = value; + }, + }) + ); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('constrains input', async () => { + el.focus(); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ type: '5' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(lastInputValue, 'last input value').to.equal(10); + expect(lastChangeValue, 'last change value').to.equal( + 0, + 'value does not change from initial value so no "change" event is dispatched' + ); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + el.focus(); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ type: '-2000' }); + await sendKeys({ press: 'Enter' }); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('dispatches onchange on setting min value', async () => { + el.value = 15; + await elementUpdated(el); + expect(changeSpy.callCount).to.equal(0); + expect(el.value).to.equal(15); + el.focus(); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: '5' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.value).to.equal(10); + expect(inputSpy.callCount).to.equal(3); + expect(changeSpy.callCount).to.equal(1); + expect(lastChangeValue, 'last change value').to.equal(10); + }); + xit('manages `inputMode` in iPad', async () => { + // setUserAgent is not currently supported by Playwright + await setUserAgent( + 'Mozilla/5.0 (iPad; CPU OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile15E148 Safari/604.1' + ); + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.min = -10; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.min = undefined; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.formatOptions = { + minimumFractionDigits: 1, + maximumFractionDigits: 2, + }; + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('decimal'); + }); + xit('manages `inputMode` in iPhone', async () => { + // setUserAgent is not currently supported by Playwright + await setUserAgent( + 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148' + ); + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.min = -10; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('text'); + el.min = undefined; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('text'); + el.formatOptions = { + minimumFractionDigits: 1, + maximumFractionDigits: 2, + }; + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('decimal'); + }); + xit('manages `inputMode` in Android', async () => { + // setUserAgent is not currently supported by Playwright + await setUserAgent( + 'Mozilla/5.0 (Linux; Android 10; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.210 Mobile Safari/537.36' + ); + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.min = -10; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.min = undefined; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + el.formatOptions = { + minimumFractionDigits: 1, + maximumFractionDigits: 2, + }; + el.min = 0; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('decimal'); + el.formatOptions = { + minimumFractionDigits: 1, + maximumFractionDigits: 2, + }; + el.min = -10; + await elementUpdated(el); + expect(el.focusElement.inputMode).to.equal('numeric'); + }); + it('constrains `value`', async () => { + el.value = 0; + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('constrains ArrowDown usage', async () => { + el.min = 0; + el.value = 0; + expect(el.value).to.equal(0); + el.focus(); + await sendKeys({ press: 'ArrowDown' }); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + await sendKeys({ press: 'Shift+ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + }); + it('constrains pointer usage', async () => { + el.min = 0; + el.value = 0; + await elementUpdated(el); + expect(el.value).to.equal(0); + const buttonDown = el.shadowRoot.querySelector( + '.step-down' + ) as HTMLElement; + await mouseClickOn(buttonDown); + await elementUpdated(el); + expect(el.value).to.equal(0); + }); + it('validates on commit', async () => { + el.focus(); + await sendKeys({ press: '0' }); + await sendKeys({ press: 'Enter' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + }); + it('disabled `stepDown` button', async () => { + await clickBySelector(el, '.step-down'); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('validates late', async () => { + el.min = 15; + await elementUpdated(el); + expect(el.formattedValue).to.equal('15'); + expect(el.valueAsString).to.equal('15'); + expect(el.value).to.equal(15); + }); + }); + describe('step', () => { + let el: NumberField; + beforeEach(async () => { + el = await getElFrom(Default({ value: 10, step: 5 })); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('via arrow up', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('15'); + expect(el.valueAsString).to.equal('15'); + expect(el.value).to.equal(15); + }); + it('via arrow down', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.value).to.equal(5); + }); + it('step up via pointer', async () => { + await clickBySelector(el, '.step-up'); + expect(el.formattedValue).to.equal('15'); + expect(el.valueAsString).to.equal('15'); + expect(el.value).to.equal(15); + }); + it('step down via pointer', async () => { + await clickBySelector(el, '.step-down'); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.value).to.equal(5); + }); + }); + describe('step + constraints', () => { + let el: NumberField; + beforeEach(async () => { + el = await getElFrom(Default({ step: 5 })); + expect(el.formattedValue).to.equal(''); + expect(el.valueAsString).to.equal('NaN'); + expect(el.value).to.be.NaN; + }); + it('steps', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('0'); + expect(el.valueAsString).to.equal('0'); + expect(el.value).to.equal(0); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.value).to.equal(5); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + }); + it('steps from min', async () => { + el.min = 5; + await elementUpdated(el); + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('5'); + expect(el.valueAsString).to.equal('5'); + expect(el.value).to.equal(5); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('10'); + expect(el.valueAsString).to.equal('10'); + expect(el.value).to.equal(10); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('15'); + expect(el.valueAsString).to.equal('15'); + expect(el.value).to.equal(15); + }); + it('steps from mismatched min', async () => { + el.min = 2; + await elementUpdated(el); + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('2'); + expect(el.valueAsString).to.equal('2'); + expect(el.value).to.equal(2); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('7'); + expect(el.valueAsString).to.equal('7'); + expect(el.value).to.equal(7); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('12'); + expect(el.valueAsString).to.equal('12'); + expect(el.value).to.equal(12); + }); + it('steps to mismatched max', async () => { + el.min = 2; + el.max = 10; + await elementUpdated(el); + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('2'); + expect(el.valueAsString).to.equal('2'); + expect(el.value).to.equal(2); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('7'); + expect(el.valueAsString).to.equal('7'); + expect(el.value).to.equal(7); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('7'); + expect(el.valueAsString).to.equal('7'); + expect(el.value).to.equal(7); + }); + it('validates max + step', async () => { + el.value = 2; + el.min = 2; + el.max = 10; + await elementUpdated(el); + expect(el.formattedValue).to.equal('2'); + expect(el.valueAsString).to.equal('2'); + expect(el.value).to.equal(2); + el.value = 11; + await elementUpdated(el); + expect(el.formattedValue).to.equal('7'); + expect(el.valueAsString).to.equal('7'); + expect(el.value).to.equal(7); + el.value = 27; + await elementUpdated(el); + expect(el.formattedValue).to.equal('7'); + expect(el.valueAsString).to.equal('7'); + expect(el.value).to.equal(7); + }); + }); + describe('indeterminate', () => { + let el: NumberField; + beforeEach(async () => { + el = await getElFrom(indeterminate(indeterminate.args)); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(indeterminatePlaceholder); + }); + it('remove "-" on focus', async () => { + el.focus(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(''); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(indeterminatePlaceholder); + }); + it('return to "-" after suplied value is removed', async () => { + el.focus(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(''); + await sendKeys({ type: '50' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('50'); + expect(el.valueAsString).to.equal('50'); + expect(el.value).to.equal(50); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('50'); + await sendKeys({ press: 'Backspace' }); + await sendKeys({ press: 'Backspace' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(''); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('100'); + expect(el.valueAsString).to.equal('100'); + expect(el.value).to.equal(100); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal(indeterminatePlaceholder); + }); + it('starts from `value` on "ArrowUp" keypresses', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowUp' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('101'); + expect(el.valueAsString).to.equal('101'); + expect(el.value).to.equal(101); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('101'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('101'); + expect(el.valueAsString).to.equal('101'); + expect(el.value).to.equal(101); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('101'); + }); + it('starts from `value` on click `.step-up`', async () => { + el.focus(); + await elementUpdated(el); + await clickBySelector(el, '.step-up'); + await elementUpdated(el); + expect(el.formattedValue).to.equal('101'); + expect(el.valueAsString).to.equal('101'); + expect(el.value).to.equal(101); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('101'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('101'); + expect(el.valueAsString).to.equal('101'); + expect(el.value).to.equal(101); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('101'); + }); + it('starts from `value` on "ArrowDown" keypresses', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'ArrowDown' }); + await elementUpdated(el); + expect(el.formattedValue).to.equal('99'); + expect(el.valueAsString).to.equal('99'); + expect(el.value).to.equal(99); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('99'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('99'); + expect(el.valueAsString).to.equal('99'); + expect(el.value).to.equal(99); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('99'); + }); + it('starts from `value` on click `.step-down`', async () => { + el.focus(); + await elementUpdated(el); + await clickBySelector(el, '.step-down'); + await elementUpdated(el); + expect(el.formattedValue).to.equal('99'); + expect(el.valueAsString).to.equal('99'); + expect(el.value).to.equal(99); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('99'); + el.blur(); + await elementUpdated(el); + expect(el.formattedValue).to.equal('99'); + expect(el.valueAsString).to.equal('99'); + expect(el.value).to.equal(99); + expect( + (el as unknown as { displayValue: string }).displayValue + ).to.equal('99'); + }); + }); + it('removes the stepper UI with [hide-stepper]', async () => { + const el = await getElFrom(Default({ hideStepper: true })); + const stepUp = el.shadowRoot.querySelector('.step-up'); + const stepDown = el.shadowRoot.querySelector('.step-down'); + expect(stepUp).to.be.null; + expect(stepDown).to.be.null; + }); + describe('Disabled', () => { + let el: NumberField; + beforeEach(async () => { + el = await getElFrom(Default({ disabled: true, value: 1337 })); + expect(el.formattedValue).to.equal('1,337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + el.focus(); + await elementUpdated(el); + }); + afterEach(async () => { + await elementUpdated(el); + expect(el.formattedValue).to.equal('1,337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + }); + it('presents as `disabled`', async () => { + await sendKeys({ type: '12345' }); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + }); + it('prevents increment via keyboard', async () => { + await sendKeys({ press: 'ArrowUp' }); + }); + it('prevents decrement via keyboard', async () => { + await sendKeys({ press: 'ArrowDown' }); + }); + it('prevents increment via scroll', async () => { + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 1 })); + }); + it('prevents decrement via scroll', async () => { + el.dispatchEvent(new WheelEvent('wheel', { deltaY: -1 })); + }); + it('prevents increment via stepper button', async () => { + await clickBySelector(el, '.step-up'); + }); + it('prevents decrement via stepper button', async () => { + await clickBySelector(el, '.step-down'); + }); + }); + describe('Readonly', () => { + let el: NumberField; + beforeEach(async () => { + el = await getElFrom(Default({ readonly: true, value: 1337 })); + expect(el.formattedValue).to.equal('1,337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + el.focus(); + await elementUpdated(el); + }); + afterEach(async () => { + await elementUpdated(el); + expect(el.formattedValue).to.equal('1,337'); + expect(el.valueAsString).to.equal('1337'); + expect(el.value).to.equal(1337); + }); + it('presents as `readonly`', async () => { + await sendKeys({ type: '12345' }); + await elementUpdated(el); + await sendKeys({ press: 'Enter' }); + }); + it('prevents increment via keyboard', async () => { + await sendKeys({ press: 'ArrowUp' }); + }); + it('prevents decrement via keyboard', async () => { + await sendKeys({ press: 'ArrowDown' }); + }); + it('prevents increment via scroll', async () => { + el.dispatchEvent(new WheelEvent('wheel', { deltaY: 1 })); + }); + it('prevents decrement via scroll', async () => { + el.dispatchEvent(new WheelEvent('wheel', { deltaY: -1 })); + }); + it('prevents increment via stepper button', async () => { + await clickBySelector(el, '.step-up'); + }); + it('prevents decrement via stepper button', async () => { + await clickBySelector(el, '.step-down'); + }); + }); + describe('accessibility model', () => { + it('increment and decrement buttons cannot receive keyboard focus', async () => { + // @TODO: skipping this test because it's flaky in WebKit in CI. Will review in the migration to Spectrum 2. + if (isWebKit()) { + return; + } + await fixture(html` +
+ ${Default({ + onChange: () => { + return; + }, + })} +
+ `); + + type NamedNode = { name: string }; + const snapshot = (await a11ySnapshot( + {} + )) as unknown as NamedNode & { + children: NamedNode[]; + }; + + expect( + findAccessibilityNode( + snapshot, + (node) => node.name === 'Increase Enter a number' + ), + '`name` is the label text' + ).to.be.null; + + expect( + findAccessibilityNode( + snapshot, + (node) => node.name === 'Decrease Enter a number' + ), + '`name` is the label text' + ).to.be.null; + }); + }); +}); diff --git a/1st-gen/packages/number-field/tsconfig.json b/1st-gen/packages/number-field/tsconfig.json new file mode 100644 index 00000000000..ea47de31ac0 --- /dev/null +++ b/1st-gen/packages/number-field/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }, { "path": "../textfield" }] +} diff --git a/1st-gen/packages/overlay/.npmrc b/1st-gen/packages/overlay/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/overlay/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/overlay/CHANGELOG.md b/1st-gen/packages/overlay/CHANGELOG.md new file mode 100644 index 00000000000..7222afdd452 --- /dev/null +++ b/1st-gen/packages/overlay/CHANGELOG.md @@ -0,0 +1,1073 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/action-button@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + - @spectrum-web-components/theme@1.9.0 + +## 1.8.0 + +### Minor Changes + +- [#5670](https://github.com/adobe/spectrum-web-components/pull/5670) [`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Added `allow-outside-click` property to `` with deprecation notice. This property allows clicks outside the overlay to close it, but is not recommended for accessibility reasons and will be removed in a future version. + + This property is being added as deprecated to support the fallback for `showModal()` which was removed as part of performance optimization. We will no longer support outside clicks for modal overlays as they violate accessibility guidelines. + + The property defaults to `false` and shows deprecation warnings when used. Consider using explicit close buttons or modal/page overlay types instead for better accessibility. + +- [#5710](https://github.com/adobe/spectrum-web-components/pull/5710) [`ee1bae6`](https://github.com/adobe/spectrum-web-components/commit/ee1bae6f9a7401dc31ebc84e4e27f9d39be692d1) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixed** : Added body scroll prevention for modal and page overlays. Overlay automatically blocks body scroll when modal or page overlays are open and restores the original scroll state when they are closed, improving user experience and accessibility for modal dialogs. + +- [#5670](https://github.com/adobe/spectrum-web-components/pull/5670) [`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixed** : external click registration behavior in the `sp-overlay` component. Programmatic clicks on elements outside of modal overlays now properly register and close the overlay, while user-initiated clicks are prevented from doing so. + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/theme@1.8.0 + - @spectrum-web-components/action-button@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Minor Changes + +- [#5477](https://github.com/adobe/spectrum-web-components/pull/5477) [`a646ae8`](https://github.com/adobe/spectrum-web-components/commit/a646ae8b0e652308d359226740d2cb189e492e45) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixed** : Overlays (like pickers and action menus) were incorrectly closing when scrolling occurred within components. The fix ensures the `handleScroll` method in `OverlayStack` only responds to document/body scrolling events and ignores component-level scrolling events, which was the original intention. + +### Patch Changes + +- Updated dependencies [[`c1669d2`](https://github.com/adobe/spectrum-web-components/commit/c1669d2dc5e1ceeb84486ce49a428f86a3173caa)]: + - @spectrum-web-components/action-button@1.7.0 + - @spectrum-web-components/theme@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5392](https://github.com/adobe/spectrum-web-components/pull/5392) [`53f3769`](https://github.com/adobe/spectrum-web-components/commit/53f3769f07b6e7853a8a4c0dc63b21fe14cf3d4b) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - Fixed layout issues in Safari when an `sp-tray` is nested inside a dialog-type `sp-overlay`. + +- Updated dependencies []: + - @spectrum-web-components/action-button@1.6.0 + - @spectrum-web-components/theme@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Minor Changes + +- [#5308](https://github.com/adobe/spectrum-web-components/pull/5308) [`8f8735c`](https://github.com/adobe/spectrum-web-components/commit/8f8735c9ec3eac3b6473424c78257cb46ee17f70) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - prevent overlay close on document scroll + +### Patch Changes + +- Updated dependencies [[`6c58f50`](https://github.com/adobe/spectrum-web-components/commit/6c58f50f7b1f5489c11e0d3484e3f4a9d576f1c8)]: + - @spectrum-web-components/action-button@1.5.0 + - @spectrum-web-components/theme@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Minor Changes + +- [#5223](https://github.com/adobe/spectrum-web-components/pull/5223) [`46cd782`](https://github.com/adobe/spectrum-web-components/commit/46cd7828f65491fc08790e5ba0aec412ee89199d) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Removed pointer-events:none from the slot-trigger under overlay-trigger to disable the overlay content and not the trigger element. + +- [#5248](https://github.com/adobe/spectrum-web-components/pull/5248) [`70f5f6f`](https://github.com/adobe/spectrum-web-components/commit/70f5f6f3a97b530fb20f9f5ee049e9a8c124b02d) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - overlay type auto stays open when interacting with elements inside + +### Patch Changes + +- Updated dependencies [[`72dbe62`](https://github.com/adobe/spectrum-web-components/commit/72dbe629cddfc57171eaaadf7206df47c19d3c98)]: + - @spectrum-web-components/action-button@1.4.0 + - @spectrum-web-components/theme@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- [#5176](https://github.com/adobe/spectrum-web-components/pull/5176) [`468314f`](https://github.com/adobe/spectrum-web-components/commit/468314f45cf5fedb2e9029da210a5886260abca9) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - 1. chore(checkbox): updated to latest css v10.1.1 for s2 fast follow 2. chore(dialog): + The error property was not properly deprecated with a full migration plan in place. This has caused confusion and false sense of urgency for consumers to migrate. We are removing it to eliminate those pain points for consumers while we take a deep look at our dialogs and patterns. 3. chore(menu): updated to latest css v9.1.1 for s2 fast follow 4. fix(overlay): + sp-overlay with type="manual" should close on pressing ESC key. When the last item is on overlay stack we are triggering the close method on esc key event. + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/action-button@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + - @spectrum-web-components/theme@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +### Bug Fixes + +- **action menu:** keyboard accessibility omnibus ([#5031](https://github.com/adobe/spectrum-web-components/issues/5031)) ([ea38ef0](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)), closes [#4623](https://github.com/adobe/spectrum-web-components/issues/4623) + +### Features + +- **overlay:** add triggeredBy property to overlay-trigger for performance optimization ([#5046](https://github.com/adobe/spectrum-web-components/issues/5046)) ([fd504aa](https://github.com/adobe/spectrum-web-components/commit/fd504aa4c83d6961abfb7db955483bf1ede6734f)) + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +### Bug Fixes + +- **picker:** stop the click events from reaching the elements below picker-tray ([#5060](https://github.com/adobe/spectrum-web-components/issues/5060)) ([7e4fdbf](https://github.com/adobe/spectrum-web-components/commit/7e4fdbf3e4487b4c148368b852129b85f88a620b)) + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +### Bug Fixes + +- **overlay:** make :focus-visible consistent when using overlay type modal ([#4912](https://github.com/adobe/spectrum-web-components/issues/4912)) ([7a5f786](https://github.com/adobe/spectrum-web-components/commit/7a5f786819ff200f5ae2648e2e2c4db3729050a2)), closes [#5021](https://github.com/adobe/spectrum-web-components/issues/5021) + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- **overlay:** make :focus-visible consistent when using overlay type modal ([#4912](https://github.com/adobe/spectrum-web-components/issues/4912)) ([7a5f786](https://github.com/adobe/spectrum-web-components/commit/7a5f786819ff200f5ae2648e2e2c4db3729050a2)), closes [#5021](https://github.com/adobe/spectrum-web-components/issues/5021) + +### Features + +- add an optional chromatic vrt action ([7d2f840](https://github.com/adobe/spectrum-web-components/commit/7d2f8401cb05c5e23872424f132a1a8edd95b666)) +- **picker:** add forcePopover property ([#5041](https://github.com/adobe/spectrum-web-components/issues/5041)) ([3651e57](https://github.com/adobe/spectrum-web-components/commit/3651e57a90a05e551e6ee650e8ccc73aa05d3e7c)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +### Bug Fixes + +- **overlay:** overlay scroll in safari and firefox ([#4969](https://github.com/adobe/spectrum-web-components/issues/4969)) ([05d24ff](https://github.com/adobe/spectrum-web-components/commit/05d24ffc4dc8e9b0281b90c768b7f983fe890def)) + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **overlay:** ensure smooth animation when opening modal overlays ([#4879](https://github.com/adobe/spectrum-web-components/issues/4879)) ([cd8dad7](https://github.com/adobe/spectrum-web-components/commit/cd8dad7b08c822a8224834b8775b0ab74bbaf3b6)) +- **overlay:** overlay closing another overlay ([#4880](https://github.com/adobe/spectrum-web-components/issues/4880)) ([30434fa](https://github.com/adobe/spectrum-web-components/commit/30434fa52194884befd528ab88842092798859cc)) +- **overlay:** remove flex display for dialog ([#4902](https://github.com/adobe/spectrum-web-components/issues/4902)) ([48448ea](https://github.com/adobe/spectrum-web-components/commit/48448ea75d7ffa61422947a18c3ea1ebf9ca25b7)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +### Features + +- **breadcrumbs:** add Breadcrumbs component ([#4578](https://github.com/adobe/spectrum-web-components/issues/4578)) ([acd4b5e](https://github.com/adobe/spectrum-web-components/commit/acd4b5e4401dad8cf26b50ee5dcda80a28b62999)) + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +### Bug Fixes + +- **overlay** replace at() polyfill ([#4628](https://github.com/adobe/spectrum-web-components/issues/4628)) ([8cef2c6](https://github.com/adobe/spectrum-web-components/commit/8cef2c639433248257a72bfc2c98d0663e265b09)) + **Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +### Bug Fixes + +- **coachmark,overlay:** adjust imports of overlay and coachmark ([#4455](https://github.com/adobe/spectrum-web-components/issues/4455)) ([39706da](https://github.com/adobe/spectrum-web-components/commit/39706dafe58a598a86d7dc33629409f086a9694e)) +- **overlay:** ensure hint Overlays within shadow roots open as expected ([#4443](https://github.com/adobe/spectrum-web-components/issues/4443)) ([7dd64b9](https://github.com/adobe/spectrum-web-components/commit/7dd64b92e58ad2fd3a36986f24022728e3cb4c36)) +- **overlay:** ensure that passing "open" to the directive manages a single strategy ([#4474](https://github.com/adobe/spectrum-web-components/issues/4474)) ([15d6ac7](https://github.com/adobe/spectrum-web-components/commit/15d6ac71d586eb496b591fa5b097707961600f75)) +- **overlay:** persist "host" in directive rendered Overlay content ([#4475](https://github.com/adobe/spectrum-web-components/issues/4475)) ([5d189c2](https://github.com/adobe/spectrum-web-components/commit/5d189c2adf91545eb64a0136fa02d7c8caee8f48)) + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **action-menu:** allow menu groups to handle their own selections ([#4397](https://github.com/adobe/spectrum-web-components/issues/4397)) ([5a19051](https://github.com/adobe/spectrum-web-components/commit/5a190518814f85cfd2e345ad6a0add1378c05bf4)) +- **base:** move lit imports to base ([#4416](https://github.com/adobe/spectrum-web-components/issues/4416)) ([b7cb07e](https://github.com/adobe/spectrum-web-components/commit/b7cb07e98e17754c83d3e0112aac9728139e043b)) +- **overlay:** prevent "receivesFocus=false" overlays from returning focus ([607819f](https://github.com/adobe/spectrum-web-components/commit/607819f053113a21cccfbc97d775551ef11bfc4a)) +- **slider,overlay:** ensure that pointer events in Slider are handled as expected in Overlay ([#4438](https://github.com/adobe/spectrum-web-components/issues/4438)) ([db193e8](https://github.com/adobe/spectrum-web-components/commit/db193e84d1ee300faaed47a5a4026b73a8d9fb30)) +- **styles,theme:** add S2 tokens and theme ([#4241](https://github.com/adobe/spectrum-web-components/issues/4241)) ([a29e4a2](https://github.com/adobe/spectrum-web-components/commit/a29e4a298090e39e009c434e48113fb8a7e90d14)), closes [#4232](https://github.com/adobe/spectrum-web-components/issues/4232) [#4228](https://github.com/adobe/spectrum-web-components/issues/4228) +- **theme:** deprecate `theme` property for `system` ([#4230](https://github.com/adobe/spectrum-web-components/issues/4230)) ([ac26168](https://github.com/adobe/spectrum-web-components/commit/ac2616878e90314e5ed307442ac026c9e4ac707a)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +### Bug Fixes + +- **overlay:** prevent "receivesFocus=false" overlays from returning focus ([607819f](https://github.com/adobe/spectrum-web-components/commit/607819f053113a21cccfbc97d775551ef11bfc4a)) +- **theme:** deprecate `theme` property for `system` ([#4230](https://github.com/adobe/spectrum-web-components/issues/4230)) ([ac26168](https://github.com/adobe/spectrum-web-components/commit/ac2616878e90314e5ed307442ac026c9e4ac707a)) + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **overlay:** prevent focus based hover interaction without :focus-visible ([79337ff](https://github.com/adobe/spectrum-web-components/commit/79337ff0c8df69203877732ce0541d9f1d49f33d)) +- **overlay:** prioritize non-"hint" Overlays on the same trigger ([b9833f3](https://github.com/adobe/spectrum-web-components/commit/b9833f3e22cfc89c34a98bd235c30f207b013781)) +- **picker:** add loading state to the picker ([#3110](https://github.com/adobe/spectrum-web-components/issues/3110)) ([d91e2c9](https://github.com/adobe/spectrum-web-components/commit/d91e2c9f3530c3c911832ea3a401fddc23e7854a)) +- **styles, theme:** surface exports that omit Spectrum Vars proactively ([#4142](https://github.com/adobe/spectrum-web-components/issues/4142)) ([5b524c1](https://github.com/adobe/spectrum-web-components/commit/5b524c1d54a64225cb3b2f71b92f581695985519)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +### Bug Fixes + +- **overlay:** ensure "manual" Overlays ignore "light dismiss" when [popover] is not supported ([#4121](https://github.com/adobe/spectrum-web-components/issues/4121)) ([eb5e1ad](https://github.com/adobe/spectrum-web-components/commit/eb5e1ad78ebde99443929aa985a38297ebb16f4e)) +- **overlay:** leverage "transition-behavior" to persist top-layer content while closing ([#4050](https://github.com/adobe/spectrum-web-components/issues/4050)) ([e3dea14](https://github.com/adobe/spectrum-web-components/commit/e3dea14fa382b4e02f61ae8b651e89cd92c348f8)) +- **slider:** double click on slider handle to reset slider position ([#3991](https://github.com/adobe/spectrum-web-components/issues/3991)) ([64c594a](https://github.com/adobe/spectrum-web-components/commit/64c594a7c305bd4946bb5801341366a1e751a614)) + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Bug Fixes + +- support generating random IDs outside of secure contexts ([485a67c](https://github.com/adobe/spectrum-web-components/commit/485a67c5401094705b711350f8ee74182a6dd64b)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +### Bug Fixes + +- **overlay:** clean position data on close ([edac590](https://github.com/adobe/spectrum-web-components/commit/edac59003ecc1af8dc4aa91c00c9593e8792e63f)) + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +### Bug Fixes + +- **overlay:** automatically reposition overlay when the contents resize ([83be807](https://github.com/adobe/spectrum-web-components/commit/83be807996ace4609486cc9d3bbf1723b3a531ad)) +- **overlay:** move closed overlays to "display: none" ([fc0278b](https://github.com/adobe/spectrum-web-components/commit/fc0278b917759ed58c3ac62a6e962633914481c0)) +- **overlay:** normalize popover toggling between native and synthetic [popover] usage ([26fa692](https://github.com/adobe/spectrum-web-components/commit/26fa6925f7f88959ba4d969c882daf7cb881c2d4)) +- **overlay:** support positioning overlays within parents leveraging container-type rules ([21044b3](https://github.com/adobe/spectrum-web-components/commit/21044b3c8b5bed0af02f836b6ee6796554a90325)) +- **overlay:** surface "overlay" property to "sp-opened" and "sp-closed" events ([957f8e9](https://github.com/adobe/spectrum-web-components/commit/957f8e9b42f5ad4672fe128fc42693d0065bb2d5)) + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +### Bug Fixes + +- **overlay:** ensure events are only bound once ([abe57ce](https://github.com/adobe/spectrum-web-components/commit/abe57cedcc18a309f3acf1b664bfa561f13b4f8f)) + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +### Bug Fixes + +- **overlay:** ensure manual overlays persist through interactions outside of their subtree ([#3788](https://github.com/adobe/spectrum-web-components/issues/3788)) ([ef5617f](https://github.com/adobe/spectrum-web-components/commit/ef5617f81b205b8bcf0a79e2b8a810cc65f13c3d)) + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **overlay:** add delay resolution from overlaid content ([#3748](https://github.com/adobe/spectrum-web-components/issues/3748)) ([5c4f1f6](https://github.com/adobe/spectrum-web-components/commit/5c4f1f6f87cac60cb1884f59aa29d256f7baabb8)) +- **overlay:** calculate more transforms ([6538a45](https://github.com/adobe/spectrum-web-components/commit/6538a45a036f60c4efce4c3ed3d1d6f2782a188e)) +- **overlay:** place longpress helper content in a more accessible, less layout affecting location ([dd12c23](https://github.com/adobe/spectrum-web-components/commit/dd12c2346142a107ee9c7824410dff5ae660e574)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +### Bug Fixes + +- **overlay:** allow overlay to persist on hover ([#3706](https://github.com/adobe/spectrum-web-components/issues/3706)) ([7707040](https://github.com/adobe/spectrum-web-components/commit/77070405fdb0d6a2bca5d5e33fe03a856f1cef6c)) + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **overlay:** allow "receives-focus" to target the root of an overlay ([#3658](https://github.com/adobe/spectrum-web-components/issues/3658)) ([0db1025](https://github.com/adobe/spectrum-web-components/commit/0db10258d84409d364b5e1bad57e71683de93fea)) +- **overlay:** ensure position when closing overlays over the top-layer ([55fab0d](https://github.com/adobe/spectrum-web-components/commit/55fab0d49047c64849ed9c8001b79b793440da48)) +- **overlay:** reduce circular dependencies ([25eeb71](https://github.com/adobe/spectrum-web-components/commit/25eeb7138b19ba0c1a6543d1f37c4e8cea2cdbd6)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- **action-menu:** added static attribute support ([#3573](https://github.com/adobe/spectrum-web-components/issues/3573)) ([25889a8](https://github.com/adobe/spectrum-web-components/commit/25889a808d6dcf11779d5c716f1b7522050ddf2b)) +- **overlay:** position for transformed and contained parents ([ca8fd8a](https://github.com/adobe/spectrum-web-components/commit/ca8fd8a48a5f4b7bbc97b5641082cf48f6869529)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +### Bug Fixes + +- address margin effected positioning ([38c8cf2](https://github.com/adobe/spectrum-web-components/commit/38c8cf2dd3f3b45a61062e3cd9b7480f903fae97)) +- ensure submenus stay open when root it clicked again ([83ced1c](https://github.com/adobe/spectrum-web-components/commit/83ced1c913f262620e7b87ad3b7e58dff0697442)) +- handle longpress and over filter overlays ([483e52d](https://github.com/adobe/spectrum-web-components/commit/483e52df24f56be027d8417c1ae530211ef0deb1)) + +### Features + +- **overlay:** ship Overlay API v2 ([67b5d1b](https://github.com/adobe/spectrum-web-components/commit/67b5d1b02e88dcb5b0b79b5a6c5ead92ad1a5aca)) + +### Performance Improvements + +- make lots of things lazy ([b8fa3ad](https://github.com/adobe/spectrum-web-components/commit/b8fa3ada062bf54bbb42e76ab156c716d5820c7c)) +- open/close timing update ([d4ebcd3](https://github.com/adobe/spectrum-web-components/commit/d4ebcd36ed5a256f211186e6863c3eee2631fa3f)) + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Bug Fixes + +- **overlay:** ensure CSS calcs resolve to the expected measurement value ([51a3feb](https://github.com/adobe/spectrum-web-components/commit/51a3feb2a42300de369aba06d7ec1eea92ffbd19)) + +### Features + +- **popover:** use core tokens ([68328cc](https://github.com/adobe/spectrum-web-components/commit/68328ccd01f44758caf987e02a17d88488f9046c)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +### Bug Fixes + +- **overlay:** address review comments ([dd8b985](https://github.com/adobe/spectrum-web-components/commit/dd8b98524b5124267531a40b35d6cf542006c7a0)) +- **overlay:** removes use of px units in overlay stack ([122f96c](https://github.com/adobe/spectrum-web-components/commit/122f96c06ac2b5349acff0497fed1697264958f8)) +- **overlay:** stop the tab trapping if shadow root is not found ([4f0ec46](https://github.com/adobe/spectrum-web-components/commit/4f0ec464bcc807e3a789bb5fd323b468d978e4a2)) + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) +- add content flow fallbacks to the position manager ([c008957](https://github.com/adobe/spectrum-web-components/commit/c0089571be599577f75b2fe7929b8ee26529358d)) +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- allow contextmenu event passing to pierce shadow roots ([05b69e9](https://github.com/adobe/spectrum-web-components/commit/05b69e90a56676c44e4757a6c2e19e6fe333b145)) +- allow detached elements to be used as content for an overlay ([3ad8383](https://github.com/adobe/spectrum-web-components/commit/3ad83837b6c9a693a4fc24501e3fc7fb2383a12b)) +- allow Picker to be reparented ([39e7309](https://github.com/adobe/spectrum-web-components/commit/39e73094be38888599fb189ed4d613f09476310f)) +- centralize updated first focusable selector ([300e84c](https://github.com/adobe/spectrum-web-components/commit/300e84c404d031ddad92b4952e48ad3332c4aafd)) +- close modal overlays with contextmenu events and pass those to the underlying page ([9e83f3c](https://github.com/adobe/spectrum-web-components/commit/9e83f3c0d2398323ebe941ba253d7a0dc0f40ba6)) +- constrain overlay to available window size ([9729b55](https://github.com/adobe/spectrum-web-components/commit/9729b55ef5246662aa50cbc8037bcaeb2f4ac74a)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- correct add/remove timing of overlay events ([474ec6e](https://github.com/adobe/spectrum-web-components/commit/474ec6e85840dc1efee8b134cc6e6163f228920f)) +- correct overlay closure order or operations for manual override ([0b7a8c4](https://github.com/adobe/spectrum-web-components/commit/0b7a8c42866ae4f2d38d90fa7b6dc34ed2c21759)) +- correct the relationship between overlayWillCloseCallback and phased animations ([c63db8d](https://github.com/adobe/spectrum-web-components/commit/c63db8d2ea4c942fbd52c6d5239ddd3f1ccea5b0)) +- delete the used cleanup method ([942ef0f](https://github.com/adobe/spectrum-web-components/commit/942ef0fdc6e7c89e4f554e032c7b9fb760ca47a0)) +- describe longpress button to screen readers ([acdcaf4](https://github.com/adobe/spectrum-web-components/commit/acdcaf49adbc701381bfdf1f95f12ab42f791a67)) +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) +- **dropdown:** correct conditional check ([a3a790f](https://github.com/adobe/spectrum-web-components/commit/a3a790f6c3f5f8f0837d619ca57c1090ab14e638)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- ensure focus is managed when tabbing out of a menu ([9bfa81d](https://github.com/adobe/spectrum-web-components/commit/9bfa81d8a677d6c0ab5ac5cd618498496761c69b)) +- ensure Overlay.update bypasses the auto close mechanism ([8f2aa2e](https://github.com/adobe/spectrum-web-components/commit/8f2aa2e98507298182356e8ea62e384680aedd2c)) +- ensure that an overlay can be released even if it does not complete its fade in animation ([4cbb36f](https://github.com/adobe/spectrum-web-components/commit/4cbb36f91569ce9b7f926437142950fc8fbd59f9)) +- ensure that entering an ancestor Menu Item without a submen closes related submenus ([efe5fa1](https://github.com/adobe/spectrum-web-components/commit/efe5fa1ff50c45487f370847444b940e1d6d8a4e)) +- expand sync offering for elements with overlay content ([0195843](https://github.com/adobe/spectrum-web-components/commit/0195843e9efac5760a78fa302d91139c84ea5747)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include sync builds in publication configuration ([e731673](https://github.com/adobe/spectrum-web-components/commit/e731673e7d171af667fc87c5b6e521450143e8fe)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- keep parent overlays open when not closing child hover overlays ([643fcff](https://github.com/adobe/spectrum-web-components/commit/643fcff10b6e455611fda76040ea0d29ecac5df9)) +- leverage "dvh" rather than measured screen height ([84b9df0](https://github.com/adobe/spectrum-web-components/commit/84b9df0d101d9870a1b0c20eb34ba33fcdd0fbe1)) +- manage "lang" via context provided by "sp-theme" ([b1e3457](https://github.com/adobe/spectrum-web-components/commit/b1e3457ae447427c54f8645c478866340329750c)) +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) +- **overlay:** add overlay lifecycle methods to stack management ([9361527](https://github.com/adobe/spectrum-web-components/commit/9361527bc63896bcee2933d96b5021aa74386057)) +- **overlay:** allow [type="modal"] hover overlays to be closed ([5a6802b](https://github.com/adobe/spectrum-web-components/commit/5a6802bc06869cd255bdbfcc460f836c247f01fb)) +- **overlay:** allow external style access to "sp-theme" elements in overlays as a CSS part ([a107f66](https://github.com/adobe/spectrum-web-components/commit/a107f66ae171e857e5f84cfff9f7a27cc5bd320d)) +- **overlay:** allow overlay-trigger to declaratively open overlay content ([194a44e](https://github.com/adobe/spectrum-web-components/commit/194a44e78df73ca4a5520e24b308667c23331880)) +- **overlay:** close when overlay-trigger becomes [disabled] ([6f27e25](https://github.com/adobe/spectrum-web-components/commit/6f27e25658dd23949ef07c6df72c43768651482b)) +- **overlay:** correct overlay content sizing ([d9bcd6f](https://github.com/adobe/spectrum-web-components/commit/d9bcd6fd6b4eecae297c6e5cc5330e79a9e198ff)) +- **overlay:** do not focus the trigger when closing an overlay, unless expected ([21d7dfe](https://github.com/adobe/spectrum-web-components/commit/21d7dfeaa94919586bede27a9c7ae077a2d214a5)) +- **overlay:** enforce the full frame ([63628e9](https://github.com/adobe/spectrum-web-components/commit/63628e93de2daec632025f2659a86ff18e487a8e)) +- **overlay:** ensure overlay addition occurs after closing previous ([7d2b102](https://github.com/adobe/spectrum-web-components/commit/7d2b102f30731513639582fed8ed0e1b46d569cf)) +- **overlay:** ensure undefined data is not passed into theme ([3e2e1ca](https://github.com/adobe/spectrum-web-components/commit/3e2e1caa4c37eedf6e569b5124c9e59f207bb92f)) +- **overlay:** export OverlayTriggerInteractions type ([4caec7f](https://github.com/adobe/spectrum-web-components/commit/4caec7f33ec97ba7b21239c0be739b56885dac0a)) +- **overlay:** extend state machine to manage disposal process ([f0f26af](https://github.com/adobe/spectrum-web-components/commit/f0f26afef2870cf545afa120c8ece076ed241f21)) +- **overlay:** focus closure action on ancestor scroll, not participant resize ([925af0a](https://github.com/adobe/spectrum-web-components/commit/925af0af345fd0b9dc532efff052ac26ebdde80b)) +- **overlay:** handle hover/longpress more directly via the "open" attribute ([7b2b64b](https://github.com/adobe/spectrum-web-components/commit/7b2b64b6be931381a1ca1c83f941677fa06750ff)) +- **overlay:** init tab trapping on OverlayStack construction ([a3121e3](https://github.com/adobe/spectrum-web-components/commit/a3121e38df47fb528f8366cdb68e83417d78dc95)) +- **overlay:** measure initial overlay data offscreen ([fecda5a](https://github.com/adobe/spectrum-web-components/commit/fecda5a6f8e34261776c2d71c1f001c0cd76c3ce)) +- **overlay:** move "escape" listener to "keydown" ([813b341](https://github.com/adobe/spectrum-web-components/commit/813b3415ab16391e717e84a61c74b304a67c2e03)) +- **overlay:** new popper version tracks scroll through assigned slots ([ea2bac4](https://github.com/adobe/spectrum-web-components/commit/ea2bac4f7d9c4df98a6a65c19229ef1c18a74791)) +- **overlay:** only "tab trap" when you mean to ([74e1bd2](https://github.com/adobe/spectrum-web-components/commit/74e1bd2182785ec14f944bef8806ecc3e8d15c10)) +- **overlay:** override SpectrumCSS tip rules and process usage in popper ([aad3dec](https://github.com/adobe/spectrum-web-components/commit/aad3dece0f6452c9eef1e0d9b828ca8694c3a9a9)) +- **overlay:** persist hover overlay when there is not click content ([27111a9](https://github.com/adobe/spectrum-web-components/commit/27111a95831dc0dc846af8f889a9479294ab8515)) +- **overlay:** place return focus element on demand ([d262237](https://github.com/adobe/spectrum-web-components/commit/d2622374346c0a0f55419f87dd4399918c3aaa15)) +- **overlay:** reduce DOM and use of "display: contents" for simplicity and accessibility ([2e02075](https://github.com/adobe/spectrum-web-components/commit/2e0207583eb8514a54254b43214f2c9e39d98e81)) +- **overlay:** reduce the control active-overlay places on its content ([9d12571](https://github.com/adobe/spectrum-web-components/commit/9d12571e59dfc7afa52ce14b70f2fdad1b607de1)) +- **overlay:** remove trapped content from a11y tree, manage focus, open projected content ([6c496c0](https://github.com/adobe/spectrum-web-components/commit/6c496c0a930737b7fd74a565766ab41339691551)) +- **overlay:** remove unused dependency ([a3f3a72](https://github.com/adobe/spectrum-web-components/commit/a3f3a72993311e4218e635d4e6e6b1dab0ef5478)) +- **overlay:** reset cached values and applied CSS before "updating" overlays ([b871e52](https://github.com/adobe/spectrum-web-components/commit/b871e52950aaa3b1d7990d77e26b8285040ecb6e)) +- **overlay:** resolve async races with closeOverlays and manageOpen ([ff3738e](https://github.com/adobe/spectrum-web-components/commit/ff3738ea7afc12f258a7745777034ee70d6bf601)) +- **overlay:** track "modalRoots" for expanded overlay management ([dceccb1](https://github.com/adobe/spectrum-web-components/commit/dceccb1617d54da4c0db8035954a4eb4e0367c30)) +- **overlay:** traverse up through shadow roots when determining parent overlay ([27f232c](https://github.com/adobe/spectrum-web-components/commit/27f232c28d30288b75187b80744b2581d6017b77)) +- **overlay:** use esm build from popper and point through to types ([078ca0f](https://github.com/adobe/spectrum-web-components/commit/078ca0fb9bc43d1ee5288e641ff1ec49f40e8df5)) +- **overlay:** use isolatedModules in tsconfig ([48d6069](https://github.com/adobe/spectrum-web-components/commit/48d60694ad5d6014b8664f515e698651f55c9e5f)) +- **overlay:** use tabindex=-1 but always remove it on open ([6047003](https://github.com/adobe/spectrum-web-components/commit/6047003eca58232f90a0c6b2ab0e5bd9fb678eb7)) +- **overlay:** vend a VirtualTrigger for overlays with no element trigger ([a359c60](https://github.com/adobe/spectrum-web-components/commit/a359c6078aa4fac3c9a7bd140609acd4d9aed81d)) +- **picker:** use "modal" as the menu overlay interaction ([c8fbbe2](https://github.com/adobe/spectrum-web-components/commit/c8fbbe27b19702909855575b1afd38fb064e8378)) +- prevent "hover" overlays from receiving focus ([7bd5ac2](https://github.com/adobe/spectrum-web-components/commit/7bd5ac26589f4248bdcde1ee3a168052b5a7bf20)) +- prevent "hover" overlays from returning focus to the root of a parent modal ([ceb8fa7](https://github.com/adobe/spectrum-web-components/commit/ceb8fa73d23f6c9ccb6f2a00c18708d496975473)) +- prevent leaving multiple submenus open at a time ([d2bfbb2](https://github.com/adobe/spectrum-web-components/commit/d2bfbb2d8334ae1a6bd21381092d54914b8f708c)) +- prevent longpress when interacting with context menu ([f8b0732](https://github.com/adobe/spectrum-web-components/commit/f8b07321741ee44515fced9923167b96561cdd48)) +- prevent touch scolling on non-modal content ([e471feb](https://github.com/adobe/spectrum-web-components/commit/e471febf14e64d35b57ebc0c1596c52282a6ff2a)) +- special case the possibility of leaving an overlay trigger by entering its overlay content ([c32a075](https://github.com/adobe/spectrum-web-components/commit/c32a075e0e80d89e9c71dea4a9529971691c1098)) +- **theme:** track default theme values dynamically ([a0c306c](https://github.com/adobe/spectrum-web-components/commit/a0c306c9682d97cefa1258e01ce6eee179f0e071)) +- **tooltip:** correct arrow orientation, remove popper-arrow-rotate ([fcd6ea2](https://github.com/adobe/spectrum-web-components/commit/fcd6ea28ef5e4f06a07994ebd8f8b9be1a934eb2)) +- update "reparentChildren" types for flexibility ([2d358be](https://github.com/adobe/spectrum-web-components/commit/2d358be094cf73785d0858545ccd0f9ca2aa8db0)) +- update presence confirmation so popper is available on update ([24f8380](https://github.com/adobe/spectrum-web-components/commit/24f83800a2011f9181947795d9249b87be99f8ab)) +- update screen reader interface with menu items list ([16756b5](https://github.com/adobe/spectrum-web-components/commit/16756b56c0f7f9561426acc202997fb098e8f19a)) +- update when events are added to manage overlays ([60cddac](https://github.com/adobe/spectrum-web-components/commit/60cddac69554d00095aee492608d85d6513c8928)) +- use "fixed" strategy to prevent unexpected overlay placement ([e39e108](https://github.com/adobe/spectrum-web-components/commit/e39e108def1336adabb21823d1454e917fd38599)) +- use height: 100% to avoid layout breaks ([1498129](https://github.com/adobe/spectrum-web-components/commit/14981291e6d860a8fde7e1746a4a03af4df1e572)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) +- use less restrictive overlay sizing ([f6917aa](https://github.com/adobe/spectrum-web-components/commit/f6917aa4ca22360ba66e40fc933c0e994a04b8c9)) +- use typescript@^4.5 for "native" document.fonts typings ([a3e4aea](https://github.com/adobe/spectrum-web-components/commit/a3e4aea802c796e9029b2bc32f58639954db831b)) +- wait for fonts ready before positioning overlays ([cb8026a](https://github.com/adobe/spectrum-web-components/commit/cb8026a1999a4458b442673291214269fc1e1cef)) + +### Features + +- add open/close events for some menus and overlays ([17f0a58](https://github.com/adobe/spectrum-web-components/commit/17f0a58722fdfee39653c2abde048391f7f24564)) +- add support for Spectrum Express ([12bfe99](https://github.com/adobe/spectrum-web-components/commit/12bfe99570122514fa88ce1a4e4a1591bcc5aa70)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- allow activation of longpress content ([55e71fd](https://github.com/adobe/spectrum-web-components/commit/55e71fdf9fd5dde489871c3d9798ef8957f4e5b6)) +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) +- **dropdown:** open menu UI with overlay system ([9811eeb](https://github.com/adobe/spectrum-web-components/commit/9811eebc33d892da46752981f5bfa49c42ab1192)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- join overlay-root and overlay-trigger as overlay ([dcde42c](https://github.com/adobe/spectrum-web-components/commit/dcde42c118b76bf8466c7475611e95783a1dcb3d)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- **overlay:** move entire package behind dynamic import by default ([9b0a74d](https://github.com/adobe/spectrum-web-components/commit/9b0a74de1f32ccd8cde6cabe4c06f990064f11ae)) +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) +- **progress-bar:** use core tokens ([540552e](https://github.com/adobe/spectrum-web-components/commit/540552ecda4cfab4f26045a6ef2ed58457190ab9)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) +- rework overlays to use popper ([e17d1bb](https://github.com/adobe/spectrum-web-components/commit/e17d1bb23082b788ea921ec15315ea955e2596eb)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **sidenav:** add keyboard accessibility ([6ff622b](https://github.com/adobe/spectrum-web-components/commit/6ff622bf89ad319a7d464fbdd2477c7b55b65cdd)) +- **split-button:** add split-button pattern ([4833a59](https://github.com/adobe/spectrum-web-components/commit/4833a598bb3da3552d194586350a3888dba79543)) +- **story-decorator:** add story decorator to replace knobs for theme application ([7c0c6be](https://github.com/adobe/spectrum-web-components/commit/7c0c6be37d58ad3e6d8973e8d4f5ccc587bf55af)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.19.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.19.4...@spectrum-web-components/overlay@0.19.5) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.19.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.19.3...@spectrum-web-components/overlay@0.19.4) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.19.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.19.2...@spectrum-web-components/overlay@0.19.3) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.19.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.19.1...@spectrum-web-components/overlay@0.19.2) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.19.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.19.0...@spectrum-web-components/overlay@0.19.1) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.19.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.11...@spectrum-web-components/overlay@0.19.0) (2023-02-08) + +### Features + +- **progress-bar:** use core tokens ([540552e](https://github.com/adobe/spectrum-web-components/commit/540552ecda4cfab4f26045a6ef2ed58457190ab9)) + +## [0.18.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.10...@spectrum-web-components/overlay@0.18.11) (2023-01-23) + +### Bug Fixes + +- **overlay:** reset cached values and applied CSS before "updating" overlays ([b871e52](https://github.com/adobe/spectrum-web-components/commit/b871e52950aaa3b1d7990d77e26b8285040ecb6e)) + +## [0.18.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.9...@spectrum-web-components/overlay@0.18.10) (2023-01-09) + +### Bug Fixes + +- use "fixed" strategy to prevent unexpected overlay placement ([e39e108](https://github.com/adobe/spectrum-web-components/commit/e39e108def1336adabb21823d1454e917fd38599)) + +## [0.18.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.8...@spectrum-web-components/overlay@0.18.9) (2022-12-08) + +### Bug Fixes + +- ensure Overlay.update bypasses the auto close mechanism ([8f2aa2e](https://github.com/adobe/spectrum-web-components/commit/8f2aa2e98507298182356e8ea62e384680aedd2c)) +- leverage "dvh" rather than measured screen height ([84b9df0](https://github.com/adobe/spectrum-web-components/commit/84b9df0d101d9870a1b0c20eb34ba33fcdd0fbe1)) + +## [0.18.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.7...@spectrum-web-components/overlay@0.18.8) (2022-11-21) + +### Bug Fixes + +- ensure that an overlay can be released even if it does not complete its fade in animation ([4cbb36f](https://github.com/adobe/spectrum-web-components/commit/4cbb36f91569ce9b7f926437142950fc8fbd59f9)) +- **overlay:** focus closure action on ancestor scroll, not participant resize ([925af0a](https://github.com/adobe/spectrum-web-components/commit/925af0af345fd0b9dc532efff052ac26ebdde80b)) + +## [0.18.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.6...@spectrum-web-components/overlay@0.18.7) (2022-11-14) + +### Bug Fixes + +- keep parent overlays open when not closing child hover overlays ([643fcff](https://github.com/adobe/spectrum-web-components/commit/643fcff10b6e455611fda76040ea0d29ecac5df9)) + +## [0.18.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.5...@spectrum-web-components/overlay@0.18.6) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.18.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.4...@spectrum-web-components/overlay@0.18.5) (2022-10-17) + +### Bug Fixes + +- correct the relationship between overlayWillCloseCallback and phased animations ([c63db8d](https://github.com/adobe/spectrum-web-components/commit/c63db8d2ea4c942fbd52c6d5239ddd3f1ccea5b0)) +- **overlay:** init tab trapping on OverlayStack construction ([a3121e3](https://github.com/adobe/spectrum-web-components/commit/a3121e38df47fb528f8366cdb68e83417d78dc95)) + +## [0.18.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.3...@spectrum-web-components/overlay@0.18.4) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.18.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.2...@spectrum-web-components/overlay@0.18.3) (2022-09-15) + +### Bug Fixes + +- special case the possibility of leaving an overlay trigger by entering its overlay content ([c32a075](https://github.com/adobe/spectrum-web-components/commit/c32a075e0e80d89e9c71dea4a9529971691c1098)) + +## [0.18.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.1...@spectrum-web-components/overlay@0.18.2) (2022-09-14) + +### Bug Fixes + +- **overlay:** move "escape" listener to "keydown" ([813b341](https://github.com/adobe/spectrum-web-components/commit/813b3415ab16391e717e84a61c74b304a67c2e03)) + +## [0.18.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.18.0...@spectrum-web-components/overlay@0.18.1) (2022-08-24) + +### Bug Fixes + +- prevent "hover" overlays from returning focus to the root of a parent modal ([ceb8fa7](https://github.com/adobe/spectrum-web-components/commit/ceb8fa73d23f6c9ccb6f2a00c18708d496975473)) +- prevent longpress when interacting with context menu ([f8b0732](https://github.com/adobe/spectrum-web-components/commit/f8b07321741ee44515fced9923167b96561cdd48)) + +# [0.18.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.17.0...@spectrum-web-components/overlay@0.18.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +# [0.17.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.5...@spectrum-web-components/overlay@0.17.0) (2022-08-04) + +### Bug Fixes + +- **overlay:** export OverlayTriggerInteractions type ([4caec7f](https://github.com/adobe/spectrum-web-components/commit/4caec7f33ec97ba7b21239c0be739b56885dac0a)) + +### Features + +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) + +## [0.16.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.4...@spectrum-web-components/overlay@0.16.5) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.16.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.3...@spectrum-web-components/overlay@0.16.4) (2022-06-29) + +### Bug Fixes + +- ensure that entering an ancestor Menu Item without a submen closes related submenus ([efe5fa1](https://github.com/adobe/spectrum-web-components/commit/efe5fa1ff50c45487f370847444b940e1d6d8a4e)) + +## [0.16.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.2...@spectrum-web-components/overlay@0.16.3) (2022-06-07) + +### Bug Fixes + +- prevent leaving multiple submenus open at a time ([d2bfbb2](https://github.com/adobe/spectrum-web-components/commit/d2bfbb2d8334ae1a6bd21381092d54914b8f708c)) + +## [0.16.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.1...@spectrum-web-components/overlay@0.16.2) (2022-05-27) + +### Bug Fixes + +- add content flow fallbacks to the position manager ([c008957](https://github.com/adobe/spectrum-web-components/commit/c0089571be599577f75b2fe7929b8ee26529358d)) +- prevent "hover" overlays from receiving focus ([7bd5ac2](https://github.com/adobe/spectrum-web-components/commit/7bd5ac26589f4248bdcde1ee3a168052b5a7bf20)) + +## [0.16.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.16.0...@spectrum-web-components/overlay@0.16.1) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.16.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.15.3...@spectrum-web-components/overlay@0.16.0) (2022-04-21) + +### Bug Fixes + +- allow Picker to be reparented ([39e7309](https://github.com/adobe/spectrum-web-components/commit/39e73094be38888599fb189ed4d613f09476310f)) +- use less restrictive overlay sizing ([f6917aa](https://github.com/adobe/spectrum-web-components/commit/f6917aa4ca22360ba66e40fc933c0e994a04b8c9)) + +### Features + +- add support for Spectrum Express ([12bfe99](https://github.com/adobe/spectrum-web-components/commit/12bfe99570122514fa88ce1a4e4a1591bcc5aa70)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) + +## [0.15.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.15.2...@spectrum-web-components/overlay@0.15.3) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.15.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.15.1...@spectrum-web-components/overlay@0.15.2) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.15.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.15.0...@spectrum-web-components/overlay@0.15.1) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.15.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.14.1...@spectrum-web-components/overlay@0.15.0) (2022-03-04) + +### Bug Fixes + +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) + +### Features + +- leverage latest Spectrum button API ([9caf2f6](https://github.com/adobe/spectrum-web-components/commit/9caf2f6313424450c91c039fafea89bf8aa72624)) + +## [0.14.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.14.0...@spectrum-web-components/overlay@0.14.1) (2022-02-22) + +### Bug Fixes + +- **dialog:** updates for delivering dialog content accessibly ([f0ed33c](https://github.com/adobe/spectrum-web-components/commit/f0ed33c3351ae9bc2017202ede8cf206fbf395c2)) +- **overlay:** measure initial overlay data offscreen ([fecda5a](https://github.com/adobe/spectrum-web-components/commit/fecda5a6f8e34261776c2d71c1f001c0cd76c3ce)) + +# [0.14.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.13.4...@spectrum-web-components/overlay@0.14.0) (2022-02-02) + +### Features + +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) + +## [0.13.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.13.3...@spectrum-web-components/overlay@0.13.4) (2022-01-26) + +### Bug Fixes + +- **overlay:** remove unused dependency ([a3f3a72](https://github.com/adobe/spectrum-web-components/commit/a3f3a72993311e4218e635d4e6e6b1dab0ef5478)) + +## [0.13.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.13.2...@spectrum-web-components/overlay@0.13.3) (2022-01-26) + +### Bug Fixes + +- describe longpress button to screen readers ([acdcaf4](https://github.com/adobe/spectrum-web-components/commit/acdcaf49adbc701381bfdf1f95f12ab42f791a67)) + +## [0.13.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.13.1...@spectrum-web-components/overlay@0.13.2) (2022-01-07) + +### Bug Fixes + +- **overlay:** reduce DOM and use of "display: contents" for simplicity and accessibility ([2e02075](https://github.com/adobe/spectrum-web-components/commit/2e0207583eb8514a54254b43214f2c9e39d98e81)) + +## [0.13.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.13.0...@spectrum-web-components/overlay@0.13.1) (2021-12-13) + +### Bug Fixes + +- use typescript@^4.5 for "native" document.fonts typings ([a3e4aea](https://github.com/adobe/spectrum-web-components/commit/a3e4aea802c796e9029b2bc32f58639954db831b)) + +# [0.13.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.12.1...@spectrum-web-components/overlay@0.13.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.12.0...@spectrum-web-components/overlay@0.12.1) (2021-11-08) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) +- prevent touch scolling on non-modal content ([e471feb](https://github.com/adobe/spectrum-web-components/commit/e471febf14e64d35b57ebc0c1596c52282a6ff2a)) + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.16...@spectrum-web-components/overlay@0.12.0) (2021-11-02) + +### Bug Fixes + +- centralize updated first focusable selector ([300e84c](https://github.com/adobe/spectrum-web-components/commit/300e84c404d031ddad92b4952e48ad3332c4aafd)) +- update screen reader interface with menu items list ([16756b5](https://github.com/adobe/spectrum-web-components/commit/16756b56c0f7f9561426acc202997fb098e8f19a)) +- **picker:** use "modal" as the menu overlay interaction ([c8fbbe2](https://github.com/adobe/spectrum-web-components/commit/c8fbbe27b19702909855575b1afd38fb064e8378)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.11.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.15...@spectrum-web-components/overlay@0.11.16) (2021-10-12) + +### Bug Fixes + +- **overlay:** allow [type="modal"] hover overlays to be closed ([5a6802b](https://github.com/adobe/spectrum-web-components/commit/5a6802bc06869cd255bdbfcc460f836c247f01fb)) +- **overlay:** resolve async races with closeOverlays and manageOpen ([ff3738e](https://github.com/adobe/spectrum-web-components/commit/ff3738ea7afc12f258a7745777034ee70d6bf601)) +- **overlay:** traverse up through shadow roots when determining parent overlay ([27f232c](https://github.com/adobe/spectrum-web-components/commit/27f232c28d30288b75187b80744b2581d6017b77)) + +## [0.11.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.14...@spectrum-web-components/overlay@0.11.15) (2021-09-20) + +### Bug Fixes + +- allow contextmenu event passing to pierce shadow roots ([05b69e9](https://github.com/adobe/spectrum-web-components/commit/05b69e90a56676c44e4757a6c2e19e6fe333b145)) +- correct add/remove timing of overlay events ([474ec6e](https://github.com/adobe/spectrum-web-components/commit/474ec6e85840dc1efee8b134cc6e6163f228920f)) + +## [0.11.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.13...@spectrum-web-components/overlay@0.11.14) (2021-09-13) + +### Bug Fixes + +- close modal overlays with contextmenu events and pass those to the underlying page ([9e83f3c](https://github.com/adobe/spectrum-web-components/commit/9e83f3c0d2398323ebe941ba253d7a0dc0f40ba6)) + +## [0.11.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.12...@spectrum-web-components/overlay@0.11.13) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.11.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.11...@spectrum-web-components/overlay@0.11.12) (2021-08-17) + +### Bug Fixes + +- update when events are added to manage overlays ([60cddac](https://github.com/adobe/spectrum-web-components/commit/60cddac69554d00095aee492608d85d6513c8928)) + +## [0.11.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.10...@spectrum-web-components/overlay@0.11.11) (2021-08-03) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- expand sync offering for elements with overlay content ([0195843](https://github.com/adobe/spectrum-web-components/commit/0195843e9efac5760a78fa302d91139c84ea5747)) + +## [0.11.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.9...@spectrum-web-components/overlay@0.11.10) (2021-07-22) + +### Bug Fixes + +- **overlay:** allow external style access to "sp-theme" elements in overlays as a CSS part ([a107f66](https://github.com/adobe/spectrum-web-components/commit/a107f66ae171e857e5f84cfff9f7a27cc5bd320d)) +- delete the used cleanup method ([942ef0f](https://github.com/adobe/spectrum-web-components/commit/942ef0fdc6e7c89e4f554e032c7b9fb760ca47a0)) + +## [0.11.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.8...@spectrum-web-components/overlay@0.11.9) (2021-07-01) + +### Bug Fixes + +- allow detached elements to be used as content for an overlay ([3ad8383](https://github.com/adobe/spectrum-web-components/commit/3ad83837b6c9a693a4fc24501e3fc7fb2383a12b)) +- manage "lang" via context provided by "sp-theme" ([b1e3457](https://github.com/adobe/spectrum-web-components/commit/b1e3457ae447427c54f8645c478866340329750c)) + +## [0.11.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.7...@spectrum-web-components/overlay@0.11.8) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.11.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.6...@spectrum-web-components/overlay@0.11.7) (2021-06-07) + +### Bug Fixes + +- ensure focus is managed when tabbing out of a menu ([9bfa81d](https://github.com/adobe/spectrum-web-components/commit/9bfa81d8a677d6c0ab5ac5cd618498496761c69b)) +- **overlay:** vend a VirtualTrigger for overlays with no element trigger ([a359c60](https://github.com/adobe/spectrum-web-components/commit/a359c6078aa4fac3c9a7bd140609acd4d9aed81d)) + +## [0.11.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.5...@spectrum-web-components/overlay@0.11.6) (2021-05-24) + +### Bug Fixes + +- **overlay:** add overlay lifecycle methods to stack management ([9361527](https://github.com/adobe/spectrum-web-components/commit/9361527bc63896bcee2933d96b5021aa74386057)) +- **overlay:** use tabindex=-1 but always remove it on open ([6047003](https://github.com/adobe/spectrum-web-components/commit/6047003eca58232f90a0c6b2ab0e5bd9fb678eb7)) + +## [0.11.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.4...@spectrum-web-components/overlay@0.11.5) (2021-05-12) + +### Bug Fixes + +- **overlay:** reduce the control active-overlay places on its content ([9d12571](https://github.com/adobe/spectrum-web-components/commit/9d12571e59dfc7afa52ce14b70f2fdad1b607de1)) +- update "reparentChildren" types for flexibility ([2d358be](https://github.com/adobe/spectrum-web-components/commit/2d358be094cf73785d0858545ccd0f9ca2aa8db0)) +- update presence confirmation so popper is available on update ([24f8380](https://github.com/adobe/spectrum-web-components/commit/24f83800a2011f9181947795d9249b87be99f8ab)) + +## [0.11.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.3...@spectrum-web-components/overlay@0.11.4) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.2...@spectrum-web-components/overlay@0.11.3) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.1...@spectrum-web-components/overlay@0.11.2) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.11.0...@spectrum-web-components/overlay@0.11.1) (2021-03-22) + +### Bug Fixes + +- **overlay:** handle hover/longpress more directly via the "open" attribute ([7b2b64b](https://github.com/adobe/spectrum-web-components/commit/7b2b64b6be931381a1ca1c83f941677fa06750ff)) + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.10.1...@spectrum-web-components/overlay@0.11.0) (2021-03-22) + +### Bug Fixes + +- **overlay:** allow overlay-trigger to declaratively open overlay content ([194a44e](https://github.com/adobe/spectrum-web-components/commit/194a44e78df73ca4a5520e24b308667c23331880)) +- **overlay:** persist hover overlay when there is not click content ([27111a9](https://github.com/adobe/spectrum-web-components/commit/27111a95831dc0dc846af8f889a9479294ab8515)) + +### Features + +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.10.0...@spectrum-web-components/overlay@0.10.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.9.0...@spectrum-web-components/overlay@0.10.0) (2021-03-04) + +### Bug Fixes + +- **overlay:** correct overlay content sizing ([d9bcd6f](https://github.com/adobe/spectrum-web-components/commit/d9bcd6fd6b4eecae297c6e5cc5330e79a9e198ff)) +- **overlay:** track "modalRoots" for expanded overlay management ([dceccb1](https://github.com/adobe/spectrum-web-components/commit/dceccb1617d54da4c0db8035954a4eb4e0367c30)) +- wait for fonts ready before positioning overlays ([cb8026a](https://github.com/adobe/spectrum-web-components/commit/cb8026a1999a4458b442673291214269fc1e1cef)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.8.2...@spectrum-web-components/overlay@0.9.0) (2021-02-11) + +### Bug Fixes + +- **overlay:** place return focus element on demand ([d262237](https://github.com/adobe/spectrum-web-components/commit/d2622374346c0a0f55419f87dd4399918c3aaa15)) + +### Features + +- allow activation of longpress content ([55e71fd](https://github.com/adobe/spectrum-web-components/commit/55e71fdf9fd5dde489871c3d9798ef8957f4e5b6)) + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.8.1...@spectrum-web-components/overlay@0.8.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.8.0...@spectrum-web-components/overlay@0.8.1) (2021-01-28) + +### Bug Fixes + +- **overlay:** remove trapped content from a11y tree, manage focus, open projected content ([6c496c0](https://github.com/adobe/spectrum-web-components/commit/6c496c0a930737b7fd74a565766ab41339691551)) +- **tooltip:** correct arrow orientation, remove popper-arrow-rotate ([fcd6ea2](https://github.com/adobe/spectrum-web-components/commit/fcd6ea28ef5e4f06a07994ebd8f8b9be1a934eb2)) + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.4...@spectrum-web-components/overlay@0.8.0) (2021-01-21) + +### Bug Fixes + +- **overlay:** do not focus the trigger when closing an overlay, unless expected ([21d7dfe](https://github.com/adobe/spectrum-web-components/commit/21d7dfeaa94919586bede27a9c7ae077a2d214a5)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- **overlay:** use esm build from popper and point through to types ([078ca0f](https://github.com/adobe/spectrum-web-components/commit/078ca0fb9bc43d1ee5288e641ff1ec49f40e8df5)) +- **overlay:** use isolatedModules in tsconfig ([48d6069](https://github.com/adobe/spectrum-web-components/commit/48d60694ad5d6014b8664f515e698651f55c9e5f)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- add open/close events for some menus and overlays ([17f0a58](https://github.com/adobe/spectrum-web-components/commit/17f0a58722fdfee39653c2abde048391f7f24564)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- **story-decorator:** add story decorator to replace knobs for theme application ([7c0c6be](https://github.com/adobe/spectrum-web-components/commit/7c0c6be37d58ad3e6d8973e8d4f5ccc587bf55af)) + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.4...@spectrum-web-components/overlay@0.7.0) (2021-01-13) + +### Bug Fixes + +- **overlay:** do not focus the trigger when closing an overlay, unless expected ([21d7dfe](https://github.com/adobe/spectrum-web-components/commit/21d7dfeaa94919586bede27a9c7ae077a2d214a5)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- **overlay:** use esm build from popper and point through to types ([078ca0f](https://github.com/adobe/spectrum-web-components/commit/078ca0fb9bc43d1ee5288e641ff1ec49f40e8df5)) +- **overlay:** use isolatedModules in tsconfig ([48d6069](https://github.com/adobe/spectrum-web-components/commit/48d60694ad5d6014b8664f515e698651f55c9e5f)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- add open/close events for some menus and overlays ([17f0a58](https://github.com/adobe/spectrum-web-components/commit/17f0a58722fdfee39653c2abde048391f7f24564)) +- **field-group:** add field-group pattern ([f8d265c](https://github.com/adobe/spectrum-web-components/commit/f8d265c3352f4a97fc103a09ce8eb56511dcedbb)) +- **story-decorator:** add story decorator to replace knobs for theme application ([7c0c6be](https://github.com/adobe/spectrum-web-components/commit/7c0c6be37d58ad3e6d8973e8d4f5ccc587bf55af)) + +## [0.6.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.3...@spectrum-web-components/overlay@0.6.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.6.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.2...@spectrum-web-components/overlay@0.6.3) (2020-10-12) + +### Bug Fixes + +- **overlay:** close when overlay-trigger becomes [disabled](<[6f27e25](https://github.com/adobe/spectrum-web-components/commit/6f27e25658dd23949ef07c6df72c43768651482b)>) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.6.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.1...@spectrum-web-components/overlay@0.6.2) (2020-09-25) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.6.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.6.0...@spectrum-web-components/overlay@0.6.1) (2020-09-15) + +### Bug Fixes + +- **overlay:** only "tab trap" when you mean to ([74e1bd2](https://github.com/adobe/spectrum-web-components/commit/74e1bd2182785ec14f944bef8806ecc3e8d15c10)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.5.2...@spectrum-web-components/overlay@0.6.0) (2020-08-31) + +### Bug Fixes + +- correct overlay closure order or operations for manual override ([0b7a8c4](https://github.com/adobe/spectrum-web-components/commit/0b7a8c42866ae4f2d38d90fa7b6dc34ed2c21759)) + +### Features + +- **split-button:** add split-button pattern ([4833a59](https://github.com/adobe/spectrum-web-components/commit/4833a598bb3da3552d194586350a3888dba79543)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.5.1...@spectrum-web-components/overlay@0.5.2) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.5.0...@spectrum-web-components/overlay@0.5.1) (2020-08-13) + +### Bug Fixes + +- include sync builds in publication configuration ([e731673](https://github.com/adobe/spectrum-web-components/commit/e731673e7d171af667fc87c5b6e521450143e8fe)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.4.3...@spectrum-web-components/overlay@0.5.0) (2020-08-13) + +### Bug Fixes + +- **overlay:** enforce the full frame ([63628e9](https://github.com/adobe/spectrum-web-components/commit/63628e93de2daec632025f2659a86ff18e487a8e)) +- **overlay:** ensure overlay addition occurs after closing previous ([7d2b102](https://github.com/adobe/spectrum-web-components/commit/7d2b102f30731513639582fed8ed0e1b46d569cf)) + +### Features + +- **overlay:** move entire package behind dynamic import by default ([9b0a74d](https://github.com/adobe/spectrum-web-components/commit/9b0a74de1f32ccd8cde6cabe4c06f990064f11ae)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.4.2...@spectrum-web-components/overlay@0.4.3) (2020-08-05) + +### Bug Fixes + +- use height: 100% to avoid layout breaks ([1498129](https://github.com/adobe/spectrum-web-components/commit/14981291e6d860a8fde7e1746a4a03af4df1e572)) + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.4.1...@spectrum-web-components/overlay@0.4.2) (2020-07-24) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.4.0...@spectrum-web-components/overlay@0.4.1) (2020-07-22) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.8...@spectrum-web-components/overlay@0.4.0) (2020-07-17) + +### Features + +- **overlay:** manage focus throwing and tab trapping ([27a0b53](https://github.com/adobe/spectrum-web-components/commit/27a0b53ea94d19bb18b7d3f89763b06dc1b42b59)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.3.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.7...@spectrum-web-components/overlay@0.3.8) (2020-06-08) + +### Bug Fixes + +- **overlay:** ensure undefined data is not passed into theme ([3e2e1ca](https://github.com/adobe/spectrum-web-components/commit/3e2e1caa4c37eedf6e569b5124c9e59f207bb92f)) + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.6...@spectrum-web-components/overlay@0.3.7) (2020-05-08) + +### Bug Fixes + +- **dropdown:** correct conditional check ([a3a790f](https://github.com/adobe/spectrum-web-components/commit/a3a790f6c3f5f8f0837d619ca57c1090ab14e638)) + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.5...@spectrum-web-components/overlay@0.3.6) (2020-05-08) + +### Bug Fixes + +- constrain overlay to available window size ([9729b55](https://github.com/adobe/spectrum-web-components/commit/9729b55ef5246662aa50cbc8037bcaeb2f4ac74a)) + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.4...@spectrum-web-components/overlay@0.3.5) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.3...@spectrum-web-components/overlay@0.3.4) (2020-04-10) + +### Bug Fixes + +- **overlay:** new popper version tracks scroll through assigned slots ([ea2bac4](https://github.com/adobe/spectrum-web-components/commit/ea2bac4f7d9c4df98a6a65c19229ef1c18a74791)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.2...@spectrum-web-components/overlay@0.3.3) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/overlay + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.1...@spectrum-web-components/overlay@0.3.2) (2020-03-16) + +### Bug Fixes + +- **theme:** track default theme values dynamically ([a0c306c](https://github.com/adobe/spectrum-web-components/commit/a0c306c)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.3.0...@spectrum-web-components/overlay@0.3.1) (2020-03-11) + +### Bug Fixes + +- **overlay:** extend state machine to manage disposal process ([f0f26af](https://github.com/adobe/spectrum-web-components/commit/f0f26af)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.2.1...@spectrum-web-components/overlay@0.3.0) (2020-02-24) + +### Features + +- **dropdown:** open menu UI with overlay system ([9811eeb](https://github.com/adobe/spectrum-web-components/commit/9811eeb)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.2.0...@spectrum-web-components/overlay@0.2.1) (2020-02-05) + +### Bug Fixes + +- **overlay:** override SpectrumCSS tip rules and process usage in popper ([aad3dec](https://github.com/adobe/spectrum-web-components/commit/aad3dec)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/overlay@0.1.0...@spectrum-web-components/overlay@0.2.0) (2020-01-30) + +### Features + +- rework overlays to use popper ([e17d1bb](https://github.com/adobe/spectrum-web-components/commit/e17d1bb)) + +# 0.1.0 (2020-01-06) + +### Features + +- join overlay-root and overlay-trigger as overlay ([dcde42c](https://github.com/adobe/spectrum-web-components/commit/dcde42c)) +- **sidenav:** add keyboard accessibility ([6ff622b](https://github.com/adobe/spectrum-web-components/commit/6ff622b)) diff --git a/1st-gen/packages/overlay/README.md b/1st-gen/packages/overlay/README.md new file mode 100644 index 00000000000..dbcef76f8d1 --- /dev/null +++ b/1st-gen/packages/overlay/README.md @@ -0,0 +1,909 @@ +## Overview + +An `` element is used to decorate content that you would like to present to your visitors as "overlaid" on the rest of the application. This includes dialogs (modal and not), pickers, tooltips, context menus, et al. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/overlay?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/overlay) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/overlay?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/overlay) + +```zsh +yarn add @spectrum-web-components/overlay +``` + +Import the side effectful registration of `` as follows: + +```ts +import '@spectrum-web-components/overlay/sp-overlay.js'; +``` + +When looking to leverage the `Overlay` base class as a type and/or for extension purposes, do so via: + +```ts +import { Overlay } from '@spectrum-web-components/overlay'; +``` + +### Example + +By leveraging the `trigger` attribute to pass an ID reference to another element within the same DOM tree, your overlay will be positioned in relation to this element. When the ID reference is followed by an `@` symbol and interaction type, like `click`, `hover`, or `longpress`, the overlay will bind itself to the referenced element via the DOM events associated with that interaction. + +```html +Overlay Trigger + + + + + +

Clicking opens this popover...

+

But, it really could be anything. Really.

+
+
+
+ + + + + I'm a tooltip and I'm triggered by hovering over the button! + + +``` + +### Anatomy + +When a `` element is opened, it will pass that state to its direct children elements as the property `open`, which it will set to `true`. Elements should react to this by initiating any transition between closed and open that they see fit. Similarly, `open` will be set to `false` when the `` element is closed. + +### Options + + +delayed + + +An Overlay that is `delayed` will wait until a warm-up period of 1000ms has completed before opening. Once the warmup period has completed, all subsequent Overlays will open immediately. When no Overlays are opened, a cool down period of 1000ms will begin. Once the cool down has completed, the next Overlay to be opened will be subject to the warm-up period if provided that option. + +```html +Overlay Trigger + + + I'm a tooltip and I'm delayed! + +``` + + +notImmediatelyCloseable + + +When an Overlay is `notImmediatelyCloseable` that means that the first interaction that would lead to the closure of the Overlay in question will be ignored. This is useful when working with non-"click" mouse interactions, like `contextmenu`, where the trigger event (e.g. `contextmenu`) occurs _before_ an event that would close said overlay (e.g. `pointerup`). + +```html-live + + +

Right click anywhere in bounded rectangle to open the menu

+
+ + + + + Menu + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + +
+ + +``` + + + +
+offset + + +The `offset` property accepts either a single number, to define the offset of the Overlay along the main axis from the trigger, or 2-tuple, to define the offset along the main axis and the cross axis. This option has no effect when there is no trigger element. + +```html +Overlay Trigger + + + + +

Clicking opens this popover...

+

An offset of 50px is applied to the overlay.

+
+
+
+``` + +
+placement + + +A `placement` of `"auto-start" | "auto-end" | "top" | "bottom" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"` will instruct the Overlay where to place itself in relationship to the trigger element. + +```html +Overlay Trigger + + + + +

Clicking opens this popover...

+

The overlay is placed to the right of the trigger.

+
+
+
+``` + +
+receivesFocus + + +Some Overlays will always be passed focus (e.g. modal or page Overlays). When this is not true, the `receivesFocus` option will inform the API whether to attempt to pass focus into the Overlay once it is open. `'true'` will pass focus, `'false'` will not (when possible), and `"auto"` (the default), will make a decision based on the `type` of the Overlay. + +```html +Overlay Trigger + + + + +

+ Clicking opens this popover but does not receive focus +

+ Enter your email + + + Sign in + +
+
+
+``` + +
+
+ +#### trigger + +The `trigger` attribute accepts a string ID reference for the trigger element combined with the interaction type. + +The format is `"elementId@interaction"`, where: + +- `elementId` is the ID of the HTML element to use as the trigger +- `interaction` is required and can be `click`, `hover`, or `longpress` + +Examples: + +```html +Open Overlay + + + + Click popover + + + + + Hover popover + + + + + Longpress popover + +``` + +#### triggerElement + +The `triggerElement` property accepts an `HTMLElement` or a `VirtualTrigger` from which to position the Overlay. + +- You can import the `VirtualTrigger` class from the overlay package to create a virtual trigger that can be used to position an Overlay. This is useful when you want to position an Overlay relative to a point on the screen that is not an element in the DOM, like the mouse cursor. + +#### type + +The `type` of an Overlay outlines a number of things about the interaction model within which it works: + + +Modal + + +`'modal'` Overlays create a modal context that traps focus within the content and prevents interaction with the rest of the page. The overlay manages focus trapping and accessibility features like `aria-modal="true"` to ensure proper screen reader behavior. + +They should be used when you need to ensure that the user has interacted with the content of the Overlay before continuing with their work. This is commonly used for dialogs that require a user to confirm or cancel an action before continuing. + +```html +open modal + + +

I am a modal type overlay.

+ Enter your email + + + Sign in + +
+
+``` + +
+Page + + +`'page'` Overlays behave similarly to `'modal'` Overlays by creating a modal context and trapping focus, but they will not be allowed to close via the "light dismiss" algorithm (e.g. the Escape key). + +A page overlay could be used for a full-screen menu on a mobile website. When the user clicks on the menu button, the entire screen is covered with the menu options. + +```html +open page + + +

I am a page type overlay.

+
+
+``` + +
+Hint + + +`'hint'` Overlays are much like tooltips so they are not just ephemeral, but they are delivered primarily as a visual helper and exist outside of the tab order. In this way, be sure _not_ to place interactive content within this type of Overlay. + +This overlay type does not accept focus and does not interfere with the user's interaction with the rest of the page. + +```html +open hint + + + I am a hint type overlay. I am not interactive and will close when the + user interacts with the page. + + +``` + + +Auto + + +`'auto'` Overlays provide a place for content that is ephemeral _and_ interactive. These Overlays can accept focus and remain open while interacting with their content. They will close when focus moves outside the overlay or when clicking elsewhere on the page. + +```html +Open Overlay + + +

+ My slider in overlay element: + +

+
+
+``` + +
+Manual + + +`'manual'` Overlays act much like `'auto'` Overlays, but do not close when losing focus or interacting with other parts of the page. + +Note: When a `'manual'` Overlay is at the top of the "overlay stack", it will still respond to the Escape key and close. + +```html + +open manual + + + + Chat Window + + Send + + + +``` + + +
+ +### Events + +When fully open the `` element will dispatch the `sp-opened` event, and when fully closed the `sp-closed` event will be dispatched. Both of these events are of type: + +```ts +type OverlayStateEvent = Event & { + overlay: Overlay; +}; +``` + +The `overlay` value in this case will hold a reference to the actual `` that is opening or closing to trigger this event. Remember that some `` element (like those creates via the imperative API) can be transiently available in the DOM, so if you choose to build a cache of Overlay elements to some end, be sure to leverage a weak reference so that the `` can be garbage collected as desired by the browser. + +#### When it is "fully" open or closed? + +"Fully" in this context means that all CSS transitions that have dispatched `transitionrun` events on the direct children of the `` element have successfully dispatched their `transitionend` or `transitioncancel` event. Keep in mind the following: + +- `transition*` events bubble; this means that while transition events on light DOM content of those direct children will be heard, those events will not be taken into account +- `transition*` events are not composed; this means that transition events on shadow DOM content of the direct children will not propagate to a level in the DOM where they can be heard + +This means that in both cases, if the transition is meant to be a part of the opening or closing of the overlay in question you will need to re-dispatch the `transitionrun`, `transitionend`, and `transitioncancel` events from that transition from the closest direct child of the ``. + +### Integration patterns + +#### Action bar system + +```html + + + + + + + + + + + + + + + Hover + + + + + + + + + + + + + + + + + + Hover + + + + + + + + + + + + + + + + + + Hover + + + + + + + + + + + + + + + + + +``` + +### Advanced topics + +#### API + +```ts + +``` + +##### API value interactions + +When a `triggerElement` is present (via `trigger` attribute or direct property setting), the following configurations apply: + + + + Configuration + Required Properties + Behavior + + + + Basic Placement + `placement` + `triggerElement` + Content positions next to trigger + + + Placement + Offset + `placement` + `offset` + `triggerElement` + Content positions with extra spacing + + + Invalid Placement + `placement` without `triggerElement` + No positioning occurs + + + No Placement + No `placement` specified + Content positioning handled by: +• Content itself +• Application + +Common in `modal`/`page` overlays for full-screen content + + + + +##### Deprecated Properties + +> **⚠️ Deprecation Notice**: The `allow-outside-click` property is deprecated and will be removed in a future version. + +The `allow-outside-click` property allows clicks outside the overlay to close it. **We do not recommend using this property for accessibility reasons** as it can cause unexpected behavior and accessibility issues. When set to `true`, it configures the focus trap to allow outside clicks, which may interfere with proper focus management and user expectations. + +```html + + + +

This overlay can be closed by clicking outside

+
+
+``` + +**Alternative approaches**: Instead of using `allow-outside-click`, consider implementing explicit close buttons or using the `type="modal"` or `type="page"` overlay types which provide better accessibility and user experience. + +#### Styling + +`` element will use the `` element or `popover` attribute to project your content onto the top-layer of the browser, without being moved in the DOM tree. That means that you can style your overlay content with whatever techniques you are already leveraging to style the content that doesn't get overlaid. This means standard CSS selectors, CSS Custom Properties, and CSS Parts applied in your parent context will always apply to your overlaid content. + +#### Top layer over complex CSS + +There are some complex CSS values that have not yet been covered by the positioning API that the `` element leverages to associate overlaid content with their trigger elements. In specific, properties like `filter`, when applied to a trigger element within which lives the related content to be overlaid, are not currently supported by the relationship created herein. If support for this is something that you and the work you are addressing would require, we'd love to hear from you in [an issue](https://github.com/adobe/spectrum-web-components/issues). We'd be particularly interested in speaking with you if you were interested in contributing support/testing to ensure this capability for all consumers of the library. + +#### Fallback support + +While the [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) is widely supported by browsers, the [`popover` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover) is still quite new. When leveraged in browsers that do not yet support the `popover` attribute, there may be additional intervention required to ensure your content is delivered to your visitors as expected. + +##### Complex layered + +When an overlay is placed within a page with complex layering, the content therein can fall behind other content in the `z-index` stack. The following example is somewhat contrived but, imagine a toolbar next to a properties panel. If the toolbar has a lower `z-index` than the properties panel, any overlaid content (tooltips, etc.) within that toolbar will display underneath any content in the properties panel with which it may share pixels. + +```html +
+
+ Trigger + + + I can be partially blocked when [popover] is not available + + +
+
+
+ +``` + +Properly managed `z-index` values will support working around this issue while browsers work to adopt the `popover` attribute. In this demo, you can achieve the same output by sharing one `z-index` between the various pieces of content, removing `z-index` values altogether, or raising the `.complex-layered-holder` element to a higher `z-index` than the `.complex-layered-blocker` element. + +##### Contained + +[CSS Containment](https://developer.mozilla.org/en-US/docs/Web/CSS/contain) gives a developer direct control over how the internals of one element affect the paint and layout of the internals of other elements on the same page. While leveraging some of its values can offer performance gains, they can interrupt the delivery of your overlaid content. + +```html +
+ Trigger + + + I can be blocked when [popover] is not available + + +
+ +``` + +You could just _remove_ the `contain` rule. But, if you are not OK with simply removing the `contain` value, you still have options. If you would like to continue to leverage `contain`, you can place your "contained" content separately from your overlaid content, like so: + +```html +
+ Trigger +
+ + I can be blocked when [popover] is not available + + +``` + +`` accepts an ID reference via the `trigger` attribute to relate it to interactions and positioning in the DOM. To fulfill this reference the two elements need to be in the same DOM tree. However, `` alternatively accepts a `triggerElement` _property_ that opens even more flexibility in addressing this situation. + +##### Clip pathed + +`clip-path` can also restrict how content in an element is surfaced at paint time. When overlaid content should display outside of the `clip-path`, without the `popover` attribute, that content could be _clipped_. + +```html +
+ Trigger + + + I can be blocked when [popover] is not available + + +
+ +``` + +Here, again, working with your content needs (whether or not you want to leverage `clip-path`) or DOM structure (not colocating clipped and non-clipped content) will allow you to avoid this issue: + +```html +
+ Trigger +
+ + I can be blocked when [popover] is not available + + +``` + +##### Non-overflowing, relative containers with z-index in Safari + +Under very specific conditions, [WebKit will incorrectly clip fixed-position content](https://bugs.webkit.org/show_bug.cgi?id=160953). +WebKit clips `position: fixed` elements within containers that have all of: + +1. `position: relative` +2. `overflow: clip` or `overflow: hidden` +3. `z-index` greater than zero + +If you notice overlay clipping _only_ in Safari, this is likely the culprit. The solution is to break up the conditions into separate elements to avoid triggering WebKit's bug. For example, leaving relative positioning and z-index on the outermost container while creating an inner container that enforces the overflow rules. + +### Accessibility + +#### Nested overlays + +When nesting multiple overlays, it is important to ensure that the nested overlays are actually nested in the HTML as well, otherwise it will not be accessible. + +```html +
+ + Open Outer Modal + + + + +

Outer Dialog

+

This is the outer modal content. Press ESC to close it.

+ + Open Inner Modal + + + + +

+ Inner Dialog +

+

+ This is the inner modal content. Press ESC to + close this first, then the outer modal. +

+
+
+
+
+
+
+
+``` + +#### Focus management + +The overlay manages focus based on its type: + +- For `modal` and `page` types, focus is always trapped within the overlay +- For `auto` and `manual` types, focus behavior is controlled by the `receives-focus` attribute +- For `hint` type, focus remains on the trigger element + +Example of proper focus management: + +```html + + + +

Settings

+ Email Notifications + Enable notifications + +
+ + Cancel + + + Save + +
+
+
+``` + +#### Keyboard navigation + + + + Key + Action + + + + ESC + Closes overlays in reverse order of opening + + + TAB/Shift+TAB + Navigates through focusable elements within modal/page overlays + + + Arrow keys + Navigate through menu items in menu overlays + + + ENTER/SPACE + Activates buttons and controls + + + + +#### Screen reader considerations + +- Use `aria-haspopup` on trigger elements to indicate the type of overlay +- Provide descriptive labels using `aria-label` or `aria-labelledby` +- Use proper heading structure within overlays +- Ensure error messages are announced using `aria-live` + +Example of a tooltip with proper screen reader support: + +```html + + + + + + Click for more information about this feature + + +``` diff --git a/1st-gen/packages/overlay/imperative-api.md b/1st-gen/packages/overlay/imperative-api.md new file mode 100644 index 00000000000..84b7cdde748 --- /dev/null +++ b/1st-gen/packages/overlay/imperative-api.md @@ -0,0 +1,198 @@ +## Overview + +While an `` element is the recommended entry point to the Spectrum Web Components Overlay API, you can also interact with this set of features via an imperative API, `Overlay.open`. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/overlay?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/overlay) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/overlay?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/overlay) + +```zsh +yarn add @spectrum-web-components/overlay +``` + +Import the `Overlay` class to leverage its capabilities within your application or custom element: + +```ts +import { Overlay } from '@spectrum-web-components/overlay'; +``` + +### Example + +Primarily, this class gives you access to the `open` method that will allow you to open an overlay: + +```ts +Overlay.open( + (overlayElement: HTMLElement), // the element that will be projected into the overlay, "content", + (options?: OverlayOptions) +); +``` + +`Overlay.open()` is an asynchronous method that returns an `` element that wraps the `HTMLElement` provided as the `overlayElement`. While this process will set the `` element to `open`, consumers of this API will need to choose where to append this element to the DOM in order for the content to be made available in the browser. + +```ts +(async () => { + const content = document.querySelector('#content'); + const options = { + offset: 0, + placement: 'bottom', + trigger: document.querySelector('#trigger'), + type: 'auto', + }; + const overlay = await Overlay.open(content, options); + document.body.append(overlay); +})(); +``` + +Keep in mind that a changing DOM tree is likely to alter the relationship between existing content. Without proper care this can negatively effect the CSS that you have applied to existing content. DOM events and DOM selection methods can also perform differently than expected as the tree shape changes. + +### Options + +When leveraging `Overlay.open()`, you can provide an optional second argument of `OverlayOptions`, with the following type: + +```ts +type OverlayOptions = { + delayed?: boolean; + notImmediatelyCloseable?: boolean; + offset?: number | [number, number]; + placement?: Placement; + receivesFocus?: 'auto' | 'true' | 'false'; + trigger?: HTMLElement | VirtualTrigger; + type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual'; +}; +``` + +### Advanced topics + +#### Using a virtual trigger + +```html-live + + +

Right click anywhere in bounded rectangle to open the menu

+
+ + +``` + + diff --git a/1st-gen/packages/overlay/local.d.ts b/1st-gen/packages/overlay/local.d.ts new file mode 100644 index 00000000000..7f6c54b7c4c --- /dev/null +++ b/1st-gen/packages/overlay/local.d.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +declare module '@popperjs/core/dist/esm/popper-lite.js' { + import { + popperGenerator, + defaultModifiers, + } from '@popperjs/core/lib/popper-lite'; + + export { popperGenerator, defaultModifiers }; +} + +declare module '@popperjs/core/dist/esm/types.js' { + import { Instance, VirtualElement } from '@popperjs/core/lib/types.js'; + + export { Instance, VirtualElement }; +} + +declare module '@popperjs/core/dist/esm/enums.js' { + import { Placement } from '@popperjs/core/lib/enums.js'; + + export { Placement }; +} + +declare module '@popperjs/core/dist/esm/modifiers/flip.js' { + import flip from '@popperjs/core/lib/modifiers/flip.js'; + + export default flip; +} + +declare module '@popperjs/core/dist/esm/modifiers/preventOverflow.js' { + import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow.js'; + + export default preventOverflow; +} + +declare module '@popperjs/core/dist/esm/modifiers/arrow.js' { + import arrow from '@popperjs/core/lib/modifiers/arrow.js'; + + export default arrow; +} + +declare module '@popperjs/core/dist/esm/modifiers/offset.js' { + import offset from '@popperjs/core/lib/modifiers/offset.js'; + + export default offset; +} diff --git a/1st-gen/packages/overlay/overlay-trigger.md b/1st-gen/packages/overlay/overlay-trigger.md new file mode 100644 index 00000000000..6aac9c0bb18 --- /dev/null +++ b/1st-gen/packages/overlay/overlay-trigger.md @@ -0,0 +1,245 @@ + +
+ triggered-by performance optimization +
+
+ Use the new triggered-by attribute to declare which types of overlays + your implementation will use. This improves performance by avoiding + unnecessary DOM operations and preventing race conditions during + rendering. For more information, read the Performance + optimization section. +
+
+ +## Overview + +An `` element supports the delivery of temporary overlay content based on interaction with a persistent trigger element. An element prepared to receive accessible interactions (e.g. an ``, or ``, etc. You can find further reading on the subject of accessible keyboard interactions at [https://www.w3.org/WAI/WCAG21/Understanding/keyboard](https://www.w3.org/WAI/WCAG21/Understanding/keyboard). diff --git a/1st-gen/packages/overlay/overlay-trigger.ts b/1st-gen/packages/overlay/overlay-trigger.ts new file mode 100644 index 00000000000..51b113aef6f --- /dev/null +++ b/1st-gen/packages/overlay/overlay-trigger.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; +import { OverlayTrigger } from './src/OverlayTrigger.js'; + +defineElement('overlay-trigger', OverlayTrigger); + +declare global { + interface HTMLElementTagNameMap { + 'overlay-trigger': OverlayTrigger; + } +} diff --git a/1st-gen/packages/overlay/package.json b/1st-gen/packages/overlay/package.json new file mode 100644 index 00000000000..eab0a79cabe --- /dev/null +++ b/1st-gen/packages/overlay/package.json @@ -0,0 +1,186 @@ +{ + "name": "@spectrum-web-components/overlay", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/overlay" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/overlay", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/AbstractOverlay.js": { + "development": "./src/AbstractOverlay.dev.js", + "default": "./src/AbstractOverlay.js" + }, + "./src/ClickController.js": { + "development": "./src/ClickController.dev.js", + "default": "./src/ClickController.js" + }, + "./src/HoverController.js": { + "development": "./src/HoverController.dev.js", + "default": "./src/HoverController.js" + }, + "./src/InteractionController.js": { + "development": "./src/InteractionController.dev.js", + "default": "./src/InteractionController.js" + }, + "./src/LongpressController.js": { + "development": "./src/LongpressController.dev.js", + "default": "./src/LongpressController.js" + }, + "./src/Overlay.js": { + "development": "./src/Overlay.dev.js", + "default": "./src/Overlay.js" + }, + "./src/OverlayDialog.js": { + "development": "./src/OverlayDialog.dev.js", + "default": "./src/OverlayDialog.js" + }, + "./src/OverlayNoPopover.js": { + "development": "./src/OverlayNoPopover.dev.js", + "default": "./src/OverlayNoPopover.js" + }, + "./src/OverlayPopover.js": { + "development": "./src/OverlayPopover.dev.js", + "default": "./src/OverlayPopover.js" + }, + "./src/OverlayStack.js": { + "development": "./src/OverlayStack.dev.js", + "default": "./src/OverlayStack.js" + }, + "./src/OverlayTrigger.js": { + "development": "./src/OverlayTrigger.dev.js", + "default": "./src/OverlayTrigger.js" + }, + "./src/PlacementController.js": { + "development": "./src/PlacementController.dev.js", + "default": "./src/PlacementController.js" + }, + "./src/VirtualTrigger.js": { + "development": "./src/VirtualTrigger.dev.js", + "default": "./src/VirtualTrigger.js" + }, + "./src/events.js": { + "development": "./src/events.dev.js", + "default": "./src/events.js" + }, + "./src/fullSizePlugin.js": { + "development": "./src/fullSizePlugin.dev.js", + "default": "./src/fullSizePlugin.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/loader.js": { + "development": "./src/loader.dev.js", + "default": "./src/loader.js" + }, + "./src/overlay-events.js": { + "development": "./src/overlay-events.dev.js", + "default": "./src/overlay-events.js" + }, + "./src/overlay-timer.js": { + "development": "./src/overlay-timer.dev.js", + "default": "./src/overlay-timer.js" + }, + "./src/overlay-trigger-directive.js": { + "development": "./src/overlay-trigger-directive.dev.js", + "default": "./src/overlay-trigger-directive.js" + }, + "./src/overlay-trigger.css.js": "./src/overlay-trigger.css.js", + "./src/overlay-types.js": { + "development": "./src/overlay-types.dev.js", + "default": "./src/overlay-types.js" + }, + "./src/overlay.css.js": "./src/overlay.css.js", + "./src/slottable-request-directive.js": { + "development": "./src/slottable-request-directive.dev.js", + "default": "./src/slottable-request-directive.js" + }, + "./src/slottable-request-event.js": { + "development": "./src/slottable-request-event.dev.js", + "default": "./src/slottable-request-event.js" + }, + "./src/strategies.js": { + "development": "./src/strategies.dev.js", + "default": "./src/strategies.js" + }, + "./active-overlay.js": { + "development": "./active-overlay.dev.js", + "default": "./active-overlay.js" + }, + "./overlay-trigger.js": { + "development": "./overlay-trigger.dev.js", + "default": "./overlay-trigger.js" + }, + "./sync/overlay-trigger.js": { + "development": "./sync/overlay-trigger.dev.js", + "default": "./sync/overlay-trigger.js" + }, + "./sp-overlay.js": { + "development": "./sp-overlay.dev.js", + "default": "./sp-overlay.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@floating-ui/dom": "1.7.4", + "@floating-ui/utils": "0.2.10", + "@spectrum-web-components/action-button": "1.9.0", + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0", + "@spectrum-web-components/theme": "1.9.0", + "focus-trap": "7.6.5" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./active-overlay.js", + "./overlay-trigger.js", + "./sp-overlay.js", + "./sync/overlay-trigger.js", + "./stories/overlay-story-components.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/overlay/slottable-request.md b/1st-gen/packages/overlay/slottable-request.md new file mode 100644 index 00000000000..60a7309232f --- /dev/null +++ b/1st-gen/packages/overlay/slottable-request.md @@ -0,0 +1,148 @@ + +
+ Experimental Feature +
+
+ The slottable-request event system is experimental. Its shape and presence in the library may change. For stable overlay content management, consider using sp-overlay or Overlay.open(). +
+
+ +## Overview + +The `slottable-request` event provides a performance optimization mechanism for overlays with large content. Instead of keeping large amounts of content in the DOM at all times, an empty `` can be used initially. The overlay will dispatch `slottable-request` events just before opening and after closing, allowing content to be lazily rendered and removed as needed. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/overlay?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/overlay) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/overlay?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/overlay) + +```zsh +yarn add @spectrum-web-components/overlay +``` + +Import the side effectful registration of `` via: + +```ts +import '@spectrum-web-components/overlay/sp-overlay.js'; +``` + +For type information and utilities, import: + +```ts +import { + removeSlottableRequest, + SlottableRequestEvent, +} from '@spectrum-web-components/overlay/src/slottable-request-event.js'; +``` + +### Example + +#### Basic usage + +Here's a basic example of using `slottable-request` with vanilla JavaScript: + +```html-live +Trigger + + + +``` + + + +### Options + +#### Event data + +The `SlottableRequestEvent` includes the following properties: + +- `data`: Contains either an empty object (when opening) or the `removeSlottableRequest` symbol (when closing) +- `name`: The name of the request +- `slotName`: The slot name, optionally with a key appended + +### Advanced topics + +#### Event timing + +The `slottable-request` event is dispatched at specific times: + +1. Just before the overlay begins to open +2. Just after the overlay finishes closing + +This timing ensures proper coordination with overlay transitions and animations. + +#### Memory management + +By starting with an empty overlay and removing content when closed, applications can better manage memory usage, especially when dealing with: + +- Large DOM trees +- Complex components +- Multiple overlays +- Resource-intensive content + +#### Integration with Lit + +For Lit-based applications, a directive is available for handling slottable requests: + +```ts +import { slottableRequest } from '@spectrum-web-components/overlay/src/slottable-request-directive.js'; + +// Use in a lit template +html` + html` + +

Lazily rendered content

+
+ ` + )} + >
+`; +``` diff --git a/1st-gen/packages/overlay/sp-overlay.ts b/1st-gen/packages/overlay/sp-overlay.ts new file mode 100644 index 00000000000..3f5e2e1f908 --- /dev/null +++ b/1st-gen/packages/overlay/sp-overlay.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; +import { Overlay } from './src/Overlay.js'; + +defineElement('sp-overlay', Overlay); + +declare global { + interface HTMLElementTagNameMap { + 'sp-overlay': Overlay; + } +} diff --git a/1st-gen/packages/overlay/src/AbstractOverlay.ts b/1st-gen/packages/overlay/src/AbstractOverlay.ts new file mode 100644 index 00000000000..e02e80f8135 --- /dev/null +++ b/1st-gen/packages/overlay/src/AbstractOverlay.ts @@ -0,0 +1,343 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { SpectrumElement } from '@spectrum-web-components/base'; +import { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js'; + +import type { + OpenableElement, + OverlayOptions, + OverlayOptionsV1, + OverlayState, + OverlayTypes, + Placement, + TriggerInteractionsV1, +} from './overlay-types.js'; +import type { Overlay } from './Overlay.js'; +import type { VirtualTrigger } from './VirtualTrigger.js'; +import { OverlayTimer } from './overlay-timer.js'; +import type { PlacementController } from './PlacementController.js'; +import type { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js'; + +export const overlayTimer = new OverlayTimer(); + +export const noop = (): void => { + return; +}; + +/** + * Apply a "transitionend" listener to an element that may not transition but + * guarantee the callback will be fired either way. + * + * @param el {HTMLElement} - Target of the "transition" listeners. + * @param action {Function} - Method to trigger the "transition". + * @param cb {Function} - Callback to trigger when the "transition" has ended. + */ +export const guaranteedAllTransitionend = ( + el: HTMLElement, + action: () => void, + cb: () => void +): void => { + const abortController = new AbortController(); + const runningTransitions = new Map(); + const cleanup = (): void => { + abortController.abort(); + cb(); + }; + let guarantee2: number; + let guarantee3: number; + // WebKit fires `transitionrun` a little earlier, the multiple guarantees here + // allow WebKit to be caught, but doesn't remove the animation listener until + // after it would have fired in Chromium. + const guarantee1 = requestAnimationFrame(() => { + guarantee2 = requestAnimationFrame(() => { + guarantee3 = requestAnimationFrame(() => { + cleanup(); + }); + }); + }); + const handleTransitionend = (event: TransitionEvent): void => { + if (event.target !== el) { + return; + } + runningTransitions.set( + event.propertyName, + (runningTransitions.get(event.propertyName) as number) - 1 + ); + if (!runningTransitions.get(event.propertyName)) { + runningTransitions.delete(event.propertyName); + } + if (runningTransitions.size === 0) { + cleanup(); + } + }; + const handleTransitionrun = (event: TransitionEvent): void => { + if (event.target !== el) { + return; + } + if (!runningTransitions.has(event.propertyName)) { + runningTransitions.set(event.propertyName, 0); + } + runningTransitions.set( + event.propertyName, + (runningTransitions.get(event.propertyName) as number) + 1 + ); + cancelAnimationFrame(guarantee1); + cancelAnimationFrame(guarantee2); + cancelAnimationFrame(guarantee3); + }; + el.addEventListener('transitionrun', handleTransitionrun, { + signal: abortController.signal, + }); + el.addEventListener('transitionend', handleTransitionend, { + signal: abortController.signal, + }); + el.addEventListener('transitioncancel', handleTransitionend, { + signal: abortController.signal, + }); + action(); +}; + +export function nextFrame(): Promise { + return new Promise((res) => requestAnimationFrame(() => res())); +} + +/** + * Abstract Overlay base class so that property tyings and imperative API + * interfaces can be held separate from the actual class definition. + */ +export class AbstractOverlay extends SpectrumElement { + protected async applyFocus( + _targetOpenState: boolean, + _focusEl: HTMLElement | null + ): Promise { + return; + } + /* c8 ignore next 6 */ + get delayed(): boolean { + return false; + } + set delayed(_delayed: boolean) { + return; + } + dialogEl!: HTMLDialogElement & { + showPopover(): void; + hidePopover(): void; + }; + /* c8 ignore next 6 */ + get disabled(): boolean { + return false; + } + set disabled(_disabled: boolean) { + return; + } + dispose = noop; + protected get elementResolver(): ElementResolutionController { + return this._elementResolver; + } + protected set elementResolver(controller) { + this._elementResolver = controller; + } + protected _elementResolver!: ElementResolutionController; + /* c8 ignore next 3 */ + protected async ensureOnDOM(_targetOpenState: boolean): Promise { + return; + } + elements!: OpenableElement[]; + /* c8 ignore next 5 */ + protected async makeTransition( + _targetOpenState: boolean + ): Promise { + return null; + } + protected async manageDelay(_targetOpenState: boolean): Promise { + return; + } + /* c8 ignore next 3 */ + protected async managePopoverOpen(): Promise { + return; + } + /* c8 ignore next 3 */ + protected managePosition(): void { + return; + } + protected offset: number | [number, number] = 0; + /* c8 ignore next 6 */ + get open(): boolean { + return false; + } + set open(_open: boolean) { + return; + } + placement?: Placement; + protected get placementController(): PlacementController { + return this._placementController; + } + protected set placementController(controller) { + this._placementController = controller; + } + protected _placementController!: PlacementController; + receivesFocus!: 'true' | 'false' | 'auto'; + protected requestSlottable(): void {} + protected returnFocus(): void { + return; + } + /* c8 ignore next 6 */ + get state(): OverlayState { + return 'closed'; + } + set state(_state: OverlayState) { + return; + } + protected _state!: OverlayState; + triggerElement!: HTMLElement | VirtualTrigger | null; + type!: OverlayTypes; + willPreventClose = false; + /* c8 ignore next 3 */ + public manuallyKeepOpen(): void { + return; + } + + public static update(): void { + const overlayUpdateEvent = new CustomEvent('sp-update-overlays', { + bubbles: true, + composed: true, + cancelable: true, + }); + document.dispatchEvent(overlayUpdateEvent); + } + + // @TODO remove this long standing legacy API + /** + * Overloaded imperative API entry point that allows for both the pre-0.37.0 + * argument signature as well as the post-0.37.0 signature. This allows for + * consumers to continue to leverage it as they had been in previous releases + * while also surfacing the more feature-rich API that has been made available. + */ + public static async open( + trigger: HTMLElement, + interaction: TriggerInteractionsV1, + content: HTMLElement, + optionsV1: OverlayOptionsV1 + ): Promise<() => void>; + public static async open( + content: HTMLElement, + options?: OverlayOptions + ): Promise; + public static async open( + triggerOrContent: HTMLElement, + interactionOrOptions: + | TriggerInteractionsV1 + | OverlayOptions + | undefined, + content?: HTMLElement, + optionsV1?: OverlayOptionsV1 + ): Promise void)> { + // eslint-disable-next-line import/no-extraneous-dependencies + await import('@spectrum-web-components/overlay/sp-overlay.js'); + const v2 = arguments.length === 2; + const overlayContent = content || triggerOrContent; + // Use the `this` from the `static` method context rather than a + // specific imported constructor to prevent opening a circular dependency. + const overlay = new this() as Overlay; + let restored = false; + overlay.dispose = () => { + overlay.addEventListener('sp-closed', () => { + if (!restored) { + restoreContent(); + restored = true; + } + requestAnimationFrame(() => { + overlay.remove(); + }); + }); + overlay.open = false; + overlay.dispose = noop; + }; + /** + * Since content must exist in an , we need a way to get it there. + * The best & most-direct way is to declaratively use an element, + * but for imperative users, we'll reparent content into an overlay that we've created for them. + **/ + const restoreContent = reparentChildren([overlayContent], overlay, { + position: 'beforeend', + prepareCallback: (el) => { + // Ensure that content to be overlaid is no longer targetted to a specific `slot`. + // This allow for it to be visible in the overlaid context. + const slot = el.slot; + el.removeAttribute('slot'); + return () => { + el.slot = slot; + }; + }, + }); + + const v1 = !v2 && overlayContent && optionsV1; + if (v1) { + if (window.__swc.DEBUG) { + window.__swc.warn( + overlay, + `You are interacting with an ${overlay.localName} element via a deprecated imperative API. This API will be removed in a future version of the SWC library. Consider leveraging an ${overlay.localName} directly.`, + 'https://opensource.adobe.com/spectrum-web-components/components/overlay/', + { level: 'deprecation' } + ); + } + const trigger = triggerOrContent; + const interaction = interactionOrOptions; + const options = optionsV1; + AbstractOverlay.applyOptions(overlay, { + ...options, + delayed: + options.delayed || overlayContent.hasAttribute('delayed'), + trigger: options.virtualTrigger || trigger, + type: + interaction === 'modal' + ? 'modal' + : interaction === 'hover' + ? 'hint' + : 'auto', + }); + trigger.insertAdjacentElement('afterend', overlay); + await overlay.updateComplete; + overlay.open = true; + return overlay.dispose; + } + + const options = interactionOrOptions as OverlayOptions; + overlay.append(overlayContent); + AbstractOverlay.applyOptions(overlay, { + ...options, + delayed: options.delayed || overlayContent.hasAttribute('delayed'), + }); + overlay.updateComplete.then(() => { + // Do we want to "open" this path, or leave that to the consumer? + overlay.open = true; + }); + return overlay; + } + + static applyOptions( + overlay: AbstractOverlay, + options: OverlayOptions + ): void { + overlay.delayed = !!options.delayed; + overlay.receivesFocus = options.receivesFocus ?? 'auto'; + overlay.triggerElement = options.trigger || null; + overlay.type = options.type || 'modal'; + overlay.offset = options.offset ?? 0; + overlay.placement = options.placement; + overlay.willPreventClose = !!options.notImmediatelyClosable; + } + + override disconnectedCallback(): void { + super.disconnectedCallback(); + } +} diff --git a/1st-gen/packages/overlay/src/ClickController.ts b/1st-gen/packages/overlay/src/ClickController.ts new file mode 100644 index 00000000000..ca5b4d92478 --- /dev/null +++ b/1st-gen/packages/overlay/src/ClickController.ts @@ -0,0 +1,54 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + InteractionController, + InteractionTypes, +} from './InteractionController.js'; + +export class ClickController extends InteractionController { + override type = InteractionTypes.click; + + /** + * An overlay with a `click` interaction should not close on click `triggerElement`. + * When a click is initiated (`pointerdown`), apply `preventNextToggle` when the + * overlay is `open` to prevent from toggling the overlay when the click event + * propagates later in the interaction. + */ + private preventNextToggle = false; + + handleClick(): void { + if (!this.preventNextToggle) { + this.open = !this.open; + } + this.preventNextToggle = false; + } + + handlePointerdown(): void { + this.preventNextToggle = this.open; + } + + override init(): void { + // Clean up listeners if they've already been bound + this.abortController?.abort(); + this.abortController = new AbortController(); + const { signal } = this.abortController; + this.target.addEventListener('click', () => this.handleClick(), { + signal, + }); + this.target.addEventListener( + 'pointerdown', + () => this.handlePointerdown(), + { signal } + ); + } +} diff --git a/1st-gen/packages/overlay/src/HoverController.ts b/1st-gen/packages/overlay/src/HoverController.ts new file mode 100644 index 00000000000..490f22bbc45 --- /dev/null +++ b/1st-gen/packages/overlay/src/HoverController.ts @@ -0,0 +1,262 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js'; +import { isWebKit } from '@spectrum-web-components/shared'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; +import { noop } from './AbstractOverlay.js'; +import { + InteractionController, + InteractionTypes, + lastInteractionType, +} from './InteractionController.js'; + +export class HoverController extends InteractionController { + override type = InteractionTypes.hover; + + private elementIds: string[] = []; + + private targetFocused = false; + + private hoverTimeout?: ReturnType; + + private hovering = false; + + private overlayFocused = false; + + handleKeyup(event: KeyboardEvent): void { + if (event.code === 'Tab') { + this.open = true; + } else if (event.code === 'Escape') { + if (this.open) { + event.preventDefault(); + event.stopPropagation(); + this.open = false; + // Return focus to trigger element + if (this.target) { + this.target.focus(); + } + } + } + } + + handleTargetFocusin(): void { + if (!this.target.matches(':focus-visible')) { + return; + } + + if ( + isWebKit() && + this.target[lastInteractionType] === InteractionTypes.click + ) { + return; + } + + this.open = true; + this.targetFocused = true; + } + + handleTargetFocusout(): void { + this.targetFocused = false; + // Don't close immediately if pointer is over the content + if (this.hovering) return; + // Use delay to allow focus to move into overlay content + this.doFocusleave(); + } + + private clearCloseTimeout(): void { + if (this.hoverTimeout) { + clearTimeout(this.hoverTimeout); + this.hoverTimeout = undefined; + } + } + + handleTargetPointerenter(): void { + this.clearCloseTimeout(); + if (this.overlay?.disabled) return; + this.open = true; + this.hovering = true; + } + + handleTargetPointerleave(): void { + this.doPointerleave(); + } + + // set a timeout once the pointer enters and the overlay is shown + // give the user time to enter the overlay + handleHostPointerenter(): void { + this.clearCloseTimeout(); + } + + handleHostPointerleave(): void { + this.doPointerleave(); + } + + handleOverlayFocusin(): void { + this.overlayFocused = true; + // Clear any pending close timeout when focus enters overlay + this.clearCloseTimeout(); + } + + handleOverlayFocusout(): void { + this.overlayFocused = false; + // Don't close immediately if pointer is over the content or trigger has focus + if (this.hovering) return; + if (this.targetFocused && this.target.matches(':focus-visible')) return; + // Use delay before closing + this.doFocusleave(); + } + + override prepareDescription(): void { + // require "content" to apply relationship + if (!this.overlay.elements.length) return; + + const triggerRoot = this.target.getRootNode(); + const contentRoot = this.overlay.elements[0].getRootNode(); + const overlayRoot = this.overlay.getRootNode(); + if (triggerRoot === overlayRoot) { + this.prepareOverlayRelativeDescription(); + } else if (triggerRoot === contentRoot) { + this.prepareContentRelativeDescription(); + } + } + + private prepareOverlayRelativeDescription(): void { + const releaseDescription = conditionAttributeWithId( + this.target, + 'aria-describedby', + [this.overlay.id] + ); + this.releaseDescription = () => { + releaseDescription(); + this.releaseDescription = noop; + }; + } + + private prepareContentRelativeDescription(): void { + const elementIds: string[] = []; + const appliedIds = this.overlay.elements.map((el) => { + elementIds.push(el.id); + if (!el.id) { + el.id = `${this.overlay.tagName.toLowerCase()}-helper-${randomID()}`; + } + return el.id; + }); + this.elementIds = elementIds; + const releaseDescription = conditionAttributeWithId( + this.target, + 'aria-describedby', + appliedIds + ); + this.releaseDescription = () => { + releaseDescription(); + this.overlay.elements.map((el, index) => { + el.id = this.elementIds[index]; + }); + this.releaseDescription = noop; + }; + } + + private scheduleClose(): void { + this.hoverTimeout = setTimeout(() => { + this.open = false; + }, 300); + } + + private doPointerleave(): void { + this.hovering = false; + const triggerElement = this.target as HTMLElement; + if (this.targetFocused && triggerElement.matches(':focus-visible')) + return; + // Don't close if focus is within overlay content + if (this.overlayFocused) return; + + this.scheduleClose(); + } + + private doFocusleave(): void { + // Clear any existing timeout + this.clearCloseTimeout(); + + // Use same delay as pointer interactions for consistency + if (!this.targetFocused && !this.overlayFocused && !this.hovering) { + this.scheduleClose(); + } + } + + override init(): void { + // Clean up listeners if they've already been bound + this.abortController?.abort(); + this.abortController = new AbortController(); + const { signal } = this.abortController; + this.target.addEventListener( + 'keyup', + (event) => this.handleKeyup(event), + { signal } + ); + this.target.addEventListener( + 'focusin', + () => this.handleTargetFocusin(), + { signal } + ); + this.target.addEventListener( + 'focusout', + () => this.handleTargetFocusout(), + { signal } + ); + this.target.addEventListener( + 'pointerenter', + () => this.handleTargetPointerenter(), + { signal } + ); + this.target.addEventListener( + 'pointerleave', + () => this.handleTargetPointerleave(), + { signal } + ); + if (this.overlay) { + this.initOverlay(); + } + } + + override initOverlay(): void { + if (!this.abortController) { + return; + } + const { signal } = this.abortController; + this.overlay.addEventListener( + 'pointerenter', + () => this.handleHostPointerenter(), + { signal } + ); + this.overlay.addEventListener( + 'pointerleave', + () => this.handleHostPointerleave(), + { signal } + ); + this.overlay.addEventListener( + 'focusin', + () => this.handleOverlayFocusin(), + { signal } + ); + this.overlay.addEventListener( + 'focusout', + () => this.handleOverlayFocusout(), + { signal } + ); + this.overlay.addEventListener( + 'keyup', + (event) => this.handleKeyup(event), + { signal } + ); + } +} diff --git a/1st-gen/packages/overlay/src/InteractionController.ts b/1st-gen/packages/overlay/src/InteractionController.ts new file mode 100644 index 00000000000..c9f9278409e --- /dev/null +++ b/1st-gen/packages/overlay/src/InteractionController.ts @@ -0,0 +1,145 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { ReactiveController } from '@spectrum-web-components/base'; +import { AbstractOverlay } from './AbstractOverlay.js'; + +export enum InteractionTypes { + click = 'click', + hover = 'hover', + longpress = 'longpress', +} + +export const lastInteractionType = Symbol('lastInteractionType'); + +export type ControllerOptions = { + overlay?: AbstractOverlay; + handleOverlayReady?: (overlay: AbstractOverlay) => void; + isPersistent?: boolean; +}; + +type InteractionTarget = HTMLElement & { + [lastInteractionType]?: InteractionTypes; +}; + +export class InteractionController implements ReactiveController { + abortController!: AbortController; + + get activelyOpening(): boolean { + return false; + } + + private handleOverlayReady?: (overlay: AbstractOverlay) => void; + + // Holds optimistic open state when an Overlay is not yet present + private isLazilyOpen = false; + + public get open(): boolean { + return this.overlay?.open ?? this.isLazilyOpen; + } + + /** + * Set `open` against the associated Overlay lazily. + */ + public set open(open: boolean) { + if (open === this.open) return; + this.isLazilyOpen = open; + if (this.overlay) { + // If there already is an Overlay, apply the value of `open` directly. + this.overlay.open = open; + this.target[lastInteractionType] = this.type; + return; + } + if (!open) { + // When `open` moves to `false` and there is not yet an Overlay, + // assume that no Overlay and a closed Overlay are the same and return early. + return; + } + // When there is no Overlay and `open` is moving to `true`, lazily import/create + // an Overlay and apply that state to it. + customElements + .whenDefined('sp-overlay') + .then(async (): Promise => { + const { Overlay } = await import('./Overlay.js'); + this.overlay = new Overlay(); + this.overlay.open = true; + this.target[lastInteractionType] = this.type; + }); + import('@spectrum-web-components/overlay/sp-overlay.js'); + } + + public get overlay(): AbstractOverlay { + return this._overlay; + } + + public set overlay(overlay: AbstractOverlay | undefined) { + if (!overlay) return; + if (this.overlay === overlay) return; + if (this.overlay) { + this.overlay.removeController(this); + } + this._overlay = overlay; + this.overlay.addController(this); + this.initOverlay(); + this.prepareDescription(this.target); + this.handleOverlayReady?.(this.overlay); + } + + private _overlay!: AbstractOverlay; + + protected isPersistent = false; + + type!: InteractionTypes; + + constructor( + public target: InteractionTarget, + { overlay, isPersistent, handleOverlayReady }: ControllerOptions + ) { + this.isPersistent = !!isPersistent; + this.handleOverlayReady = handleOverlayReady; + if (this.isPersistent) { + this.init(); + } + this.overlay = overlay; + } + + prepareDescription(_: HTMLElement): void {} + + releaseDescription(): void {} + + shouldCompleteOpen(): void {} + + /* c8 ignore next 3 */ + init(): void { + // Abstract init() method. + } + + /* c8 ignore next 3 */ + initOverlay(): void { + // Abstract initOverlay() method. + } + + abort(): void { + this.releaseDescription(); + this.abortController?.abort(); + } + + hostConnected(): void { + this.init(); + } + + hostDisconnected(): void { + if (!this.isPersistent) { + this.abort(); + } + } +} diff --git a/1st-gen/packages/overlay/src/LongpressController.ts b/1st-gen/packages/overlay/src/LongpressController.ts new file mode 100644 index 00000000000..8cf38bb6d76 --- /dev/null +++ b/1st-gen/packages/overlay/src/LongpressController.ts @@ -0,0 +1,212 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + isAndroid, + isIOS, +} from '@spectrum-web-components/shared/src/platform.js'; +import { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; + +import { noop } from './AbstractOverlay.js'; +import { + InteractionController, + InteractionTypes, +} from './InteractionController.js'; + +const LONGPRESS_DURATION = 300; +export const LONGPRESS_INSTRUCTIONS = { + touch: 'Double tap and long press for additional options', + keyboard: 'Press Space or Alt+Down Arrow for additional options', + mouse: 'Click and hold for additional options', +}; + +type LongpressEvent = { + source: 'pointer' | 'keyboard'; +}; + +export class LongpressController extends InteractionController { + override type = InteractionTypes.longpress; + + override get activelyOpening(): boolean { + return ( + this.longpressState === 'opening' || + this.longpressState === 'pressed' + ); + } + + protected longpressState: null | 'potential' | 'opening' | 'pressed' = null; + + override releaseDescription = noop; + + private timeout!: ReturnType; + + handleLongpress(): void { + this.open = true; + this.longpressState = + this.longpressState === 'potential' ? 'opening' : 'pressed'; + } + + handlePointerdown(event: PointerEvent): void { + if (!this.target) return; + if (event.button !== 0) return; + this.longpressState = 'potential'; + document.addEventListener('pointerup', this.handlePointerup); + document.addEventListener('pointercancel', this.handlePointerup); + // Only dispatch longpress event if the trigger element isn't doing it for us. + const triggerHandlesLongpress = 'holdAffordance' in this.target; + if (triggerHandlesLongpress) return; + this.timeout = setTimeout(() => { + if (!this.target) return; + this.target.dispatchEvent( + new CustomEvent('longpress', { + bubbles: true, + composed: true, + detail: { + source: 'pointer', + }, + }) + ); + }, LONGPRESS_DURATION); + } + + private handlePointerup = (): void => { + clearTimeout(this.timeout); + if (!this.target) return; + // When triggered by the pointer, the last of `opened` + // or `pointerup` should move the `longpressState` to + // `null` so that the earlier event can void the "light + // dismiss" and keep the Overlay open. + this.longpressState = + this.overlay?.state === 'opening' ? 'pressed' : null; + document.removeEventListener('pointerup', this.handlePointerup); + document.removeEventListener('pointercancel', this.handlePointerup); + }; + + private handleKeydown(event: KeyboardEvent): void { + const { code, altKey } = event; + if (altKey && code === 'ArrowDown') { + event.stopPropagation(); + event.stopImmediatePropagation(); + } + } + + private handleKeyup(event: KeyboardEvent): void { + const { code, altKey } = event; + if (code === 'Space' || (altKey && code === 'ArrowDown')) { + if (!this.target) { + return; + } + event.stopPropagation(); + this.target.dispatchEvent( + new CustomEvent('longpress', { + bubbles: true, + composed: true, + detail: { + source: 'keyboard', + }, + }) + ); + setTimeout(() => { + this.longpressState = null; + }); + } + } + + override prepareDescription(trigger: HTMLElement): void { + if ( + // do not reapply until target is recycled + this.releaseDescription !== noop || + // require "longpress content" to apply relationship + !this.overlay.elements.length + ) { + return; + } + + const longpressDescription = document.createElement('div'); + longpressDescription.id = `longpress-describedby-descriptor-${randomID()}`; + const messageType = isIOS() || isAndroid() ? 'touch' : 'keyboard'; + longpressDescription.textContent = LONGPRESS_INSTRUCTIONS[messageType]; + longpressDescription.slot = 'longpress-describedby-descriptor'; + const triggerParent = trigger.getRootNode() as HTMLElement; + const overlayParent = this.overlay.getRootNode() as HTMLElement; + // Manage the placement of the helper element in an accessible place with + // the lowest chance of negatively affecting the layout of the page. + if (triggerParent === overlayParent) { + // Trigger and Overlay in same DOM tree... + // Append helper element to Overlay. + this.overlay.append(longpressDescription); + } else { + // If Trigger in , hide helper + longpressDescription.hidden = !('host' in triggerParent); + // Trigger and Overlay in different DOM tree, Trigger in shadow tree... + // Insert helper element after Trigger. + trigger.insertAdjacentElement('afterend', longpressDescription); + } + + const releaseDescription = conditionAttributeWithId( + trigger, + 'aria-describedby', + [longpressDescription.id] + ); + this.releaseDescription = () => { + releaseDescription(); + longpressDescription.remove(); + this.releaseDescription = noop; + }; + } + + override shouldCompleteOpen(): void { + // When triggered by the pointer, the last of `opened` + // or `pointerup` should move the `longpressState` to + // `null` so that the earlier event can void the "light + // dismiss" and keep the Overlay open. + this.longpressState = + this.longpressState === 'pressed' ? null : this.longpressState; + } + + override init(): void { + // Clean up listeners if they've already been bound + this.abortController?.abort(); + this.abortController = new AbortController(); + const { signal } = this.abortController; + this.target.addEventListener( + 'longpress', + () => this.handleLongpress(), + { signal } + ); + this.target.addEventListener( + 'pointerdown', + (event: PointerEvent) => this.handlePointerdown(event), + { signal } + ); + + this.prepareDescription(this.target); + if ( + (this.target as HTMLElement & { holdAffordance: boolean }) + .holdAffordance + ) { + // Only bind keyboard events when the trigger element isn't doing it for us. + return; + } + this.target.addEventListener( + 'keydown', + (event: KeyboardEvent) => this.handleKeydown(event), + { signal } + ); + this.target.addEventListener( + 'keyup', + (event: KeyboardEvent) => this.handleKeyup(event), + { signal } + ); + } +} diff --git a/1st-gen/packages/overlay/src/Overlay.ts b/1st-gen/packages/overlay/src/Overlay.ts new file mode 100644 index 00000000000..f1ec3e07f29 --- /dev/null +++ b/1st-gen/packages/overlay/src/Overlay.ts @@ -0,0 +1,1214 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + html, + PropertyValues, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, + queryAssignedElements, + state, +} from '@spectrum-web-components/base/src/decorators.js'; +import { + ElementResolutionController, + elementResolverUpdatedSymbol, +} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js'; +import { + ifDefined, + StyleInfo, + styleMap, +} from '@spectrum-web-components/base/src/directives.js'; +import { randomID } from '@spectrum-web-components/shared/src/random-id.js'; +import type { + OpenableElement, + OverlayState, + OverlayTypes, + Placement, + TriggerInteraction, +} from './overlay-types.js'; +import { AbstractOverlay, nextFrame } from './AbstractOverlay.js'; +import { OverlayPopover } from './OverlayPopover.js'; +import { OverlayNoPopover } from './OverlayNoPopover.js'; +import { overlayStack } from './OverlayStack.js'; +import { VirtualTrigger } from './VirtualTrigger.js'; +import { PlacementController } from './PlacementController.js'; +import type { ClickController } from './ClickController.js'; +import type { HoverController } from './HoverController.js'; +import type { LongpressController } from './LongpressController.js'; +export { LONGPRESS_INSTRUCTIONS } from './LongpressController.js'; +import { strategies } from './strategies.js'; +import { + removeSlottableRequest, + SlottableRequestEvent, +} from './slottable-request-event.js'; + +import styles from './overlay.css.js'; +import { FocusTrap } from 'focus-trap'; + +const browserSupportsPopover = 'showPopover' in document.createElement('div'); + +// Start the base class and add the popover or no-popover functionality +let ComputedOverlayBase = OverlayPopover(AbstractOverlay); +if (!browserSupportsPopover) { + ComputedOverlayBase = OverlayNoPopover(AbstractOverlay); +} + +/** + * @element sp-overlay + * + * @slot default - The content that will be displayed in the overlay + * + * @fires sp-opened - announces that an overlay has completed any entry animations + * @fires sp-closed - announce that an overlay has compelted any exit animations + * @fires slottable-request - requests to add or remove slottable content + * + * @attr {string} placement - The placement of the overlay relative to the trigger + * @attr {number} offset - The distance between the overlay and the trigger + * @attr {boolean} disabled - Whether the overlay trigger is disabled + * @attr {string} receives-focus - How focus should be handled ('true'|'false'|'auto') + * @attr {boolean} delayed - Whether the overlay should wait for a warm-up period before opening + * @attr {boolean} open - Whether the overlay is currently open + * @attr {boolean} allow-outside-click - @deprecated Whether clicks outside the overlay should close it (not recommended for accessibility) + */ +export class Overlay extends ComputedOverlayBase { + static override styles = [styles]; + + /** + * An Overlay that is `delayed` will wait until a warm-up period of 1000ms + * has completed before opening. Once the warm-up period has completed, all + * subsequent Overlays will open immediately. When no Overlays are opened, + * a cool-down period of 1000ms will begin. Once the cool-down has completed, + * the next Overlay to be opened will be subject to the warm-up period if + * provided that option. + * + * This behavior helps to manage the performance and user experience by + * preventing multiple overlays from opening simultaneously and ensuring + * a smooth transition between opening and closing overlays. + * + * @type {boolean} + * @default false + */ + @property({ type: Boolean }) + override get delayed(): boolean { + return this.elements.at(-1)?.hasAttribute('delayed') || this._delayed; + } + + override set delayed(delayed: boolean) { + this._delayed = delayed; + } + + private _delayed = false; + + /** + * A reference to the dialog element within the overlay. + * This element is expected to have `showPopover` and `hidePopover` methods. + */ + @query('.dialog') + override dialogEl!: HTMLDialogElement & { + showPopover(): void; + hidePopover(): void; + }; + + /** + * Indicates whether the overlay is currently functional or not. + * + * When set to `true`, the overlay is disabled, and any active strategy is aborted. + * The overlay will also close if it is currently open. When set to `false`, the + * overlay will re-bind events and re-open if it was previously open. + * + * @type {boolean} + * @default false + */ + @property({ type: Boolean }) + override get disabled(): boolean { + return this._disabled; + } + + override set disabled(disabled: boolean) { + this._disabled = disabled; + if (disabled) { + // Abort any active strategy and close the overlay if it is currently open + this.strategy?.abort(); + this.wasOpen = this.open; + this.open = false; + } else { + // Re-bind events and re-open the overlay if it was previously open + this.bindEvents(); + this.open = this.open || this.wasOpen; + this.wasOpen = false; + } + } + + private _disabled = false; + + /** + * A query to gather all elements slotted into the default slot, excluding elements + * with the slot name "longpress-describedby-descriptor". + */ + @queryAssignedElements({ + flatten: true, + selector: ':not([slot="longpress-describedby-descriptor"], slot)', + }) + override elements!: OpenableElement[]; + + /** + * A reference to the parent overlay that should be force-closed, if any. + */ + public parentOverlayToForceClose?: Overlay; + + /** + * Determines if the overlay has a non-virtual trigger element. + * + * @returns {boolean} `true` if the trigger element is not a virtual trigger, otherwise `false`. + */ + private get hasNonVirtualTrigger(): boolean { + return ( + !!this.triggerElement && + !(this.triggerElement instanceof VirtualTrigger) + ); + } + + /** + * The `offset` property accepts either a single number to define the offset of the + * Overlay along the main axis from the trigger, or a 2-tuple to define the offset + * along both the main axis and the cross axis. This option has no effect when there + * is no trigger element. + * + * @type {number | [number, number]} + * @default 0 + */ + @property({ type: Number }) + override offset: number | [number, number] = 0; + + /** + * Provides an instance of the `PlacementController` for managing the positioning + * of the overlay relative to its trigger element. + * + * If the `PlacementController` instance does not already exist, it is created and + * assigned to the `_placementController` property. + * + * @protected + * @returns {PlacementController} The `PlacementController` instance. + */ + protected override get placementController(): PlacementController { + if (!this._placementController) { + this._placementController = new PlacementController(this); + } + return this._placementController; + } + + /** + * Indicates whether the Overlay is projected onto the "top layer" or not. + * + * When set to `true`, the overlay is open and visible. When set to `false`, the overlay is closed and hidden. + * + * @type {boolean} + * @default false + */ + @property({ type: Boolean, reflect: true }) + override get open(): boolean { + return this._open; + } + + override set open(open: boolean) { + // Don't respond if the overlay is disabled. + if (open && this.disabled) return; + + // Don't respond if the state is not changing. + if (open === this.open) return; + + // Don't respond if the overlay is in the shadow state during a longpress. + // The shadow state occurs when the first "click" would normally close the popover. + if (this.strategy?.activelyOpening && !open) return; + + // Update the internal _open property. + this._open = open; + + // Increment the open count if the overlay is opening. + if (this.open) { + Overlay.openCount += 1; + } + + // Request an update to re-render the component if necessary. + this.requestUpdate('open', !this.open); + + // Request slottable content if the overlay is opening. + if (this.open) { + this.requestSlottable(); + } + } + + private _open = false; + + /** + * Tracks the number of overlays that have been opened. + * + * This static property is used to manage the stacking context of multiple overlays. + * + * @type {number} + * @default 1 + */ + static openCount = 1; + + /** + * Instruct the Overlay where to place itself in relationship to the trigger element. + * + * @type {"top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end"} + */ + @property() + override placement?: Placement; + + /** + * The state in which the last `request-slottable` event was dispatched. + * + * This property ensures that overlays do not dispatch the same state twice in a row. + * + * @type {boolean} + * @default false + */ + private lastRequestSlottableState = false; + + /** + * Whether to pass focus to the overlay once opened, or + * to the appropriate value based on the "type" of the overlay + * when set to `"auto"`. + * + * @type {'true' | 'false' | 'auto'} + * @default 'auto' + */ + @property({ attribute: 'receives-focus' }) + override receivesFocus: 'true' | 'false' | 'auto' = 'auto'; + + /** + * @deprecated This property will be removed in a future version. + * We do not recommend using this property for accessibility reasons. + * It allows clicks outside the overlay to close it, which can cause + * unexpected behavior and accessibility issues. + * + * @type {boolean} + * @default false + */ + @property({ type: Boolean, attribute: 'allow-outside-click' }) + allowOutsideClick = false; + + /** + * A reference to the slot element within the overlay. + * + * This element is used to manage the content slotted into the overlay. + * + * @type {HTMLSlotElement} + */ + @query('slot') + slotEl!: HTMLSlotElement; + + /** + * The current state of the overlay. + * + * This property reflects the current state of the overlay, such as 'opened' or 'closed'. + * When the state changes, it triggers the appropriate actions and updates the component. + * + * @type {OverlayState} + * @default 'closed' + */ + @state() + override get state(): OverlayState { + return this._state; + } + + override set state(state) { + // Do not respond if the state is not changing. + if (state === this.state) return; + + const oldState = this.state; + + this._state = state; + + // Complete the opening strategy if the state is 'opened' or 'closed'. + if (this.state === 'opened' || this.state === 'closed') { + this.strategy?.shouldCompleteOpen(); + } + + // Request an update to re-render the component if necessary. + this.requestUpdate('state', oldState); + } + + override _state: OverlayState = 'closed'; + + /** + * The interaction strategy for opening the overlay. + * This can be a ClickController, HoverController, or LongpressController. + */ + public strategy?: ClickController | HoverController | LongpressController; + + /** + * The padding around the tip of the overlay. + * This property defines the padding around the tip of the overlay, which can be used to adjust its positioning. + * + * @type {number} + */ + @property({ type: Number, attribute: 'tip-padding' }) + tipPadding?: number; + + /** + * An optional ID reference for the trigger element combined with the optional + * interaction (click | hover | longpress) by which the overlay should open. + * The format is `trigger@interaction`, e.g., `trigger@click` opens the overlay + * when an element with the ID "trigger" is clicked. + * + * @type {string} + */ + @property() + trigger?: string; + + /** + * An element reference for the trigger element that the overlay should relate to. + * This property is not reflected as an attribute. + * + * @type {HTMLElement | VirtualTrigger | null} + */ + @property({ attribute: false }) + override triggerElement: HTMLElement | VirtualTrigger | null = null; + + /** + * The specific interaction to listen for on the `triggerElement` to open the overlay. + * This property is not reflected as an attribute. + * + * @type {TriggerInteraction} + */ + @property({ attribute: false }) + triggerInteraction?: TriggerInteraction; + + /** + * Configures the open/close heuristics of the Overlay. + * + * @type {"auto" | "hint" | "manual" | "modal" | "page"} + * @default "auto" + */ + @property() + override type: OverlayTypes = 'auto'; + + /** + * Tracks whether the overlay was previously open. + * This is used to restore the open state when re-enabling the overlay. + * + * @type {boolean} + * @default false + */ + protected wasOpen = false; + + /** + * Focus trap to keep focus within the dialog + * @private + */ + private _focusTrap: FocusTrap | null = null; + + /** + * Provides an instance of the `ElementResolutionController` for managing the element + * that the overlay should be associated with. If the instance does not already exist, + * it is created and assigned to the `_elementResolver` property. + * + * @protected + * @returns {ElementResolutionController} The `ElementResolutionController` instance. + */ + protected override get elementResolver(): ElementResolutionController { + if (!this._elementResolver) { + this._elementResolver = new ElementResolutionController(this); + } + + return this._elementResolver; + } + + /** + * Determines the value for the popover attribute based on the overlay type. + * + * @private + * @returns {'auto' | 'manual' | undefined} The popover value or undefined if not applicable. + */ + private get popoverValue(): 'auto' | 'manual' | undefined { + const hasPopoverAttribute = 'popover' in this; + + if (!hasPopoverAttribute) { + return undefined; + } + + switch (this.type) { + case 'modal': + return 'auto'; + case 'page': + return 'manual'; + case 'hint': + return 'manual'; + default: + return this.type; + } + } + + /** + * Determines if the overlay requires positioning based on its type and state. + * + * @protected + * @returns {boolean} True if the overlay requires positioning, otherwise false. + */ + protected get requiresPositioning(): boolean { + // Do not position "page" overlays as they should block the entire UI. + if (this.type === 'page' || !this.open) return false; + + // Do not position content without a trigger element, as there is nothing to position it relative to. + // Do not automatically position content unless it is a "hint". + if (!this.triggerElement || (!this.placement && this.type !== 'hint')) + return false; + + return true; + } + + /** + * Manages the positioning of the overlay relative to its trigger element. + * + * This method calculates the necessary parameters for positioning the overlay, + * such as offset, placement, and tip padding, and then delegates the actual + * positioning to the `PlacementController`. + * + * @protected + * @override + */ + protected override managePosition(): void { + // Do not proceed if positioning is not required or the overlay is not open. + if (!this.requiresPositioning || !this.open) return; + + const offset = this.offset || 0; + + const trigger = this.triggerElement as HTMLElement; + + const placement = (this.placement as Placement) || 'right'; + + const tipPadding = this.tipPadding; + + this.placementController.placeOverlay(this.dialogEl, { + offset, + placement, + tipPadding, + trigger, + type: this.type, + }); + } + + /** + * Manages the process of opening the popover. + * + * This method handles the necessary steps to open the popover, including managing delays, + * ensuring the popover is in the DOM, making transitions, and applying focus. + * @protected + * @override + * @returns {Promise} A promise that resolves when the popover has been fully opened. + */ + protected override async managePopoverOpen(): Promise { + // Call the base class method to handle any initial setup. + super.managePopoverOpen(); + + const targetOpenState = this.open; + + // Ensure the open state has not changed before proceeding. + if (this.open !== targetOpenState) { + return; + } + + // Manage any delays before opening the popover. + await this.manageDelay(targetOpenState); + + if (this.open !== targetOpenState) { + return; + } + + // Only wait for next frame if `longpress` is the trigger. + // In Safari, awaiting nextFrame here causes layout issues + // when rendering trays inside modals, so we skip it otherwise. + if (this.triggerInteraction === 'longpress') { + await nextFrame(); + } + + // Ensure the popover is in the DOM before proceeding. + await this.ensureOnDOM(targetOpenState); + + if (this.open !== targetOpenState) { + return; + } + + // Make any necessary transitions for opening the popover. + const focusEl = await this.makeTransition(targetOpenState); + + if (this.open !== targetOpenState) { + return; + } + if (targetOpenState) { + const focusTrap = await import('focus-trap'); + this._focusTrap = focusTrap.createFocusTrap(this.dialogEl, { + initialFocus: focusEl || undefined, + tabbableOptions: { + getShadowRoot: true, + }, + fallbackFocus: () => { + // set tabIndex to -1 allow the focus-trap to still be applied + this.dialogEl.setAttribute('tabIndex', '-1'); + return this.dialogEl; + }, + // disable escape key capture to close the overlay, the focus-trap library captures it otherwise + escapeDeactivates: false, + allowOutsideClick: this.allowOutsideClick, + }); + + if (this.type === 'modal' || this.type === 'page') { + this._focusTrap.activate(); + } + } + // Apply focus to the appropriate element after opening the popover. + await this.applyFocus(targetOpenState, focusEl); + } + + /** + * Applies focus to the appropriate element after the popover has been opened. + * + * This method handles the focus management for the overlay, ensuring that the correct + * element receives focus based on the overlay's type and state. + * + * @protected + * @override + * @param {boolean} targetOpenState - The target open state of the overlay. + * @param {HTMLElement | null} focusEl - The element to focus after opening the popover. + * @returns {Promise} A promise that resolves when the focus has been applied. + */ + protected override async applyFocus( + targetOpenState: boolean, + focusEl: HTMLElement | null + ): Promise { + // Do not move focus when explicitly told not to or when the overlay is a "hint". + if (this.receivesFocus === 'false' || this.type === 'hint') { + return; + } + + // Wait for the next two animation frames to ensure the DOM is updated. + await nextFrame(); + await nextFrame(); + + // If the open state has changed during the delay, do not proceed. + if (targetOpenState === this.open && !this.open) { + // If the overlay is closing and the trigger element is still focused, return focus to the trigger element. + if ( + this.hasNonVirtualTrigger && + this.contains((this.getRootNode() as Document).activeElement) + ) { + (this.triggerElement as HTMLElement).focus(); + } + return; + } + + // Apply focus to the specified focus element. + focusEl?.focus(); + } + + /** + * Returns focus to the trigger element if the overlay is closed. + * + * This method ensures that focus is returned to the trigger element when the overlay is closed, + * unless the overlay is of type "hint" or the focus is already outside the overlay. + * + * @protected + * @override + */ + protected override returnFocus(): void { + // Do not proceed if the overlay is open or if the overlay type is "hint". + if (this.open || this.type === 'hint') return; + + /** + * Retrieves the ancestors of the currently focused element. + * + * @returns {HTMLElement[]} An array of ancestor elements. + */ + const getAncestors = (): HTMLElement[] => { + const ancestors: HTMLElement[] = []; + + // eslint-disable-next-line @spectrum-web-components/document-active-element + let currentNode = document.activeElement; + + // Traverse the shadow DOM to find the active element. + while (currentNode?.shadowRoot?.activeElement) { + currentNode = currentNode.shadowRoot.activeElement; + } + + // Traverse the DOM tree to collect ancestor elements. + while (currentNode) { + const ancestor = + currentNode.assignedSlot || + currentNode.parentElement || + (currentNode.getRootNode() as ShadowRoot)?.host; + if (ancestor) { + ancestors.push(ancestor as HTMLElement); + } + currentNode = ancestor; + } + return ancestors; + }; + + // Check if focus should be returned to the trigger element. + if ( + this.receivesFocus !== 'false' && + !!(this.triggerElement as HTMLElement)?.focus && + (this.contains((this.getRootNode() as Document).activeElement) || + getAncestors().includes(this) || + // eslint-disable-next-line @spectrum-web-components/document-active-element + document.activeElement === document.body) + ) { + // Return focus to the trigger element. + (this.triggerElement as HTMLElement).focus(); + } + } + + /** + * Handles the focus out event to close the overlay if the focus moves outside of it. + * + * This method ensures that the overlay is closed when the focus moves to an element + * outside of the overlay, unless the focus is moved to a related element. + * + * @private + * @param {FocusEvent} event - The focus out event. + */ + private closeOnFocusOut = (event: FocusEvent): void => { + // If the related target (newly focused element) is not known, do nothing. + if (!event.relatedTarget) { + return; + } + + // Create a custom event to query the relationship of the newly focused element. + const relationEvent = new Event('overlay-relation-query', { + bubbles: true, + composed: true, + }); + + // Add an event listener to the related target to handle the custom event. + event.relatedTarget.addEventListener( + relationEvent.type, + (event: Event) => { + // Check if the newly focused element is within the overlay or its children + const path = event.composedPath(); + const isWithinOverlay = path.some((el) => el === this); + + // Only close if focus moves outside the overlay and its children + if (!isWithinOverlay) { + this.open = false; + } + } + ); + + // Dispatch the custom event to the related target. + event.relatedTarget.dispatchEvent(relationEvent); + }; + + private closeOnCancelEvent = (): void => { + this.open = false; + }; + + /** + * Manages the process of opening or closing the overlay. + * + * This method handles the necessary steps to open or close the overlay, including updating the state, + * managing the overlay stack, and handling focus events. + * + * @protected + * @param {boolean} oldOpen - The previous open state of the overlay. + * @returns {Promise} A promise that resolves when the overlay has been fully managed. + */ + protected async manageOpen(oldOpen: boolean): Promise { + // Prevent entering the manage workflow if the overlay is not connected to the DOM. + // The `.showPopover()` event will error on content that is not connected to the DOM. + if (!this.isConnected && this.open) return; + + // Wait for the component to finish updating if it has not already done so. + if (!this.hasUpdated) { + await this.updateComplete; + } + + if (this.open) { + // Add the overlay to the overlay stack. + overlayStack.add(this); + + if (this.willPreventClose) { + // Add an event listener to handle the pointerup event and toggle the 'not-immediately-closable' class. + document.addEventListener( + 'pointerup', + () => { + this.dialogEl.classList.toggle( + 'not-immediately-closable', + false + ); + this.willPreventClose = false; + }, + { once: true } + ); + this.dialogEl.classList.toggle( + 'not-immediately-closable', + true + ); + } + } else { + if (oldOpen) { + this._focusTrap?.deactivate(); + this._focusTrap = null; + // Dispose of the overlay if it was previously open. + this.dispose(); + } + + // Remove the overlay from the overlay stack. + overlayStack.remove(this); + } + + // Update the state of the overlay based on the open property. + if (this.open && this.state !== 'opened') { + this.state = 'opening'; + } else if (!this.open && this.state !== 'closed') { + this.state = 'closing'; + } + + this.managePopoverOpen(); + + const listenerRoot = this.getRootNode() as Document; + // Handle focus events for auto type overlays. + if (this.type === 'auto') { + if (this.open) { + listenerRoot.addEventListener( + 'focusout', + this.closeOnFocusOut, + { capture: true } + ); + } else { + listenerRoot.removeEventListener( + 'focusout', + this.closeOnFocusOut, + { capture: true } + ); + } + } + + // Handle cancel events for modal and page type overlays. + if (this.type === 'modal' || this.type === 'page') { + if (this.open) { + listenerRoot.addEventListener( + 'cancel', + this.closeOnCancelEvent, + { + capture: true, + } + ); + } else { + listenerRoot.removeEventListener( + 'cancel', + this.closeOnCancelEvent, + { + capture: true, + } + ); + } + } + } + + /** + * Binds event handling strategies to the overlay based on the specified trigger interaction. + * + * This method sets up the appropriate event handling strategy for the overlay, ensuring that + * it responds correctly to user interactions such as clicks, hovers, or long presses. + * + * @protected + */ + protected bindEvents(): void { + // Abort any existing strategy to ensure a clean setup. + this.strategy?.abort(); + this.strategy = undefined; + + // Return early if there is no non-virtual trigger element. + if (!this.hasNonVirtualTrigger) return; + + // Return early if no trigger interaction is specified. + if (!this.triggerInteraction) return; + + // Set up a new event handling strategy based on the specified trigger interaction. + this.strategy = new strategies[this.triggerInteraction]( + this.triggerElement as HTMLElement, + { + overlay: this, + } + ); + } + + /** + * Handles the `beforetoggle` event to manage the overlay's state. + * + * This method checks the new state of the event and calls `handleBrowserClose` + * if the new state is not 'open'. + * + * @protected + * @param {Event & { newState: string }} event - The `beforetoggle` event with the new state. + */ + protected handleBeforetoggle(event: Event & { newState: string }): void { + if (event.newState !== 'open') { + this.handleBrowserClose(event); + } + } + + /** + * Handles the browser's close event to manage the overlay's state. + * + * This method stops the propagation of the event and closes the overlay if it is not + * actively opening. If the overlay is actively opening, it calls `manuallyKeepOpen`. + * + * @protected + * @param {Event} event - The browser's close event. + */ + protected handleBrowserClose(event: Event): void { + event.stopPropagation(); + if (!this.strategy?.activelyOpening) { + this.open = false; + return; + } + this.manuallyKeepOpen(); + } + + /** + * Manually keeps the overlay open. + * + * This method sets the overlay to open, allows placement updates, and manages the open state. + * + * @public + * @override + */ + public override manuallyKeepOpen(): void { + this.open = true; + this.placementController.allowPlacementUpdate = true; + this.manageOpen(false); + } + + /** + * Handles the `slotchange` event to manage the overlay's state. + * + * This method checks if there are any elements in the slot. If there are no elements, + * it releases the description from the strategy. If there are elements and the trigger + * is non-virtual, it prepares the description for the trigger element. + * + * @protected + */ + protected handleSlotchange(): void { + if (!this.elements.length) { + // Release the description if there are no elements in the slot. + this.strategy?.releaseDescription(); + } else if (this.hasNonVirtualTrigger) { + // Prepare the description for the trigger element if it is non-virtual. + this.strategy?.prepareDescription( + this.triggerElement as HTMLElement + ); + } + } + + /** + * Determines whether the overlay should prevent closing. + * + * This method checks the `willPreventClose` flag and resets it to `false`. + * It returns the value of the `willPreventClose` flag. + * + * @public + * @returns {boolean} `true` if the overlay should prevent closing, otherwise `false`. + */ + public shouldPreventClose(): boolean { + const shouldPreventClose = this.willPreventClose; + this.willPreventClose = false; + return shouldPreventClose; + } + + /** + * Requests slottable content for the overlay. + * + * This method dispatches a `SlottableRequestEvent` to request or remove slottable content + * based on the current open state of the overlay. It ensures that the same state is not + * dispatched twice in a row. + * + * @protected + * @override + */ + protected override requestSlottable(): void { + // Do not dispatch the same state twice in a row. + if (this.lastRequestSlottableState === this.open) { + return; + } + + // Force a reflow if the overlay is closing. + if (!this.open) { + document.body.offsetHeight; + } + + /** + * @ignore + */ + // Dispatch a custom event to request or remove slottable content based on the open state. + this.dispatchEvent( + new SlottableRequestEvent( + 'overlay-content', + this.open ? {} : removeSlottableRequest + ) + ); + + // Update the last request slottable state. + this.lastRequestSlottableState = this.open; + } + + /** + * Lifecycle method called before the component updates. + * + * This method handles various tasks before the component updates, such as setting an ID, + * managing the open state, resolving the trigger element, and binding events. + * + * @override + * @param {PropertyValues} changes - The properties that have changed. + */ + override willUpdate(changes: PropertyValues): void { + // Ensure the component has an ID attribute. + if (!this.hasAttribute('id')) { + this.setAttribute( + 'id', + `${this.tagName.toLowerCase()}-${randomID()}` + ); + } + + // Warn about deprecated allowOutsideClick property + if (changes.has('allowOutsideClick') && this.allowOutsideClick) { + if (window.__swc?.DEBUG) { + window.__swc.warn( + this, + `The "allow-outside-click" attribute on <${this.localName}> has been deprecated and will be removed in a future release. We do not recommend using this attribute for accessibility reasons. It allows clicks outside the overlay to close it, which can cause unexpected behavior and accessibility issues.`, + 'https://opensource.adobe.com/spectrum-web-components/components/overlay/', + { level: 'deprecation' } + ); + } else { + // Fallback for testing environments or when SWC is not available + console.warn( + `[${this.localName}] The "allow-outside-click" attribute has been deprecated and will be removed in a future release. We do not recommend using this attribute for accessibility reasons. It allows clicks outside the overlay to close it, which can cause unexpected behavior and accessibility issues.` + ); + } + } + + // Manage the open state if the 'open' property has changed. + if (changes.has('open') && (this.hasUpdated || this.open)) { + this.manageOpen(changes.get('open')); + } + + // Resolve the trigger element if the 'trigger' property has changed. + if (changes.has('trigger')) { + const [id, interaction] = this.trigger?.split('@') || []; + this.elementResolver.selector = id ? `#${id}` : ''; + this.triggerInteraction = interaction as + | 'click' + | 'longpress' + | 'hover' + | undefined; + } + + // Initialize oldTrigger to track the previous trigger element. + let oldTrigger: HTMLElement | false | undefined = false; + + // Check if the element resolver has been updated. + if (changes.has(elementResolverUpdatedSymbol)) { + // Store the current trigger element. + oldTrigger = this.triggerElement as HTMLElement; + // Update the trigger element from the element resolver. + this.triggerElement = this.elementResolver.element; + } + + // Check if the 'triggerElement' property has changed. + if (changes.has('triggerElement')) { + // Store the old trigger element. + oldTrigger = changes.get('triggerElement'); + } + + // If the trigger element has changed, bind the new events. + if (oldTrigger !== false) { + this.bindEvents(); + } + } + + /** + * Lifecycle method called after the component updates. + * + * This method handles various tasks after the component updates, such as updating the placement + * attribute, resetting the overlay position, and clearing the overlay position based on the state. + * + * @override + * @param {PropertyValues} changes - The properties that have changed. + */ + protected override updated(changes: PropertyValues): void { + // Call the base class method to handle any initial setup. + super.updated(changes); + + // Check if the 'placement' property has changed. + if (changes.has('placement')) { + if (this.placement) { + // Set the 'actual-placement' attribute on the dialog element. + this.dialogEl.setAttribute('actual-placement', this.placement); + } else { + // Remove the 'actual-placement' attribute from the dialog element. + this.dialogEl.removeAttribute('actual-placement'); + } + + // If the overlay is open and the 'placement' property has changed, reset the overlay position. + if (this.open && typeof changes.get('placement') !== 'undefined') { + this.placementController.resetOverlayPosition(); + } + } + + // Check if the 'state' property has changed and the overlay is closed. + if ( + changes.has('state') && + this.state === 'closed' && + typeof changes.get('state') !== 'undefined' + ) { + // Clear the overlay position. + this.placementController.clearOverlayPosition(); + } + } + + /** + * Renders the content of the overlay. + * + * This method returns a template result containing a slot element. The slot element + * listens for the `slotchange` event to manage the overlay's state. + * + * @protected + * @returns {TemplateResult} The template result containing the slot element. + */ + protected renderContent(): TemplateResult { + return html` + + `; + } + + /** + * Generates a style map for the dialog element. + * + * This method returns an object containing CSS custom properties for the dialog element. + * The `--swc-overlay-open-count` custom property is set to the current open count of overlays. + * + * @private + * @returns {StyleInfo} The style map for the dialog element. + */ + private get dialogStyleMap(): StyleInfo { + return { + '--swc-overlay-open-count': Overlay.openCount.toString(), + }; + } + + /** + * Renders the popover element for the overlay. + * + * This method returns a template result containing a div element styled as a popover. + * The popover element includes various attributes and event listeners to manage the overlay's state and behavior. + * + * @protected + * @returns {TemplateResult} The template result containing the popover element. + */ + protected renderPopover(): TemplateResult { + /** + * The `--swc-overlay-open-count` custom property is applied to mimic the single stack + * nature of the top layer in browsers that do not yet support it. + * + * The value should always represent the total number of overlays that have ever been opened. + * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be + * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000 + * to ensure that the overlay stacks above most other elements during fallback delivery. + */ + return html` +
+ ${this.renderContent()} +
+ `; + } + + /** + * Renders the overlay component. + * + * This method returns a template result containing either a dialog or popover element + * based on the overlay type. It also includes a slot for longpress descriptors. + * + * @override + * @returns {TemplateResult} The template result containing the overlay content. + */ + public override render(): TemplateResult { + return html` + ${this.renderPopover()} + + `; + } + + /** + * Lifecycle method called when the component is added to the DOM. + * + * This method sets up event listeners and binds events if the component has already updated. + * + * @override + */ + override connectedCallback(): void { + super.connectedCallback(); + + // Add an event listener to handle the 'close' event and update the 'open' property. + this.addEventListener('close', () => { + this.open = false; + }); + + // Bind events if the component has already updated. + if (this.hasUpdated) { + this.bindEvents(); + } + } + + /** + * Lifecycle method called when the component is removed from the DOM. + * + * This method releases the description from the strategy and updates the 'open' property. + * + * @override + */ + override disconnectedCallback(): void { + // Release the description from the strategy. + this.strategy?.releaseDescription(); + // Update the 'open' property to false. + this.open = false; + super.disconnectedCallback(); + } +} diff --git a/1st-gen/packages/overlay/src/OverlayNoPopover.ts b/1st-gen/packages/overlay/src/OverlayNoPopover.ts new file mode 100644 index 00000000000..f2e71f76f7c --- /dev/null +++ b/1st-gen/packages/overlay/src/OverlayNoPopover.ts @@ -0,0 +1,153 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + firstFocusableIn, + firstFocusableSlottedIn, +} from '@spectrum-web-components/shared/src/first-focusable-in.js'; +import type { SpectrumElement } from '@spectrum-web-components/base'; +import { VirtualTrigger } from './VirtualTrigger.js'; +import { Constructor, OpenableElement } from './overlay-types.js'; +import { + guaranteedAllTransitionend, + nextFrame, + overlayTimer, +} from './AbstractOverlay.js'; +import { + BeforetoggleClosedEvent, + BeforetoggleOpenEvent, + OverlayStateEvent, +} from './events.js'; +import type { AbstractOverlay } from './AbstractOverlay.js'; +import { userFocusableSelector } from '@spectrum-web-components/shared'; + +export function OverlayNoPopover>( + constructor: T +): T & Constructor { + class OverlayWithNoPopover extends constructor { + protected override async managePopoverOpen(): Promise { + await this.managePosition(); + } + + protected override async manageDelay( + targetOpenState: boolean + ): Promise { + if (targetOpenState === false || targetOpenState !== this.open) { + overlayTimer.close(this); + return; + } + if (this.delayed) { + const cancelled = await overlayTimer.openTimer(this); + if (cancelled) { + this.open = !targetOpenState; + } + } + } + + protected override async ensureOnDOM( + _targetOpenState: boolean + ): Promise { + // force the browser to paint + document.body.offsetHeight; + } + + protected override async makeTransition( + targetOpenState: boolean + ): Promise { + if (this.open !== targetOpenState) { + return null; + } + let focusEl = null as HTMLElement | null; + const start = (el: OpenableElement, index: number) => (): void => { + if (targetOpenState !== this.open) { + return; + } + el.open = targetOpenState; + if (index === 0) { + const event = targetOpenState + ? BeforetoggleOpenEvent + : BeforetoggleClosedEvent; + this.dispatchEvent(new event()); + } + if (targetOpenState !== true) { + return; + } + if (el.matches(userFocusableSelector)) { + focusEl = el; + } + focusEl = focusEl || firstFocusableIn(el); + if (focusEl) { + return; + } + const childSlots = el.querySelectorAll('slot'); + childSlots.forEach((slot) => { + if (!focusEl) { + focusEl = firstFocusableSlottedIn(slot); + } + }); + }; + const finish = + (el: OpenableElement, index: number) => + async (): Promise => { + if (this.open !== targetOpenState) { + return; + } + const eventName = targetOpenState + ? 'sp-opened' + : 'sp-closed'; + el.dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + }) + ); + if (index > 0) { + return; + } + const hasVirtualTrigger = + this.triggerElement instanceof VirtualTrigger; + this.dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: hasVirtualTrigger, + }) + ); + if (this.triggerElement && !hasVirtualTrigger) { + (this.triggerElement as HTMLElement).dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: true, + }) + ); + } + this.state = targetOpenState ? 'opened' : 'closed'; + this.returnFocus(); + // Ensure layout and paint are done and the Overlay is still closed before removing the slottable request. + await nextFrame(); + await nextFrame(); + if ( + targetOpenState === this.open && + targetOpenState === false + ) { + this.requestSlottable(); + } + }; + this.elements.forEach((el, index) => { + guaranteedAllTransitionend( + el, + start(el, index), + finish(el, index) + ); + }); + return focusEl; + } + } + return OverlayWithNoPopover; +} diff --git a/1st-gen/packages/overlay/src/OverlayPopover.ts b/1st-gen/packages/overlay/src/OverlayPopover.ts new file mode 100644 index 00000000000..5a1aaead2e1 --- /dev/null +++ b/1st-gen/packages/overlay/src/OverlayPopover.ts @@ -0,0 +1,250 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + firstFocusableIn, + firstFocusableSlottedIn, +} from '@spectrum-web-components/shared/src/first-focusable-in.js'; +import type { SpectrumElement } from '@spectrum-web-components/base'; +import { VirtualTrigger } from './VirtualTrigger.js'; +import { Constructor, OpenableElement } from './overlay-types.js'; +import { + guaranteedAllTransitionend, + nextFrame, + overlayTimer, +} from './AbstractOverlay.js'; +import { + BeforetoggleClosedEvent, + BeforetoggleOpenEvent, + OverlayStateEvent, +} from './events.js'; +import type { AbstractOverlay } from './AbstractOverlay.js'; +import { userFocusableSelector } from '@spectrum-web-components/shared'; + +const supportsOverlayAuto = CSS.supports('(overlay: auto)'); + +function isOpen(el: HTMLElement): boolean { + let popoverOpen = false; + try { + popoverOpen = el.matches(':popover-open'); + // eslint-disable-next-line no-empty + } catch (error) {} + let open = false; + try { + open = el.matches(':open'); + // eslint-disable-next-line no-empty + } catch (error) {} + return popoverOpen || open; +} + +export function OverlayPopover>( + constructor: T +): T & Constructor { + class OverlayWithPopover extends constructor { + protected override async manageDelay( + targetOpenState: boolean + ): Promise { + if (targetOpenState === false || targetOpenState !== this.open) { + overlayTimer.close(this); + return; + } + if (this.delayed) { + const cancelled = await overlayTimer.openTimer(this); + if (cancelled) { + this.open = !targetOpenState; + } + } + } + + /** + * A popover should be hidden _after_ it is no longer on top-layer because + * the position metrics will have changed from when it was originally positioned. + */ + private async shouldHidePopover( + targetOpenState: boolean + ): Promise { + if (targetOpenState && this.open !== targetOpenState) { + return; + } + const update = async ({ + newState, + }: { newState?: string } = {}): Promise => { + if (newState === 'open') { + return; + } + // When in a parent Overlay, this Overlay may need to position itself + // while closing in due to the parent _also_ closing which means the + // location can no longer rely on "top layer over transform" math. + await this.placementController.resetOverlayPosition(); + }; + if (!isOpen(this.dialogEl)) { + // The means the Overlay was closed from the outside, it is already off of top-layer + // so we need to position it in regards to this new state. + update(); + return; + } + // `toggle` is an async event, so it's possible for this handler to run a frame late + this.dialogEl.addEventListener('toggle', update as EventListener, { + once: true, + }); + } + + private shouldShowPopover(targetOpenState: boolean): void { + let popoverOpen = false; + try { + popoverOpen = this.dialogEl.matches(':popover-open'); + // eslint-disable-next-line no-empty + } catch (error) {} + let open = false; + try { + open = this.dialogEl.matches(':open'); + // eslint-disable-next-line no-empty + } catch (error) {} + if ( + targetOpenState && + this.open === targetOpenState && + !popoverOpen && + !open && + this.isConnected + ) { + this.dialogEl.showPopover(); + this.managePosition(); + } + } + + protected override async ensureOnDOM( + targetOpenState: boolean + ): Promise { + if (!supportsOverlayAuto) { + await this.shouldHidePopover(targetOpenState); + } + this.shouldShowPopover(targetOpenState); + await nextFrame(); + } + + protected override async makeTransition( + targetOpenState: boolean + ): Promise { + if (this.open !== targetOpenState) { + return null; + } + let focusEl = null as HTMLElement | null; + const start = (el: OpenableElement, index: number) => (): void => { + el.open = targetOpenState; + if (index === 0) { + const event = targetOpenState + ? BeforetoggleOpenEvent + : BeforetoggleClosedEvent; + this.dispatchEvent(new event()); + } + if (!targetOpenState) { + return; + } + if (el.matches(userFocusableSelector)) { + focusEl = el; + } + focusEl = focusEl || firstFocusableIn(el); + if (focusEl) { + return; + } + const childSlots = el.querySelectorAll('slot'); + childSlots.forEach((slot) => { + if (!focusEl) { + focusEl = firstFocusableSlottedIn(slot); + } + }); + }; + const finish = + (el: OpenableElement, index: number) => + async (): Promise => { + if (this.open !== targetOpenState) { + return; + } + const eventName = targetOpenState + ? 'sp-opened' + : 'sp-closed'; + if (index > 0) { + el.dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: false, + }) + ); + return; + } + const reportChange = async (): Promise => { + if (this.open !== targetOpenState) { + return; + } + await nextFrame(); + const hasVirtualTrigger = + this.triggerElement instanceof VirtualTrigger; + this.dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: hasVirtualTrigger, + }) + ); + el.dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: false, + }) + ); + if (this.triggerElement && !hasVirtualTrigger) { + (this.triggerElement as HTMLElement).dispatchEvent( + new OverlayStateEvent(eventName, this, { + interaction: this.type, + publish: true, + }) + ); + } + this.state = targetOpenState ? 'opened' : 'closed'; + this.returnFocus(); + // Ensure layout and paint are done and the Overlay is still closed before removing the slottable request. + await nextFrame(); + await nextFrame(); + if ( + targetOpenState === this.open && + targetOpenState === false + ) { + this.requestSlottable(); + } + }; + if (this.open !== targetOpenState) { + return; + } + const open = isOpen(this.dialogEl); + if (targetOpenState !== true && open && this.isConnected) { + this.dialogEl.addEventListener( + 'beforetoggle', + () => { + reportChange(); + }, + { once: true } + ); + this.dialogEl.hidePopover(); + } else { + reportChange(); + } + }; + this.elements.forEach((el, index) => { + guaranteedAllTransitionend( + el, + start(el, index), + finish(el, index) + ); + }); + return focusEl; + } + } + return OverlayWithPopover; +} diff --git a/1st-gen/packages/overlay/src/OverlayStack.ts b/1st-gen/packages/overlay/src/OverlayStack.ts new file mode 100644 index 00000000000..cc5c8ffd99b --- /dev/null +++ b/1st-gen/packages/overlay/src/OverlayStack.ts @@ -0,0 +1,283 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { Overlay } from './Overlay.js'; + +const supportsPopover = 'showPopover' in document.createElement('div'); + +class OverlayStack { + private get document(): Document { + return this.root.ownerDocument /* c8 ignore next */ || document; + } + + private pointerdownPath?: EventTarget[]; + + private lastOverlay?: Overlay; + + private root: HTMLElement = document.body; + + stack: Overlay[] = []; + + private originalBodyOverflow = ''; + + private bodyScrollBlocked = false; + + constructor() { + this.bindEvents(); + } + + bindEvents(): void { + this.document.addEventListener('pointerdown', this.handlePointerdown); + this.document.addEventListener('pointerup', this.handlePointerup); + this.document.addEventListener('keydown', this.handleKeydown); + this.document.addEventListener('scroll', this.handleScroll, { + capture: true, + }); + } + + private handleScroll = (event: Event): void => { + // Only handle document/body level scrolls + // Skip any component scrolls + if ( + event.target !== document && + event.target !== document.documentElement && + event.target !== document.body + ) { + return; + } + // Update positions of all open overlays + this.stack.forEach((overlay) => { + if (overlay.open) { + // Don't close pickers on document scroll + if ( + overlay.type === 'auto' && + overlay.triggerElement instanceof HTMLElement && + overlay.triggerElement.closest('sp-picker, sp-action-menu') + ) { + event.stopPropagation(); + } + // Update the overlay's position by dispatching the update event + document.dispatchEvent( + new CustomEvent('sp-update-overlays', { + bubbles: true, + composed: true, + cancelable: true, + }) + ); + } + }); + }; + + private closeOverlay(overlay: Overlay): void { + const overlayIndex = this.stack.indexOf(overlay); + if (overlayIndex > -1) { + this.stack.splice(overlayIndex, 1); + } + overlay.open = false; + + this.manageBodyScroll(); + } + + /** + * Manage body scroll blocking based on modal/page overlays + */ + private manageBodyScroll(): void { + const shouldBlock = this.stack.some( + (overlay) => overlay.type === 'modal' || overlay.type === 'page' + ); + if (shouldBlock && !this.bodyScrollBlocked) { + this.originalBodyOverflow = document.body.style.overflow || ''; + document.body.style.overflow = 'hidden'; + this.bodyScrollBlocked = true; + } else if (!shouldBlock && this.bodyScrollBlocked) { + document.body.style.overflow = this.originalBodyOverflow; + this.bodyScrollBlocked = false; + } + } + + /** + * Cach the `pointerdownTarget` for later testing + * + * @param event {ClickEvent} + */ + handlePointerdown = (event: Event): void => { + this.pointerdownPath = event.composedPath(); + this.lastOverlay = this.stack[this.stack.length - 1]; + }; + + /** + * Close all overlays that are not ancestors of this click event + * + * @param event {ClickEvent} + */ + handlePointerup = (): void => { + // Test against the composed path in `pointerdown` in case the visitor moved their + // pointer during the course of the interaction. + // Ensure that this value is cleared even if the work in this method goes undone. + const composedPath = this.pointerdownPath; + this.pointerdownPath = undefined; + if (!this.stack.length) return; + if (!composedPath?.length) return; + const lastOverlay = this.lastOverlay; + this.lastOverlay = undefined; + + const lastIndex = this.stack.length - 1; + const nonAncestorOverlays = this.stack.filter((overlay, i) => { + const inStack = composedPath.find( + (el) => + // The Overlay is in the stack + el === overlay || + // The Overlay trigger is in the stack and the Overlay is a "hint" + (el === overlay?.triggerElement && + 'hint' === overlay?.type) || + // The last Overlay in the stack is not the last Overlay at `pointerdown` time and has a + // `triggerInteraction` of "longpress", meaning it was opened by this poitner interaction + (i === lastIndex && + overlay !== lastOverlay && + overlay.triggerInteraction === 'longpress') + ); + return ( + !inStack && + !overlay.shouldPreventClose() && + overlay.type !== 'manual' && + // Don't close if this overlay is modal and not on top of the overlay stack. + !(overlay.type === 'modal' && lastOverlay !== overlay) + ); + }) as Overlay[]; + nonAncestorOverlays.reverse(); + nonAncestorOverlays.forEach((overlay) => { + this.closeOverlay(overlay); + let parentToClose = overlay.parentOverlayToForceClose; + while (parentToClose) { + this.closeOverlay(parentToClose); + parentToClose = parentToClose.parentOverlayToForceClose; + } + }); + }; + + handleBeforetoggle = (event: Event): void => { + const { target, newState: open } = event as Event & { + newState: string; + }; + if (open === 'open') return; + this.closeOverlay(target as Overlay); + }; + + private handleKeydown = (event: KeyboardEvent): void => { + if (event.code !== 'Escape') return; + if (!this.stack.length) return; + const last = this.stack[this.stack.length - 1]; + if (last?.type === 'page') { + event.preventDefault(); + return; + } + if (last?.type === 'manual') { + // Manual overlays should close on "Escape" key, but not when losing focus or interacting with other parts of the page. + this.closeOverlay(last); + return; + } + if (supportsPopover) return; + if (!last) return; + this.closeOverlay(last); + }; + + /** + * Get an array of Overlays that all share the same trigger element. + * + * @param triggerElement {HTMLELement} + * @returns {Overlay[]} + */ + overlaysByTriggerElement(triggerElement: HTMLElement): Overlay[] { + return this.stack.filter( + (overlay) => overlay.triggerElement === triggerElement + ); + } + + /** + * When overlays are added manage the open state of exisiting overlays appropriately: + * - 'modal': should close other non-'modal' and non-'manual' overlays + * - 'page': should close other non-'modal' and non-'manual' overlays + * - 'auto': should close other 'auto' overlays and other 'hint' overlays, but not 'manual' overlays + * - 'manual': shouldn't close other overlays + * - 'hint': shouldn't close other overlays and give way to all other overlays on a trigger + */ + add(overlay: Overlay): void { + if (this.stack.includes(overlay)) { + const overlayIndex = this.stack.indexOf(overlay); + if (overlayIndex > -1) { + this.stack.splice(overlayIndex, 1); + this.stack.push(overlay); + } + return; + } + if ( + overlay.type === 'auto' || + overlay.type === 'modal' || + overlay.type === 'page' + ) { + // manage closing open overlays + const queryPathEventName = 'sp-overlay-query-path'; + const queryPathEvent = new Event(queryPathEventName, { + composed: true, + bubbles: true, + }); + overlay.addEventListener( + queryPathEventName, + (event: Event) => { + const path = event.composedPath(); + this.stack.forEach((overlayEl) => { + const inPath = path.find((el) => el === overlayEl); + if ( + !inPath && + overlayEl.type !== 'manual' && + overlayEl.type !== 'modal' + ) { + this.closeOverlay(overlayEl); + } + }); + }, + { once: true } + ); + overlay.dispatchEvent(queryPathEvent); + } else if (overlay.type === 'hint') { + const hasPrevious = this.stack.some((overlayEl) => { + return ( + overlayEl.type !== 'manual' && + overlayEl.triggerElement && + overlayEl.triggerElement === overlay.triggerElement + ); + }); + if (hasPrevious) { + overlay.open = false; + return; + } + this.stack.forEach((overlayEl) => { + if (overlayEl.type === 'hint') { + this.closeOverlay(overlayEl); + } + }); + } + requestAnimationFrame(() => { + this.stack.push(overlay); + overlay.addEventListener('beforetoggle', this.handleBeforetoggle, { + once: true, + }); + this.manageBodyScroll(); + }); + } + + remove(overlay: Overlay): void { + this.closeOverlay(overlay); + } +} + +export const overlayStack = new OverlayStack(); diff --git a/1st-gen/packages/overlay/src/OverlayTrigger.ts b/1st-gen/packages/overlay/src/OverlayTrigger.ts new file mode 100644 index 00000000000..9e1085ae18f --- /dev/null +++ b/1st-gen/packages/overlay/src/OverlayTrigger.ts @@ -0,0 +1,359 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, + state, +} from '@spectrum-web-components/base/src/decorators.js'; +import type { Placement } from '@floating-ui/dom'; + +import type { BeforetoggleOpenEvent } from './events.js'; +import type { Overlay } from './Overlay.js'; +import type { OverlayTypes } from './overlay-types.js'; +// eslint-disable-next-line import/no-extraneous-dependencies +import '@spectrum-web-components/overlay/sp-overlay.js'; + +import overlayTriggerStyles from './overlay-trigger.css.js'; + +export type OverlayContentTypes = 'click' | 'hover' | 'longpress'; + +// Helper type to create all unique combinations of OverlayContentTypes +type Combinations = T extends string + ? T | `${T} ${Combinations>}` + : never; + +export type TriggeredByType = Combinations; + +/** + * @element overlay-trigger + * + * A component that manages overlay content triggered by different interactions. + * Supports click, hover, and longpress triggered overlays with configurable + * placement and behavior. + * + * @slot trigger - The content that will trigger the various overlays + * @slot hover-content - The content that will be displayed on hover + * @slot click-content - The content that will be displayed on click + * @slot longpress-content - The content that will be displayed on longpress + * @slot longpress-describedby-descriptor - Description for longpress content + * + * @fires sp-opened - Announces that the overlay has been opened + * @fires sp-closed - Announces that the overlay has been closed + * + * @attr {string} placement - The placement of the overlay relative to the trigger + * @attr {number} offset - The distance between the overlay and the trigger + * @attr {boolean} disabled - Whether the overlay trigger is disabled + * @attr {string} receives-focus - How focus should be handled ('true'|'false'|'auto') + * @attr {string} triggered-by - The type of interaction that will trigger the overlay ('click'|'hover'|'longpress') + */ +export class OverlayTrigger extends SpectrumElement { + public static override get styles(): CSSResultArray { + return [overlayTriggerStyles]; + } + + /** + * Optional property to optimize performance and prevent race conditions. + * + * By explicitly declaring which content types are used (e.g. "click", "longpress hover"), + * we can avoid: + * 1. Extra renders from unnecessary slot reparenting + * 2. Potential infinite render loops during content detection + * 3. Race conditions during slot assignment + * + * By only returning overlay wrappers for explicitly declared content types, + * we minimize unecessary DOM nodes, operations and ensure a more stable rendering behavior. + */ + @property({ attribute: 'triggered-by' }) + public triggeredBy?: TriggeredByType; + + /** + * @type {"top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end"} + * @attr + */ + @property({ reflect: true }) + public placement?: Placement; + + @property() + public type?: OverlayTypes; + + @property({ type: Number }) + public offset = 6; + + @property({ reflect: true }) + public open?: OverlayContentTypes; + + @property({ type: Boolean, reflect: true }) + public disabled = false; + + @property({ attribute: 'receives-focus' }) + public receivesFocus: 'true' | 'false' | 'auto' = 'auto'; + + @state() + private clickContent: HTMLElement[] = []; + + private clickPlacement?: Placement; + + @state() + private longpressContent: HTMLElement[] = []; + + private longpressPlacement?: Placement; + + @state() + private hoverContent: HTMLElement[] = []; + + private hoverPlacement?: Placement; + + @state() + private targetContent: HTMLElement[] = []; + + @query('#click-overlay', true) + clickOverlayElement!: Overlay; + + @query('#longpress-overlay', true) + longpressOverlayElement!: Overlay; + + @query('#hover-overlay', true) + hoverOverlayElement!: Overlay; + + private getAssignedElementsFromSlot(slot: HTMLSlotElement): HTMLElement[] { + return slot.assignedElements({ flatten: true }) as HTMLElement[]; + } + + private handleTriggerContent( + event: Event & { target: HTMLSlotElement } + ): void { + this.targetContent = this.getAssignedElementsFromSlot(event.target); + } + + private handleSlotContent( + event: Event & { target: HTMLSlotElement } + ): void { + switch (event.target.name) { + case 'click-content': + this.clickContent = this.getAssignedElementsFromSlot( + event.target + ); + break; + case 'longpress-content': + this.longpressContent = this.getAssignedElementsFromSlot( + event.target + ); + break; + case 'hover-content': + this.hoverContent = this.getAssignedElementsFromSlot( + event.target + ); + break; + } + } + + private handleBeforetoggle(event: BeforetoggleOpenEvent): void { + const { target } = event; + let type: OverlayContentTypes; + if (target === this.clickOverlayElement) { + type = 'click'; + } else if (target === this.longpressOverlayElement) { + type = 'longpress'; + } else if (target === this.hoverOverlayElement) { + type = 'hover'; + /* c8 ignore next 3 */ + } else { + return; + } + if (event.newState === 'open') { + this.open = type; + } else if (this.open === type) { + this.open = undefined; + } + } + + protected override update(changes: PropertyValues): void { + if (changes.has('clickContent')) { + this.clickPlacement = + ((this.clickContent[0]?.getAttribute('placement') || + this.clickContent[0]?.getAttribute( + 'direction' + )) as Placement) || undefined; + } + if (changes.has('hoverContent')) { + this.hoverPlacement = + ((this.hoverContent[0]?.getAttribute('placement') || + this.hoverContent[0]?.getAttribute( + 'direction' + )) as Placement) || undefined; + } + if (changes.has('longpressContent')) { + this.longpressPlacement = + ((this.longpressContent[0]?.getAttribute('placement') || + this.longpressContent[0]?.getAttribute( + 'direction' + )) as Placement) || undefined; + } + super.update(changes); + } + + protected renderSlot(name: string): TemplateResult { + return html` + + `; + } + + protected renderClickOverlay(): TemplateResult { + const slot = this.renderSlot('click-content'); + const clickOverlay = html` + + ${slot} + + `; + + // If click interactions are explicitly enabled by customers, always return the overlay + if (this.triggeredBy?.includes('click')) { + return clickOverlay; + } + + if (!this.clickContent.length) { + return slot; + } else { + return clickOverlay; + } + } + + protected renderHoverOverlay(): TemplateResult { + const slot = this.renderSlot('hover-content'); + const hoverOverlay = html` + + ${slot} + + `; + + // If hover interactions are explicitly enabled by customers, always return the overlay + if (this.triggeredBy?.includes('hover')) { + return hoverOverlay; + } + + if (!this.hoverContent.length) { + return slot; + } else { + return hoverOverlay; + } + } + + protected renderLongpressOverlay(): TemplateResult { + const slot = this.renderSlot('longpress-content'); + const longpressOverlay = html` + + ${slot} + + + `; + + // If click interactions are explicitly enabled by customers, always return the overlay + if (this.triggeredBy?.includes('longpress')) { + return longpressOverlay; + } + + if (!this.longpressContent.length) { + return slot; + } else { + return longpressOverlay; + } + } + + protected override render(): TemplateResult { + // Keyboard event availability documented in README.md + return html` + + ${[ + this.renderClickOverlay(), + this.renderHoverOverlay(), + this.renderLongpressOverlay(), + ]} + `; + } + + protected override updated(changedProperties: PropertyValues): void { + super.updated(changedProperties); + + if (window.__swc?.DEBUG && !this.triggeredBy) { + const issues = [ + 'You have not specified the `triggeredBy` property. For optimal performance, consider explicitly declaring which overlay types you plan to use.', + 'Example: triggered-by="click hover"', + 'This helps avoid unnecessary DOM operations and potential race conditions.', + ]; + + window.__swc.warn( + this, + 'Performance optimization available for :', + 'https://opensource.adobe.com/spectrum-web-components/components/overlay-trigger/#performance-optimization', + { issues } + ); + } + + if (this.disabled && changedProperties.has('disabled')) { + this.open = undefined; + return; + } + } + + protected override async getUpdateComplete(): Promise { + const complete = (await super.getUpdateComplete()) as boolean; + return complete; + } +} diff --git a/1st-gen/packages/overlay/src/PlacementController.ts b/1st-gen/packages/overlay/src/PlacementController.ts new file mode 100644 index 00000000000..2dfe32ea364 --- /dev/null +++ b/1st-gen/packages/overlay/src/PlacementController.ts @@ -0,0 +1,471 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { + ReactiveController, + ReactiveElement, +} from '@spectrum-web-components/base'; +import { + arrow, + autoUpdate, + computePosition, + flip, + offset, + Placement, + shift, + size, +} from '@floating-ui/dom'; +import type { VirtualTrigger } from './VirtualTrigger.js'; +import type { OpenableElement } from './overlay-types.js'; +import type { Overlay } from './Overlay.js'; + +type OverlayOptionsV1 = { + abortPromise?: Promise; + delayed?: boolean; + offset?: number | [number, number]; // supporting multi-axis + placement: Placement; + notImmediatelyClosable?: boolean; // rename or place behind other API options + receivesFocus?: 'auto'; + root?: HTMLElement; + tipPadding?: number; + trigger: HTMLElement | VirtualTrigger; + type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual'; +}; + +/** + * Rounds a number by the device pixel ratio (DPR). + * + * @param {number} [num] - The number to round. + * @returns {number} The rounded number. + */ +function roundByDPR(num?: number): number { + if (typeof num === 'undefined') return 0; + const dpr = window.devicePixelRatio || 1; + return Math.round(num * dpr) / dpr; +} + +// Minimum distance required between the overlay and the edge of the container. +// See: https://spectrum.adobe.com/page/popover/#Container-padding +const REQUIRED_DISTANCE_TO_EDGE = 8; +// Minimum height for the overlay. +// See: https://github.com/adobe/spectrum-web-components/issues/910 +const MIN_OVERLAY_HEIGHT = 100; + +/** + * Gets fallback placements for the overlay based on the initial placement. + * + * @param {Placement} placement - The initial placement of the overlay. + * @returns {Placement[]} An array of fallback placements. + */ +const getFallbackPlacements = (placement: Placement): Placement[] => { + const fallbacks: Record = { + left: ['right', 'bottom', 'top'], + 'left-start': ['right-start', 'bottom', 'top'], + 'left-end': ['right-end', 'bottom', 'top'], + right: ['left', 'bottom', 'top'], + 'right-start': ['left-start', 'bottom', 'top'], + 'right-end': ['left-end', 'bottom', 'top'], + top: ['bottom', 'left', 'right'], + 'top-start': ['bottom-start', 'left', 'right'], + 'top-end': ['bottom-end', 'left', 'right'], + bottom: ['top', 'left', 'right'], + 'bottom-start': ['top-start', 'left', 'right'], + 'bottom-end': ['top-end', 'left', 'right'], + }; + return fallbacks[placement] ?? [placement]; +}; + +/** + * Symbol used to indicate that the placement has been updated. + */ +export const placementUpdatedSymbol = Symbol('placement updated'); + +/** + * Controller for managing the placement of an overlay. + * + * This class implements the ReactiveController interface and provides methods + * for managing the positioning and constraints of an overlay element. + */ +export class PlacementController implements ReactiveController { + /** + * Function to clean up resources when the controller is no longer needed. + * + * @private + */ + private cleanup?: () => void; + + /** + * Initial height of the overlay. + * + * @type {number} + */ + initialHeight?: number; + + /** + * Indicates whether the overlay is constrained by available space. + * + * @type {boolean} + */ + isConstrained?: boolean; + + /** + * The host element that uses this controller. + * + * @private + * @type {ReactiveElement & { elements: OpenableElement[] }} + */ + private host!: ReactiveElement & { elements: OpenableElement[] }; + + /** + * Options for configuring the overlay placement. + * + * @private + * @type {OverlayOptionsV1} + */ + private options!: OverlayOptionsV1; + + /** + * A WeakMap to store the original placements of overlay elements. + * + * @private + * @type {WeakMap} + */ + private originalPlacements = new WeakMap(); + + /** + * The target element for the overlay. + * + * @private + * @type {HTMLElement} + */ + private target!: HTMLElement; + + /** + * Creates an instance of the PlacementController. + * + * @param {ReactiveElement & { elements: OpenableElement[] }} host - The host element that uses this controller. + */ + constructor(host: ReactiveElement & { elements: OpenableElement[] }) { + this.host = host; + // Add the controller after the MutationObserver has been created in preparation + // for the `hostConnected`/`hostDisconnected` callbacks to be run. + this.host.addController(this); + } + + /** + * Places the overlay relative to the target element. + * + * This method sets up the necessary configurations and event listeners to manage the + * positioning and constraints of the overlay element. + * + * @param {HTMLElement} [target=this.target] - The target element for the overlay. + * @param {OverlayOptionsV1} [options=this.options] - The options for configuring the overlay placement. + * @returns {Promise} A promise that resolves when the overlay has been placed. + */ + public async placeOverlay( + target: HTMLElement = this.target, + options: OverlayOptionsV1 = this.options + ): Promise { + // Set the target and options for the overlay. + this.target = target; + this.options = options; + if (!target || !options) return; + + // Set up auto-update for ancestor resize events. + const cleanupAncestorResize = autoUpdate( + options.trigger, + target, + this.closeForAncestorUpdate, + { + ancestorResize: false, + elementResize: false, + layoutShift: false, + } + ); + + // Set up auto-update for element resize events. + const cleanupElementResize = autoUpdate( + options.trigger, + target, + this.updatePlacement, + { + ancestorScroll: false, + } + ); + + // Define the cleanup function to remove event listeners and reset placements. + this.cleanup = () => { + this.host.elements?.forEach((element) => { + element.addEventListener( + 'sp-closed', + () => { + const placement = this.originalPlacements.get(element); + + if (placement) { + element.setAttribute('placement', placement); + } + + this.originalPlacements.delete(element); + }, + { once: true } + ); + }); + cleanupAncestorResize(); + cleanupElementResize(); + }; + } + + /** + * Flag to allow or disallow placement updates. + * + * @type {boolean} + */ + public allowPlacementUpdate = false; + + /** + * Closes the overlay if an ancestor element is updated. + * + * This method checks if placement updates are allowed and if the overlay type is not 'modal'. + * If these conditions are met and a cleanup function is defined, it dispatches a 'close' event + * on the target element to close the overlay. + */ + closeForAncestorUpdate = (): void => { + if ( + !this.allowPlacementUpdate && + this.options.type !== 'modal' && + this.cleanup + ) { + // Dispatch a 'close' event to close the overlay. + this.target.dispatchEvent(new Event('close', { bubbles: true })); + } + + // Reset the flag to disallow placement updates. + this.allowPlacementUpdate = false; + }; + + /** + * Updates the placement of the overlay. + * + * This method calls the computePlacement method to recalculate the overlay's position. + * + * @private + */ + private updatePlacement = (): void => { + this.computePlacement(); + }; + + /** + * Computes the placement of the overlay relative to the target element. + * + * This method calculates the necessary positioning and constraints for the overlay element + * using various middleware functions. It updates the overlay's style and attributes based + * on the computed position. + * + * @returns {Promise} A promise that resolves when the placement has been computed. + */ + async computePlacement(): Promise { + const { options, target } = this; + + // Wait for document fonts to be ready before computing placement. + await (document.fonts ? document.fonts.ready : Promise.resolve()); + + // Determine the flip middleware based on the type of trigger element. + const flipMiddleware = !(options.trigger instanceof HTMLElement) + ? flip({ + padding: REQUIRED_DISTANCE_TO_EDGE, + fallbackPlacements: getFallbackPlacements(options.placement), + }) + : flip(); + + // Extract main axis and cross axis offsets from options. + const [mainAxis = 0, crossAxis = 0] = Array.isArray(options?.offset) + ? options.offset + : [options.offset, 0]; + + // Find the tip element within the host elements. + const tipElement = this.host.elements.find( + (el) => el.tipElement + )?.tipElement; + + // Define middleware functions for positioning and constraints. + const middleware = [ + offset({ + mainAxis, + crossAxis, + }), + shift({ padding: REQUIRED_DISTANCE_TO_EDGE }), + flipMiddleware, + size({ + padding: REQUIRED_DISTANCE_TO_EDGE, + apply: ({ + availableWidth, + availableHeight, + rects: { floating }, + }) => { + const maxHeight = Math.max( + MIN_OVERLAY_HEIGHT, + Math.floor(availableHeight) + ); + const actualHeight = floating.height; + this.initialHeight = !this.isConstrained // && !this.virtualTrigger + ? actualHeight + : this.initialHeight || actualHeight; + this.isConstrained = + actualHeight < this.initialHeight || + maxHeight <= actualHeight; + const appliedHeight = this.isConstrained + ? `${maxHeight}px` + : ''; + Object.assign(target.style, { + maxWidth: `${Math.floor(availableWidth)}px`, + maxHeight: appliedHeight, + }); + }, + }), + ...(tipElement + ? [ + arrow({ + element: tipElement, + padding: + options.tipPadding || REQUIRED_DISTANCE_TO_EDGE, + }), + ] + : []), + ]; + + // Compute the position of the overlay using the defined middleware. + const { x, y, placement, middlewareData } = await computePosition( + options.trigger, + target, + { + placement: options.placement, + middleware, + strategy: 'fixed', + } + ); + + // Update the overlay's style with the computed position. + Object.assign(target.style, { + top: '0px', + left: '0px', + translate: `${roundByDPR(x)}px ${roundByDPR(y)}px`, + }); + + // Set the 'actual-placement' attribute on the target element. + target.setAttribute('actual-placement', placement); + + // Update the placement attribute for each host element. + this.host.elements?.forEach((element) => { + if (!this.originalPlacements.has(element)) { + this.originalPlacements.set( + element, + element.getAttribute('placement') as Placement + ); + } + element.setAttribute('placement', placement); + }); + + // Update the tip element's style with the computed arrow position. + if (tipElement && middlewareData.arrow) { + const { x: arrowX, y: arrowY } = middlewareData.arrow; + + Object.assign(tipElement.style, { + top: + placement.startsWith('right') || + placement.startsWith('left') + ? '0px' + : '', + left: + placement.startsWith('bottom') || + placement.startsWith('top') + ? '0px' + : '', + translate: `${roundByDPR(arrowX)}px ${roundByDPR(arrowY)}px`, + }); + } + } + + /** + * Clears the overlay's position styles. + * + * This method removes the max-height and max-width styles from the target element, + * and resets the initial height and constrained state of the overlay. + */ + public clearOverlayPosition(): void { + if (!this.target) { + return; + } + // Remove max-height and max-width styles from the target element. + this.target.style.removeProperty('max-height'); + this.target.style.removeProperty('max-width'); + // Reset the initial height and constrained state. + this.initialHeight = undefined; + this.isConstrained = false; + } + + /** + * Resets the overlay's position. + * + * This method clears the overlay's position, forces a reflow, and recomputes the placement. + */ + public resetOverlayPosition = (): void => { + if (!this.target || !this.options) return; + // Clear the overlay's position. + this.clearOverlayPosition(); + + // Force a reflow. + this.host.offsetHeight; + // Recompute the placement. + this.computePlacement(); + }; + + /** + * Lifecycle method called when the host element is connected to the DOM. + * + * This method sets up an event listener to reset the overlay's position when the 'sp-update-overlays' event is dispatched. + */ + hostConnected(): void { + document.addEventListener( + 'sp-update-overlays', + this.resetOverlayPosition + ); + } + + /** + * Lifecycle method called when the host element is updated. + * + * This method cleans up resources if the overlay is not open. + */ + hostUpdated(): void { + if (!(this.host as Overlay).open) { + // Clean up resources if the overlay is not open. + this.cleanup?.(); + this.cleanup = undefined; + } + } + + /** + * Lifecycle method called when the host element is disconnected from the DOM. + * + * This method removes the event listener and cleans up resources. + */ + hostDisconnected(): void { + // Clean up resources. + this.cleanup?.(); + this.cleanup = undefined; + // Remove the event listener. + document.removeEventListener( + 'sp-update-overlays', + this.resetOverlayPosition + ); + } +} diff --git a/1st-gen/packages/overlay/src/VirtualTrigger.ts b/1st-gen/packages/overlay/src/VirtualTrigger.ts new file mode 100644 index 00000000000..2aa083a59ed --- /dev/null +++ b/1st-gen/packages/overlay/src/VirtualTrigger.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { AbstractOverlay } from './AbstractOverlay.js'; + +export class VirtualTrigger { + private x = 0; + private y = 0; + + public constructor(x: number, y: number) { + this.x = x; + this.y = y; + } + + public updateBoundingClientRect(x: number, y: number): void { + this.x = x; + this.y = y; + AbstractOverlay.update(); + } + + public getBoundingClientRect(): DOMRect { + return { + width: 0, + height: 0, + top: this.y, + right: this.x, + y: this.y, + x: this.x, + bottom: this.y, + left: this.x, + /* c8 ignore next 3 */ + toJSON() { + return; + }, + }; + } +} diff --git a/1st-gen/packages/overlay/src/events.ts b/1st-gen/packages/overlay/src/events.ts new file mode 100644 index 00000000000..aaab20f144e --- /dev/null +++ b/1st-gen/packages/overlay/src/events.ts @@ -0,0 +1,65 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { TriggerInteractions } from './overlay-types.js'; + +export class BeforetoggleClosedEvent extends Event { + currentState = 'open'; + newState = 'closed'; + constructor() { + super('beforetoggle', { + bubbles: false, + composed: false, + }); + } +} + +export class BeforetoggleOpenEvent extends Event { + currentState = 'closed'; + newState = 'open'; + constructor() { + super('beforetoggle', { + bubbles: false, + composed: false, + }); + } +} + +export class OverlayStateEvent extends Event { + detail!: { + interaction: string; + reason?: 'external-click'; + }; + + constructor( + type: string, + public overlay: HTMLElement, + { + publish, + interaction, + reason, + }: { + publish?: boolean; + interaction: TriggerInteractions; + reason?: 'external-click'; + } + ) { + super(type, { + bubbles: publish, + composed: publish, + }); + this.detail = { + interaction, + reason, + }; + } +} diff --git a/1st-gen/packages/overlay/src/fullSizePlugin.ts b/1st-gen/packages/overlay/src/fullSizePlugin.ts new file mode 100644 index 00000000000..569f02df401 --- /dev/null +++ b/1st-gen/packages/overlay/src/fullSizePlugin.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + detectOverflow, + MiddlewareArguments, + MiddlewareReturn, +} from '@floating-ui/dom'; + +export const fullSize = (options: { padding: number } = { padding: 0 }) => ({ + name: 'fullSize', + async fn(middlewareArguments: MiddlewareArguments): Promise< + MiddlewareReturn & { + data: { availableWidth: number; availableHeight: number }; + } + > { + const overflow = await detectOverflow(middlewareArguments, options); + let availableHeight = + -overflow.top - + overflow.bottom + + middlewareArguments.rects.floating.height; + let availableWidth = + -overflow.left - + overflow.right + + middlewareArguments.rects.floating.width; + if (middlewareArguments.placement.startsWith('bottom')) { + availableHeight -= middlewareArguments.rects.reference.height; + availableHeight -= middlewareArguments.rects.reference.y; + availableHeight -= + middlewareArguments.middlewareData.offset?.y || 0; + availableHeight += options.padding; + } else if (middlewareArguments.placement.startsWith('top')) { + availableHeight = middlewareArguments.rects.reference.y; + availableHeight -= + middlewareArguments.middlewareData.offset?.y || 0; + availableHeight += options.padding; + } else if (middlewareArguments.placement.startsWith('right')) { + availableWidth -= middlewareArguments.rects.reference.width; + availableWidth -= middlewareArguments.rects.reference.x; + availableWidth -= middlewareArguments.middlewareData.offset?.x || 0; + availableWidth += options.padding; + } else if (middlewareArguments.placement.startsWith('left')) { + availableWidth = middlewareArguments.rects.reference.x; + availableWidth -= middlewareArguments.middlewareData.offset?.x || 0; + availableWidth += options.padding; + } + return { + data: { + availableWidth, + availableHeight, + }, + }; + }, +}); diff --git a/1st-gen/packages/overlay/src/index.ts b/1st-gen/packages/overlay/src/index.ts new file mode 100644 index 00000000000..93a2474d158 --- /dev/null +++ b/1st-gen/packages/overlay/src/index.ts @@ -0,0 +1,17 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Overlay.js'; +export * from './OverlayTrigger.js'; +export * from './overlay-types.js'; +export * from './VirtualTrigger.js'; +export * from './loader.js'; +export * from './overlay-trigger-directive.js'; diff --git a/1st-gen/packages/overlay/src/loader.ts b/1st-gen/packages/overlay/src/loader.ts new file mode 100644 index 00000000000..bfb10a347eb --- /dev/null +++ b/1st-gen/packages/overlay/src/loader.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { + OverlayOptions, + OverlayOptionsV1, + TriggerInteractionsV1, +} from './overlay-types.js'; +import { Overlay } from './Overlay.js'; + +// Re-export Overlay.open and openOverlay to persist functionality from before 0.37.0. +// Wrap it in a method (which needs duplicate argument typings) instead of exporting +// the static member directly to ensure `this` is bound correctly therein. +export async function openOverlay( + trigger: HTMLElement, + interaction: TriggerInteractionsV1, + content: HTMLElement, + optionsV1: OverlayOptionsV1 +): Promise<() => void>; +export async function openOverlay( + content: HTMLElement, + options?: OverlayOptions +): Promise; +export async function openOverlay( + triggerOrContent: HTMLElement, + interactionOrOptions: TriggerInteractionsV1 | OverlayOptions | undefined, + content?: HTMLElement, + optionsV1?: OverlayOptionsV1 +): Promise void)> { + return Overlay.open( + triggerOrContent, + interactionOrOptions as TriggerInteractionsV1, + content as HTMLElement, + optionsV1 as OverlayOptionsV1 + ); +} diff --git a/1st-gen/packages/overlay/src/overlay-events.ts b/1st-gen/packages/overlay/src/overlay-events.ts new file mode 100644 index 00000000000..1c1776ba56e --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay-events.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export class OverlayCloseEvent extends Event { + root?: HTMLElement; + constructor({ root }: { root?: HTMLElement }) { + super('sp-overlay-close', { bubbles: true, composed: true }); + this.root = root; + } +} + +declare global { + interface GlobalEventHandlersEventMap { + 'sp-overlay-close': CustomEvent; + } +} diff --git a/1st-gen/packages/overlay/src/overlay-timer.ts b/1st-gen/packages/overlay/src/overlay-timer.ts new file mode 100644 index 00000000000..9a154bd52e2 --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay-timer.ts @@ -0,0 +1,105 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +const DEFAULT_WARMUP = 1000; +const DEFAULT_COOLDOWN = 1000; + +/** + * A timer to help with implementation of warnup/cooldown behavior as described here: + * https://spectrum.adobe.com/page/tooltip/#Immediate-or-delayed-appearance + */ +export class OverlayTimer { + private warmUpDelay = DEFAULT_WARMUP; + private coolDownDelay = DEFAULT_COOLDOWN; + + private isWarm = false; + private cooldownTimeout?: number; + + private component?: HTMLElement; + private timeout = 0; + private promise?: Promise; + private resolve?: (cancelled: boolean) => void; + + constructor( + options: { warmUpDelay?: number; coolDownDelay?: number } = {} + ) { + Object.assign(this, options); + } + + public async openTimer(component: HTMLElement): Promise { + this.cancelCooldownTimer(); + + if (!this.component || component !== this.component) { + if (this.component) { + this.close(this.component); + this.cancelCooldownTimer(); + } + this.component = component; + + if (this.isWarm) { + return false; + } + + this.promise = new Promise((resolve) => { + this.resolve = resolve; + this.timeout = window.setTimeout(() => { + if (this.resolve) { + this.resolve(false); + this.isWarm = true; + } + }, this.warmUpDelay); + }); + return this.promise; + } else if (this.promise) { + return this.promise; + /* c8 ignore next 4 */ + } else { + // This should never happen + throw new Error('Inconsistent state'); + } + } + + public close(component: HTMLElement): void { + if (this.component && this.component === component) { + this.resetCooldownTimer(); + if (this.timeout > 0) { + clearTimeout(this.timeout); + this.timeout = 0; + } + if (this.resolve) { + this.resolve(true); + delete this.resolve; + } + delete this.promise; + delete this.component; + } + } + + private resetCooldownTimer(): void { + if (this.isWarm) { + if (this.cooldownTimeout) { + window.clearTimeout(this.cooldownTimeout); + } + this.cooldownTimeout = window.setTimeout(() => { + this.isWarm = false; + delete this.cooldownTimeout; + }, this.coolDownDelay); + } + } + + private cancelCooldownTimer(): void { + if (this.cooldownTimeout) { + window.clearTimeout(this.cooldownTimeout); + } + delete this.cooldownTimeout; + } +} diff --git a/1st-gen/packages/overlay/src/overlay-trigger-directive.ts b/1st-gen/packages/overlay/src/overlay-trigger-directive.ts new file mode 100644 index 00000000000..09f35a539a9 --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay-trigger-directive.ts @@ -0,0 +1,140 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + type ElementPart, + nothing, + render, + type RenderOptions, + type TemplateResult, +} from '@spectrum-web-components/base'; +import { directive } from '@spectrum-web-components/base/src/async-directive.js'; +import { strategies } from './strategies.js'; +import type { OverlayOptions, TriggerInteraction } from './overlay-types.js'; +import type { ClickController } from './ClickController.js'; +import type { HoverController } from './HoverController.js'; +import type { LongpressController } from './LongpressController.js'; +import { + removeSlottableRequest, + type SlottableRequestEvent, +} from './slottable-request-event.js'; +import { SlottableRequestDirective } from './slottable-request-directive.js'; +import { AbstractOverlay } from './AbstractOverlay.js'; +import { InteractionTypes } from './InteractionController.js'; + +export type InsertionOptions = { + el: HTMLElement | (() => HTMLElement); + where: InsertPosition; +}; + +export type OverlayTriggerOptions = { + open?: boolean; + triggerInteraction: TriggerInteraction; + overlayOptions: OverlayOptions; + insertionOptions?: InsertionOptions; +}; + +export class OverlayTriggerDirective extends SlottableRequestDirective { + private host?: object; + private overlay!: AbstractOverlay; + private strategy!: ClickController | HoverController | LongpressController; + + protected defaultOptions: OverlayTriggerOptions = { + triggerInteraction: 'click', + overlayOptions: { + type: 'auto', + offset: 0, + }, + }; + protected options: OverlayOptions = { + ...this.defaultOptions.overlayOptions, + }; + protected insertionOptions?: InsertionOptions; + + /* c8 ignore next 9 */ + override render( + _template: () => TemplateResult, + _options?: Partial + ): unknown { + // render function here just defines the interface to the update call later + // we don't have anything to render since this is intended to be an ElementPart directive + // so will be used on an element and is not itself rendered + return nothing; + } + + override update( + part: ElementPart, + [template, options]: Parameters + ): void { + this.options = { + ...this.defaultOptions.overlayOptions, + ...options?.overlayOptions, + }; + this.insertionOptions = options?.insertionOptions; + this.template = template; + this.host = part.options?.host; + let newTarget = false; + const triggerInteraction = (options?.triggerInteraction || + this.defaultOptions.triggerInteraction) as TriggerInteraction; + const newStrategy = + InteractionTypes[this.strategy?.type] !== triggerInteraction; + if (this.target !== part.element) { + this.target = part.element as HTMLElement; + newTarget = true; + } + if (newTarget || newStrategy) { + this.strategy?.abort(); + this.strategy = new strategies[ + triggerInteraction as TriggerInteraction + ](this.target, { + isPersistent: true, + handleOverlayReady: (overlay: AbstractOverlay) => { + this.listenerHost = this.overlay = overlay; + this.init(); + }, + }); + } + this.strategy.open = options?.open ?? false; + } + + override handleSlottableRequest(event: SlottableRequestEvent): void { + /* c8 ignore next 1 */ + if (event.target !== event.currentTarget) return; + + const willRemoveSlottable = event.data === removeSlottableRequest; + const options = {} as RenderOptions; + if (this.host) { + options.host = this.host; + } + render( + willRemoveSlottable ? undefined : this.template(), + this.overlay, + options + ); + + if (willRemoveSlottable) { + this.overlay.remove(); + } else { + AbstractOverlay.applyOptions(this.overlay, { + ...this.options, + trigger: this.target, + }); + const insertionEl = + typeof this.insertionOptions?.el === 'function' + ? this.insertionOptions.el() + : this.insertionOptions?.el || this.target; + const { where = 'afterend' } = this.insertionOptions || {}; + insertionEl.insertAdjacentElement(where, this.overlay); + } + } +} + +export const trigger = directive(OverlayTriggerDirective); diff --git a/1st-gen/packages/overlay/src/overlay-trigger.css b/1st-gen/packages/overlay/src/overlay-trigger.css new file mode 100644 index 00000000000..42a9d10e455 --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay-trigger.css @@ -0,0 +1,15 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +slot[name="longpress-describedby-descriptor"] { + display: none; +} diff --git a/1st-gen/packages/overlay/src/overlay-types.ts b/1st-gen/packages/overlay/src/overlay-types.ts new file mode 100644 index 00000000000..2811f9cfcd0 --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay-types.ts @@ -0,0 +1,96 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { Placement } from '@floating-ui/dom'; +import type { VirtualTrigger } from './VirtualTrigger.js'; + +export type Constructor> = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + new (...args: any[]): T; + prototype: T; +}; + +export { Placement }; + +export type OverlayTypes = 'auto' | 'hint' | 'manual' | 'modal' | 'page'; + +// Constant array for runtime use (tests, validation, etc.) +export const OVERLAY_TYPES = [ + 'auto', + 'hint', + 'manual', + 'modal', + 'page', +] as const satisfies readonly OverlayTypes[]; + +export type TriggerInteraction = 'click' | 'longpress' | 'hover'; + +export type TriggerInteractions = OverlayTypes; + +export type TriggerInteractionsV1 = + | 'click' + | 'longpress' + | 'hover' + | 'custom' + | 'replace' + | 'inline' + | 'modal'; + +export type OverlayTriggerInteractions = Extract< + TriggerInteractions, + 'inline' | 'modal' | 'replace' +>; + +export interface OverlayOpenCloseDetail { + interaction: TriggerInteractions; + reason?: 'external-click'; +} + +export interface OverlayCloseReasonDetail { + reason?: 'external-click'; +} + +export type OverlayOptions = { + delayed?: boolean; + notImmediatelyClosable?: boolean; + offset?: number | [number, number]; // supporting multi-axis + placement?: Placement; + receivesFocus?: 'auto' | 'true' | 'false'; + trigger?: HTMLElement | VirtualTrigger; + type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual'; +}; + +export type OverlayOptionsV1 = { + root?: HTMLElement; + delayed?: boolean; + placement?: Placement; + offset?: number; + receivesFocus?: 'true' | 'false' | 'auto'; + notImmediatelyClosable?: boolean; + abortPromise?: Promise; + virtualTrigger?: VirtualTrigger; +}; + +declare global { + interface GlobalEventHandlersEventMap { + 'sp-opened': CustomEvent; + 'sp-closed': CustomEvent; + } +} + +export type OpenableElement = HTMLElement & { + open: boolean; + tipElement?: HTMLElement; + updateComplete?: Promise; +}; + +export type OverlayState = 'closed' | 'opening' | 'opened' | 'closing'; diff --git a/1st-gen/packages/overlay/src/overlay.css b/1st-gen/packages/overlay/src/overlay.css new file mode 100644 index 00000000000..74202e5f601 --- /dev/null +++ b/1st-gen/packages/overlay/src/overlay.css @@ -0,0 +1,202 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + display: contents; + pointer-events: none; + + /** + * Duplicate --spectrum-overlay-animation-distance, which is out of scope. + * Currently is is statically `--spectrum-spacing-100` across a number of places + * so that is leveraged here as the default. + **/ + --swc-overlay-animation-distance: var(--spectrum-spacing-100); +} + +/** + * :host(:has(...)) {} currently only work in Firefox and Safari + * Chromium will resolve to the default of 6px above. Tooltip leverages a scale custom + * value for this measurement, this adopts it where we can. + **/ + +:host(:has(> sp-tooltip)) { + --swc-overlay-animation-distance: var(--spectrum-tooltip-animation-distance); +} + +.dialog { + margin: 0; + border: 0; + background: none; + padding: 0; + position: fixed; + overflow: visible; + opacity: 1 !important; + box-sizing: border-box; + max-height: calc(100vh - 16px); + max-height: calc(100dvh - 16px); + max-width: calc(100vw - 16px); + height: auto; + inset: auto; + top: 0; + left: 0; + display: flex; + + --sp-overlay-open: true; +} + +.dialog:not([is-visible]) { + display: none; +} + +.dialog:focus { + outline: none; +} + +dialog:modal { + --mod-popover-filter: var(--spectrum-popover-filter); +} + +:host(:not([open])) .dialog { + --sp-overlay-open: false; +} + +.dialog::backdrop { + display: none; +} + +.dialog:before { + position: absolute; + inset: -999em; + content: ""; + pointer-events: auto !important; +} + +.dialog:not(.not-immediately-closable):before { + display: none; +} + +.dialog > div { + width: 100%; +} + +::slotted(*) { + pointer-events: auto; + visibility: visible !important; +} + +::slotted(sp-popover) { + position: static; +} + +/** + * Offset the transition displacement from the trigger edge by + * padding the equivelent distance off of the opposite edge. + * + * + * Prepare for Context Menus with [popover] by adding margin/border + * that _should_ still be under the pointer when `pointerup` is dispatched. + * + **/ +.dialog:not([actual-placement])[placement*="top"] { + padding-block: var(--swc-overlay-animation-distance); + margin-top: var(--swc-overlay-animation-distance); +} + +.dialog:not([actual-placement])[placement*="right"] { + padding-inline: var(--swc-overlay-animation-distance); + margin-left: calc(-1 * var(--swc-overlay-animation-distance)); +} + +.dialog:not([actual-placement])[placement*="bottom"] { + padding-block: var(--swc-overlay-animation-distance); + margin-top: calc(-1 * var(--swc-overlay-animation-distance)); +} + +.dialog:not([actual-placement])[placement*="left"] { + padding-inline: var(--swc-overlay-animation-distance); + margin-left: var(--swc-overlay-animation-distance); +} + +.dialog[actual-placement*="top"] { + padding-block: var(--swc-overlay-animation-distance); + margin-top: var(--swc-overlay-animation-distance); +} + +.dialog[actual-placement*="right"] { + padding-inline: var(--swc-overlay-animation-distance); + margin-left: calc(-1 * var(--swc-overlay-animation-distance)); +} + +.dialog[actual-placement*="bottom"] { + padding-block: var(--swc-overlay-animation-distance); + margin-top: calc(-1 * var(--swc-overlay-animation-distance)); +} + +.dialog[actual-placement*="left"] { + padding-inline: var(--swc-overlay-animation-distance); + margin-left: var(--swc-overlay-animation-distance); +} + +slot[name="longpress-describedby-descriptor"] { + display: none; +} + +/* stylelint-disable */ +@supports selector(:open) { + .dialog { + opacity: 0; + } + + .dialog:open { + opacity: 1; + + --mod-popover-filter: var(--spectrum-popover-filter); + } +} + +@supports selector(:popover-open) { + .dialog { + opacity: 0; + } + + .dialog:popover-open { + opacity: 1; + + --mod-popover-filter: var(--spectrum-popover-filter); + } +} + +@supports (overlay: auto) { + .dialog { + display: none; + transition: + all var(--mod-overlay-animation-duration, var(--spectrum-animation-duration-100, 0.13s)), + translate 0s, + display var(--mod-overlay-animation-duration, var(--spectrum-animation-duration-100, 0.13s)); + transition-behavior: allow-discrete; + } + + .dialog:popover-open { + display: flex; + } +} + +@supports (not selector(:open)) and (not selector(:popover-open)) { + :host:not([open]) .dialog { + pointer-events: none; + } + + .dialog[actual-placement] { + z-index: calc(var(--swc-overlay-z-index-base, 1000) + var(--swc-overlay-open-count)); + } +} +/* stylelint-enable */ diff --git a/1st-gen/packages/overlay/src/slottable-request-directive.ts b/1st-gen/packages/overlay/src/slottable-request-directive.ts new file mode 100644 index 00000000000..965a9e81bd3 --- /dev/null +++ b/1st-gen/packages/overlay/src/slottable-request-directive.ts @@ -0,0 +1,100 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + ElementPart, + nothing, + render, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + AsyncDirective, + directive, +} from '@spectrum-web-components/base/src/async-directive.js'; +import { + removeSlottableRequest, + SlottableRequestEvent, +} from './slottable-request-event.js'; + +export class SlottableRequestDirective extends AsyncDirective { + protected template!: () => TemplateResult; + protected target!: HTMLElement; + private renderBefore: HTMLElement | undefined; + protected listenerHost!: HTMLElement; + protected listeners!: AbortController; + + /* c8 ignore next 9 */ + render(_template: () => TemplateResult): unknown { + // render function here just defines the interface to the update call later + // we don't have anything to render since this is intended to be an ElementPart directive + // so will be used on an element and is not itself rendered + return nothing; + } + + override update( + part: ElementPart, + [template]: Parameters + ): void { + this.template = template; + if (this.target !== part.element) { + this.target = part.element as HTMLElement; + this.renderBefore = this.target.children[0] as HTMLElement; + } + this.listenerHost = this.target; + this.init(); + } + + handleSlottableRequest(event: SlottableRequestEvent): void { + /* c8 ignore next 1 */ + if (event.target !== event.currentTarget) return; + + const willRemoveSlottable = event.data === removeSlottableRequest; + + render(willRemoveSlottable ? undefined : this.template(), this.target, { + renderBefore: this.renderBefore, + }); + } + + init(): void { + this.listeners?.abort(); + this.listeners = new AbortController(); + const { signal } = this.listeners; + this.listenerHost.addEventListener( + 'slottable-request', + (event: Event) => + this.handleSlottableRequest(event as SlottableRequestEvent), + { signal } + ); + + if (window.__swc.DEBUG) { + window.__swc.warn( + undefined, + `⚠️ WARNING ⚠️ : The Overlay Trigger Directive is experimental and there is no guarantees behind its usage in an application!! Its API and presence within the library could be changed at anytime. See "sp-overlay" or "Overlay.open()" for a stable API for overlaying content on your application.`, + 'https://opensource.adobe.com/spectrum-web-components/components/overlay', + { + level: 'high', + type: 'api', + } + ); + } + } + + override disconnected(): void { + this.listeners?.abort(); + } + + /* c8 ignore next 3 */ + override reconnected(): void { + this.init(); + } +} + +export const slottableRequest = directive(SlottableRequestDirective); diff --git a/1st-gen/packages/overlay/src/slottable-request-event.ts b/1st-gen/packages/overlay/src/slottable-request-event.ts new file mode 100644 index 00000000000..6d6caa2050c --- /dev/null +++ b/1st-gen/packages/overlay/src/slottable-request-event.ts @@ -0,0 +1,48 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export class SlottableRequestEvent extends Event { + readonly data: unknown; + readonly name: string; + readonly slotName: string; + constructor(name: string, data: unknown, key?: string) { + super('slottable-request', { + bubbles: false, + cancelable: true, + composed: false, + }); + this.name = name; + this.data = data; + this.slotName = key !== undefined ? `${name}.${key}` : name; + if (window.__swc.DEBUG) { + window.__swc.warn( + undefined, + `⚠️ WARNING ⚠️ : \`slottable-request\` events are experimental and there is no guarantees behind usage of them in an application!! Their shape and presence within the library could be changed at anytime. + +Learn more about the protocol these events are based on below:`, + 'https://github.com/webcomponents-cg/community-protocols/pull/45', + { + level: 'high', + type: 'api', + } + ); + } + } +} + +export const removeSlottableRequest = Symbol('remove-slottable-request'); + +declare global { + interface GlobalEventHandlersEventMap { + 'slottable-request': SlottableRequestEvent; + } +} diff --git a/1st-gen/packages/overlay/src/strategies.ts b/1st-gen/packages/overlay/src/strategies.ts new file mode 100644 index 00000000000..577d4333ab6 --- /dev/null +++ b/1st-gen/packages/overlay/src/strategies.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { ClickController } from './ClickController.js'; +import { HoverController } from './HoverController.js'; +import { LongpressController } from './LongpressController.js'; + +export const strategies = { + click: ClickController, + longpress: LongpressController, + hover: HoverController, +}; diff --git a/1st-gen/packages/overlay/stories/index.ts b/1st-gen/packages/overlay/stories/index.ts new file mode 100644 index 00000000000..de45458e2d4 --- /dev/null +++ b/1st-gen/packages/overlay/stories/index.ts @@ -0,0 +1,275 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, TemplateResult } from '@spectrum-web-components/base'; +import type { Overlay } from '@spectrum-web-components/overlay'; + +function nextFrame(): Promise { + return new Promise((res) => requestAnimationFrame(() => res())); +} + +class IsOverlayOpen extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + constructor() { + super(); + this.readyPromise = new Promise((res) => { + this.ready = res; + this.setup(); + }); + } + + async setup(): Promise { + await nextFrame(); + document.addEventListener('sp-opened', this.handleOpened); + } + + private sendFocus = async (): Promise => { + const selectedItem = document + .querySelector('[focusable]') + ?.querySelector('[selected]') as HTMLElement & { + focused?: boolean; + }; + + if (selectedItem) { + selectedItem.focus(); + selectedItem.focused = true; + + // scroll the selected item into view with block start alignment to ensure consistent behavior in VRTs + await nextFrame(); + selectedItem.scrollIntoView({ block: 'start' }); + await nextFrame(); + } + }; + + handleOpened = async (event: Event): Promise => { + const overlay = event.target as Overlay; + const actions = [nextFrame(), overlay.updateComplete, this.sendFocus()]; + + await Promise.all(actions); + // Focus happens _after_ `sp-opened` by at least two frames. + await nextFrame(); + await nextFrame(); + await nextFrame(); + await nextFrame(); + + this.ready(true); + }; + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } + + // remove event listeners in disconnectCallback + disconnectedCallback(): void { + document.removeEventListener('sp-opened', this.handleOpened); + } +} + +customElements.define('is-overlay-open', IsOverlayOpen); + +export const isOverlayOpen = (story: () => TemplateResult): TemplateResult => { + return html` + ${story()} + + `; +}; + +class AreIconsPresent extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + constructor() { + super(); + this.readyPromise = new Promise((res) => { + this.ready = res; + this.setup(); + }); + } + + async setup(): Promise { + await nextFrame(); + // First, wait for the overlay to open + document.addEventListener('sp-opened', this.handleOpened); + } + + private overlayTimeout: ReturnType | null = null; + + private sendFocus = async (): Promise => { + const selectedItem = document + .querySelector('[focusable]') + ?.querySelector('[selected]') as HTMLElement & { + focused?: boolean; + }; + + if (selectedItem) { + selectedItem.focus(); + selectedItem.focused = true; + + // scroll the selected item into view with block start alignment to ensure consistent behavior in VRTs + await nextFrame(); + selectedItem.scrollIntoView({ block: 'start' }); + await nextFrame(); + } + }; + + handleOpened = async (event: Event): Promise => { + // Clear the timeout since overlay opened + if (this.overlayTimeout) { + clearTimeout(this.overlayTimeout); + this.overlayTimeout = null; + } + + const overlay = event.target as Overlay; + const actions = [nextFrame(), overlay.updateComplete, this.sendFocus()]; + + await Promise.all(actions); + // Focus happens _after_ `sp-opened` by at least two frames. + await nextFrame(); + await nextFrame(); + await nextFrame(); + await nextFrame(); + + this.checkIcons(); + }; + + private checkIcons = async (): Promise => { + const icons = [...document.querySelectorAll('sp-icon')]; + + // there is an icon inside the picker also + const picker = document.querySelector('sp-picker'); + if (picker) { + const pickerIcon = picker.querySelector('sp-icon'); + if (pickerIcon) { + icons.push(pickerIcon); + } + } + + // Create an array of promises for each icon to load + const iconLoadPromises = Array.from(icons).map((icon) => { + return new Promise((resolve) => { + // First check if the icon has an updateComplete promise we can use + if ( + 'updateComplete' in icon && + typeof icon.updateComplete?.then === 'function' + ) { + icon.updateComplete.then(() => { + resolve(); + }); + return; + } + + // Check if the icon has a src attribute + const src = icon.getAttribute('src'); + if (!src) { + // No src, check if it has an internal img element + const imgElement = icon.querySelector('img'); + if (imgElement) { + if (imgElement.complete) { + // Image is already loaded + resolve(); + } else { + // Wait for the image to load + imgElement.addEventListener( + 'load', + () => { + resolve(); + }, + { once: true } + ); + imgElement.addEventListener( + 'error', + () => { + console.warn(`Failed to load icon image`); + resolve(); + }, + { once: true } + ); + } + return; + } + + // No src and no img element, resolve immediately + resolve(); + return; + } + + // For icons with src attribute, check if there's an internal img element first + const imgElement = icon.querySelector('img'); + if (imgElement) { + if (imgElement.complete) { + // Image is already loaded + resolve(); + } else { + // Wait for the image to load + imgElement.addEventListener( + 'load', + () => { + resolve(); + }, + { once: true } + ); + imgElement.addEventListener( + 'error', + () => { + console.warn( + `Failed to load icon image: ${src}` + ); + resolve(); + }, + { once: true } + ); + } + return; + } + + // Fallback to creating a new Image instance + const img = new Image(); + img.onload = () => resolve(); + img.onerror = () => { + console.warn(`Failed to load icon: ${src}`); + resolve(); + }; + img.src = src; + }); + }); + + // Wait for all icons to load + await Promise.all(iconLoadPromises); + await nextFrame(); + + this.ready(true); + }; + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } + + // remove event listeners in disconnectCallback + disconnectedCallback(): void { + document.removeEventListener('sp-opened', this.handleOpened); + } +} + +customElements.define('are-icons-present', AreIconsPresent); + +export const areIconsPresent = ( + story: () => TemplateResult +): TemplateResult => { + return html` + ${story()} + + `; +}; diff --git a/1st-gen/packages/overlay/stories/overlay-directive.stories.ts b/1st-gen/packages/overlay/stories/overlay-directive.stories.ts new file mode 100644 index 00000000000..4a3e123d6ed --- /dev/null +++ b/1st-gen/packages/overlay/stories/overlay-directive.stories.ts @@ -0,0 +1,376 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + OverlayContentTypes, + OverlayOpenCloseDetail, + Placement, + TriggerInteractions, +} from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/dialog/sp-dialog-wrapper.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-open-in.js'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; +import { + InsertionOptions, + trigger, +} from '@spectrum-web-components/overlay/src/overlay-trigger-directive.js'; + +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/picker/sp-picker.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/radio/sp-radio.js'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import '../../../projects/story-decorator/src/types.js'; + +import './overlay-story-components.js'; +import { tooltip } from '@spectrum-web-components/tooltip/src/tooltip-directive.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import { state } from '@spectrum-web-components/base/src/decorators.js'; + +const storyStyles = html` + +`; + +export default { + title: 'Overlay Directive', + argTypes: { + offset: { control: 'number' }, + placement: { + control: { + type: 'inline-radio', + options: [ + 'top', + 'top-start', + 'top-end', + 'bottom', + 'bottom-start', + 'bottom-end', + 'left', + 'left-start', + 'left-end', + 'right', + 'right-start', + 'right-end', + 'auto', + 'auto-start', + 'auto-end', + 'none', + ], + }, + }, + type: { + control: { + type: 'inline-radio', + options: ['modal', 'replace', 'inline'], + }, + }, + colorStop: { + control: { + type: 'inline-radio', + options: ['light', 'dark'], + }, + }, + open: { + name: 'open', + type: { name: 'boolean', required: false }, + description: 'Whether the second accordion item is open.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + }, + args: { + placement: 'bottom', + offset: 0, + colorStop: 'light', + triggerOn: 'click', + open: false, + }, +}; + +interface Properties { + placement?: Placement; + offset?: number; + triggerOn?: OverlayContentTypes; + type?: Extract; + insertionOptions?: InsertionOptions; + open?: boolean; +} + +const template = ({ + placement, + offset, + open, + triggerOn, + insertionOptions, +}: Properties): TemplateResult => { + const renderTooltip = (): TemplateResult => html` + Click to open a popover. + `; + const renderPopover = (): TemplateResult => html` + + +
+ +
+ The background of this div should be blue +
+ html` + Click to open another popover. + ` + )} + ${trigger( + () => html` + + +
+ Another Popover +
+
+
+ `, + { + triggerInteraction: 'click', + overlayOptions: { + placement: 'bottom', + }, + } + )} + > + Press Me +
+
+
+
+ `; + return html` + ${storyStyles} + + Show Popover + + `; +}; + +export const Default = ({ open }: Properties = {}): TemplateResult => { + const renderPopover = (): TemplateResult => html` + + Popover content goes here + + `; + const options = typeof open !== 'undefined' ? { open } : undefined; + return html` + Open Popover + `; +}; + +Default.swc_vrt = { + skip: true, +}; + +Default.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const configured = (args: Properties): TemplateResult => template(args); + +configured.swc_vrt = { + skip: true, +}; + +configured.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const insertionOptions = (args: Properties = {}): TemplateResult => html` + ${template(args)} +
+`; + +insertionOptions.args = { + insertionOptions: { + el: () => document.querySelector('#other-element'), + where: 'afterbegin', + }, +} as Properties; + +insertionOptions.swc_vrt = { + skip: true, +}; + +insertionOptions.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +class ManagedOverlayTrigger extends LitElement { + @state() + private isRenderOverlay = false; + + @state() + private isOpenState = false; + + protected override render(): TemplateResult { + return html` + { + this.isRenderOverlay = !this.isRenderOverlay; + }} + > + Toggle Overlay Render Button + + + { + this.isRenderOverlay = true; + this.isOpenState = true; + }} + > + Create Overlay Render Button And Open Overlay + + + ${this.isRenderOverlay ? this.renderOverlayButton() : html``} + `; + } + + private renderOverlayButton(): TemplateResult { + return html` + html` + + ) => { + if (event.target !== event.currentTarget) { + return; + } + console.log('sp-opened'); + this.isOpenState = true; + }} + @sp-closed=${( + event: CustomEvent + ) => { + if (event.target !== event.currentTarget) { + return; + } + console.log('sp-closed'); + this.isOpenState = false; + }} + > +

My Test Popover

+
+ `, + { + triggerInteraction: 'click', + overlayOptions: { placement: 'bottom-end' }, + open: this.isOpenState, + } + )} + > + Toggle Popover +
+ `; + } +} + +customElements.define('managed-overlay-trigger', ManagedOverlayTrigger); + +export const managedOverlayTrigger = (): TemplateResult => html` + +`; + +managedOverlayTrigger.swc_vrt = { + skip: true, +}; + +managedOverlayTrigger.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; diff --git a/1st-gen/packages/overlay/stories/overlay-element.stories.ts b/1st-gen/packages/overlay/stories/overlay-element.stories.ts new file mode 100644 index 00000000000..d94690c76d7 --- /dev/null +++ b/1st-gen/packages/overlay/stories/overlay-element.stories.ts @@ -0,0 +1,982 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, render, TemplateResult } from '@spectrum-web-components/base'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/dialog/sp-dialog-wrapper.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/action-menu/sp-action-menu.js'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/link/sp-link.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-anchor-select.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-polygon-select.js'; +import '@spectrum-web-components/textfield/sp-textfield.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/table/sp-table.js'; +import '@spectrum-web-components/table/sp-table-checkbox-cell.js'; +import '@spectrum-web-components/table/sp-table-head.js'; +import '@spectrum-web-components/table/sp-table-head-cell.js'; +import '@spectrum-web-components/table/sp-table-body.js'; +import '@spectrum-web-components/table/sp-table-row.js'; +import '@spectrum-web-components/table/sp-table-cell.js'; + +import '@spectrum-web-components/icons-workflow/icons/sp-icon-rect-select.js'; +import { Placement } from '@floating-ui/dom'; +import { OverlayTypes } from '../src/overlay-types.js'; +import { notAgain } from '../../dialog/stories/dialog-base.stories.js'; +import './overlay-story-components.js'; +import { + removeSlottableRequest, + SlottableRequestEvent, +} from '../src/slottable-request-event.js'; + +export default { + title: 'Overlay Element', + component: 'sp-overlay', + args: { + open: true, + delayed: false, + }, + argTypes: { + open: { + name: 'open', + type: { name: 'boolean', required: false }, + description: 'Whether the second accordion item is open.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + delayed: { + name: 'delayed', + type: { name: 'boolean', required: false }, + description: 'Whether the tooltips are delayed.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + }, +}; + +type WrapperStyleType = 'will-change' | 'container-type'; + +type Properties = { + delayed: boolean; + interaction: 'click' | 'hover' | 'longpress'; + open?: boolean; + placement?: Placement; + receivesFocus: 'true' | 'false' | 'auto'; + style?: WrapperStyleType; + type?: OverlayTypes; +}; + +const Template = ({ + interaction, + open, + placement, + type, + delayed, + style, +}: Properties): TemplateResult => html` + ${style === 'will-change' + ? html` + + ` + : html` + + `} +
+ Open the overlay + + + +

+ Content goes here. + ${type === 'modal' || type === 'page' + ? html` + Or, a link, + + Spectrum Web Components + + . + ` + : ''} +

+
+
+
+
+`; + +export const modal = (args: Properties): TemplateResult => Template(args); +modal.args = { + interaction: 'click', + placement: 'right', + style: 'will-change', + type: 'modal', +}; + +export const page = ({ + interaction, + open, + placement, + type, +}: Properties): TemplateResult => html` + Open the overlay + + ${notAgain()} + +`; +page.args = { + interaction: 'click', + placement: 'right', + type: 'page', +}; + +export const complexSlowPage = (): TemplateResult => html` +
+ +

+ This is a complex slow page. It has a lot of content. Even with a lot of content on the page, + the overlay should still be able to open and close without extreme delay. +

+ +
+ + open modal + + + +

I am a modal type overlay.

+ Enter your email + + + Sign in + +
+
+ + open page + + +

I am a page type overlay.

+
+
+ + + open manual + + + + Chat Window + + Send + + + + +
+ + + ${Array(30) + .fill(0) + .map( + () => html` +
+ + + + Column Title + + + Column Title + + + Column Title + + + + + + Row Item Alpha + + + Row Item Alpha + + + Row Item Alpha + + + + + Row Item Bravo + + + Row Item Bravo + + + Row Item Bravo + + + + + Row Item Charlie + + + Row Item Charlie + + + Row Item Charlie + + + + + Row Item Delta + + + Row Item Delta + + + Row Item Delta + + + + Row Item Echo + Row Item Echo + Row Item Echo + + + + + + + + + + + + + + Menu Group + Option 1 + Option 2 + + Option 3 + +
+ ` + )} +
+`; + +complexSlowPage.swc_vrt = { + skip: true, +}; + +complexSlowPage.parameters = { + chromatic: { disableSnapshot: true }, +}; + +export const click = (args: Properties): TemplateResult => Template(args); +click.args = { + interaction: 'click', + placement: 'right', + style: 'container-type' as WrapperStyleType, + type: 'auto', +}; + +export const withSlider = (): TemplateResult => html` + Button popover + + + +

Try clicking the slider after popover opens

+

It shouldn't close the popover

+ + Press me +
+
+
+`; +withSlider.swc_vrt = { + skip: true, +}; + +withSlider.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const hover = (args: Properties): TemplateResult => Template(args); +hover.args = { + interaction: 'hover', + placement: 'right', + style: 'will-change', +}; + +export const hoverTooltip = ({ + interaction, + open, + placement, + type, +}: Properties): TemplateResult => html` + +
+ Open the overlay + + Tooltip goes here. + +
+`; +hoverTooltip.args = { + interaction: 'hover', + placement: 'right', +}; + +export const longpress = (args: Properties): TemplateResult => Template(args); +longpress.args = { + interaction: 'longpress', + placement: 'right', + style: 'container-type', + type: 'auto', +}; + +/** + * Proxy for fully encapsulated overlay containers that need to + * pass `focus` into a shadow child element. + */ +export const receivesFocus = ({ + interaction, + open, + placement, + receivesFocus, + type, +}: Properties): TemplateResult => html` + + Open the overlay (with focus) + + + + + Click Content + + + +`; +receivesFocus.args = { + interaction: 'click', + placement: 'bottom-start', + type: 'auto', + receivesFocus: 'true', +} as Properties; + +export const transformed = (args: Properties): TemplateResult => html` + +
${Template(args)}
+`; +transformed.args = { + interaction: 'click', + placement: 'right', + type: 'auto', +}; + +export const contained = (args: Properties): TemplateResult => html` + +
${Template(args)}
+`; +contained.args = { + interaction: 'click', + placement: 'right', + type: 'auto', +}; + +export const all = ({ delayed }: Properties): TemplateResult => html` + + Open the overlay + + + + Click content + + + + Hover content + + + + Longpress content + + +`; + +export const actionGroup = ({ delayed }: Properties): TemplateResult => { + const popoverOffset = [6, -13] as [number, number]; + return html` + + + + + + + + + + + + + + + cms + + Update All Content + + + Refresh All XDs + + + + ssg + + Clear Cache + + + + vrt + + Contributions + + + Internal + + Public + + Patterns + + All + + + + Logout + + + + + + Hover + + + + + + + + + + + + + + + + + + Hover + + + + + + + + + + + + + + + + + + Hover + + + + + + + + + + + + + + + + + `; +}; + +export const actionGroupWithFilters = ({ + delayed, +}: Properties): TemplateResult => { + const popoverOffset = [6, -13] as [number, number]; + return html` + +

+ This story outlines some CSS usage that is not yet covered by the + placement calculations within the Overlay API. +

+ + + + + + Hover + + + + + + + + + + + + + + + + + + + + + + + + Hover + + + + + cms + + Update All Content + + + Refresh All XDs + + + + ssg + + Clear Cache + + + + vrt + + Contributions + + + Internal + + Public + + Patterns + + All + + + + Logout + + + + + + Hover + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; +}; + +// Test #3795 in browser +export const transientHover = (): TemplateResult => html` + +`; +transientHover.swc_vrt = { + skip: true, +}; + +transientHover.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const lazyElements = (): TemplateResult => { + const handleSlottableRequest = (event: SlottableRequestEvent): void => { + const template = + event.data === removeSlottableRequest + ? undefined + : html` + + + +
+ The background of this div should be blue +
+ + Press Me + + Click to open another popover. + + +
+
+ `; + render(template, event.target as HTMLElement); + }; + return html` + Trigger + + `; +}; + +lazyElements.swc_vrt = { + skip: true, +}; + +lazyElements.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const nestedModalOverlays = (): TemplateResult => html` +
+ + Open Outer Modal + + + + + +

+ This is the outer modal content. Press ESC to close it. +

+ + Open Inner Modal + + + + +

+ This is the inner modal content. Press ESC + to close this first, then the outer modal. +

+
+
+
+
+
+
+
+`; + +nestedModalOverlays.swc_vrt = { + skip: true, +}; + +nestedModalOverlays.parameters = { + chromatic: { disableSnapshot: true }, +}; diff --git a/1st-gen/packages/overlay/stories/overlay-story-components.ts b/1st-gen/packages/overlay/stories/overlay-story-components.ts new file mode 100644 index 00000000000..d192d244489 --- /dev/null +++ b/1st-gen/packages/overlay/stories/overlay-story-components.ts @@ -0,0 +1,386 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + css, + CSSResultGroup, + html, + LitElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; + +import { + Overlay, + OverlayTrigger, + Placement, +} from '@spectrum-web-components/overlay'; +import { RadioGroup } from '@spectrum-web-components/radio'; +import '@spectrum-web-components/button/sp-button.js'; +import { Button } from '@spectrum-web-components/button'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/radio/sp-radio.js'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; + +// Prevent infinite recursion in browser +const MAX_DEPTH = 7; + +class OverlayTargetIcon extends LitElement { + static override get styles(): CSSResultGroup { + return css` + :host { + position: absolute; + display: block; + color: var(--spectrum-magenta-900); + width: 64px; + height: 64px; + top: 0; + left: 0; + } + `; + } + + public override render(): TemplateResult { + return html` + + `; + } +} +customElements.define('overlay-target-icon', OverlayTargetIcon); + +class OverlayDrag extends LitElement { + @property({ type: Number }) + private top = 100; + @property({ type: Number }) + private left = 100; + + private targetElement: HTMLElement | undefined | null; + + static override get styles(): CSSResultGroup { + return css` + :host { + display: block; + width: 100%; + height: 100%; + position: relative; + } + + ::slotted(*) { + display: block; + width: 100%; + height: 100%; + } + `; + } + + private onSlotChange(event: Event & { target: HTMLSlotElement }): void { + const slot = event.target as HTMLSlotElement; + this.targetElement = undefined; + + const nodes = slot.assignedNodes(); + const slotElement = nodes.find( + (node) => node instanceof HTMLElement + ) as HTMLElement; + if (!slotElement) return; + + this.targetElement = slotElement.querySelector( + '[slot="trigger"]' + ) as HTMLElement; + if (!this.targetElement) return; + + this.targetElement.addEventListener( + 'pointerdown', + (event: PointerEvent) => this.onMouseDown(event) + ); + + this.resetTargetPosition(); + } + + private onMouseDown(event: PointerEvent): void { + const target = event.target as HTMLElement; + const parent = target.parentElement; + if (!parent) return; + target.setPointerCapture(event.pointerId); + + const max = { + x: parent.offsetWidth - target.offsetWidth, + y: parent.offsetHeight - target.offsetHeight, + }; + const dragStart = { + x: event.clientX, + y: event.clientY, + }; + const originalPos = { + x: this.left, + y: this.top, + }; + + const onMouseMove = (event: MouseEvent): void => { + const dragDelta = { + x: event.clientX - dragStart.x, + y: event.clientY - dragStart.y, + }; + const newPosition = { + x: dragDelta.x + originalPos.x, + y: dragDelta.y + originalPos.y, + }; + this.left = Math.min(Math.max(newPosition.x, 0), max.x); + this.top = Math.min(Math.max(newPosition.y, 0), max.y); + Overlay.update(); + }; + + const onMouseUp = (event: PointerEvent): void => { + target.setPointerCapture(event.pointerId); + document.removeEventListener('pointermove', onMouseMove); + document.removeEventListener('pointerup', onMouseUp); + }; + + document.addEventListener('pointermove', onMouseMove); + document.addEventListener('pointerup', onMouseUp); + } + + public resetTargetPosition(): void { + if (!this.targetElement) return; + const target = this.targetElement as HTMLElement; + const parent = target.parentElement; + if (!parent) return; + + this.left = (parent.offsetWidth - target.offsetWidth) / 2; + this.top = (parent.offsetHeight - target.offsetHeight) / 2; + } + + public override updated(): void { + if (this.targetElement) { + this.targetElement.style.transform = `translate(${this.left}px, ${this.top}px)`; + } + } + + public override render(): TemplateResult { + return html` + + `; + } +} +customElements.define('overlay-drag', OverlayDrag); + +class RecursivePopover extends LitElement { + @property({ type: String }) + private placement: Placement; + + @property({ type: Number }) + private depth = 0; + + @query('[slot="trigger"]') + private trigger!: Button; + + protected isShiftTabbing = false; + + public override shadowRoot!: ShadowRoot; + + public static override get styles(): CSSResultGroup { + return [ + css` + :host { + display: block; + text-align: center; + } + + overlay-trigger { + display: inline-flex; + margin-top: 11px; + } + `, + ]; + } + + public constructor() { + super(); + this.placement = 'right'; + this.depth = 0; + this.addEventListener('keydown', (event: KeyboardEvent) => { + const { code } = event; + if (code === 'Enter') { + this.trigger.click(); + } + }); + this.addEventListener('focusin', this.handleFocusin); + } + + private handleFocusin(): void { + this.focus(); + } + + public override focus(): void { + if (this.shadowRoot.activeElement !== null) { + return; + } + const firstFocusable = this.shadowRoot.querySelector( + 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' + ) as LitElement; + if (firstFocusable) { + if (firstFocusable.updateComplete) { + firstFocusable.updateComplete.then(() => + firstFocusable.focus() + ); + } else { + firstFocusable.focus(); + } + return; + } + super.focus(); + } + + public onRadioChange(event: Event): void { + const target = event.target as RadioGroup; + this.placement = target.selected as Placement; + } + + private captureEnter(event: KeyboardEvent): void { + const { code } = event; + if (code === 'Enter') { + event.stopPropagation(); + } + } + + public override render(): TemplateResult { + return html` + + Top + Right + Bottom + Left + + + + Open Popover + + + + ${this.depth < MAX_DEPTH + ? html` + + ` + : html` +
Maximum Depth
+ `} +
+
+
+ `; + } +} +customElements.define('recursive-popover', RecursivePopover); + +export class PopoverContent extends LitElement { + @query('[slot="trigger"]') + public button!: Button; + + @query('overlay-trigger') + public trigger!: OverlayTrigger; + + override render(): TemplateResult { + return html` + + Open me + + +

This is all the content.

+

This is all the content.

+

This is all the content.

+

This is all the content.

+
+
+
+ `; + } +} + +customElements.define('popover-content', PopoverContent); + +declare global { + interface HTMLElementTagNameMap { + 'popover-content': PopoverContent; + } +} + +export default class TransientHover extends LitElement { + @property() + open = false; + + protected override render(): TemplateResult { + return html` + + Button popover + + { + this.open = true; + }} + > + My Popover + + + ${!this.open + ? html` + + My tooltip + + ` + : html``} + `; + } +} + +customElements.define('transient-hover', TransientHover); diff --git a/1st-gen/packages/overlay/stories/overlay.stories.ts b/1st-gen/packages/overlay/stories/overlay.stories.ts new file mode 100644 index 00000000000..2477841dfd6 --- /dev/null +++ b/1st-gen/packages/overlay/stories/overlay.stories.ts @@ -0,0 +1,1909 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import { html, TemplateResult } from '@spectrum-web-components/base'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; +import '@spectrum-web-components/button/sp-button.js'; +import { DialogWrapper } from '@spectrum-web-components/dialog'; +import '@spectrum-web-components/dialog/sp-dialog-wrapper.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-open-in.js'; +import '@spectrum-web-components/link/sp-link.js'; +import { + openOverlay, + Overlay, + OverlayContentTypes, + OverlayTrigger, + Placement, + TriggerInteractions, + VirtualTrigger, +} from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; + +import '@spectrum-web-components/accordion/sp-accordion-item.js'; +import '@spectrum-web-components/accordion/sp-accordion.js'; +import '@spectrum-web-components/button-group/sp-button-group.js'; +import '@spectrum-web-components/menu/sp-menu-divider.js'; +import '@spectrum-web-components/menu/sp-menu-group.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/menu/sp-menu.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; +import { Picker } from '@spectrum-web-components/picker'; +import '@spectrum-web-components/picker/sp-picker.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +import '@spectrum-web-components/radio/sp-radio.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; + +import '../../../projects/story-decorator/src/types.js'; + +import { Button } from '@spectrum-web-components/button'; +import { Popover } from '@spectrum-web-components/popover'; +import { render } from 'lit-html'; +import './overlay-story-components.js'; +import { PopoverContent } from './overlay-story-components.js'; + +const storyStyles = html` + +`; + +export default { + title: 'Overlay', + argTypes: { + offset: { control: 'number' }, + placement: { + control: { + type: 'inline-radio', + options: [ + 'top', + 'top-start', + 'top-end', + 'bottom', + 'bottom-start', + 'bottom-end', + 'left', + 'left-start', + 'left-end', + 'right', + 'right-start', + 'right-end', + 'auto', + 'auto-start', + 'auto-end', + 'none', + ], + }, + }, + type: { + control: { + type: 'inline-radio', + options: ['modal', 'replace', 'inline'], + }, + }, + colorStop: { + control: { + type: 'inline-radio', + options: ['light', 'dark'], + }, + }, + }, + args: { + placement: 'bottom', + offset: 0, + colorStop: 'light', + }, +}; + +interface Properties { + placement: Placement; + offset: number; + open?: OverlayContentTypes; + type?: Extract; +} + +const template = ({ + placement, + offset, + open, + type, +}: Properties): TemplateResult => { + return html` + ${storyStyles} + + Show Popover + + + +
+ The background of this div should be blue +
+ + Press Me + + + Another Popover + + + + + Click to open another popover. + + +
+
+ + Click to open a popover. + +
+ `; +}; + +const extraText = html` +

This is some text.

+

This is some text.

+

+ This is a + link + . +

+`; + +function nextFrame(): Promise { + return new Promise((res) => requestAnimationFrame(() => res())); +} + +export const Default = (args: Properties): TemplateResult => template(args); + +export const accordion = (): TemplateResult => { + return html` + + + + Open overlay w/ accordion + + + + + +

+ Thing +
+
+
+
+
+
+
+ more things +

+
+ +

+ Thing +
+
+
+
+
+
+
+ more things +

+
+ +

+ Thing +
+
+
+
+
+
+
+ more things +

+
+ +

+ Thing +
+
+
+
+
+
+
+ more things +

+
+
+
+
+
+ `; +}; + +accordion.swc_vrt = { + skip: true, +}; +accordion.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const clickAndHoverTarget = (): TemplateResult => { + return html` + + Button + + Popover content + + + Tooltip content + + + `; +}; +clickAndHoverTarget.swc_vrt = { + skip: true, +}; +clickAndHoverTarget.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const clickAndHoverTargets = (): TemplateResult => { + return html` +
+ ${storyStyles} + + +
+ Click me +
+ + Ok, now hover the other trigger + +
+ +
+ Then hover me +
+ + Now click my trigger -- I should stay open, but the other + overlay should close + +
+
+ `; +}; +clickAndHoverTargets.swc_vrt = { + skip: true, +}; + +clickAndHoverTargets.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +class ScrollForcer extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + constructor() { + super(); + this.readyPromise = new Promise((res) => { + this.ready = res; + }); + this.setup(); + } + + async setup(): Promise { + await nextFrame(); + await nextFrame(); + + this.previousElementSibling?.addEventListener( + 'sp-opened', + this.doScroll + ); + await nextFrame(); + await nextFrame(); + (this.previousElementSibling?.lastElementChild as OverlayTrigger).open = + 'click'; + } + + doScroll = async (): Promise => { + this.previousElementSibling?.addEventListener( + 'sp-opened', + this.doScroll + ); + await nextFrame(); + await nextFrame(); + await nextFrame(); + await nextFrame(); + + if (document.scrollingElement) { + document.scrollingElement.scrollTop = 100; + } + + await nextFrame(); + await nextFrame(); + this.ready(true); + }; + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } +} + +customElements.define('scroll-forcer', ScrollForcer); + +export const clickContentClosedOnScroll = ( + args: Properties +): TemplateResult => html` +
+ ${template({ + ...args, + })} +
+`; +clickContentClosedOnScroll.decorators = [ + (story: () => TemplateResult): TemplateResult => html` + + ${story()} + + `, +]; + +class ComplexModalReady extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + constructor() { + super(); + this.readyPromise = new Promise((res) => { + this.ready = res; + this.setup(); + }); + } + + async setup(): Promise { + await nextFrame(); + + const overlay = document.querySelector( + `overlay-trigger` + ) as OverlayTrigger; + overlay.addEventListener('sp-opened', this.handleTriggerOpened); + } + + handleTriggerOpened = async (): Promise => { + await nextFrame(); + + const picker = document.querySelector('#test-picker') as Picker; + picker.addEventListener('sp-opened', this.handlePickerOpen); + picker.open = true; + }; + + handlePickerOpen = async (): Promise => { + const picker = document.querySelector('#test-picker') as Picker; + const actions = [nextFrame, picker.updateComplete]; + picker.focus(); + + await Promise.all(actions); + + this.ready(true); + }; + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } +} + +customElements.define('complex-modal-ready', ComplexModalReady); + +const complexModalDecorator = (story: () => TemplateResult): TemplateResult => { + return html` + ${story()} + + `; +}; + +export const complexModal = (): TemplateResult => { + return html` + + + + + Selection type: + + + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + Toggle Dialog + + + `; +}; + +complexModal.decorators = [complexModalDecorator]; + +export const customizedClickContent = ( + args: Properties +): TemplateResult => html` + + ${template({ + ...args, + open: 'click', + })} +`; + +export const deep = (): TemplateResult => html` + + + Open popover 1 with buttons + selfmanaged Tooltips + + + + + + My Tooltip 1 + + A + + + + My Tooltip 1 + + B + + + + + + + + Open popover 2 with buttons without ToolTips + + + + X + Y + + + +`; +deep.swc_vrt = { + skip: true, +}; + +deep.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const deepChildTooltip = (): TemplateResult => html` + + Open popover + + +

Let us open another overlay here

+ + + Open sub popover + + + +

+ Render an action button with tooltips. Clicking + the action button shouldn't close everything +

+ + Button with self-managed tooltip + + Deep Child ToolTip + + + Just a button +
+
+
+
+
+
+`; + +export const deepNesting = (): TemplateResult => { + const color = window.__swc_hack_knobs__.defaultColor; + const outter = color === 'light' ? 'dark' : 'light'; + return html` + ${storyStyles} + + + + + + `; +}; + +class DefinedOverlayReady extends HTMLElement { + ready!: (value: boolean | PromiseLike) => void; + + connectedCallback(): void { + if (!!this.ready) return; + + this.readyPromise = new Promise((res) => { + this.ready = res; + this.setup(); + }); + } + + overlayElement!: OverlayTrigger; + popoverElement!: PopoverContent; + + async setup(): Promise { + await nextFrame(); + await nextFrame(); + + this.overlayElement = document.querySelector( + `overlay-trigger` + ) as OverlayTrigger; + const button = document.querySelector( + `[slot="trigger"]` + ) as HTMLButtonElement; + this.overlayElement.addEventListener( + 'sp-opened', + this.handleTriggerOpened + ); + await nextFrame(); + await nextFrame(); + button.click(); + } + + handleTriggerOpened = async (): Promise => { + this.overlayElement.removeEventListener( + 'sp-opened', + this.handleTriggerOpened + ); + await nextFrame(); + await nextFrame(); + await nextFrame(); + await nextFrame(); + + this.popoverElement = document.querySelector( + 'popover-content' + ) as PopoverContent; + if (!this.popoverElement) { + return; + } + this.popoverElement.addEventListener( + 'sp-opened', + this.handlePopoverOpen + ); + await nextFrame(); + await nextFrame(); + this.popoverElement.button.click(); + }; + + handlePopoverOpen = async (): Promise => { + await nextFrame(); + + this.ready(true); + }; + + disconnectedCallback(): void { + this.overlayElement.removeEventListener( + 'sp-opened', + this.handleTriggerOpened + ); + this.popoverElement.removeEventListener( + 'sp-opened', + this.handlePopoverOpen + ); + } + + private readyPromise: Promise = Promise.resolve(false); + + get updateComplete(): Promise { + return this.readyPromise; + } +} + +customElements.define('defined-overlay-ready', DefinedOverlayReady); + +const definedOverlayDecorator = ( + story: () => TemplateResult +): TemplateResult => { + return html` + ${story()} + + `; +}; + +export const definedOverlayElement = (): TemplateResult => { + return html` + + Open popover + + + + + + + `; +}; + +definedOverlayElement.decorators = [definedOverlayDecorator]; + +export const detachedElement = (): TemplateResult => { + let overlay: Overlay | undefined; + const openDetachedOverlayContent = async ({ + target, + }: { + target: HTMLElement; + }): Promise => { + if (overlay) { + overlay.open = false; + overlay = undefined; + return; + } + const div = document.createElement('div'); + (div as HTMLDivElement & { open: boolean }).open = false; + div.textContent = 'This div is overlaid'; + div.setAttribute( + 'style', + ` + background-color: var(--spectrum-gray-50); + color: var(--spectrum-gray-800); + border: 1px solid; + padding: 2em; + ` + ); + overlay = await Overlay.open(div, { + type: 'auto', + trigger: target, + receivesFocus: 'auto', + placement: 'bottom', + offset: 0, + }); + overlay.addEventListener('sp-closed', () => { + overlay = undefined; + }); + target.insertAdjacentElement('afterend', overlay); + }; + requestAnimationFrame(() => { + openDetachedOverlayContent({ + target: document.querySelector( + '#detached-content-trigger' + ) as HTMLElement, + }); + }); + return html` + + + + + `; +}; + +export const edges = (): TemplateResult => { + return html` + + + + Top/ +
+ Left +
+ + Triskaidekaphobia and More + +
+ + + Top/ +
+ Right +
+ + Triskaidekaphobia and More + +
+ + + Bottom/ +
+ Left +
+ + Triskaidekaphobia and More + +
+ + + Bottom/ +
+ Right +
+ + Triskaidekaphobia and More + +
+ `; +}; + +export const inline = (): TemplateResult => { + const closeEvent = new Event('close', { bubbles: true, composed: true }); + return html` + + Open + + { + event.target.dispatchEvent(closeEvent); + }} + > + Close + + + + ${extraText} + `; +}; + +export const longpress = (): TemplateResult => { + return html` + + + + + Search real hard... + + + event.target.dispatchEvent( + new Event('close', { bubbles: true }) + )} + selects="single" + vertical + style="margin: calc(var(--spectrum-actiongroup-button-gap-y,calc(var(--swc-scale-factor) * 10px)) / 2);" + > + + + + + + + + + + + + + `; +}; + +export const modalLoose = (): TemplateResult => { + const closeEvent = new Event('close', { bubbles: true, composed: true }); + return html` + + Open + + event.target.dispatchEvent(closeEvent)} + > +

Loose Dialog

+

+ The + sp-dialog + element is not "meant" to be a modal alone. In that way it + does not manage its own + open + attribute or outline when it should have + pointer-events: auto + . It's a part of this test suite to prove that content in + this way can be used in an + overlay-trigger + element. +

+
+
+ ${extraText} + `; +}; + +export const modalNoFocus = (): TemplateResult => { + const closeEvent = new Event('close', { bubbles: true, composed: true }); + return html` + + Open + +

+ The + sp-dialog-wrapper + element has been prepared for use in an + overlay-trigger + element by it's combination of modal, underlay, etc. styles + and features. +

+ + + event.target.dispatchEvent(closeEvent)} + > + ${'Cancel'} + + + event.target.dispatchEvent(closeEvent)} + > + ${'Override'} + + +
+
+ `; +}; + +export const modalManaged = (): TemplateResult => { + const closeEvent = new Event('close', { bubbles: true, composed: true }); + return html` + + Open + { + event.target.dispatchEvent(closeEvent); + }} + @secondary=${( + event: Event & { target: DialogWrapper } + ): void => { + event.target.dispatchEvent(closeEvent); + }} + @cancel=${(event: Event & { target: DialogWrapper }): void => { + event.target.dispatchEvent(closeEvent); + }} + > +

+ The + sp-dialog-wrapper + element has been prepared for use in an + overlay-trigger + element by it's combination of modal, underlay, etc. styles + and features. +

+
+
+ ${extraText} + `; +}; + +export const modalWithinNonModal = (): TemplateResult => { + return html` + + + Open inline overlay + + + + + + Open modal overlay + + + + Modal overlay + + + + + + + `; +}; + +export const noCloseOnResize = (args: Properties): TemplateResult => html` + + ${template({ + ...args, + open: 'click', + })} +`; +noCloseOnResize.swc_vrt = { + skip: true, +}; + +noCloseOnResize.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const openClickContent = (args: Properties): TemplateResult => + template({ + ...args, + open: 'click', + }); + +export const openHoverContent = (args: Properties): TemplateResult => + template({ + ...args, + open: 'hover', + }); + +export const replace = (): TemplateResult => { + const closeEvent = new Event('close', { bubbles: true, composed: true }); + return html` + + Open + + { + event.target.dispatchEvent(closeEvent); + }} + > + Close + + + + ${extraText} + `; +}; + +export const sideHoverDraggable = (): TemplateResult => { + return html` + ${storyStyles} + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Vivamus egestas sed enim sed condimentum. Nunc facilisis + scelerisque massa sed luctus. Orci varius natoque penatibus + et magnis dis parturient montes, nascetur ridiculus mus. + Suspendisse sagittis sodales purus vitae ultricies. Integer + at dui sem. Sed quam tortor, ornare in nisi et, rhoncus + lacinia mauris. Sed vel rutrum mauris, ac pellentesque nibh. + Sed feugiat semper libero, sit amet vehicula orci fermentum + id. Vivamus imperdiet egestas luctus. Mauris tincidunt + malesuada ante, faucibus viverra nunc blandit a. Fusce et + nisl nisi. Aenean dictum quam id mollis faucibus. Nulla a + ultricies dui. In hac habitasse platea dictumst. Curabitur + gravida lobortis vestibulum. + + + + `; +}; + +export const superComplexModal = (): TemplateResult => { + return html` + + Toggle Dialog + + + + + Toggle Dialog + + + + + + Toggle Dialog + + + +

+ When you get this deep, this + ActiveOverlay should be the only + one in [slot="open"]. +

+

+ All of the rest of the + ActiveOverlay elements should + have had their [slot] attribute + removed. +

+

+ Closing this ActiveOverlay + should replace them... +

+
+
+
+
+
+
+
+
+
+ `; +}; + +export const updated = (): TemplateResult => { + return html` + ${storyStyles} + + + + + + Click to open popover + + + + +
+ The background of this div should be blue +
+ + Press Me + + + Another Popover + + + + + Click to open another popover. + + +
+
+
+
+ `; +}; + +export const updating = (): TemplateResult => { + const update = (): void => { + const button = document.querySelector('[slot="trigger"]') as Button; + button.style.left = `${Math.floor(Math.random() * 200)}px`; + button.style.top = `${Math.floor(Math.random() * 200)}px`; + button.style.position = 'fixed'; + }; + return html` + + + Open inline overlay + + + + + Update trigger location. + + + + + `; +}; + +updating.swc_vrt = { + skip: true, +}; + +updating.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +class StartEndContextmenu extends HTMLElement { + override shadowRoot!: ShadowRoot; + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot.innerHTML = ` + +
+
+ `; + } +} + +customElements.define('start-end-contextmenu', StartEndContextmenu); + +export const virtualElementV1 = (args: Properties): TemplateResult => { + const contextMenuTemplate = (kind = ''): TemplateResult => html` + { + if ( + (event.target as HTMLElement).localName === 'sp-menu-item' + ) { + event.target?.dispatchEvent( + new Event('close', { bubbles: true }) + ); + } + }} + > + + + Menu source: ${kind} + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + `; + const handleContextmenu = async (event: PointerEvent): Promise => { + event.preventDefault(); + event.stopPropagation(); + + const source = event.composedPath()[0] as HTMLDivElement; + const { id } = source; + const trigger = event.target as HTMLElement; + const virtualTrigger = new VirtualTrigger(event.clientX, event.clientY); + const fragment = document.createDocumentFragment(); + render(contextMenuTemplate(id), fragment); + const popover = fragment.querySelector('sp-popover') as Popover; + + openOverlay(trigger, 'click', popover, { + placement: args.placement, + receivesFocus: 'auto', + virtualTrigger, + offset: 0, + notImmediatelyClosable: true, + }); + }; + return html` + + + `; +}; + +virtualElementV1.args = { + placement: 'right-start' as Placement, +}; + +export const virtualElement = (args: Properties): TemplateResult => { + const contextMenuTemplate = (kind = ''): TemplateResult => html` + { + if ( + (event.target as HTMLElement).localName === 'sp-menu-item' + ) { + event.target?.dispatchEvent( + new Event('close', { bubbles: true }) + ); + } + }} + > + + + Menu source: ${kind} + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + `; + const handleContextmenu = async (event: PointerEvent): Promise => { + event.preventDefault(); + event.stopPropagation(); + + const source = event.composedPath()[0] as HTMLDivElement; + const { id } = source; + const trigger = event.target as HTMLElement; + const virtualTrigger = new VirtualTrigger(event.clientX, event.clientY); + const fragment = document.createDocumentFragment(); + render(contextMenuTemplate(id), fragment); + const popover = fragment.querySelector('sp-popover') as Popover; + + const overlay = await openOverlay(popover, { + trigger: virtualTrigger, + placement: args.placement, + offset: 0, + notImmediatelyClosable: true, + type: 'auto', + }); + trigger.insertAdjacentElement('afterend', overlay); + }; + return html` + + + `; +}; + +virtualElement.args = { + placement: 'right-start' as Placement, +}; + +export const virtualElementDeclaratively = ( + args: Properties +): TemplateResult => { + const handleContextmenu = async (event: PointerEvent): Promise => { + event.preventDefault(); + event.stopPropagation(); + + const overlay = document.querySelector( + 'sp-overlay:not([open])' + ) as Overlay; + + if (overlay.triggerElement instanceof VirtualTrigger) { + overlay.triggerElement.updateBoundingClientRect( + event.clientX, + event.clientY + ); + } + overlay.willPreventClose = true; + overlay.open = true; + }; + const overlay = (): TemplateResult => html` + + { + event.target?.dispatchEvent( + new Event('close', { bubbles: true }) + ); + }} + > + + + Menu + Deselect + Select inverse + Feather... + Select and mask... + + Save selection + Make work path + + + + + `; + + return html` + +
+ ${overlay()} ${overlay()} +
+ `; +}; + +virtualElementDeclaratively.args = { + placement: 'right-start' as Placement, +}; + +virtualElementDeclaratively.swc_vrt = { + skip: true, +}; + +virtualElementDeclaratively.parameters = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const triggeredByOptimization = (): TemplateResult => { + return html` +

"triggered-by" attribute optimization

+

+ This demo shows different ways to trigger overlays using the + triggered-by + attribute. +

+

+ Pro tip: + Inspect the DOM to verify that only the respective overlay elements + are being rendered into the DOM based on the + triggered-by + value. +

+

+ Unused interaction types aren't rendered. This improves performance, + reduces the number of unecessary DOM nodes and avoids race + conditions in slot reparenting. +

+
+ + + Click and hover trigger + + Click content + + Hover content + + + + + Longpress trigger + + Longpress content + +
+ Press and hold to reveal more options +
+
+ + + + Click only trigger + + Click content + + + + + + Hover only trigger + Hover content + +
+ `; +}; + +export const hoverWithInteractiveContent = (): TemplateResult => { + return html` +
+ + + + Hover for interactive buttons + + + +

Interactive content

+

Tab into these buttons:

+
+ Action 1 + Action 2 + Action 3 +
+
+
+
+ + + + + Hover for interactive links + + + +

Quick links

+
    +
  • + + Example link 1 + +
  • +
  • + + Example link 2 + +
  • +
  • + + Example link 3 + +
  • +
+
+
+
+ + + + Hover for action group + + + + + Send to Front + + + + Send to Back + + + + Align Center + + + + +
+ `; +}; + +hoverWithInteractiveContent.swc_vrt = { + skip: true, +}; + +export const pickerInDialog = (): TemplateResult => { + return html` + Button popover + + + + + Open picker, then try clicking outside to close it: + + + Deselect + + Select inverse + + Feather... + + Select and mask... + + + + Save selection + + + Make work path + + + + + + `; +}; + +pickerInDialog.swc_vrt = { + skip: true, +}; + +pickerInDialog.args = { + // Disables Chromatic's snapshotting on a global level + chromatic: { disableSnapshot: true }, +}; + +export const disabledOverlayTrigger = (): TemplateResult => { + return html` + ${storyStyles} +

Disabled Overlay Trigger

+

This demonstrates how disabled overlay-triggers should work:

+
    +
  • + The overlay (tooltip/popover) functionality should be disabled +
  • +
  • But the trigger content itself should remain interactive
  • +
+ +
+ +
+

Disabled overlay-trigger

+ +
+

This container has a disabled overlay-trigger

+ + This button should still be clickable + +
+ + This tooltip should not appear (disabled) + + + + This popover should not appear (disabled) + + +
+

Button not clicked yet

+
+ + +
+

Regular overlay-trigger (for comparison)

+ +
+

This container has a regular overlay-trigger

+ + This button should be clickable + +
+ + This tooltip should appear on hover + + + + This popover should appear on click + + +
+

Button not clicked yet

+
+
+ + + `; +}; + +disabledOverlayTrigger.swc_vrt = { + skip: true, +}; + +export const WithInteractiveContent = (): TemplateResult => { + return html` +
+ Open Overlay + + +

+ My slider in overlay element: + +

+
+
+
+ `; +}; diff --git a/1st-gen/packages/overlay/sync/overlay-trigger.ts b/1st-gen/packages/overlay/sync/overlay-trigger.ts new file mode 100644 index 00000000000..e84d088a4bb --- /dev/null +++ b/1st-gen/packages/overlay/sync/overlay-trigger.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { OverlayTrigger } from '../src/OverlayTrigger.js'; +import { OverlayOptionsV1, TriggerInteractions } from '../src/index.js'; +import '../overlay-trigger.js'; +import '../sp-overlay.js'; + +export { OverlayTrigger }; +export type { OverlayOptionsV1, TriggerInteractions }; diff --git a/1st-gen/packages/overlay/test/benchmark/basic-test.ts b/1st-gen/packages/overlay/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..82bfc75182d --- /dev/null +++ b/1st-gen/packages/overlay/test/benchmark/basic-test.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/overlay/overlay-trigger.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + Trigger + + + +
+ The background of this div should be blue +
+ + Press Me + + Click to open another popover. + + +
+
+
+`); diff --git a/1st-gen/packages/overlay/test/benchmark/directive-test.ts b/1st-gen/packages/overlay/test/benchmark/directive-test.ts new file mode 100644 index 00000000000..8ad486d658e --- /dev/null +++ b/1st-gen/packages/overlay/test/benchmark/directive-test.ts @@ -0,0 +1,53 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { trigger } from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import { html, TemplateResult } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const renderPopover = (): TemplateResult => { + import('@spectrum-web-components/popover/sp-popover.js'); + import('@spectrum-web-components/dialog/sp-dialog.js'); + import('@spectrum-web-components/slider/sp-slider.js'); + import('@spectrum-web-components/tooltip/sp-tooltip.js'); + return html` + + + +
+ The background of this div should be blue +
+ + Press Me + + Click to open another popover. + + +
+
+ `; +}; + +measureFixtureCreation(html` + Trigger +`); diff --git a/1st-gen/packages/overlay/test/benchmark/element-test.ts b/1st-gen/packages/overlay/test/benchmark/element-test.ts new file mode 100644 index 00000000000..fffa92de895 --- /dev/null +++ b/1st-gen/packages/overlay/test/benchmark/element-test.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/overlay/sp-overlay.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import '@spectrum-web-components/slider/sp-slider.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + Trigger + + + + +
+ The background of this div should be blue +
+ + Press Me + + Click to open another popover. + + +
+
+
+`); diff --git a/1st-gen/packages/overlay/test/benchmark/lazy-test.ts b/1st-gen/packages/overlay/test/benchmark/lazy-test.ts new file mode 100644 index 00000000000..c64ddb34c66 --- /dev/null +++ b/1st-gen/packages/overlay/test/benchmark/lazy-test.ts @@ -0,0 +1,61 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/overlay/sp-overlay.js'; +import '@spectrum-web-components/button/sp-button.js'; +import { + removeSlottableRequest, + type SlottableRequestEvent, +} from '@spectrum-web-components/overlay/src/slottable-request-event.js'; +import { html, render } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +const handleSlottableRequest = (event: SlottableRequestEvent): void => { + import('@spectrum-web-components/popover/sp-popover.js'); + import('@spectrum-web-components/dialog/sp-dialog.js'); + import('@spectrum-web-components/slider/sp-slider.js'); + import('@spectrum-web-components/tooltip/sp-tooltip.js'); + const template = + event.data === removeSlottableRequest + ? undefined + : html` + + + +
+ The background of this div should be blue +
+ + Press Me + + Click to open another popover. + + +
+
+ `; + render(template, event.target as HTMLElement); +}; + +measureFixtureCreation(html` + Trigger + +`); diff --git a/1st-gen/packages/overlay/test/index.ts b/1st-gen/packages/overlay/test/index.ts new file mode 100644 index 00000000000..8f2d39c82b3 --- /dev/null +++ b/1st-gen/packages/overlay/test/index.ts @@ -0,0 +1,750 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + aTimeout, + elementUpdated, + expect, + html, + nextFrame, + oneEvent, +} from '@open-wc/testing'; +import { fixture, isOnTopLayer } from '../../../test/testing-helpers.js'; + +import { Button } from '@spectrum-web-components/button'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import { + OVERLAY_TYPES, + OverlayTrigger, +} from '@spectrum-web-components/overlay'; +import { Popover } from '@spectrum-web-components/popover'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { sendMouse } from '../../../test/plugins/browser.js'; + +export const runOverlayTriggerTests = (type: string): void => { + describe(`Overlay Trigger - ${type}`, () => { + describe('open/close', () => { + beforeEach(async function () { + this.testDiv = await fixture(html` +
+ + + + + Show Popover + + + + + + Press Me + + + + Another Popover + + Does nothing + + + + + + +
+ Tooltip +
+
+
+ `); + + this.innerTrigger = this.testDiv.querySelector( + '#inner-trigger' + )! as OverlayTrigger; + this.outerTrigger = this.testDiv.querySelector( + '#trigger' + )! as OverlayTrigger; + this.innerButton = this.testDiv.querySelector( + '#inner-button' + ) as Button; + this.outerButton = this.testDiv.querySelector( + '#outer-button' + ) as Button; + this.innerClickContent = this.testDiv.querySelector( + '#inner-popover' + ) as Popover; + this.outerClickContent = this.testDiv.querySelector( + '#outer-popover' + ) as Popover; + this.hoverContent = this.testDiv.querySelector( + '#hover-content' + ) as HTMLDivElement; + + await Promise.all([ + this.innerTrigger.updateComplete, + this.outerTrigger.updateComplete, + this.innerButton.updateComplete, + this.outerButton.updateComplete, + this.innerClickContent.updateComplete, + this.outerClickContent.updateComplete, + ]); + this.testDiv.querySelector('input').focus(); + }); + + it('opens a popover', async function () { + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + + expect(this.outerButton).to.exist; + const open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + }); + + it('[disabled] closes a popover', async function () { + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + expect(this.outerTrigger.disabled).to.be.false; + + expect(this.outerButton).to.exist; + + const opened = oneEvent(this.outerButton, 'sp-opened'); + this.outerButton.click(); + await opened; + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + + const closed = oneEvent(this.outerButton, 'sp-closed'); + this.outerTrigger.disabled = true; + await closed; + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + }); + + it('resizes a popover', async function () { + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + + expect(this.outerButton).to.exist; + const open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + + window.dispatchEvent(new Event('resize')); + window.dispatchEvent(new Event('resize')); + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + }); + + OVERLAY_TYPES.map((type) => { + it(`opens a popover - [type="${type}"]`, async function () { + const outerTrigger = this.outerTrigger as OverlayTrigger; + + outerTrigger.type = type; + await elementUpdated(outerTrigger); + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + + expect(this.outerButton).to.exist; + const opened = oneEvent(outerTrigger, 'sp-opened'); + this.outerButton.click(); + await opened; + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + }); + }); + + it('does not open a hover popover when a click popover is open', async function () { + expect( + await isOnTopLayer(this.outerClickContent), + 'popover not available at point' + ).to.be.false; + expect( + await isOnTopLayer(this.hoverContent), + 'hover not available at point' + ).to.be.false; + + expect(this.outerButton).to.exist; + const open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.hoverContent), + 'hover not available at point' + ).to.be.false; + + this.outerButton.dispatchEvent( + new Event('mouseenter', { + bubbles: true, + composed: true, + }) + ); + + await nextFrame(); + + expect( + await isOnTopLayer(this.outerClickContent), + 'popover available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.hoverContent), + 'hover not available at point' + ).to.be.false; + }); + + it('does not open a popover when [disabled]', async function () { + const triggerZone = this.outerTrigger.shadowRoot.querySelector( + '#trigger' + ) as HTMLDivElement; + + expect(this.outerTrigger.disabled).to.be.false; + let open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + expect( + await isOnTopLayer(this.outerClickContent), + 'hover available at point' + ).to.be.true; + let closed = oneEvent(this.outerTrigger, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [1, 1], + }); + await closed; + expect( + await isOnTopLayer(this.outerClickContent), + 'hover not available at point' + ).to.be.false; + + this.outerTrigger.disabled = true; + await elementUpdated(this.outerTrigger); + + expect(this.outerTrigger.disabled).to.be.true; + expect(this.outerTrigger.hasAttribute('disabled')).to.be.true; + // // The overlay shouldn't open here. + this.outerButton.click(); + await aTimeout(150); + expect( + await isOnTopLayer(this.outerClickContent), + 'hover not available at point' + ).to.be.false; + // The overlay shouldn't open here, either. + triggerZone.dispatchEvent(new Event('mouseenter')); + await aTimeout(150); + expect( + await isOnTopLayer(this.outerClickContent), + 'hover not available at point' + ).to.be.false; + + this.outerTrigger.disabled = false; + await elementUpdated(this.outerTrigger); + + expect(this.outerTrigger.disabled).to.be.false; + expect(this.outerTrigger.hasAttribute('disabled')).to.be.false; + open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + expect( + await isOnTopLayer(this.outerClickContent), + 'hover available at point' + ).to.be.true; + closed = oneEvent(this.outerTrigger, 'sp-closed'); + this.outerButton.click(); + await closed; + + expect( + await isOnTopLayer(this.outerClickContent), + 'hover not available at point' + ).to.be.false; + }); + + it('opens a nested popover', async function () { + expect( + await isOnTopLayer(this.outerClickContent), + 'hover not available at point' + ).to.be.false; + expect( + await isOnTopLayer(this.innerClickContent), + 'hover not available at point' + ).to.be.false; + + expect(this.outerButton).to.exist; + let open = oneEvent(this.outerTrigger, 'sp-opened'); + this.outerButton.click(); + await open; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect(await isOnTopLayer(this.innerClickContent)).to.be.false; + + open = oneEvent(this.innerTrigger, 'sp-opened'); + this.innerButton.click(); + await open; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content available at point' + ).to.be.true; + }); + + it('focus previous "modal" when closing nested "modal"', async function () { + this.outerTrigger.type = 'modal'; + this.innerTrigger.type = 'modal'; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content not available at point' + ).to.be.false; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content not available at point' + ).to.be.false; + + const outerOpen = oneEvent(this.outerButton, 'sp-opened'); + this.outerButton.click(); + await outerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content available at point' + ).to.be.false; + + const innerOpen = oneEvent(this.innerButton, 'sp-opened'); + this.innerButton.click(); + await innerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content available at point' + ).to.be.true; + + // Why does this make the test pass in Chromium? 🤷🏻‍♂️ + await sendKeys({ press: 'Space' }); + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content available at point' + ).to.be.true; + + const innerClose = oneEvent(this.innerButton, 'sp-closed'); + await sendKeys({ press: 'Escape' }); + await innerClose; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content not available at point' + ).to.be.false; + + expect( + document.activeElement === this.innerButton, + `outer popover recieved focus: ${document.activeElement?.localName}` + ).to.be.true; + }); + + it('escape closes an open popover', async function () { + this.outerTrigger.type = 'modal'; + this.innerTrigger.type = 'modal'; + const outerOpen = oneEvent(this.outerButton, 'sp-opened'); + this.outerButton.click(); + await outerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point' + ).to.be.true; + + const innerOpen = oneEvent(this.innerButton, 'sp-opened'); + this.innerButton.click(); + await innerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point, 1' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content available at point' + ).to.be.true; + + const innerClose = oneEvent(this.innerButton, 'sp-closed'); + await sendKeys({ press: 'Escape' }); + await innerClose; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content available at point, 2' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content not available at point, 1' + ).to.be.false; + + const outerClose = oneEvent(this.outerButton, 'sp-closed'); + await sendKeys({ press: 'Escape' }); + await outerClose; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content not available at point' + ).to.be.false; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content not available at point, 2' + ).to.be.false; + }); + + it('click closes an open popover', async function () { + this.outerTrigger.type = 'auto'; + this.innerTrigger.type = 'auto'; + const outerOpen = oneEvent(this.outerButton, 'sp-opened'); + this.outerButton.click(); + await outerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content is available at point' + ).to.be.true; + + const innerOpen = oneEvent(this.innerButton, 'sp-opened'); + this.innerButton.click(); + await innerOpen; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content is available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content is available at point' + ).to.be.true; + + // Test that clicking in the overlay content does not close the overlay + // 200ms is slightly more than the overlay animation fade out time (130ms) + this.innerClickContent.click(); + await aTimeout(200); + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content is available at point' + ).to.be.true; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content is available at point' + ).to.be.true; + + const innerClose = oneEvent(this.innerButton, 'sp-closed'); + const outerClose = oneEvent(this.outerButton, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [1, 1], + }); + await innerClose; + await outerClose; + + expect( + await isOnTopLayer(this.outerClickContent), + 'outer click content is not available at point' + ).to.be.not; + expect( + await isOnTopLayer(this.innerClickContent), + 'inner click content is not available at point' + ).to.be.not; + }); + + it('opens a hover popover', async function () { + expect(await isOnTopLayer(this.hoverContent)).to.be.false; + + const rect = this.outerTrigger.getBoundingClientRect(); + const open = oneEvent(this.outerTrigger, 'sp-opened'); + await sendMouse({ + type: 'move', + position: [ + rect.left + rect.width / 2, + rect.top + rect.height / 2, + ], + }); + await open; + expect( + await isOnTopLayer(this.hoverContent), + 'hover content is available at point' + ).to.be.true; + + const close = oneEvent(this.outerTrigger, 'sp-closed'); + await sendMouse({ + type: 'move', + position: [ + rect.left + rect.width * 2, + rect.top + rect.height / 2, + ], + }); + await close; + expect( + await isOnTopLayer(this.hoverContent), + 'hover content is not available at point' + ).to.be.false; + }); + + it('closes a hover popover', async function () { + expect(await isOnTopLayer(this.hoverContent)).to.be.false; + + const rect = this.outerTrigger.getBoundingClientRect(); + const open = oneEvent(this.outerTrigger, 'sp-opened'); + await sendMouse({ + type: 'move', + position: [ + rect.left + rect.width / 2, + rect.top + rect.height / 2, + ], + }); + await open; + const close = oneEvent(this.outerTrigger, 'sp-closed'); + expect( + await isOnTopLayer(this.hoverContent), + 'hover content is available at point' + ).to.be.true; + await sendMouse({ + type: 'move', + position: [ + rect.left + rect.width * 2, + rect.top + rect.height / 2, + ], + }); + await close; + expect( + await isOnTopLayer(this.hoverContent), + 'hover content is not available at point' + ).to.be.false; + }); + + it('dispatches events on open/close', async function () { + const opened = oneEvent(this.outerButton, 'sp-opened'); + this.outerButton.click(); + const openedEvent = await opened; + + expect( + await isOnTopLayer(this.outerClickContent), + 'hover content is available at point' + ).to.be.true; + expect(this.outerTrigger.open).to.equal('click'); + + expect(openedEvent.detail.interaction).to.equal('auto'); + + const closed = oneEvent(this.outerButton, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [1, 1], + }); + const closedEvent = await closed; + expect(closedEvent.detail.interaction).to.equal('auto'); + expect( + await isOnTopLayer(this.outerClickContent), + 'hover content is not available at point' + ).to.be.false; + }); + + it('blocks body scroll when modal overlay is opened and restores when closed', async function () { + const originalBodyOverflow = document.body.style.overflow; + + const modalTrigger = this.outerTrigger; + modalTrigger.type = 'modal'; + await elementUpdated(modalTrigger); + + // Open modal overlay + const opened = oneEvent(modalTrigger, 'sp-opened'); + this.outerButton.click(); + await opened; + + // Check that body scroll is blocked + expect(document.body.style.overflow).to.equal('hidden'); + + // Close modal overlay + const closed = oneEvent(modalTrigger, 'sp-closed'); + sendMouse({ + steps: [ + { + type: 'click', + position: [1, 1], + }, + ], + }); + await closed; + + // Check that body scroll is restored + expect(document.body.style.overflow).to.equal( + originalBodyOverflow + ); + }); + + it('actually prevents page scrolling when modal overlay is open and restores scrolling when closed', async function () { + // Create a long enough page to enable scrolling + const longContent = document.createElement('div'); + longContent.style.height = '200vh'; // Make page twice viewport height + longContent.style.width = '100%'; + longContent.style.backgroundColor = 'transparent'; + document.body.appendChild(longContent); + + const modalTrigger = this.outerTrigger; + modalTrigger.type = 'modal'; + await elementUpdated(modalTrigger); + + // Open modal overlay + const opened = oneEvent(modalTrigger, 'sp-opened'); + this.outerButton.click(); + await opened; + + // Attempt to scroll while modal is open + const scrollYBeforeScroll = window.scrollY; + window.scrollTo(0, 100); + await nextFrame(); + + // Verify that scrolling was prevented + expect(window.scrollY).to.equal(scrollYBeforeScroll); + + // Close modal overlay + const closed = oneEvent(modalTrigger, 'sp-closed'); + await sendMouse({ + steps: [ + { + type: 'click', + position: [1, 1], + }, + ], + }); + await closed; + + // Verify scrolling works again after modal is closed + window.scrollTo(0, 100); + await nextFrame(); + expect(window.scrollY).to.equal(100); + + // Clean up + document.body.removeChild(longContent); + }); + }); + describe('System interactions', () => { + afterEach(async () => { + const triggers = + document.querySelectorAll( + 'overlay-trigger' + ); + const closes: Promise>[] = []; + triggers.forEach((trigger) => { + if (trigger.open) { + const close = oneEvent(trigger, 'sp-closed'); + trigger.open = undefined; + closes.push(close); + } + }); + await Promise.all(closes); + }); + }); + }); +}; diff --git a/1st-gen/packages/overlay/test/overlay-directive.test.ts b/1st-gen/packages/overlay/test/overlay-directive.test.ts new file mode 100644 index 00000000000..aef487ef250 --- /dev/null +++ b/1st-gen/packages/overlay/test/overlay-directive.test.ts @@ -0,0 +1,159 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@spectrum-web-components/base'; +import { + elementUpdated, + expect, + nextFrame, + oneEvent, + waitUntil, +} from '@open-wc/testing'; +import { Button } from '@spectrum-web-components/button'; +import { Overlay } from '@spectrum-web-components/overlay'; +import { + Default, + insertionOptions, +} from '../stories/overlay-directive.stories.js'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { + fixture, + mouseClickAway, + mouseClickOn, + mouseMoveOver, +} from '../../../test/testing-helpers.js'; + +describe('Overlay Directive', () => { + it('opens declaratively', async function () { + const test = await fixture + `); + + const content = document.createElement('sp-popover'); + content.textContent = textContent; + + const opened = oneEvent(content, 'sp-opened'); + const closeOverlay = await Overlay.open(el, 'click', content, { + placement: 'bottom', + }); + await opened; + + expect(await isInteractive(content)).to.be.true; + + const closed = oneEvent(content, 'sp-closed'); + closeOverlay(); + await closed; + + expect(await isInteractive(content)).to.be.false; + + content.remove(); + }); +}); +describe('Overlay - type="modal", v1', () => { + describe('handle multiple separate `contextmenu` events', async () => { + let width = 0; + let height = 0; + let firstMenu: Popover; + let firstRect: DOMRect; + let secondMenu: Popover; + let secondRect: DOMRect; + before(async () => { + render( + html` + + ${virtualElementV1({ + ...virtualElementV1.args, + offset: 6, + })} + + `, + document.body + ); + + width = window.innerWidth; + height = window.innerHeight; + }); + after(() => { + document.querySelector('sp-theme')?.remove(); + }); + it('opens the first "contextmenu" overlay', async () => { + const opened = oneEvent(document, 'sp-opened'); + // Right click to open "context menu" overlay. + await sendMouse({ + steps: [ + { + type: 'move', + position: [width / 2 + 50, height / 2], + }, + { + type: 'click', + options: { + button: 'right', + }, + position: [width / 2 + 50, height / 2], + }, + ], + }); + await opened; + firstMenu = document.querySelector('sp-popover') as Popover; + expect(firstMenu.textContent).to.include('Menu source: end'); + firstRect = firstMenu.getBoundingClientRect(); + expect(firstMenu).to.not.be.null; + }); + it('closes the first "contextmenu" when opening a second', async () => { + const closed = oneEvent(document, 'sp-closed'); + const opened = oneEvent(document, 'sp-opened'); + /** + * Right click out of the "context menu" overlay to both close + * the first overlay and have the event passed to the surfacing page + * in order to open a subsequent "context menu" overlay. + * + * Using `sendMouse` here triggers the light dismiss for some reason while + * manual interacting in this way does not... + */ + const trigger = document.querySelector( + 'start-end-contextmenu' + ) as HTMLElement; + trigger.shadowRoot?.querySelector('#start')?.dispatchEvent( + new Event('contextmenu', { + composed: true, + }) + ); + await nextFrame(); + trigger.shadowRoot?.querySelector('#start')?.dispatchEvent( + new Event('pointerup', { + composed: true, + bubbles: true, + }) + ); + await closed; + await opened; + secondMenu = document.querySelector('sp-popover') as Popover; + expect(secondMenu.textContent).to.include('Menu source: start'); + secondRect = secondMenu.getBoundingClientRect(); + expect(secondMenu).to.not.be.null; + }); + it('closes the second "contextmenu" when clicking away', async () => { + const closed = oneEvent(document, 'sp-closed'); + await mouseClickAway(secondMenu); + await closed; + await elementUpdated(secondMenu); + await elementUpdated(firstMenu); + expect(firstRect.top).to.not.equal(secondRect.top); + expect(firstRect.left).to.not.equal(secondRect.left); + }); + }); + + it('does not open content off of the viewport', async () => { + before(async () => { + await setViewport({ width: 360, height: 640 }); + // Allow viewport update to propagate. + await nextFrame(); + }); + after(async () => { + await setViewport({ width: 800, height: 600 }); + // Allow viewport update to propagate. + await nextFrame(); + }); + + await fixture(html` + ${virtualElementV1({ + ...virtualElementV1.args, + offset: 6, + })} + `); + + const opened = oneEvent(document, 'sp-opened'); + // Right click to open "context menu" overlay. + await sendMouse([ + { + type: 'move', + position: [270, 10], + }, + { + type: 'click', + options: { + button: 'right', + }, + position: [270, 10], + }, + ]); + await opened; + + const firstMenu = document.querySelector('sp-menu') as Menu; + expect(firstMenu).to.not.be.null; + expect(await isInteractive(firstMenu)).to.be.true; + + const closed = oneEvent(document, 'sp-closed'); + sendKeys({ press: 'Escape' }); + await closed; + + expect(await isInteractive(firstMenu)).to.be.false; + }); + + it('opens children in the modal stack through shadow roots', async () => { + const el = await fixture(definedOverlayElement()); + const trigger = el.querySelector( + '[slot="trigger"]' + ) as HTMLButtonElement; + let open = oneEvent(el, 'sp-opened'); + trigger.click(); + await open; + expect(el.open).to.equal('click'); + const content = document.querySelector( + 'popover-content' + ) as PopoverContent; + open = oneEvent(content, 'sp-opened'); + content.button.click(); + await open; + expect(content.trigger.open).to.equal('click'); + let close = oneEvent(content, 'sp-closed'); + content.trigger.removeAttribute('open'); + await close; + expect(content.trigger.open).to.be.null; + close = oneEvent(el, 'sp-closed'); + el.removeAttribute('open'); + await close; + expect(el.open).to.be.null; + }); +}); diff --git a/1st-gen/packages/overlay/test/overlay.test.ts b/1st-gen/packages/overlay/test/overlay.test.ts new file mode 100644 index 00000000000..41c188e0f33 --- /dev/null +++ b/1st-gen/packages/overlay/test/overlay.test.ts @@ -0,0 +1,1175 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/button/sp-button.js'; +import { Dialog } from '@spectrum-web-components/dialog'; +import '@spectrum-web-components/dialog/sp-dialog.js'; +import { + Overlay, + OverlayTrigger, + Placement, + VirtualTrigger, +} from '@spectrum-web-components/overlay'; +import '@spectrum-web-components/overlay/overlay-trigger.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; +import { Popover } from '@spectrum-web-components/popover'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/tooltip/sp-tooltip.js'; +import { setViewport } from '@web/test-runner-commands'; + +import { + elementUpdated, + expect, + html, + nextFrame, + oneEvent, +} from '@open-wc/testing'; +import { render, TemplateResult } from '@spectrum-web-components/base'; +import { Button } from '@spectrum-web-components/button'; +import { Menu } from '@spectrum-web-components/menu'; +import { Theme } from '@spectrum-web-components/theme'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { spy } from 'sinon'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { isFirefox } from '@spectrum-web-components/shared/src/platform.js'; +import { + fixture, + isInteractive, + isOnTopLayer, + sendShiftTabKey, + sendTabKey, +} from '../../../test/testing-helpers.js'; +import { PopoverContent } from '../stories/overlay-story-components.js'; +import { + clickAndHoverTarget, + definedOverlayElement, + virtualElement, +} from '../stories/overlay.stories'; +// import { isWebKit } from '@spectrum-web-components/shared'; + +async function styledFixture( + story: TemplateResult +): Promise { + const test = await fixture(html` + + ${story} + + `); + return test.children[0] as T; +} + +describe('Overlays', () => { + let testDiv!: HTMLDivElement; + let openOverlays: Overlay[] = []; + + describe('shared fixture', () => { + beforeEach(async () => { + testDiv = await styledFixture(html` +
+ + + Show Popover + +
+ + +
+ A popover message +
+ + Test 1 + + Test 2 + Test 3 +
+
+ + Hover message + + + Other hover message + +
+
+ `); + await elementUpdated(testDiv); + }); + + afterEach(() => { + openOverlays.map((overlay) => (overlay.open = false)); + openOverlays = []; + }); + + [ + 'bottom', + 'bottom-start', + 'bottom-end', + 'top', + 'top-start', + 'top-end', + 'left', + 'left-start', + 'left-end', + 'right', + 'right-start', + 'right-end', + ].map((direction) => { + const placement = direction as Placement; + it(`opens a popover - ${placement}`, async () => { + const clickSpy = spy(); + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const outerPopover = testDiv.querySelector( + '#outer-popover' + ) as Popover; + outerPopover.addEventListener('click', () => { + clickSpy(); + }); + + expect( + await isInteractive(outerPopover), + 'outside popover is not interactive' + ).to.be.false; + expect(button).to.exist; + + const opened = oneEvent(outerPopover, 'sp-opened'); + openOverlays.push( + await Overlay.open(outerPopover, { + trigger: button, + type: 'auto', + delayed: false, + placement, + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isInteractive(outerPopover)).to.be.true; + }); + }); + + it(`opens a modal dialog`, async () => { + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const outerPopover = testDiv.querySelector( + '#outer-popover' + ) as Popover; + + expect(await isInteractive(outerPopover)).to.be.false; + + expect(button).to.exist; + + const opened = oneEvent(outerPopover, 'sp-opened'); + openOverlays.push( + await Overlay.open(outerPopover, { + trigger: button, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + + const firstFocused = outerPopover.querySelector( + '#outer-focus-target' + ) as HTMLElement; + expect(document.activeElement === firstFocused).to.be.true; + + /** + * Tab cycle is awkward in the headless browser, forward tab to just before the known end of the page + * and the backward tab past the known beginning of the page. Test that you never focused the button + * that triggered the dialog and is outside of the modal. A test that was able to cycle would be better. + */ + + await sendTabKey(); + + expect(document.activeElement === button).to.be.false; + await sendTabKey(); + + expect(document.activeElement === button).to.be.false; + + await sendShiftTabKey(); + + expect(document.activeElement === button).to.be.false; + + await sendShiftTabKey(); + + expect(document.activeElement === button).to.be.false; + + await sendShiftTabKey(); + + expect(document.activeElement === button).to.be.false; + }); + + it(`updates a popover`, async () => { + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const outerPopover = testDiv.querySelector( + '#outer-popover' + ) as Popover; + + expect(await isInteractive(outerPopover)).to.be.false; + + expect(button).to.exist; + + const opened = oneEvent(outerPopover, 'sp-opened'); + openOverlays.push( + await Overlay.open(outerPopover, { + trigger: button, + type: 'auto', + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + + expect(await isInteractive(outerPopover)).to.be.true; + + Overlay.update(); + + expect(await isInteractive(outerPopover)).to.be.true; + }); + + it(`opens a popover w/ delay`, async () => { + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const outerPopover = testDiv.querySelector( + '#outer-popover' + ) as Popover; + + expect(await isInteractive(outerPopover)).to.be.false; + expect(button).to.exist; + + const opened = oneEvent(outerPopover, 'sp-opened'); + const start = performance.now(); + openOverlays.push( + await Overlay.open(outerPopover, { + trigger: button, + type: 'auto', + delayed: true, + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + const end = performance.now(); + expect(await isInteractive(outerPopover)).to.be.true; + expect(end - start).to.be.greaterThan(1000); + }); + + it('opens hover overlay', async () => { + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const hoverOverlay = testDiv.querySelector( + '#hover-1' + ) as HTMLElement; + const clickOverlay = testDiv.querySelector( + '#outer-popover' + ) as HTMLElement; + + expect(await isOnTopLayer(hoverOverlay)).to.be.false; + expect(await isOnTopLayer(clickOverlay)).to.be.false; + + let opened = oneEvent(hoverOverlay, 'sp-opened'); + openOverlays.push( + await Overlay.open(hoverOverlay, { + trigger: button, + type: 'hint', + placement: 'top', + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isOnTopLayer(hoverOverlay)).to.be.true; + + opened = oneEvent(clickOverlay, 'sp-opened'); + const closed = oneEvent(hoverOverlay, 'sp-closed'); + // Opening click overlay should close the hover overlay + openOverlays.push( + await Overlay.open(clickOverlay, { + trigger: button, + type: 'auto', + placement: 'bottom', + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + await closed; + expect( + await isInteractive(clickOverlay), + 'click overlay not interactive' + ).to.be.true; + expect( + await isOnTopLayer(hoverOverlay), + 'hover overlay interactive' + ).to.be.false; + }); + + it('opens custom overlay', async () => { + const button = testDiv.querySelector( + '#first-button' + ) as HTMLElement; + const customOverlay = testDiv.querySelector( + '#hover-1' + ) as HTMLElement; + const clickOverlay = testDiv.querySelector( + '#outer-popover' + ) as HTMLElement; + + expect(button).to.exist; + expect(customOverlay).to.exist; + + expect(await isOnTopLayer(customOverlay)).to.be.false; + expect(await isOnTopLayer(clickOverlay)).to.be.false; + + let opened = oneEvent(customOverlay, 'sp-opened'); + openOverlays.push( + await Overlay.open(customOverlay, { + trigger: button, + type: 'auto', + placement: 'top', + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isOnTopLayer(customOverlay)).to.be.true; + + opened = oneEvent(clickOverlay, 'sp-opened'); + openOverlays.push( + await Overlay.open(clickOverlay, { + trigger: button, + type: 'auto', + placement: 'bottom', + offset: 10, + }) + ); + button.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isOnTopLayer(clickOverlay), 'click content open').to.be + .true; + }); + }); + + it('closes via events', async () => { + const test = await fixture(html` +
+ + + Some Content for the Dialog. + + +
+ `); + + const el = test.querySelector('sp-popover') as Popover; + const dialog = el.querySelector('sp-dialog') as Dialog; + + const opened = oneEvent(el, 'sp-opened'); + openOverlays.push( + await Overlay.open(el, { + trigger: test, + type: 'auto', + placement: 'bottom', + offset: 10, + }) + ); + test.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isInteractive(el)).to.be.true; + + const closed = oneEvent(el, 'sp-closed'); + dialog.close(); + await closed; + expect(await isInteractive(el)).to.be.false; + }); + + it('positions with a VirtualTrigger', async () => { + const test = await fixture(html` +
+ + + Some Content for the Dialog. + + +
+ `); + + const el = test.querySelector('sp-popover') as Popover; + const trigger = new VirtualTrigger(100, 100); + + const opened = oneEvent(el, 'sp-opened'); + openOverlays.push( + await Overlay.open(el, { + trigger, + type: 'auto', + placement: 'right', + offset: 10, + }) + ); + test.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + expect(await isInteractive(el)).to.be.true; + + const initial = el.getBoundingClientRect(); + trigger.updateBoundingClientRect(500, 500); + await nextFrame(); + await nextFrame(); + const final = el.getBoundingClientRect(); + expect(initial.x).to.not.equal(8); + expect(initial.y).to.not.equal(8); + expect(initial.x).to.not.equal(final.x); + expect(initial.y).to.not.equal(final.y); + }); + + it('closes an inline overlay when tabbing past the content', async () => { + const el = await fixture(html` +
+ Trigger + + + + +
+ `); + + const trigger = el.querySelector('.trigger') as HTMLElement; + const content = el.querySelector('.content') as HTMLElement; + const input = el.querySelector('input') as HTMLInputElement; + const after = el.querySelector('#after') as HTMLAnchorElement; + + const opened = oneEvent(content, 'sp-opened'); + openOverlays.push( + await Overlay.open(content, { + trigger, + type: 'auto', + receivesFocus: 'auto', + }) + ); + trigger.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await opened; + + expect(await isInteractive(content)).to.be.true; + expect(document.activeElement).to.equal(input); + + const closed = oneEvent(content, 'sp-closed'); + await sendShiftTabKey(); + await closed; + + expect(document.activeElement).to.equal(trigger); + + await sendTabKey(); + expect(document.activeElement).to.equal(after); + expect(await isInteractive(content)).to.be.false; + }); + + it('closes an inline overlay when tabbing before the trigger', async () => { + const el = await fixture(html` +
+ + Trigger +
+ +
+
+ `); + + const trigger = el.querySelector('.trigger') as HTMLElement; + const content = el.querySelector('.content') as HTMLElement; + const input = el.querySelector('.content input') as HTMLInputElement; + const before = el.querySelector('#before') as HTMLAnchorElement; + + const open = oneEvent(trigger, 'sp-opened'); + openOverlays.push( + await Overlay.open(content, { + trigger, + type: 'auto', + }) + ); + trigger.insertAdjacentElement( + 'afterend', + openOverlays.at(-1) as HTMLElement + ); + await open; + + expect(document.activeElement).to.equal(input); + + await sendShiftTabKey(); + + expect(document.activeElement).to.equal(trigger); + + await sendShiftTabKey(); + + expect(document.activeElement).to.equal(before); + }); + + it('opens detached content', async () => { + const textContent = 'This is a detached element that has been overlaid'; + const el = await fixture(html` + + `); + + const content = document.createElement('sp-popover'); + content.textContent = textContent; + + const opened = oneEvent(content, 'sp-opened'); + const overlay = await Overlay.open(content, { + trigger: el, + type: 'auto', + placement: 'bottom', + }); + el.insertAdjacentElement('afterend', overlay); + await opened; + + expect(await isInteractive(content)).to.be.true; + + const closed = oneEvent(content, 'sp-closed'); + overlay.open = false; + await closed; + + expect(await isInteractive(content)).to.be.false; + + content.remove(); + }); +}); +describe('Overlay - type="modal"', () => { + describe('handle multiple separate `contextmenu` events', async () => { + let width = 0; + let height = 0; + let firstMenu: Popover; + let firstRect: DOMRect; + let secondMenu: Popover; + let secondRect: DOMRect; + before(async () => { + render( + html` + + ${virtualElement({ + ...virtualElement.args, + offset: 6, + })} + + `, + document.body + ); + + width = window.innerWidth; + height = window.innerHeight; + }); + after(() => { + document.querySelector('sp-theme')?.remove(); + }); + it('opens the first "contextmenu" overlay', async () => { + const opened = oneEvent(document, 'sp-opened'); + // Right click to open "context menu" overlay. + await sendMouse({ + steps: [ + { + type: 'move', + position: [width / 2 + 50, height / 2], + }, + { + type: 'click', + options: { + button: 'right', + }, + position: [width / 2 + 50, height / 2], + }, + ], + }); + await opened; + firstMenu = document.querySelector('sp-popover') as Popover; + expect(firstMenu.textContent).to.include('Menu source: end'); + firstRect = firstMenu.getBoundingClientRect(); + expect(firstMenu).to.not.be.null; + }); + it('closes the first "contextmenu" when opening a second', async () => { + const closed = oneEvent(document, 'sp-closed'); + const opened = oneEvent(document, 'sp-opened'); + /** + * Right click out of the "context menu" overlay to both close + * the first overlay and have the event passed to the surfacing page + * in order to open a subsequent "context menu" overlay. + * + * Using `sendMouse` here triggers the light dismiss for some reason while + * manual interacting in this way does not... + */ + const trigger = document.querySelector( + 'start-end-contextmenu' + ) as HTMLElement; + trigger.shadowRoot?.querySelector('#start')?.dispatchEvent( + new Event('contextmenu', { + composed: true, + }) + ); + await nextFrame(); + trigger.shadowRoot?.querySelector('#start')?.dispatchEvent( + new Event('pointerup', { + composed: true, + bubbles: true, + }) + ); + await closed; + await opened; + secondMenu = document.querySelector('sp-popover') as Popover; + expect(secondMenu.textContent).to.include('Menu source: start'); + secondRect = secondMenu.getBoundingClientRect(); + expect(secondMenu).to.not.be.null; + }); + it('closes the second "contextmenu" when clicking away', async () => { + const closed = oneEvent(document, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [width - width / 8, height - height / 8], + }); + await closed; + await elementUpdated(firstMenu); + await elementUpdated(secondMenu); + expect(firstRect.top).to.not.equal(secondRect.top); + expect(firstRect.left).to.not.equal(secondRect.left); + }); + }); + + it('does not open content off of the viewport', async () => { + before(async () => { + await setViewport({ width: 360, height: 640 }); + // Allow viewport update to propagate. + await nextFrame(); + }); + after(async () => { + await setViewport({ width: 800, height: 600 }); + // Allow viewport update to propagate. + await nextFrame(); + }); + + await fixture(html` + ${virtualElement({ + ...virtualElement.args, + offset: 6, + })} + `); + + const opened = oneEvent(document, 'sp-opened'); + // Right click to open "context menu" overlay. + await sendMouse([ + { + type: 'move', + position: [270, 10], + }, + { + type: 'click', + options: { + button: 'right', + }, + position: [270, 10], + }, + ]); + await opened; + + const firstMenu = document.querySelector('sp-menu') as Menu; + expect(firstMenu).to.not.be.null; + expect(await isInteractive(firstMenu)).to.be.true; + + const closed = oneEvent(document, 'sp-closed'); + sendKeys({ press: 'Escape' }); + await closed; + + expect(await isInteractive(firstMenu)).to.be.false; + }); + + it('opens children in the modal stack through shadow roots', async () => { + const el = await fixture(definedOverlayElement()); + const trigger = el.querySelector( + '[slot="trigger"]' + ) as HTMLButtonElement; + let open = oneEvent(el, 'sp-opened'); + trigger.click(); + await open; + expect(el.open).to.equal('click'); + const content = document.querySelector( + 'popover-content' + ) as PopoverContent; + open = oneEvent(content, 'sp-opened'); + content.button.click(); + await open; + expect(content.trigger.open).to.equal('click'); + let close = oneEvent(content, 'sp-closed'); + content.trigger.removeAttribute('open'); + await close; + expect(content.trigger.open).to.be.null; + close = oneEvent(el, 'sp-closed'); + el.removeAttribute('open'); + await close; + expect(el.open).to.be.null; + }); + + it('should not open hover overlay right after closing the click overlay using the mouse', async () => { + const overlayTrigger = await fixture( + clickAndHoverTarget() + ); + + await elementUpdated(overlayTrigger); + expect(overlayTrigger.open).to.be.undefined; + + const trigger = overlayTrigger.querySelector( + 'sp-button[slot="trigger"]' + ) as Button; + + const opened = oneEvent(trigger, 'sp-opened'); + trigger.click(); + await opened; + + expect(overlayTrigger.open).to.equal('click'); + + const closed = oneEvent(trigger, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [1, 1], + }); + await closed; + + expect(overlayTrigger.open).to.be.undefined; + expect(document.activeElement === trigger, 'trigger focused').to.be + .true; + }); + + it('should not open hover overlay right after closing the click overlay using the keyboard', async () => { + // @TODO: skipping on Firefox due to flakiness. Will review in the migration to Spectrum 2. + if (isFirefox()) return; + const overlayTrigger = await fixture( + clickAndHoverTarget() + ); + + const trigger = overlayTrigger.querySelector( + 'sp-button[slot="trigger"]' + ) as Button; + + const opened = oneEvent(trigger, 'sp-opened'); + trigger.click(); + await opened; + + expect(overlayTrigger.open).to.equal('click'); + + const closed = oneEvent(trigger, 'sp-closed'); + sendKeys({ press: 'Escape' }); + await closed; + await elementUpdated(overlayTrigger); + + expect(overlayTrigger.open).to.be.undefined; + expect(document.activeElement === trigger, 'trigger focused').to.be + .true; + }); +}); +describe('Overlay - timing', () => { + it('manages multiple modals in a row without preventing them from closing', async () => { + const test = await fixture(html` +
+ + Trigger 1 + +

Hover contentent for "Trigger 1".

+
+
+ + Trigger 2 + +

Click contentent for "Trigger 2".

+
+ +

Hover contentent for "Trigger 2".

+
+
+
+ `); + + const overlayTrigger1 = test.querySelector('#test-1') as OverlayTrigger; + const overlayTrigger2 = test.querySelector('#test-2') as OverlayTrigger; + const trigger1 = overlayTrigger1.querySelector( + '[slot="trigger"]' + ) as HTMLButtonElement; + const trigger2 = overlayTrigger2.querySelector( + '[slot="trigger"]' + ) as HTMLButtonElement; + + const boundingRectTrigger1 = trigger1.getBoundingClientRect(); + const boundingRectTrigger2 = trigger2.getBoundingClientRect(); + const trigger1Position: [number, number] = [ + boundingRectTrigger1.left + boundingRectTrigger1.width / 2, + boundingRectTrigger1.top + boundingRectTrigger1.height / 2, + ]; + const outsideTriggers: [number, number] = [ + boundingRectTrigger1.left + boundingRectTrigger1.width / 2, + 300, + ]; + const trigger2Position: [number, number] = [ + boundingRectTrigger2.left + boundingRectTrigger2.width / 2, + boundingRectTrigger2.top + boundingRectTrigger2.height / 4, + ]; + + // Move pointer over "Trigger 1", should _start_ to open "hover" content. + await sendMouse({ + type: 'move', + position: trigger1Position, + }); + await nextFrame(); + await nextFrame(); + + // Move pointer out of "Trigger 1", should _start_ to close "hover" content. + await sendMouse({ + type: 'move', + position: outsideTriggers, + }); + await nextFrame(); + await nextFrame(); + // Move pointer over "Trigger 2", should _start_ to open "hover" content. + await sendMouse({ + type: 'move', + position: trigger2Position, + }); + await nextFrame(); + await nextFrame(); + + const opened = oneEvent(trigger2, 'sp-opened'); + // Click "Trigger 2", should _start_ to open "click" content and _start_ to close "hover" content. + await sendMouse({ + type: 'click', + position: trigger2Position, + }); + await opened; + await nextFrame(); + await nextFrame(); + + // "click" content for "Trigger 2", _only_, open. + expect(overlayTrigger1.hasAttribute('open')).to.be.false; + expect(overlayTrigger2.hasAttribute('open')).to.be.true; + expect(overlayTrigger2.getAttribute('open')).to.equal('click'); + + const closed = oneEvent(overlayTrigger2, 'sp-closed'); + await sendMouse({ + type: 'click', + position: outsideTriggers, + }); + await closed; + + // Both overlays are closed. + // Neither trigger received "focus" because the pointer "clicked" away, redirecting focus to + expect(overlayTrigger1.hasAttribute('open')).to.be.false; + expect(overlayTrigger2.hasAttribute('open')).to.be.false; + }); +}); + +describe('maintains focus consistency in all browsers', () => { + it('should not have a focus-visible on trigger when focus happens after click', async () => { + const overlayTrigger = await fixture( + clickAndHoverTarget() + ); + await elementUpdated(overlayTrigger); + expect(overlayTrigger.open).to.be.undefined; + const trigger = overlayTrigger.querySelector( + 'sp-button[slot="trigger"]' + ) as Button; + + const boundingRect = trigger.getBoundingClientRect(); + + const opened = oneEvent(trigger, 'sp-opened'); + await sendMouse({ + type: 'click', + position: [ + boundingRect.left + boundingRect.width / 2, + boundingRect.top + boundingRect.height / 2, + ], + }); + await opened; + + expect(overlayTrigger.open).to.equal('click'); + + const closed = oneEvent(trigger, 'sp-closed'); + await sendMouse({ + type: 'click', + position: [0, 0], + }); + await closed; + + expect(trigger.matches(':focus-visible')).to.be.false; + }); +}); + +describe('Overlay - Interactive Content', () => { + it('stays open when interacting with elements inside', async () => { + const el = await fixture(html` +
+ Open Overlay + + +

+ My slider in overlay element: + +

+
+
+
+ `); + + const trigger = el.querySelector('#trigger') as HTMLElement; + const overlay = el.querySelector('sp-overlay') as Overlay; + + await elementUpdated(overlay); + + const opened = oneEvent(overlay, 'sp-opened'); + trigger.click(); + await opened; + + expect(overlay.open).to.be.true; + + await nextFrame(); + await nextFrame(); + + const slider = el.querySelector('sp-slider') as HTMLElement; + expect(slider).to.exist; + + slider.click(); + await nextFrame(); + await nextFrame(); + expect(overlay.open).to.be.true; + }); +}); + +describe('Overlay should correctly trap focus', () => { + it('should trap focus when the overlay type is modal', async () => { + const el = await fixture(html` +
+ Open Overlay + + +

Overlay content

+ button 1 + button 2 +
+
+
+ `); + + const trigger = el.querySelector('#trigger') as HTMLElement; + const overlay = el.querySelector('sp-overlay') as Overlay; + + await elementUpdated(overlay); + + const opened = oneEvent(overlay, 'sp-opened'); + // use keyboard to open the overlay + trigger.focus(); + await sendKeys({ press: 'Enter' }); + await opened; + + expect(overlay.open).to.be.true; + + const button1 = el.querySelector('#button-1') as HTMLElement; + const button2 = el.querySelector('#button-2') as HTMLElement; + + // expect button1 to be focused + expect(document.activeElement).to.equal(button1); + + // press tab to focus on button2 + await sendTabKey(); + expect(document.activeElement).to.equal(button2); + + // press tab to focus on button1 + await sendTabKey(); + expect(document.activeElement).to.equal(button1); + + // press tab to focus on button2 + await sendTabKey(); + expect(document.activeElement).to.equal(button2); + }); + it('should trap focus when the overlay type is page', async () => { + const el = await fixture(html` +
+ Open Overlay + + +

Overlay content

+ button 1 + button 2 +
+
+
+ `); + + const trigger = el.querySelector('#trigger') as HTMLElement; + const overlay = el.querySelector('sp-overlay') as Overlay; + + await elementUpdated(overlay); + + const opened = oneEvent(overlay, 'sp-opened'); + trigger.click(); + await opened; + + expect(overlay.open).to.be.true; + + const button1 = el.querySelector('#button-1') as HTMLElement; + const button2 = el.querySelector('#button-2') as HTMLElement; + + // expect button1 to be focused + expect(document.activeElement).to.equal(button1); + + // press tab to focus on button2 + await sendTabKey(); + expect(document.activeElement).to.equal(button2); + + // press tab to focus on button1 + await sendTabKey(); + expect(document.activeElement).to.equal(button1); + + // press tab to focus on button2 + await sendTabKey(); + expect(document.activeElement).to.equal(button2); + }); + it('should not trap focus when the overlay type is auto', async () => { + const el = await fixture(html` +
+ Open Overlay + + +

Overlay content

+ test +
+
+ +
+ `); + + const trigger = el.querySelector('#trigger') as HTMLElement; + const overlay = el.querySelector('sp-overlay') as Overlay; + + await elementUpdated(overlay); + + const opened = oneEvent(overlay, 'sp-opened'); + trigger.click(); + await opened; + + expect(overlay.open).to.be.true; + + await sendTabKey(); + + const input = el.querySelector('#input') as HTMLInputElement; + expect(document.activeElement).to.equal(input); + }); +}); + +describe('Overlay - Deprecated Properties', () => { + it('should support allowOutsideClick property with deprecation warning', async () => { + const consoleSpy = spy(console, 'warn'); + + const el = await fixture(html` +
+ Open Overlay + + +

Overlay content

+
+
+
+ `); + + const overlay = el.querySelector('sp-overlay') as Overlay; + await elementUpdated(overlay); + + // Verify the property is set correctly + expect(overlay.allowOutsideClick).to.be.true; + expect(overlay.hasAttribute('allow-outside-click')).to.be.true; + + // Verify the deprecation warning is shown (either via SWC or console.warn fallback) + expect(consoleSpy.calledOnce).to.be.true; + expect(consoleSpy.firstCall.args[0]).to.include('allow-outside-click'); + expect(consoleSpy.firstCall.args[0]).to.include('deprecated'); + + consoleSpy.restore(); + }); +}); diff --git a/1st-gen/packages/overlay/trigger-directive.md b/1st-gen/packages/overlay/trigger-directive.md new file mode 100644 index 00000000000..6ed0a1d6014 --- /dev/null +++ b/1st-gen/packages/overlay/trigger-directive.md @@ -0,0 +1,129 @@ +## Overview + +To support consumers that leverage `lit-html`, Spectrum Web Components also vends a [directive](https://lit.dev/docs/api/directives/) to further simplify the management of content conditional to whether or not the Overlay is currently visible. + +### Usage + +```zsh +yarn add @spectrum-web-components/overlay +``` + +Import the `trigger` directive as follows: + +```ts +import { trigger } from '@spectrum-web-components/overlay'; +``` + +### Example + +Pass a `TemplateResult` into the `trigger()` directive, as follows in order to have it rendered to the DOM when the associated Overlay is about to open and the removed after the Overlay has closed. + +```html-live +
+ + +``` + + + +### Options + +The `trigger()` directive accepts two arguments: + +- a required method returning the `TemplateResult` defining the content of the open overlay + +```ts +() => TemplateResult; +``` + +- an optional options object which is shaped as follows: + +```ts +{ + open?: boolean; // Whether the Overlay in question should be rendered open. + triggerInteraction: TriggerInteraction; // 'click' | 'longpress' | 'hover' + overlayOptions: OverlayOptions; + insertionOptions?: InsertionOptions; +} +``` + +`OverlayOptions` are leveraged in the same way as outlined [here](https://opensource.adobe.com/spectrum-web-components/components/imperative-api/#overlayoptions) and `InsertionOptions` are leveraged to outline where in the DOM the Overlay should be inserted: + +```ts +type InsertionOptions = { + el: HTMLElement | (() => HTMLElement); // returning a reference to the element the Overlay should be inserted adjacent to + where: InsertPosition; // 'afterbegin' | 'afterend' | 'beforebegin' | 'beforeend' +}; +``` diff --git a/1st-gen/packages/overlay/tsconfig.json b/1st-gen/packages/overlay/tsconfig.json new file mode 100644 index 00000000000..35c7daa560e --- /dev/null +++ b/1st-gen/packages/overlay/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts", "sync/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [ + { "path": "../../tools/base" }, + { "path": "../../tools/theme" }, + { "path": "../../tools/shared" } + ] +} diff --git a/1st-gen/packages/picker-button/.npmignore b/1st-gen/packages/picker-button/.npmignore new file mode 100644 index 00000000000..c50cbe188c0 --- /dev/null +++ b/1st-gen/packages/picker-button/.npmignore @@ -0,0 +1,2 @@ +stories +test \ No newline at end of file diff --git a/1st-gen/packages/picker-button/.npmrc b/1st-gen/packages/picker-button/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/picker-button/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/picker-button/CHANGELOG.md b/1st-gen/packages/picker-button/CHANGELOG.md new file mode 100644 index 00000000000..2f056c55b30 --- /dev/null +++ b/1st-gen/packages/picker-button/CHANGELOG.md @@ -0,0 +1,346 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies [[`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e)]: + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5202](https://github.com/adobe/spectrum-web-components/pull/5202) [`fa4be70`](https://github.com/adobe/spectrum-web-components/commit/fa4be70e9ab9dbeff26867edd3bdeb3f41c423e3) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Updates the picker button component from version 6.0.0-s2-foundations.16 to 6.1.2. The update should bring the background colors for the picker button in line with S2-foundations design specs: + + default state: `gray-50` to `gray-100` + hover state: `gray-100` to `gray-200` + key-focus state: `gray-100` to `gray-200` + +- Updated dependencies [[`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5)]: + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **picker-button:** update quiet styles ([#4383](https://github.com/adobe/spectrum-web-components/issues/4383)) ([42bf291](https://github.com/adobe/spectrum-web-components/commit/42bf291f9301c139c960cfc7ffb69ece08d945f3)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +### Bug Fixes + +- **combobox:** add combobox pattern ([#3894](https://github.com/adobe/spectrum-web-components/issues/3894)) ([47d7d71](https://github.com/adobe/spectrum-web-components/commit/47d7d71bc9e17b67452d45b9495c970dac15ff89)), closes [#3887](https://github.com/adobe/spectrum-web-components/issues/3887) + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +### Bug Fixes + +- update deps graph, update link docs ([#3709](https://github.com/adobe/spectrum-web-components/issues/3709)) ([2deb284](https://github.com/adobe/spectrum-web-components/commit/2deb2847e6ad458c3cbaec02732fffde133e0c54)) + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +### Bug Fixes + +- **picker-button:** include missing dependency on @spectrum-web-components/button ([#3515](https://github.com/adobe/spectrum-web-components/issues/3515)) ([ed44c2b](https://github.com/adobe/spectrum-web-components/commit/ed44c2bd5c729d8a563d9bd25e5d61f58ba1d074)) + +### Features + +- **picker-button:** migrate to core tokens ([b39219c](https://github.com/adobe/spectrum-web-components/commit/b39219cd92f8f17420eadc74a655e0f1d074cae3)) + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# 0.30.0 (2023-05-03) + +### Features + +- add Picker Button pattern ([31337b8](https://github.com/adobe/spectrum-web-components/commit/31337b86acdade3d93bea44a781ad0ea7042ca32)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) + +## [0.1.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.10...@spectrum-web-components/picker-button@0.1.11) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.9...@spectrum-web-components/picker-button@0.1.10) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.8...@spectrum-web-components/picker-button@0.1.9) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.7...@spectrum-web-components/picker-button@0.1.8) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.6...@spectrum-web-components/picker-button@0.1.7) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.5...@spectrum-web-components/picker-button@0.1.6) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.4...@spectrum-web-components/picker-button@0.1.5) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.3...@spectrum-web-components/picker-button@0.1.4) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.2...@spectrum-web-components/picker-button@0.1.3) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.1...@spectrum-web-components/picker-button@0.1.2) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker-button@0.1.0...@spectrum-web-components/picker-button@0.1.1) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/picker-button + +# 0.1.0 (2022-10-10) + +### Features + +- add Picker Button pattern ([31337b8](https://github.com/adobe/spectrum-web-components/commit/31337b86acdade3d93bea44a781ad0ea7042ca32)) diff --git a/1st-gen/packages/picker-button/README.md b/1st-gen/packages/picker-button/README.md new file mode 100644 index 00000000000..b0c66865677 --- /dev/null +++ b/1st-gen/packages/picker-button/README.md @@ -0,0 +1,209 @@ +## Overview + +An `` is used as a sub-component of patterns like the `` (release pending) to pair a button interface with a text input. With its many custom states and alterations, it isn't likely to be leveraged directly outside of more complex UIs. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/picker-button?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/picker-button) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/picker-button?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/picker-button) + +``` +yarn add @spectrum-web-components/picker-button +``` + +Import the side effectful registration of `` via: + +``` +import '@spectrum-web-components/picker-button/sp-picker-button.js'; +``` + +When looking to leverage the `PickerButton` base class as a type and/or for extension purposes, do so via: + +``` +import { PickerButton } from '@spectrum-web-components/picker-button'; +``` + +### Anatomy + +#### Text and icon + +With the use of the `label` slot, you can deliver an `` with both an icon and a text label: + +```html +All +``` + +#### Icon only + +Without content addressed to the `label` slot, the `` with both an icon and a text label: + +```html + +``` + +#### Custom icon + +You can customize the icon in an `` by addressing a new icon to the `icon` slot: + +```html + +``` + +### Options + +#### Sizes + + +Small + + +```html + +
+All +``` + +
+Medium + + +```html + +
+All +``` + +
+Large + + +```html + +
+All +``` + +
+Extra Large + + +```html + +
+All +``` + +
+
+ +#### Rounded + +When delivered as part of the `express` system, an `` with the `rounded` attribute will be given deeply rounded corners: + +```html + +
+All +``` + +#### Quiet + +When delivered with the `quiet` attribute, the `` will take a less pronounced visual delivery: + +```html + +
+All +``` + +#### Position + +By default the `` will be given a `position` attribute with the value `right`, which is best leveraged at the right edge of an associated `` element. If your UI desires that the `` be placed to the left of the related input, use the `position` attribute and set it to `left`: + +```html + +
+ + All + +``` + +### States + +#### Open + +When paired with an expanded UI, e.g. an `` with its autocomplete options visible, an `` should be given the `open` attribute to visual match the delivered state in the larger UI: + +```html + +
+All +``` + +#### Disabled + +Leveraging the `disabled` attribute will dim the `` and alter its presentation in the accessibility tree: + +```html + +
+All +``` + +#### Invalid + +When delivered as part of the `spectrum` system, an `` with the `invalid` attribute will be given a red border: + +```html + +
+All +``` + +### Accessibility + +The example below is for demonstration purposes. For an example implementation of `` view [`Combobox.ts`](https://github.com/adobe/spectrum-web-components/blob/main/packages/combobox/src/Combobox.ts). For comprehensive information on menu button accessibility, see WAI ARIA Authoring Practice Guide's [Menu Button Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/). + +```html +Color + + + + + + Red + Blue + + + +``` + +#### Include a label + +To ensure menu items can be read by assistive technology, do _one_ of the following: + +- Place visible text in the component's `label` slot. +- Use `aria-label` attribute. +- Set the `aria-labelledby` attribute to the ID reference of the menu element. + +#### Set aria properties correctly + +To indicate to assistive technology what the button does, do _all_ of the following: + +- Set the `aria-controls` property to the ID reference of the menu element. +- Set the `aria-haspopup` property to `"menu"` or `"true"`. +- Set the `aria-expanded` property to `"menu"` or `"true"` or `"false"` depending on whether the menu is displayed. + +### Add keyboard interaction + +Ensure that picker button can be operated by keyboard users: + +- Required: Open the menu and focus on first menu item when Enter or Space is pressed. +- _Optional_: Open the menu and focus on first menu item when Down Arrow is pressed. +- _Optional_: Open the menu and focus on last menu item when Up Arrow is pressed. diff --git a/1st-gen/packages/picker-button/package.json b/1st-gen/packages/picker-button/package.json new file mode 100644 index 00000000000..15f4a7dddda --- /dev/null +++ b/1st-gen/packages/picker-button/package.json @@ -0,0 +1,79 @@ +{ + "name": "@spectrum-web-components/picker-button", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "Web component implementation of a Spectrum design PickerButton", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/picker-button" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/picker-button", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/PickerButton.js": { + "development": "./src/PickerButton.dev.js", + "default": "./src/PickerButton.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/picker-button-overrides.css.js": "./src/picker-button-overrides.css.js", + "./src/picker-button.css.js": "./src/picker-button.css.js", + "./sp-picker-button.js": { + "development": "./sp-picker-button.dev.js", + "default": "./sp-picker-button.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/button": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-ui": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/picker-button/sp-picker-button.ts b/1st-gen/packages/picker-button/sp-picker-button.ts new file mode 100644 index 00000000000..b1b93efc834 --- /dev/null +++ b/1st-gen/packages/picker-button/sp-picker-button.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { PickerButton } from './src/PickerButton.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-picker-button', PickerButton); + +declare global { + interface HTMLElementTagNameMap { + 'sp-picker-button': PickerButton; + } +} diff --git a/1st-gen/packages/picker-button/src/PickerButton.ts b/1st-gen/packages/picker-button/src/PickerButton.ts new file mode 100644 index 00000000000..ce850c759ae --- /dev/null +++ b/1st-gen/packages/picker-button/src/PickerButton.ts @@ -0,0 +1,81 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + CSSResultArray, + DefaultElementSize, + html, + SizedMixin, + TemplateResult, +} from '@spectrum-web-components/base'; +import { classMap } from '@spectrum-web-components/base/src/directives.js'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { ButtonBase } from '@spectrum-web-components/button/src/ButtonBase.js'; +import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js'; +import { ObserveSlotPresence } from '@spectrum-web-components/shared/src/observe-slot-presence.js'; + +import styles from './picker-button.css.js'; +import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js'; + +const chevronClass = { + s: 'spectrum-UIIcon-ChevronDown75', + m: 'spectrum-UIIcon-ChevronDown100', + l: 'spectrum-UIIcon-ChevronDown200', + xl: 'spectrum-UIIcon-ChevronDown300', +}; + +/** + * @element sp-picker-button + */ +export class PickerButton extends SizedMixin( + ObserveSlotPresence(ButtonBase, '[slot="label"]') +) { + public static override get styles(): CSSResultArray { + return [styles, chevronStyles]; + } + + @property({ type: Boolean, reflect: true }) + invalid = false; + + @property({ reflect: true }) + position: 'left' | 'right' = 'right'; + + protected get hasText(): boolean { + return this.slotContentIsPresent; + } + + protected override render(): TemplateResult { + const rootClasses = { + root: true, + uiicononly: !this.hasText, + textuiicon: this.hasText, + }; + return html` +
+
+ + + + + + +
+
+ `; + } +} diff --git a/1st-gen/packages/picker-button/src/index.ts b/1st-gen/packages/picker-button/src/index.ts new file mode 100644 index 00000000000..7d30784a32a --- /dev/null +++ b/1st-gen/packages/picker-button/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './PickerButton.js'; diff --git a/1st-gen/packages/picker-button/src/picker-button-overrides.css b/1st-gen/packages/picker-button/src/picker-button-overrides.css new file mode 100644 index 00000000000..c71c79cfa81 --- /dev/null +++ b/1st-gen/packages/picker-button/src/picker-button-overrides.css @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.root { + --spectrum-picker-button-background-color: var(--system-picker-button-background-color); + --spectrum-picker-button-background-color-hover: var(--system-picker-button-background-color-hover); + --spectrum-picker-button-background-color-down: var(--system-picker-button-background-color-down); + --spectrum-picker-button-background-color-key-focus: var(--system-picker-button-background-color-key-focus); + --spectrum-picker-button-border-color: var(--system-picker-button-border-color); + --spectrum-picker-button-border-radius: var(--system-picker-button-border-radius); + --spectrum-picker-button-border-radius-rounded-sided: var(--system-picker-button-border-radius-rounded-sided); + --spectrum-picker-button-border-radius-sided: var(--system-picker-button-border-radius-sided); + --spectrum-picker-button-border-width: var(--system-picker-button-border-width); + --spectrum-picker-button-padding: var(--system-picker-button-padding); +} diff --git a/1st-gen/packages/picker-button/src/picker-button.css b/1st-gen/packages/picker-button/src/picker-button.css new file mode 100644 index 00000000000..eef2d1abff2 --- /dev/null +++ b/1st-gen/packages/picker-button/src/picker-button.css @@ -0,0 +1,22 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-picker-button.css"); +@import url("./picker-button-overrides.css"); + +:host { + display: inline-flex; +} + +.root { + display: flex; +} diff --git a/1st-gen/packages/picker-button/src/spectrum-picker-button-modifier.css b/1st-gen/packages/picker-button/src/spectrum-picker-button-modifier.css new file mode 100644 index 00000000000..02fb71ea34c --- /dev/null +++ b/1st-gen/packages/picker-button/src/spectrum-picker-button-modifier.css @@ -0,0 +1,11 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ diff --git a/1st-gen/packages/picker-button/src/spectrum-picker-button.css b/1st-gen/packages/picker-button/src/spectrum-picker-button.css new file mode 100644 index 00000000000..4571d552e23 --- /dev/null +++ b/1st-gen/packages/picker-button/src/spectrum-picker-button.css @@ -0,0 +1,194 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +.root { + --spectrum-picker-button-height: var(--spectrum-component-height-100); + --spectrum-picker-button-width: var(--spectrum-component-height-100); + --spectrum-picker-button-gap: var(--spectrum-text-to-visual-50); + --spectrum-picker-button-label-padding: var(--spectrum-text-to-visual-50); + --spectrum-picker-button-fill-padding: var(--spectrum-field-edge-to-disclosure-icon-100); + --spectrum-picker-button-icon-color: var(--spectrum-neutral-content-color-default); + --spectrum-picker-button-icon-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-picker-button-icon-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-picker-button-icon-color-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-picker-button-font-color: var(--spectrum-neutral-content-color-default); + --spectrum-picker-button-font-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-picker-button-font-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-picker-button-font-color-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-picker-button-font-family: var(--spectrum-sans-font-family-stack); + --spectrum-picker-button-font-style: var(--spectrum-default-font-style); + --spectrum-picker-button-font-weight: var(--spectrum-body-sans-serif-font-weight); + --spectrum-picker-button-font-size: var(--spectrum-font-size-100); + --spectrum-picker-button-border-radius-rounded: var(--spectrum-corner-radius-200); + --spectrum-picker-button-background-animation-duration: var(--spectrum-animation-duration-100); +} + +@media (hover: hover) { + .root:hover { + --mod-picker-button-background-color: var(--mod-picker-button-background-color-hover, var(--spectrum-picker-button-background-color-hover)); + --mod-picker-button-font-color: var(--mod-picker-button-font-color-hover, var(--spectrum-picker-button-font-color-hover)); + --mod-picker-button-icon-color: var(--mod-picker-button-icon-color-hover, var(--spectrum-picker-button-icon-color-hover)); + } +} + +:host([open]) .root, +:host(:is(:active, [active])) .root { + --mod-picker-button-background-color: var(--mod-picker-button-background-color-down, var(--spectrum-picker-button-background-color-down)); + --mod-picker-button-font-color: var(--mod-picker-button-font-color-down, var(--spectrum-picker-button-font-color-down)); + --mod-picker-button-icon-color: var(--mod-picker-button-icon-color-down, var(--spectrum-picker-button-icon-color-down)); +} + +:host([focused]) .root, +.root.is-keyboardFocused, +.root:focus, +.root:focus-visible { + --mod-picker-button-background-color: var(--mod-picker-button-background-color-key-focus, var(--spectrum-picker-button-background-color-key-focus)); + --mod-picker-button-font-color: var(--mod-picker-button-font-color-key-focus, var(--spectrum-picker-button-font-color-key-focus)); + --mod-picker-button-icon-color: var(--mod-picker-button-icon-color-key-focus, var(--spectrum-picker-button-icon-color-key-focus)); +} + +:host([disabled]) .root { + --mod-picker-button-background-color: var(--mod-picker-button-background-color-disabled, var(--spectrum-disabled-background-color)); + --mod-picker-button-background-color-hover: var(--mod-picker-button-background-color-hover-disabled, var(--spectrum-disabled-background-color)); + --mod-picker-button-background-color-down: var(--mod-picker-button-background-color-down-disabled, var(--spectrum-disabled-background-color)); + --mod-picker-button-border-color: var(--mod-picker-button-border-color-disabled, var(--spectrum-disabled-background-color)); + --mod-picker-button-font-color: var(--mod-picker-button-font-color-disabled, var(--spectrum-disabled-content-color)); + --mod-picker-button-font-color-hover: var(--mod-picker-button-font-color-hover-disabled, var(--spectrum-disabled-content-color)); + --mod-picker-button-font-color-down: var(--mod-picker-button-font-color-down-disabled, var(--spectrum-disabled-content-color)); + --mod-picker-button-icon-color: var(--mod-picker-button-icon-color-disabled, var(--spectrum-disabled-content-color)); + --mod-picker-button-icon-color-hover: var(--mod-picker-button-icon-color-hover-disabled, var(--spectrum-disabled-content-color)); + --mod-picker-button-icon-color-down: var(--mod-picker-button-icon-color-down-disabled, var(--spectrum-disabled-content-color)); +} + +:host([quiet]) .root { + --mod-picker-button-background-color: var(--mod-picker-button-background-color-quiet, transparent); + --mod-picker-button-background-color-hover: var(--mod-picker-button-background-color-hover-quiet, transparent); + --mod-picker-button-background-color-down: var(--mod-picker-button-background-color-down-quiet, transparent); + --mod-picker-button-background-color-key-focus: var(--mod-picker-button-background-color-key-focus-quiet, transparent); + --mod-picker-button-border-color: var(--mod-picker-button-border-color-quiet, transparent); +} + +:host([size="s"]) .root { + --spectrum-picker-button-height: var(--spectrum-component-height-75); + --spectrum-picker-button-width: var(--spectrum-component-height-75); + --spectrum-picker-button-label-padding: var(--spectrum-spacing-75); + --spectrum-picker-button-font-size: var(--spectrum-font-size-75); + --spectrum-picker-button-fill-padding: var(--spectrum-field-edge-to-disclosure-icon-75); +} + +:host([size="l"]) .root { + --spectrum-picker-button-height: var(--spectrum-component-height-200); + --spectrum-picker-button-width: var(--spectrum-component-height-200); + --spectrum-picker-button-label-padding: var(--spectrum-text-to-visual-200); + --spectrum-picker-button-font-size: var(--spectrum-font-size-200); + --spectrum-picker-button-fill-padding: var(--spectrum-field-edge-to-disclosure-icon-200); +} + +:host([size="xl"]) .root { + --spectrum-picker-button-height: var(--spectrum-component-height-300); + --spectrum-picker-button-width: var(--spectrum-component-height-300); + --spectrum-picker-button-label-padding: var(--spectrum-text-to-visual-300); + --spectrum-picker-button-font-size: var(--spectrum-font-size-300); + --spectrum-picker-button-fill-padding: var(--spectrum-field-edge-to-disclosure-icon-300); +} + +.root { + background-color: initial; + block-size: var(--mod-picker-button-width, var(--spectrum-picker-button-width)); + box-sizing: border-box; + padding: var(--mod-picker-button-padding, var(--spectrum-picker-button-padding)); + border-style: none; + justify-content: center; + align-items: center; + display: flex; +} + +.root.uiicononly { + inline-size: var(--mod-picker-button-height, var(--spectrum-picker-button-height)); +} + +.spectrum-PickerButton-label { + color: var(--mod-picker-button-font-color, var(--spectrum-picker-button-font-color)); + white-space: nowrap; + font-family: var(--mod-picker-button-font-family, var(--spectrum-picker-button-font-family)); + font-style: var(--mod-picker-button-font-style, var(--spectrum-picker-button-font-style)); + font-weight: var(--mod-picker-button-font-weight, var(--spectrum-picker-button-font-weight)); + font-size: var(--mod-picker-button-font-size, var(--spectrum-picker-button-font-size)); + flex: auto; + padding-block-start: var(--mod-picker-button-label-padding, var(--spectrum-picker-button-label-padding)); + padding-block-end: var(--mod-picker-button-label-padding, var(--spectrum-picker-button-label-padding)); + overflow: hidden; +} + +.uiicononly .spectrum-PickerButton-label { + display: none; +} + +.spectrum-PickerButton-fill { + box-sizing: border-box; + block-size: 100%; + inline-size: 100%; + justify-content: center; + align-items: center; + gap: var(--mod-picker-button-gap, var(--spectrum-picker-button-gap)); + background-color: var(--mod-picker-button-background-color, var(--spectrum-picker-button-background-color)); + border-color: var(--mod-picker-button-border-color, var(--spectrum-picker-button-border-color)); + border-width: var(--mod-picker-button-border-width, var(--spectrum-picker-button-border-width)); + padding: calc(var(--mod-picker-button-fill-padding, var(--spectrum-picker-button-fill-padding)) - var(--mod-picker-button-padding, var(--spectrum-picker-button-padding)) - var(--mod-picker-button-border-width, var(--spectrum-picker-button-border-width))); + transition: border-color var(--mod-picker-button-background-animation-duration, var(--spectrum-picker-button-background-animation-duration)) ease-in-out; + border-style: solid; + border-start-start-radius: var(--mod-picker-button-border-radius, var(--spectrum-picker-button-border-radius)); + border-start-end-radius: var(--mod-picker-button-border-radius, var(--spectrum-picker-button-border-radius)); + border-end-end-radius: var(--mod-picker-button-border-radius, var(--spectrum-picker-button-border-radius)); + border-end-start-radius: var(--mod-picker-button-border-radius, var(--spectrum-picker-button-border-radius)); + display: flex; +} + +:host([position="right"]) .spectrum-PickerButton-fill { + border-start-start-radius: var(--mod-picker-button-border-radius-sided, var(--spectrum-picker-button-border-radius-sided)); + border-end-start-radius: var(--mod-picker-button-border-radius-sided, var(--spectrum-picker-button-border-radius-sided)); +} + +:host([position="right"][rounded]) .spectrum-PickerButton-fill { + border-start-start-radius: var(--mod-picker-button-border-radius-rounded-sided, var(--spectrum-picker-button-border-radius-rounded-sided)); + border-end-start-radius: var(--mod-picker-button-border-radius-rounded-sided, var(--spectrum-picker-button-border-radius-rounded-sided)); +} + +:host([position="left"]) .spectrum-PickerButton-fill { + border-start-end-radius: var(--mod-picker-button-border-radius-sided, var(--spectrum-picker-button-border-radius-sided)); + border-end-end-radius: var(--mod-picker-button-border-radius-sided, var(--spectrum-picker-button-border-radius-sided)); +} + +:host([position="left"][rounded]) .spectrum-PickerButton-fill { + border-start-end-radius: var(--mod-picker-button-border-radius-rounded-sided, var(--spectrum-picker-button-border-radius-rounded-sided)); + border-end-end-radius: var(--mod-picker-button-border-radius-rounded-sided, var(--spectrum-picker-button-border-radius-rounded-sided)); +} + +:host([rounded]) .spectrum-PickerButton-fill { + border-start-start-radius: var(--mod-picker-button-border-radius-rounded, var(--spectrum-picker-button-border-radius-rounded)); + border-start-end-radius: var(--mod-picker-button-border-radius-rounded, var(--spectrum-picker-button-border-radius-rounded)); + border-end-end-radius: var(--mod-picker-button-border-radius-rounded, var(--spectrum-picker-button-border-radius-rounded)); + border-end-start-radius: var(--mod-picker-button-border-radius-rounded, var(--spectrum-picker-button-border-radius-rounded)); +} + +.uiicononly .spectrum-PickerButton-fill { + padding: 0; +} + +.textuiicon .spectrum-PickerButton-fill { + inline-size: auto; +} + +.spectrum-PickerButton-icon { + color: var(--mod-picker-button-icon-color, var(--spectrum-picker-button-icon-color)); + flex-shrink: 0; +} diff --git a/1st-gen/packages/picker-button/stories/index.ts b/1st-gen/packages/picker-button/stories/index.ts new file mode 100644 index 00000000000..96a55fe8a2f --- /dev/null +++ b/1st-gen/packages/picker-button/stories/index.ts @@ -0,0 +1,89 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html, nothing, TemplateResult } from '@spectrum-web-components/base'; +import { + ifDefined, + unsafeHTML, +} from '@spectrum-web-components/base/src/directives.js'; + +export type StoryArgs = { + active: boolean; + icon?: string | undefined; + invalid: boolean; + label: boolean | string; + open: boolean; + position?: 'right' | 'left'; + quiet: boolean; + rounded: boolean; + size: 's' | 'm' | 'l' | 'xl'; +}; + +export const Template = ({ + active, + icon, + invalid, + label, + open, + position, + quiet, + rounded, + size, +}: StoryArgs): TemplateResult => { + return html` + + ${icon ? unsafeHTML(icon) : nothing} + ${label + ? html` + + ${typeof label === 'string' ? label : 'All'} + + ` + : nothing} + + `; +}; + +export const argTypes = { + argTypes: { + open: { + control: { + type: 'boolean', + }, + }, + position: { + control: { + type: 'inline-radio', + options: ['right', 'left'], + }, + }, + quiet: { + control: { + type: 'boolean', + }, + }, + size: { + control: { + type: 'inline-radio', + options: ['s', 'm', 'l', 'xl'], + }, + }, + }, +}; diff --git a/1st-gen/packages/picker-button/stories/picker-button-sizes.stories.ts b/1st-gen/packages/picker-button/stories/picker-button-sizes.stories.ts new file mode 100644 index 00000000000..2986bfa8826 --- /dev/null +++ b/1st-gen/packages/picker-button/stories/picker-button-sizes.stories.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { TemplateResult } from '@spectrum-web-components/base'; + +import { argTypes, StoryArgs, Template } from './index.js'; +import '@spectrum-web-components/picker-button/sp-picker-button.js'; + +export default { + title: 'Picker Button/Sizes', + component: 'sp-picker-button', + ...argTypes, +}; + +export const s = (args: StoryArgs): TemplateResult => Template(args); +s.args = { size: 's' }; + +export const m = (args: StoryArgs): TemplateResult => Template(args); +m.args = { size: 'm' }; + +export const l = (args: StoryArgs): TemplateResult => Template(args); +l.args = { size: 'l' }; + +export const XL = (args: StoryArgs): TemplateResult => Template(args); +XL.args = { size: 'xl' }; + +export const sLabel = (args: StoryArgs): TemplateResult => Template(args); +sLabel.args = { size: 's', label: true }; + +export const mLabel = (args: StoryArgs): TemplateResult => Template(args); +mLabel.args = { size: 'm', label: true }; + +export const lLabel = (args: StoryArgs): TemplateResult => Template(args); +lLabel.args = { size: 'l', label: true }; + +export const XLLabel = (args: StoryArgs): TemplateResult => Template(args); +XLLabel.args = { size: 'xl', label: true }; diff --git a/1st-gen/packages/picker-button/stories/picker-button.stories.ts b/1st-gen/packages/picker-button/stories/picker-button.stories.ts new file mode 100644 index 00000000000..f28591b5cce --- /dev/null +++ b/1st-gen/packages/picker-button/stories/picker-button.stories.ts @@ -0,0 +1,63 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { TemplateResult } from '@spectrum-web-components/base'; + +import { argTypes, StoryArgs, Template } from './index.js'; +import '@spectrum-web-components/picker-button/sp-picker-button.js'; + +import '@spectrum-web-components/icons-workflow/icons/sp-icon-add.js'; + +export default { + title: 'Picker Button', + component: 'sp-picker-button', + ...argTypes, +}; + +export const active = (args: StoryArgs): TemplateResult => Template(args); +active.args = { active: true }; + +export const customIcon = (args: StoryArgs): TemplateResult => Template(args); +customIcon.args = { + icon: ``, +}; + +export const invalid = (args: StoryArgs): TemplateResult => Template(args); +invalid.args = { invalid: true }; + +export const quiet = (args: StoryArgs): TemplateResult => Template(args); +quiet.args = { label: true, quiet: true }; + +export const label = (args: StoryArgs): TemplateResult => Template(args); +label.args = { label: true }; + +export const labelCustom = (args: StoryArgs): TemplateResult => Template(args); +labelCustom.args = { label: 'Some' }; + +export const open = (args: StoryArgs): TemplateResult => Template(args); +open.args = { open: true }; + +export const positionLeft = (args: StoryArgs): TemplateResult => Template(args); +positionLeft.args = { position: 'left' }; + +export const positionRight = (args: StoryArgs): TemplateResult => + Template(args); +positionRight.args = { position: 'right' }; + +export const rounded = (args: StoryArgs): TemplateResult => Template(args); +rounded.args = { rounded: true }; + +export const roundedLabel = (args: StoryArgs): TemplateResult => Template(args); +roundedLabel.args = { + label: true, + rounded: true, +}; diff --git a/1st-gen/packages/picker-button/test/benchmark/basic-test.ts b/1st-gen/packages/picker-button/test/benchmark/basic-test.ts new file mode 100644 index 00000000000..557b6352c9a --- /dev/null +++ b/1st-gen/packages/picker-button/test/benchmark/basic-test.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/picker-button/sp-picker-button.js'; +import { html } from '@spectrum-web-components/base'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + +`); diff --git a/1st-gen/packages/picker-button/test/picker-button-memory.test.ts b/1st-gen/packages/picker-button/test/picker-button-memory.test.ts new file mode 100644 index 00000000000..affe457920f --- /dev/null +++ b/1st-gen/packages/picker-button/test/picker-button-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/picker-button/sp-picker-button.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/picker-button/test/picker-button.test.ts b/1st-gen/packages/picker-button/test/picker-button.test.ts new file mode 100644 index 00000000000..14008e68bd7 --- /dev/null +++ b/1st-gen/packages/picker-button/test/picker-button.test.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + +import '@spectrum-web-components/picker-button/sp-picker-button.js'; +import { PickerButton } from '..'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('PickerButton', () => { + testForLitDevWarnings( + async () => + await fixture(html` + + `) + ); + it('loads default picker-button accessibly', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('loads labeled picker-button accessibly', async () => { + const el = await fixture(html` + + All + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); +}); diff --git a/1st-gen/packages/picker-button/tsconfig.json b/1st-gen/packages/picker-button/tsconfig.json new file mode 100644 index 00000000000..c90873db4cf --- /dev/null +++ b/1st-gen/packages/picker-button/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/base" }] +} diff --git a/1st-gen/packages/picker/.npmrc b/1st-gen/packages/picker/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/picker/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/picker/CHANGELOG.md b/1st-gen/packages/picker/CHANGELOG.md new file mode 100644 index 00000000000..a565b3ee3b6 --- /dev/null +++ b/1st-gen/packages/picker/CHANGELOG.md @@ -0,0 +1,905 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- [#5733](https://github.com/adobe/spectrum-web-components/pull/5733) [`dbba861`](https://github.com/adobe/spectrum-web-components/commit/dbba8617475b9e20b304935ab65ca43f744efe93) Thanks [@iuliauta](https://github.com/iuliauta)! - - **Fixed**: Picker border color should be hidden in S2 theme + +- [#5730](https://github.com/adobe/spectrum-web-components/pull/5730) [`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8) Thanks [@caseyisonit](https://github.com/caseyisonit)! - - **Fixed**: Pending state handling and accessibility in `` component. + - **Changed**: Removed dependency on `PendingStateController` and implemented inline pending state handling + - **Fixed**: Updated aria-labelledby attribute ordering to improve screen reader experience (`icon label applied-label pending-label`) + - **Fixed**: Updated progress circle implementation to use `role="presentation"` instead of `aria-valuetext` + - **Added**: Direct pending state visual rendering with improved accessibility + + These changes improve accessibility for pending states while reducing unnecessary component dependencies. + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`4880da4`](https://github.com/adobe/spectrum-web-components/commit/4880da4f80a25ae1b475f52ce4ba7914cdcd9de4), [`bdf54c1`](https://github.com/adobe/spectrum-web-components/commit/bdf54c1bc6d3eb20da1a1bf3b40650e6ab1ba399), [`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/menu@1.9.0 + - @spectrum-web-components/icons-workflow@1.9.0 + - @spectrum-web-components/progress-circle@1.9.0 + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/field-label@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/overlay@1.9.0 + - @spectrum-web-components/tooltip@1.9.0 + - @spectrum-web-components/tray@1.9.0 + - @spectrum-web-components/icons-ui@1.9.0 + - @spectrum-web-components/popover@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Minor Changes + +- [#5672](https://github.com/adobe/spectrum-web-components/pull/5672) [`6c2acaf`](https://github.com/adobe/spectrum-web-components/commit/6c2acaf14ca1c210a876bdbd65a273d6a5fc22d0) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - **Fixed** escape key behavior in modal overlays containing picker components. Previously, pressing the Escape key when a picker was open inside a modal overlay would not properly close the modal, instead moving focus to the picker. Now, the escape key correctly closes the picker first (if open), then closes the modal overlay on subsequent escape key presses. + + This fix adds a check for `this.open` in the picker's `handleEscape` method to ensure proper modal overlay closure behavior. + +### Patch Changes + +- Updated dependencies [[`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7), [`f27ab09`](https://github.com/adobe/spectrum-web-components/commit/f27ab096f4d53543dc53f75ec196c696b78b3baa), [`ee1bae6`](https://github.com/adobe/spectrum-web-components/commit/ee1bae6f9a7401dc31ebc84e4e27f9d39be692d1), [`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba), [`14486d6`](https://github.com/adobe/spectrum-web-components/commit/14486d620e88976c794225edb54eaca8392015c7)]: + - @spectrum-web-components/overlay@1.8.0 + - @spectrum-web-components/menu@1.8.0 + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/popover@1.8.0 + - @spectrum-web-components/tooltip@1.8.0 + - @spectrum-web-components/field-label@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-ui@1.8.0 + - @spectrum-web-components/icons-workflow@1.8.0 + - @spectrum-web-components/progress-circle@1.8.0 + - @spectrum-web-components/tray@1.8.0 + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies [[`3aeafdd`](https://github.com/adobe/spectrum-web-components/commit/3aeafddab98fe30f4db538ded9052997aaa05b07), [`a646ae8`](https://github.com/adobe/spectrum-web-components/commit/a646ae8b0e652308d359226740d2cb189e492e45), [`cde976d`](https://github.com/adobe/spectrum-web-components/commit/cde976ddfa71f898e2d0404ecc53150db149a861)]: + - @spectrum-web-components/menu@1.7.0 + - @spectrum-web-components/overlay@1.7.0 + - @spectrum-web-components/tooltip@1.7.0 + - @spectrum-web-components/popover@1.7.0 + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/field-label@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-ui@1.7.0 + - @spectrum-web-components/icons-workflow@1.7.0 + - @spectrum-web-components/progress-circle@1.7.0 + - @spectrum-web-components/tray@1.7.0 + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5358](https://github.com/adobe/spectrum-web-components/pull/5358) [`3c3bc2b`](https://github.com/adobe/spectrum-web-components/commit/3c3bc2bed9f1c731bc662220fe96f67f03331015) Thanks [@nikkimk](https://github.com/nikkimk)! - `PickerBase`(used in `` and `sp-action-menu>`): + + Fixes focus so that it is not set on `` elements when opened via mouse. + + A keyboard interaction is the only interaction that should set focus on an `` when the menu is opened. A user with a mouse would expect the focus to stay where the mouse is. + + Fixes: #2950 + +- Updated dependencies [[`03a4439`](https://github.com/adobe/spectrum-web-components/commit/03a443946b760aedc668630f33ac660443ff915e), [`f6cebbd`](https://github.com/adobe/spectrum-web-components/commit/f6cebbd90008a2abb1232c355ae06e8566086093), [`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e), [`700489f`](https://github.com/adobe/spectrum-web-components/commit/700489f87e96b895a687431486fb329c7497f2d6), [`a9727d2`](https://github.com/adobe/spectrum-web-components/commit/a9727d2975b01f440c09789c9e7e0122063b6f7e), [`53f3769`](https://github.com/adobe/spectrum-web-components/commit/53f3769f07b6e7853a8a4c0dc63b21fe14cf3d4b)]: + - @spectrum-web-components/popover@1.6.0 + - @spectrum-web-components/icons-workflow@1.6.0 + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/tooltip@1.6.0 + - @spectrum-web-components/menu@1.6.0 + - @spectrum-web-components/overlay@1.6.0 + - @spectrum-web-components/field-label@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/icons-ui@1.6.0 + - @spectrum-web-components/progress-circle@1.6.0 + - @spectrum-web-components/tray@1.6.0 + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies [[`86bcd12`](https://github.com/adobe/spectrum-web-components/commit/86bcd122003e99d490a64d466dab3e7d609a6ff3), [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0), [`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5), [`8f8735c`](https://github.com/adobe/spectrum-web-components/commit/8f8735c9ec3eac3b6473424c78257cb46ee17f70), [`4c2f908`](https://github.com/adobe/spectrum-web-components/commit/4c2f908a92b383d49eb7197d954966fe1798aa20), [`a69accb`](https://github.com/adobe/spectrum-web-components/commit/a69accb8b44b2612d53d31ba52c99aa751ce9f3a)]: + - @spectrum-web-components/menu@1.5.0 + - @spectrum-web-components/field-label@1.5.0 + - @spectrum-web-components/tray@1.5.0 + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/overlay@1.5.0 + - @spectrum-web-components/popover@1.5.0 + - @spectrum-web-components/tooltip@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-ui@1.5.0 + - @spectrum-web-components/icons-workflow@1.5.0 + - @spectrum-web-components/progress-circle@1.5.0 + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Minor Changes + +- [#5187](https://github.com/adobe/spectrum-web-components/pull/5187) [`2a0422e`](https://github.com/adobe/spectrum-web-components/commit/2a0422ec1b667a9f236858f8cc9dca261ba27f9f) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - Disabled drag and select functionality of picker in mobile devices. This is done to prevent click event being captured behind the menu-tray combination because the menu was closing immediately on pointerup. + - Fixed a bug where the picker in a dialog was not closing when clicking outside the dialog. ([#5111](https://github.com/adobe/spectrum-web-components/issues/5111)) + - Fixed another bug where the elements behind the menu were receiving click events. ([#5060](https://github.com/adobe/spectrum-web-components/issues/5060)) + +- [#5247](https://github.com/adobe/spectrum-web-components/pull/5247) [`1fc141c`](https://github.com/adobe/spectrum-web-components/commit/1fc141cefc01b8a98910c43a1e4ffaa61e952225) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - fix: moved tooltip outside of the trigger button content which prevents event propagation issues and fixes CSS hover state problems by properly separating the tooltip from the button's content (it no longer is a direct child in the DOM). + +### Patch Changes + +- [#5213](https://github.com/adobe/spectrum-web-components/pull/5213) [`82212f4`](https://github.com/adobe/spectrum-web-components/commit/82212f4b67c0514120652e3923cc87f1378809e7) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Updated the attribute name from `forcePopover` to `force-popover` in the Picker and Action menu documentation + +- Updated dependencies [[`2a0422e`](https://github.com/adobe/spectrum-web-components/commit/2a0422ec1b667a9f236858f8cc9dca261ba27f9f), [`46cd782`](https://github.com/adobe/spectrum-web-components/commit/46cd7828f65491fc08790e5ba0aec412ee89199d), [`6618422`](https://github.com/adobe/spectrum-web-components/commit/6618422848df234e420eed95f4a5a30557e1e46f), [`70f5f6f`](https://github.com/adobe/spectrum-web-components/commit/70f5f6f3a97b530fb20f9f5ee049e9a8c124b02d)]: + - @spectrum-web-components/menu@1.4.0 + - @spectrum-web-components/overlay@1.4.0 + - @spectrum-web-components/popover@1.4.0 + - @spectrum-web-components/tooltip@1.4.0 + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/field-label@1.4.0 + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-ui@1.4.0 + - @spectrum-web-components/icons-workflow@1.4.0 + - @spectrum-web-components/progress-circle@1.4.0 + - @spectrum-web-components/tray@1.4.0 + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Minor Changes + +- [#5031](https://github.com/adobe/spectrum-web-components/pull/5031) [`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f) Thanks [@nikkimk](https://github.com/nikkimk)! - Used WAI ARIA Authoring Practices Guide (APG) to make accessibility improvements for ``, ``, and ``, including: + - Numpad keys now work with `` and `` -``'s `` elements can now be read by a screen reader ([#4556](https://github.com/adobe/spectrum-web-components/issues/4556)) + - `` href can now be clicked by a screen reader ([#4997](https://github.com/adobe/spectrum-web-components/issues/4997)) + - Opening a ``, ``, and `` with a keyboard now sets focus on an item within the menu. ([#4557](https://github.com/adobe/spectrum-web-components/issues/4557)) + + See the following APG examples for more information: + - [Navigation Menu Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/) + - [Editor Menubar Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-editor/) + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f), [`468314f`](https://github.com/adobe/spectrum-web-components/commit/468314f45cf5fedb2e9029da210a5886260abca9)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/menu@1.3.0 + - @spectrum-web-components/overlay@1.3.0 + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/field-label@1.3.0 + - @spectrum-web-components/tooltip@1.3.0 + - @spectrum-web-components/tray@1.3.0 + - @spectrum-web-components/popover@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-ui@1.3.0 + - @spectrum-web-components/icons-workflow@1.3.0 + - @spectrum-web-components/progress-circle@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +### Bug Fixes + +- **action menu:** keyboard accessibility omnibus ([#5031](https://github.com/adobe/spectrum-web-components/issues/5031)) ([ea38ef0](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)), closes [#4623](https://github.com/adobe/spectrum-web-components/issues/4623) +- **picker:** update picker when menu item icons change ([#5088](https://github.com/adobe/spectrum-web-components/issues/5088)) ([63ef1ad](https://github.com/adobe/spectrum-web-components/commit/63ef1adad473ce58647ffe4d5e2a8727caaee07b)) + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +### Bug Fixes + +- **overlay:** derive popover placement from host in interaction controller ([#5078](https://github.com/adobe/spectrum-web-components/issues/5078)) ([635cf53](https://github.com/adobe/spectrum-web-components/commit/635cf53df237b7f833633cb05d09c0697e61f6f4)) +- **picker:** stop the click events from reaching the elements below picker-tray ([#5060](https://github.com/adobe/spectrum-web-components/issues/5060)) ([7e4fdbf](https://github.com/adobe/spectrum-web-components/commit/7e4fdbf3e4487b4c148368b852129b85f88a620b)) + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +### Bug Fixes + +- **overlay:** make :focus-visible consistent when using overlay type modal ([#4912](https://github.com/adobe/spectrum-web-components/issues/4912)) ([7a5f786](https://github.com/adobe/spectrum-web-components/commit/7a5f786819ff200f5ae2648e2e2c4db3729050a2)), closes [#5021](https://github.com/adobe/spectrum-web-components/issues/5021) + +### Features + +- **picker:** add forcePopover property ([#5041](https://github.com/adobe/spectrum-web-components/issues/5041)) ([3651e57](https://github.com/adobe/spectrum-web-components/commit/3651e57a90a05e551e6ee650e8ccc73aa05d3e7c)) + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) +- **overlay:** make :focus-visible consistent when using overlay type modal ([#4912](https://github.com/adobe/spectrum-web-components/issues/4912)) ([7a5f786](https://github.com/adobe/spectrum-web-components/commit/7a5f786819ff200f5ae2648e2e2c4db3729050a2)), closes [#5021](https://github.com/adobe/spectrum-web-components/issues/5021) + +### Features + +- add an optional chromatic vrt action ([7d2f840](https://github.com/adobe/spectrum-web-components/commit/7d2f8401cb05c5e23872424f132a1a8edd95b666)) +- **picker:** add forcePopover property ([#5041](https://github.com/adobe/spectrum-web-components/issues/5041)) ([3651e57](https://github.com/adobe/spectrum-web-components/commit/3651e57a90a05e551e6ee650e8ccc73aa05d3e7c)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **picker:** don't handle pointerdown for touch devices ([#4850](https://github.com/adobe/spectrum-web-components/issues/4850)) ([3a62d13](https://github.com/adobe/spectrum-web-components/commit/3a62d133b8074e5b40f1eedfa9a5566dc53b30ad)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +### Bug Fixes + +- **action-menu:** dispatch scroll event ([#4715](https://github.com/adobe/spectrum-web-components/issues/4715)) ([c76f3f5](https://github.com/adobe/spectrum-web-components/commit/c76f3f54f5a08df82ea4247252f2e0114836a778)) +- **picker:** added a custom class to make `:focus-visible` styles consistent across all browsers ([#4724](https://github.com/adobe/spectrum-web-components/issues/4724)) ([d667d08](https://github.com/adobe/spectrum-web-components/commit/d667d0853b8122008ce8fe50c6c479a42dc96a9f)) + +### Features + +- **reactive-controller:** new pending state controller ([#4605](https://github.com/adobe/spectrum-web-components/issues/4605)) ([68baf94](https://github.com/adobe/spectrum-web-components/commit/68baf94f257b9c7525253819a2ed3c8fa1b6c408)) + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +### Bug Fixes + +- **picker:** updated type for mobile and desktop ([#4666](https://github.com/adobe/spectrum-web-components/issues/4666)) ([d11da1f](https://github.com/adobe/spectrum-web-components/commit/d11da1ffb7faa7804a1383cffba90277cf401e45)) + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +### Bug Fixes + +- **picker** pointerup in mobile does not automatically make a selection. ([4227](https://github.com/adobe/spectrum-web-components/issues/4227)) ([56366ce] (https://github.com/adobe/spectrum-web-components/commit/56366ce2750bb4bb5c6e3fa5fe7d809434497adb)) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +### Features + +- **action-bar:** support for action-menus ([#3780](https://github.com/adobe/spectrum-web-components/issues/3780)) ([4aff599](https://github.com/adobe/spectrum-web-components/commit/4aff5995f6a22eefae0dd8e580d743c27ceb2c2d)) + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +### Bug Fixes + +- **action-menu:** allow menu groups to handle their own selections ([#4397](https://github.com/adobe/spectrum-web-components/issues/4397)) ([5a19051](https://github.com/adobe/spectrum-web-components/commit/5a190518814f85cfd2e345ad6a0add1378c05bf4)) + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Bug Fixes + +- **picker:** add loading state to the picker ([#3110](https://github.com/adobe/spectrum-web-components/issues/3110)) ([d91e2c9](https://github.com/adobe/spectrum-web-components/commit/d91e2c9f3530c3c911832ea3a401fddc23e7854a)) +- **picker:** allow open/close in tablet ([dcfc96e](https://github.com/adobe/spectrum-web-components/commit/dcfc96e779c0dd6005f4697450d1edcf7809e8ea)) +- **picker:** correctly process the CSS for the quiet hover effect ([#4167](https://github.com/adobe/spectrum-web-components/issues/4167)) ([eb282fa](https://github.com/adobe/spectrum-web-components/commit/eb282fad1d1b4f5e7c2bce65df6ca56f46e6870e)) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +### Bug Fixes + +- **overlay:** leverage "transition-behavior" to persist top-layer content while closing ([#4050](https://github.com/adobe/spectrum-web-components/issues/4050)) ([e3dea14](https://github.com/adobe/spectrum-web-components/commit/e3dea14fa382b4e02f61ae8b651e89cd92c348f8)) +- **picker:** support inline labeling of quiet Picker ([#3704](https://github.com/adobe/spectrum-web-components/issues/3704)) ([3372286](https://github.com/adobe/spectrum-web-components/commit/337228659bfcd831700ce782254e5cb539c503d2)) + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +### Bug Fixes + +- **picker:** correct implementation of "disabled", expand stories and documentation ([#4040](https://github.com/adobe/spectrum-web-components/issues/4040)) ([84c2fef](https://github.com/adobe/spectrum-web-components/commit/84c2fef72cb8be6d77ce62c21ed6d9d0d866d849)) + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +### Bug Fixes + +- **picker,action-menu,split-button:** update interaction model ([#3935](https://github.com/adobe/spectrum-web-components/issues/3935)) ([bae7d52](https://github.com/adobe/spectrum-web-components/commit/bae7d527e513d2588267c62cc70f5e1c1289f903)) + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +### Bug Fixes + +- **picker:** force close slotted Tooltip elements with disabled when Menu openes ([82c8f12](https://github.com/adobe/spectrum-web-components/commit/82c8f129d8a378f51ca083c4020a15b3cbde1fe7)) +- **picker:** prevent the Menu opening until required dependencies are loaded ([55e6174](https://github.com/adobe/spectrum-web-components/commit/55e617497477f2627982f877743f1635e32ee583)) + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +### Bug Fixes + +- **picker:** ensure menu placement in mobile ([#3835](https://github.com/adobe/spectrum-web-components/issues/3835)) ([4aba1c6](https://github.com/adobe/spectrum-web-components/commit/4aba1c6094e45481dec428fcc95fb4148f62dbc9)) + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +### Bug Fixes + +- **overlay:** calculate more transforms ([6538a45](https://github.com/adobe/spectrum-web-components/commit/6538a45a036f60c4efce4c3ed3d1d6f2782a188e)) + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +### Bug Fixes + +- **picker,split-button:** include "tooltip" slot in the main button ([699b8af](https://github.com/adobe/spectrum-web-components/commit/699b8af2612f2dab8f7c65b9c105844f6feaa6ed)) + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- **action-menu,split-button:** ensure toggling the Menu closed completes ([2dd0f98](https://github.com/adobe/spectrum-web-components/commit/2dd0f9871a4d76a27f5d432ea2df230ab99cbdd1)) +- **picker:** ensure the Menu opens in a Tray on mobile ([6be2bed](https://github.com/adobe/spectrum-web-components/commit/6be2bed36b364c5abcd1210db9c95ebc883125ec)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +### Bug Fixes + +- allow non-selection carying Picker derivatives to report value ([02c0134](https://github.com/adobe/spectrum-web-components/commit/02c013454cb2189f3026d1d928198fe815dd933d)) + +### Features + +- **picker,action-group,split-button:** leverage Overlay v2 ([170a223](https://github.com/adobe/spectrum-web-components/commit/170a223d74870ed3eda452285943716f8cbf4b7c)) + +### Performance Improvements + +- make lots of things lazy ([b8fa3ad](https://github.com/adobe/spectrum-web-components/commit/b8fa3ada062bf54bbb42e76ab156c716d5820c7c)) +- make submenus lazier ([a2d661c](https://github.com/adobe/spectrum-web-components/commit/a2d661cf4095f4ccb826d17b6f2e665c8c5bf70f)) + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +### Features + +- **menu:** convert to core tokens ([#3254](https://github.com/adobe/spectrum-web-components/issues/3254)) ([da43540](https://github.com/adobe/spectrum-web-components/commit/da43540abcea3db75bf145194be800b61153ebe0)) + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **action-button,action-menu,picker,split-button:** expand and update application of aria-\* attributes ([52c0156](https://github.com/adobe/spectrum-web-components/commit/52c015636d42f2baf1524446a0db9d5e5cfeb689)) +- **picker:** correct label application for screen readers ([8ce0cb0](https://github.com/adobe/spectrum-web-components/commit/8ce0cb0b76fcb76af34fdd3228ae268509f80ee0)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.33.1](https://github.com/adobe/spectrum-web-components/compare/v0.33.0...v0.33.1) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Bug Fixes + +- **picker:** correct attribute spelling of "aria-label" in dismiss button ([5fc9b30](https://github.com/adobe/spectrum-web-components/commit/5fc9b30260f7d6df4d6e3cb6a3e49a149ece5458)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +### Bug Fixes + +- generate react/picker and pass react TS checks ([101b88c](https://github.com/adobe/spectrum-web-components/commit/101b88c9d1607023e073a985a2b46d2dce2c9c82)) + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) +- **action-menu:** fix 2510, unable to control top-level action-menu selection ([c9198c2](https://github.com/adobe/spectrum-web-components/commit/c9198c29c0f2f9be83d9e153147e5634c6c00b06)) +- **action-menu:** never set item selected values when selects is undefined ([5237fdb](https://github.com/adobe/spectrum-web-components/commit/5237fdb30694364934e1cd30f3d9cf82efa2c5c5)) +- **action-menu:** stop stripping selected state from submenu items ([968d1f2](https://github.com/adobe/spectrum-web-components/commit/968d1f26e4f075ad20dbaba07baf73d5a0c4d55c)) +- add icon present and icon-only support to Picker ([f6887a3](https://github.com/adobe/spectrum-web-components/commit/f6887a34e228473e33893c81017492bf3e8fd6c3)) +- add support for "readonly" attribute ([4bce3b7](https://github.com/adobe/spectrum-web-components/commit/4bce3b7b6910ac50e80efe6a8f63f57843feafb3)) +- add t-shirt sizing to Thumbnail and support for "xxs"/"xs" sizes ([520a642](https://github.com/adobe/spectrum-web-components/commit/520a642b33e2ca5a4fdc67c15ace029d33e895ff)) +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- allow Picker to be reparented ([39e7309](https://github.com/adobe/spectrum-web-components/commit/39e73094be38888599fb189ed4d613f09476310f)) +- analyze errors, properly this time ([df685a2](https://github.com/adobe/spectrum-web-components/commit/df685a20f57379442d54f026b8ad7cef474a067b)) +- analyze type errors, and add deprecated syntax tests ([b7e67a1](https://github.com/adobe/spectrum-web-components/commit/b7e67a103d5a3bb355a8ee4682ef9621d8d59872)) +- bad merge conflict resolution ([e408d61](https://github.com/adobe/spectrum-web-components/commit/e408d61c82ee4ea8463be7d76f480b260fd5aa30)) +- correct custom property hoisting ([a1d98dc](https://github.com/adobe/spectrum-web-components/commit/a1d98dccadb790afb61d761636754ed337a0d50c)) +- correct max size calculation for overlays ([0585f7f](https://github.com/adobe/spectrum-web-components/commit/0585f7f30bf502d147bd467a942ee180656b2413)) +- ensure Action Menu Item with [href] close the menu ([6b3d87f](https://github.com/adobe/spectrum-web-components/commit/6b3d87f8c922df782432bca3ef93d21637bad78b)) +- ensure correct Menu Items are "selected" when passed into the overlay ([46a25db](https://github.com/adobe/spectrum-web-components/commit/46a25db6303adbbcdfe76cb3bf97541adc418367)) +- ensure focus is managed when tabbing out of a menu ([9bfa81d](https://github.com/adobe/spectrum-web-components/commit/9bfa81d8a677d6c0ab5ac5cd618498496761c69b)) +- expand sync offering for elements with overlay content ([0195843](https://github.com/adobe/spectrum-web-components/commit/0195843e9efac5760a78fa302d91139c84ea5747)) +- give Picker a focus helper to enable tab navigation in Safari ([e796525](https://github.com/adobe/spectrum-web-components/commit/e7965251651b42e28bfbcaf752f2ab9b19700835)) +- hopefully fix CI ([ea87245](https://github.com/adobe/spectrum-web-components/commit/ea87245359128ad4f9d790d2dc5d5dd36208bc25)) +- include late added items in the item list for the Picker ([9232eb1](https://github.com/adobe/spectrum-web-components/commit/9232eb1009ccbcdf6166e48928bd8416c23d50b2)) +- issues with optionsMenu & menuItems ([01a7e35](https://github.com/adobe/spectrum-web-components/commit/01a7e35099cef1d8185e79ee94dfad36ece7ba8d)) +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) +- **menu:** clarify menu internal focus management via preventScroll option ([9ae092c](https://github.com/adobe/spectrum-web-components/commit/9ae092c7d09ef9359dbf9ed9373aef0650967f40)) +- **menu:** ensure active descendant is in view when activated ([6edc351](https://github.com/adobe/spectrum-web-components/commit/6edc3518fd305cbd35b74f013546bb32aef7616b)) +- **menu:** only scrollIntoView when keyboard navigating ([f4e9278](https://github.com/adobe/spectrum-web-components/commit/f4e9278048287a45bba2da25144834b0b8297c66)) +- **overlay:** move "escape" listener to "keydown" ([813b341](https://github.com/adobe/spectrum-web-components/commit/813b3415ab16391e717e84a61c74b304a67c2e03)) +- **picker:** accept new "value" and new option post first render ([8f8c93f](https://github.com/adobe/spectrum-web-components/commit/8f8c93f1045b07d5e108769c4efffa54213d20e3)) +- **picker:** add "quick select" action to right/left arrow keys ([21895ee](https://github.com/adobe/spectrum-web-components/commit/21895eed8d194b0a570cbb2bafeaa06c9511bf27)) +- **picker:** allow menu items to be added, updated, and removed ([73511ba](https://github.com/adobe/spectrum-web-components/commit/73511ba996154c006602dfd1c7f1d94746049782)) +- **picker:** ensure focus visibility application ([2679081](https://github.com/adobe/spectrum-web-components/commit/2679081978788bd68b5e2c9cd1c05161cc571446)) +- **picker:** ensure that width is customizable from the outside ([702b052](https://github.com/adobe/spectrum-web-components/commit/702b052f9ea1686d2a964648d4bb1d365178160f)) +- **picker:** make "change" event bubbling and composed ([1fdd33d](https://github.com/adobe/spectrum-web-components/commit/1fdd33de0f8a01640b91ecda2cb9e81bd8076adf)) +- **picker:** query less strictly to support automatically selecting values ([969f966](https://github.com/adobe/spectrum-web-components/commit/969f966585256c3a496eddb4cb84c0142aa7ae9c)) +- **picker:** use "modal" as the menu overlay interaction ([c8fbbe2](https://github.com/adobe/spectrum-web-components/commit/c8fbbe27b19702909855575b1afd38fb064e8378)) +- prevent console.log in source and test files ([3ee082c](https://github.com/adobe/spectrum-web-components/commit/3ee082ceadd9eeef167bb8ac6241fe1501e4426c)) +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) +- simplify focus application in Menu ([6140169](https://github.com/adobe/spectrum-web-components/commit/61401699b36298b6f11cc80703aff664cbb867a7)) +- simplify optionsMenu usage and fix tests ([91241b7](https://github.com/adobe/spectrum-web-components/commit/91241b7bddc434c7220fc0fbd65389d0ca38f674)) +- slot documentation ([0ebd260](https://github.com/adobe/spectrum-web-components/commit/0ebd2609bad9e95ee24428cb2fa666d23bdb85f8)) +- split-button tests & lots of cleanup based on review feedback ([10b4a04](https://github.com/adobe/spectrum-web-components/commit/10b4a04c5791d1acd9e59d48a8960b9c17aa89c7)), closes [#1189](https://github.com/adobe/spectrum-web-components/issues/1189) +- style icons in Picker correctly ([0bbdf84](https://github.com/adobe/spectrum-web-components/commit/0bbdf84df595a573b355721698262b1c5a1f3b01)) +- support a wider number of sizes ([ee44978](https://github.com/adobe/spectrum-web-components/commit/ee4497830da0d3bc63d4414ad5548291a39588c7)) +- update Picker label via MutationObserver instead of "slotchange" ([196998e](https://github.com/adobe/spectrum-web-components/commit/196998e9433dc938d86bfbe77db9e3accd6d9bbc)) +- update screen reader interface with menu items list ([16756b5](https://github.com/adobe/spectrum-web-components/commit/16756b56c0f7f9561426acc202997fb098e8f19a)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- add selects attribute to menu ([bdf2578](https://github.com/adobe/spectrum-web-components/commit/bdf25780e56c7b92368904dce2a02f2594c364a2)) +- add t-shirt sizing with visual regressions to checkbox and picker elements ([ce47ec8](https://github.com/adobe/spectrum-web-components/commit/ce47ec88bd2c6c8d236c05826d28b2d0dadf12b8)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) +- deprecate sp-menu in PickerBase derived classes ([bbb773c](https://github.com/adobe/spectrum-web-components/commit/bbb773c915587b9d92875e333a6b422ec878a8ea)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) +- **picker:** replace dropdown with picker component ([30b8bc7](https://github.com/adobe/spectrum-web-components/commit/30b8bc791be37ba53a12244f3dd2cccd55c490a3)) +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) +- **picker:** update "icons-only" to "icons=only" to support more variations ([de16a62](https://github.com/adobe/spectrum-web-components/commit/de16a628f6ec7cfcbe405c71414bef6ed72b1726)) +- **picker:** use new tokens ([7d65b69](https://github.com/adobe/spectrum-web-components/commit/7d65b69d47d69a34f75b456a5aa457f22ec04aca)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) +- sets action-menu quiet to false by default, fixes [#3040](https://github.com/adobe/spectrum-web-components/issues/3040) ([8414cab](https://github.com/adobe/spectrum-web-components/commit/8414cab2ef916be40be9f624f485fb02184eec2b)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- reorganize inheritance and composition in Menu Items ([d96ccb6](https://github.com/adobe/spectrum-web-components/commit/d96ccb621833277444d69535126c3669343c2eaf)) + +## [0.15.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.15.1...@spectrum-web-components/picker@0.15.2) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.15.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.15.0...@spectrum-web-components/picker@0.15.1) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.15.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.14.2...@spectrum-web-components/picker@0.15.0) (2023-03-22) + +### Features + +- sets action-menu quiet to false by default, fixes [#3040](https://github.com/adobe/spectrum-web-components/issues/3040) ([8414cab](https://github.com/adobe/spectrum-web-components/commit/8414cab2ef916be40be9f624f485fb02184eec2b)) + +## [0.14.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.14.1...@spectrum-web-components/picker@0.14.2) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.14.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.14.0...@spectrum-web-components/picker@0.14.1) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.14.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.11...@spectrum-web-components/picker@0.14.0) (2023-02-08) + +### Features + +- **picker:** use new tokens ([7d65b69](https://github.com/adobe/spectrum-web-components/commit/7d65b69d47d69a34f75b456a5aa457f22ec04aca)) + +## [0.13.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.10...@spectrum-web-components/picker@0.13.11) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.9...@spectrum-web-components/picker@0.13.10) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.8...@spectrum-web-components/picker@0.13.9) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.7...@spectrum-web-components/picker@0.13.8) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.6...@spectrum-web-components/picker@0.13.7) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.5...@spectrum-web-components/picker@0.13.6) (2022-10-28) + +### Bug Fixes + +- ensure Action Menu Item with [href] close the menu ([6b3d87f](https://github.com/adobe/spectrum-web-components/commit/6b3d87f8c922df782432bca3ef93d21637bad78b)) + +## [0.13.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.4...@spectrum-web-components/picker@0.13.5) (2022-10-17) + +### Bug Fixes + +- style icons in Picker correctly ([0bbdf84](https://github.com/adobe/spectrum-web-components/commit/0bbdf84df595a573b355721698262b1c5a1f3b01)) + +## [0.13.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.3...@spectrum-web-components/picker@0.13.4) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.13.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.2...@spectrum-web-components/picker@0.13.3) (2022-09-15) + +### Bug Fixes + +- **action-menu:** fix 2510, unable to control top-level action-menu selection ([c9198c2](https://github.com/adobe/spectrum-web-components/commit/c9198c29c0f2f9be83d9e153147e5634c6c00b06)) +- **action-menu:** never set item selected values when selects is undefined ([5237fdb](https://github.com/adobe/spectrum-web-components/commit/5237fdb30694364934e1cd30f3d9cf82efa2c5c5)) + +## [0.13.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.1...@spectrum-web-components/picker@0.13.2) (2022-09-14) + +### Bug Fixes + +- **overlay:** move "escape" listener to "keydown" ([813b341](https://github.com/adobe/spectrum-web-components/commit/813b3415ab16391e717e84a61c74b304a67c2e03)) + +## [0.13.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.13.0...@spectrum-web-components/picker@0.13.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.13.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.12.0...@spectrum-web-components/picker@0.13.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.5...@spectrum-web-components/picker@0.12.0) (2022-08-04) + +### Bug Fixes + +- **action-menu:** stop stripping selected state from submenu items ([968d1f2](https://github.com/adobe/spectrum-web-components/commit/968d1f26e4f075ad20dbaba07baf73d5a0c4d55c)) +- **picker:** query less strictly to support automatically selecting values ([969f966](https://github.com/adobe/spectrum-web-components/commit/969f966585256c3a496eddb4cb84c0142aa7ae9c)) + +### Features + +- delivery dev mode messages in various packages ([62370a1](https://github.com/adobe/spectrum-web-components/commit/62370a19c77ab00e5b5702833bb1e40fb81e7d48)) + +## [0.11.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.4...@spectrum-web-components/picker@0.11.5) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.11.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.3...@spectrum-web-components/picker@0.11.4) (2022-06-29) + +### Bug Fixes + +- update Picker label via MutationObserver instead of "slotchange" ([196998e](https://github.com/adobe/spectrum-web-components/commit/196998e9433dc938d86bfbe77db9e3accd6d9bbc)) + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.2...@spectrum-web-components/picker@0.11.3) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.1...@spectrum-web-components/picker@0.11.2) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.11.0...@spectrum-web-components/picker@0.11.1) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.6...@spectrum-web-components/picker@0.11.0) (2022-04-21) + +### Bug Fixes + +- allow Picker to be reparented ([39e7309](https://github.com/adobe/spectrum-web-components/commit/39e73094be38888599fb189ed4d613f09476310f)) +- correct custom property hoisting ([a1d98dc](https://github.com/adobe/spectrum-web-components/commit/a1d98dccadb790afb61d761636754ed337a0d50c)) +- ensure correct Menu Items are "selected" when passed into the overlay ([46a25db](https://github.com/adobe/spectrum-web-components/commit/46a25db6303adbbcdfe76cb3bf97541adc418367)) + +### Features + +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) +- reparentChildren - refactored arguments - breaking change ([dea2bc5](https://github.com/adobe/spectrum-web-components/commit/dea2bc5cba1185e790a834db43daf8fc45f4e4f7)) + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.5...@spectrum-web-components/picker@0.10.6) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.4...@spectrum-web-components/picker@0.10.5) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.3...@spectrum-web-components/picker@0.10.4) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.2...@spectrum-web-components/picker@0.10.3) (2022-03-04) + +### Bug Fixes + +- **menu:** add support for submenu interactions ([68399af](https://github.com/adobe/spectrum-web-components/commit/68399af396bfb70b9c84c83ee2265aa9daa05e10)) + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.1...@spectrum-web-components/picker@0.10.2) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.10.0...@spectrum-web-components/picker@0.10.1) (2022-02-03) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.9.4...@spectrum-web-components/picker@0.10.0) (2022-02-02) + +### Features + +- **picker:** support responsive delivery of menu ([20031d1](https://github.com/adobe/spectrum-web-components/commit/20031d1b42b36cdaa129a25ee70eb2bcbcdbdb5e)) + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.9.3...@spectrum-web-components/picker@0.9.4) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.9.2...@spectrum-web-components/picker@0.9.3) (2022-01-26) + +### Bug Fixes + +- **picker:** make "change" event bubbling and composed ([1fdd33d](https://github.com/adobe/spectrum-web-components/commit/1fdd33de0f8a01640b91ecda2cb9e81bd8076adf)) + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.9.1...@spectrum-web-components/picker@0.9.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.9.0...@spectrum-web-components/picker@0.9.1) (2021-12-13) + +### Bug Fixes + +- add t-shirt sizing to Thumbnail and support for "xxs"/"xs" sizes ([520a642](https://github.com/adobe/spectrum-web-components/commit/520a642b33e2ca5a4fdc67c15ace029d33e895ff)) +- **picker:** allow menu items to be added, updated, and removed ([73511ba](https://github.com/adobe/spectrum-web-components/commit/73511ba996154c006602dfd1c7f1d94746049782)) + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.8.1...@spectrum-web-components/picker@0.9.0) (2021-11-08) + +### Features + +- update lit-\* dependencies, wip ([377f3c8](https://github.com/adobe/spectrum-web-components/commit/377f3c848b09e64fa1ecc1e18208f534fefcd9e4)) + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.8.0...@spectrum-web-components/picker@0.8.1) (2021-11-08) + +### Bug Fixes + +- abstract "hasVisibleFocusInTree" functionality and return trigger focus after close ([4f39f2c](https://github.com/adobe/spectrum-web-components/commit/4f39f2c506066b789834584d2c9c24185ea57118)) + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.5...@spectrum-web-components/picker@0.8.0) (2021-11-02) + +### Bug Fixes + +- update screen reader interface with menu items list ([16756b5](https://github.com/adobe/spectrum-web-components/commit/16756b56c0f7f9561426acc202997fb098e8f19a)) +- **picker:** use "modal" as the menu overlay interaction ([c8fbbe2](https://github.com/adobe/spectrum-web-components/commit/c8fbbe27b19702909855575b1afd38fb064e8378)) +- include late added items in the item list for the Picker ([9232eb1](https://github.com/adobe/spectrum-web-components/commit/9232eb1009ccbcdf6166e48928bd8416c23d50b2)) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.7.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.4...@spectrum-web-components/picker@0.7.5) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.7.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.3...@spectrum-web-components/picker@0.7.4) (2021-10-05) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.2...@spectrum-web-components/picker@0.7.3) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.1...@spectrum-web-components/picker@0.7.2) (2021-09-13) + +### Bug Fixes + +- give Picker a focus helper to enable tab navigation in Safari ([e796525](https://github.com/adobe/spectrum-web-components/commit/e7965251651b42e28bfbcaf752f2ab9b19700835)) +- simplify focus application in Menu ([6140169](https://github.com/adobe/spectrum-web-components/commit/61401699b36298b6f11cc80703aff664cbb867a7)) + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.7.0...@spectrum-web-components/picker@0.7.1) (2021-08-24) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.6.0...@spectrum-web-components/picker@0.7.0) (2021-08-17) + +### Features + +- **picker:** update "icons-only" to "icons=only" to support more variations ([de16a62](https://github.com/adobe/spectrum-web-components/commit/de16a628f6ec7cfcbe405c71414bef6ed72b1726)) + +### Performance Improvements + +- reorganize inheritance and composition in Menu Items ([d96ccb6](https://github.com/adobe/spectrum-web-components/commit/d96ccb621833277444d69535126c3669343c2eaf)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.5.4...@spectrum-web-components/picker@0.6.0) (2021-08-03) + +### Bug Fixes + +- allow "updateComplete" to resolve to a boolean like the LitElement default ([6127946](https://github.com/adobe/spectrum-web-components/commit/6127946fd3ffd048a30b7eb4bf6aadf9e7c8752a)) +- expand sync offering for elements with overlay content ([0195843](https://github.com/adobe/spectrum-web-components/commit/0195843e9efac5760a78fa302d91139c84ea5747)) + +### Features + +- add selects attribute to menu ([bdf2578](https://github.com/adobe/spectrum-web-components/commit/bdf25780e56c7b92368904dce2a02f2594c364a2)) + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.5.3...@spectrum-web-components/picker@0.5.4) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/picker + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.5.2...@spectrum-web-components/picker@0.5.3) (2021-07-01) + +### Bug Fixes + +- add icon present and icon-only support to Picker ([f6887a3](https://github.com/adobe/spectrum-web-components/commit/f6887a34e228473e33893c81017492bf3e8fd6c3)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.5.1...@spectrum-web-components/picker@0.5.2) (2021-06-16) + +### Bug Fixes + +- prevent console.log in source and test files ([3ee082c](https://github.com/adobe/spectrum-web-components/commit/3ee082ceadd9eeef167bb8ac6241fe1501e4426c)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.5.0...@spectrum-web-components/picker@0.5.1) (2021-06-07) + +### Bug Fixes + +- **menu:** clarify menu internal focus management via preventScroll option ([9ae092c](https://github.com/adobe/spectrum-web-components/commit/9ae092c7d09ef9359dbf9ed9373aef0650967f40)) +- ensure focus is managed when tabbing out of a menu ([9bfa81d](https://github.com/adobe/spectrum-web-components/commit/9bfa81d8a677d6c0ab5ac5cd618498496761c69b)) + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.5...@spectrum-web-components/picker@0.5.0) (2021-05-24) + +### Features + +- **tabs:** add sp-tab-panel element ([b17d276](https://github.com/adobe/spectrum-web-components/commit/b17d2765cf415578a31e5fa23515c25ff4c3922d)) + +## [0.4.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.4...@spectrum-web-components/picker@0.4.5) (2021-05-12) + +### Bug Fixes + +- **picker:** ensure focus visibility application ([2679081](https://github.com/adobe/spectrum-web-components/commit/2679081978788bd68b5e2c9cd1c05161cc571446)) + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.3...@spectrum-web-components/picker@0.4.4) (2021-04-15) + +### Bug Fixes + +- **menu:** only scrollIntoView when keyboard navigating ([f4e9278](https://github.com/adobe/spectrum-web-components/commit/f4e9278048287a45bba2da25144834b0b8297c66)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.2...@spectrum-web-components/picker@0.4.3) (2021-04-09) + +### Bug Fixes + +- **picker:** accept new "value" and new option post first render ([8f8c93f](https://github.com/adobe/spectrum-web-components/commit/8f8c93f1045b07d5e108769c4efffa54213d20e3)) + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.1...@spectrum-web-components/picker@0.4.2) (2021-03-29) + +### Bug Fixes + +- correct max size calculation for overlays ([0585f7f](https://github.com/adobe/spectrum-web-components/commit/0585f7f30bf502d147bd467a942ee180656b2413)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.4.0...@spectrum-web-components/picker@0.4.1) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.3.1...@spectrum-web-components/picker@0.4.0) (2021-03-22) + +### Bug Fixes + +- add support for "readonly" attribute ([4bce3b7](https://github.com/adobe/spectrum-web-components/commit/4bce3b7b6910ac50e80efe6a8f63f57843feafb3)) +- analyze errors, properly this time ([df685a2](https://github.com/adobe/spectrum-web-components/commit/df685a20f57379442d54f026b8ad7cef474a067b)) +- analyze type errors, and add deprecated syntax tests ([b7e67a1](https://github.com/adobe/spectrum-web-components/commit/b7e67a103d5a3bb355a8ee4682ef9621d8d59872)) +- bad merge conflict resolution ([e408d61](https://github.com/adobe/spectrum-web-components/commit/e408d61c82ee4ea8463be7d76f480b260fd5aa30)) +- hopefully fix CI ([ea87245](https://github.com/adobe/spectrum-web-components/commit/ea87245359128ad4f9d790d2dc5d5dd36208bc25)) +- issues with optionsMenu & menuItems ([01a7e35](https://github.com/adobe/spectrum-web-components/commit/01a7e35099cef1d8185e79ee94dfad36ece7ba8d)) +- remove `` usage where deprecated ([387db3b](https://github.com/adobe/spectrum-web-components/commit/387db3be95c98ab220e517fe12a4db7a2496fe5f)) +- simplify optionsMenu usage and fix tests ([91241b7](https://github.com/adobe/spectrum-web-components/commit/91241b7bddc434c7220fc0fbd65389d0ca38f674)) +- slot documentation ([0ebd260](https://github.com/adobe/spectrum-web-components/commit/0ebd2609bad9e95ee24428cb2fa666d23bdb85f8)) +- split-button tests & lots of cleanup based on review feedback ([10b4a04](https://github.com/adobe/spectrum-web-components/commit/10b4a04c5791d1acd9e59d48a8960b9c17aa89c7)), closes [#1189](https://github.com/adobe/spectrum-web-components/issues/1189) + +### Features + +- **picker:** process field-label content for more accurate a11y tree ([dc9df54](https://github.com/adobe/spectrum-web-components/commit/dc9df54d052edc46c2399f0f7b12d3b5d4aff740)) +- deprecate sp-menu in PickerBase derived classes ([bbb773c](https://github.com/adobe/spectrum-web-components/commit/bbb773c915587b9d92875e333a6b422ec878a8ea)) + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.3.0...@spectrum-web-components/picker@0.3.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/picker + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.2.0...@spectrum-web-components/picker@0.3.0) (2021-03-04) + +### Bug Fixes + +- **menu:** ensure active descendant is in view when activated ([6edc351](https://github.com/adobe/spectrum-web-components/commit/6edc3518fd305cbd35b74f013546bb32aef7616b)) +- **picker:** add "quick select" action to right/left arrow keys ([21895ee](https://github.com/adobe/spectrum-web-components/commit/21895eed8d194b0a570cbb2bafeaa06c9511bf27)) +- **picker:** ensure that width is customizable from the outside ([702b052](https://github.com/adobe/spectrum-web-components/commit/702b052f9ea1686d2a964648d4bb1d365178160f)) +- support a wider number of sizes ([ee44978](https://github.com/adobe/spectrum-web-components/commit/ee4497830da0d3bc63d4414ad5548291a39588c7)) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/picker@0.1.0...@spectrum-web-components/picker@0.2.0) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +### Features + +- add t-shirt sizing with visual regressions to checkbox and picker elements ([ce47ec8](https://github.com/adobe/spectrum-web-components/commit/ce47ec88bd2c6c8d236c05826d28b2d0dadf12b8)) + +# 0.1.0 (2021-02-02) + +### Features + +- **picker:** replace dropdown with picker component ([30b8bc7](https://github.com/adobe/spectrum-web-components/commit/30b8bc791be37ba53a12244f3dd2cccd55c490a3)) diff --git a/1st-gen/packages/picker/README.md b/1st-gen/packages/picker/README.md new file mode 100644 index 00000000000..c204e93d66e --- /dev/null +++ b/1st-gen/packages/picker/README.md @@ -0,0 +1,694 @@ +## Overview + +An `` is an alternative to HTML's `` element. + +```html + + Web component + +``` + +### Accessibility + +Tabbing into a group of radio buttons places the focus on the first radio button selected. If none of the radio buttons are selected, the focus is set on the first one in the group. Space selects the radio button in focus (if not already selected). Using the arrow keys moves focus and selection to the previous or next radio button in the group (last becomes first, and first becomes last). The new radio button in focus gets selected even if the previous one was not. + +#### Provide a label + +Radio groups and radio items should always have labels. diff --git a/1st-gen/packages/radio/package.json b/1st-gen/packages/radio/package.json new file mode 100644 index 00000000000..0acd031b61c --- /dev/null +++ b/1st-gen/packages/radio/package.json @@ -0,0 +1,87 @@ +{ + "name": "@spectrum-web-components/radio", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/radio" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/radio", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Radio.js": { + "development": "./src/Radio.dev.js", + "default": "./src/Radio.js" + }, + "./src/RadioGroup.js": { + "development": "./src/RadioGroup.dev.js", + "default": "./src/RadioGroup.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/radio-overrides.css.js": "./src/radio-overrides.css.js", + "./src/radio.css.js": "./src/radio.css.js", + "./sp-radio.js": { + "development": "./sp-radio.dev.js", + "default": "./sp-radio.js" + }, + "./sp-radio-group.js": { + "development": "./sp-radio-group.dev.js", + "default": "./sp-radio-group.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/field-group": "1.9.0", + "@spectrum-web-components/help-text": "1.9.0", + "@spectrum-web-components/reactive-controllers": "1.9.0", + "@spectrum-web-components/shared": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/radio/radio-group.md b/1st-gen/packages/radio/radio-group.md new file mode 100644 index 00000000000..b7158f97ec0 --- /dev/null +++ b/1st-gen/packages/radio/radio-group.md @@ -0,0 +1,268 @@ +## Overview + +[``](../radio) and `` allow users to select a single option from a list of mutually exclusive options. All possible options are exposed up front for users to compare. + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/radio?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/radio) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/radio?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/radio) + +```zsh +yarn add @spectrum-web-components/radio +``` + +Import the side effectful registration of `` or `` via: + +```js +import '@spectrum-web-components/radio/sp-radio.js'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +``` + +When looking to leverage the `Radio` or `RadioGroup` base classes as a type and/or for extension purposes, do so via: + +```js +import { Radio, RadioGroup } from '@spectrum-web-components/radio'; +``` + +### Anatomy + +`` holds a list of `` elements, and is responsible for deselecting radio buttons when a new one is selected, which in turn makes it responsible for keeping track of which one is selected. `` is responsible for handling user interactions and for visually reflecting if it is the one that is checked or not. + +```html + + Option 1 + Option 2 + Option 3 + Option 4 + +``` + +#### Label + +The `` element can be labeled with the `label` attribute or with an <`sp-field-label>` element: + + +`label` attribute + + +```html + + Option 1 + Option 2 + Option 3 + Option 4 + +``` + + +Using a field label + + +```html +Choose an option + + Option 1 + Option 2 + Option 3 + Option 4 + +``` + + + + +#### Help Text + +Help text can be accessibly associated with an `` element by using the `help-text` or `negative-help-text` slots. When using the `negative-help-text` slot, `` will self manage the presence of this content based on the value of the `invalid` property on your `` element. Content within the `help-text` slot will be show by default. When your `` should receive help text based on state outside of the complexity of `invalid` or not, manage the content addressed to the `help-text` from above to ensure that it displays the right messaging and possesses the right `variant`. + +Read more about using [help text](../help-text). + + +Self managed + + +```html + + What is your favorite ice cream flavor? + + + Vanilla + Chocolate + Strawberry + I don't like ice cream + Everyone likes ice cream. + + You can't not like ice cream. + + +``` + + +Managed from above + + +```html + + What is your favorite ice cream flavor? + + + Vanilla + Chocolate + Strawberry + I don't like ice cream + Everyone likes ice cream. + +``` + + + + +### States + +Standard radio buttons are the default style for radio buttons. They are optimal for application panels where all visual elements are monochrome in order to direct focus to the content. + +**Emphasized** radio buttons are a secondary style for radio buttons. The blue color provides a visual prominence that is optimal for forms, settings, etc. where the radio buttons need to be noticed. + + +Default + + +```html +
+
+ +
Standard
+
+ + Kittens + Puppies + +
+ +
+ +
Emphasized
+
+ + Kittens + Puppies + +
+
+``` + +
+Invalid + + +```html +
+
+ +
Standard
+
+ + Kittens + Puppies + + This selection is invalid. + + +
+ +
+ +
Emphasized
+
+ + Kittens + + Puppies + + + This selection is invalid. + + +
+
+``` + +
+Disabled + + +```html +
+
+ +
Standard
+ + + Kittens + Puppies + +
+ +
+ +
Emphasized
+ + + Kittens + Puppies + +
+
+``` + +
+
+ +### Behaviors + +#### Handling events + +Event handlers for changes can be registered on an `` element. + +```html + + Option 1 + Option 2 + Option 3 + Option 4 + +``` + +### Accessibility + +Tabbing into a group of radio buttons places the focus on the first radio button selected. If none of the radio buttons are selected, the focus is set on the first one in the group. Space selects the radio button in focus (if not already selected). Using the arrow keys moves focus and selection to the previous or next radio button in the group (last becomes first, and first becomes last). The new radio button in focus gets selected even if the previous one was not. + +#### Provide a label + +Radio groups and radio items should always have labels. + +#### Provide help text in the correct location + +Radio groups should use help text for error messaging and descriptions. Descriptions are valuable for giving context behind why a selection is required, or for clarifying the options. + +It is [not currently possible](https://w3c.github.io/webcomponents-cg/#cross-root-aria) to provide accessible ARIA references between elements in different shadow roots. To ensure proper association between elements, help text must be included via the `slot="help-text"` or `slot="negative-help-text"`. + +See [help text](../help-text) for more information. diff --git a/1st-gen/packages/radio/sp-radio-group.ts b/1st-gen/packages/radio/sp-radio-group.ts new file mode 100644 index 00000000000..204f970f4ec --- /dev/null +++ b/1st-gen/packages/radio/sp-radio-group.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { RadioGroup } from './src/RadioGroup.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-radio-group', RadioGroup); + +declare global { + interface HTMLElementTagNameMap { + 'sp-radio-group': RadioGroup; + } +} diff --git a/1st-gen/packages/radio/sp-radio.ts b/1st-gen/packages/radio/sp-radio.ts new file mode 100644 index 00000000000..c6aff256c14 --- /dev/null +++ b/1st-gen/packages/radio/sp-radio.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Radio } from './src/Radio.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-radio', Radio); + +declare global { + interface HTMLElementTagNameMap { + 'sp-radio': Radio; + } +} diff --git a/1st-gen/packages/radio/src/Radio.ts b/1st-gen/packages/radio/src/Radio.ts new file mode 100644 index 00000000000..050f15c867f --- /dev/null +++ b/1st-gen/packages/radio/src/Radio.ts @@ -0,0 +1,155 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + PropertyValues, + SizedMixin, + SpectrumElement, + TemplateResult, +} from '@spectrum-web-components/base'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { FocusVisiblePolyfillMixin } from '@spectrum-web-components/shared/src/focus-visible.js'; + +import radioStyles from './radio.css.js'; + +/** + * @element sp-radio + * + * @slot - text label of the Radio button + * @attr invalid - Uses the invalid style + * @attr disabled - Uses the disabled style + * @attr checked - Represents when the input is checked + * @attr value - Identifies this radio button within its radio group + * + * @fires change - When the input is interacted with and its state is changed + */ +export class Radio extends SizedMixin( + FocusVisiblePolyfillMixin(SpectrumElement), + { noDefaultSize: true } +) { + public static override get styles(): CSSResultArray { + return [radioStyles]; + } + + /** + * When this control is rendered, focus it automatically + * @private + */ + @property({ type: Boolean }) + public override autofocus = false; + + @property({ type: String, reflect: true }) + public value = ''; + + @property({ type: Boolean, reflect: true }) + public checked = false; + + @property({ type: Boolean, reflect: true }) + public disabled = false; + + @property({ type: Boolean, reflect: true }) + public emphasized = false; + + @property({ type: Boolean, reflect: true }) + public invalid = false; + + @property({ type: Boolean, reflect: true }) + public readonly = false; + + public override click(): void { + if (this.disabled) { + return; + } + this.activate(); + } + + protected manageAutoFocus(): void { + if (this.autofocus) { + /** + * Trick :focus-visible polyfill into thinking keyboard based focus + * + * @private + **/ + this.dispatchEvent( + new KeyboardEvent('keydown', { + code: 'Tab', + }) + ); + this.focus(); + } + } + + protected activate(): void { + if (this.checked) { + return; + } + this.checked = true; + this.dispatchEvent( + new Event('change', { + bubbles: true, + composed: true, + }) + ); + } + + protected handleKeyup(event: KeyboardEvent): void { + if (event.code === 'Space') { + this.activate(); + } + } + + protected override render(): TemplateResult { + return html` +
+ + + `; + } + + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes); + this.setAttribute('role', 'radio'); + if (!this.hasAttribute('tabindex')) { + this.tabIndex = 0; + } + this.manageAutoFocus(); + this.addEventListener('click', this.activate); + this.addEventListener('keyup', this.handleKeyup); + } + + protected override updated(changes: PropertyValues): void { + super.updated(changes); + if (changes.has('invalid')) { + if (this.invalid) { + this.setAttribute('aria-invalid', 'true'); + } else { + this.removeAttribute('aria-invalid'); + } + } + if (changes.has('checked')) { + if (this.checked) { + this.setAttribute('aria-checked', 'true'); + } else { + this.setAttribute('aria-checked', 'false'); + } + } + if (changes.has('disabled')) { + if (this.disabled) { + this.setAttribute('aria-disabled', 'true'); + } else { + this.removeAttribute('aria-disabled'); + } + } + } +} diff --git a/1st-gen/packages/radio/src/RadioGroup.ts b/1st-gen/packages/radio/src/RadioGroup.ts new file mode 100644 index 00000000000..a4a74e0052d --- /dev/null +++ b/1st-gen/packages/radio/src/RadioGroup.ts @@ -0,0 +1,143 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { PropertyValues } from '@spectrum-web-components/base'; +import { + property, + queryAssignedNodes, +} from '@spectrum-web-components/base/src/decorators.js'; +import { FocusVisiblePolyfillMixin } from '@spectrum-web-components/shared/src/focus-visible.js'; +import { FieldGroup } from '@spectrum-web-components/field-group'; + +import { Radio } from './Radio.js'; +import { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js'; + +/** + * @element sp-radio-group + * + * @slot - The `sp-radio` elements to display/manage in the group. + * @slot help-text - default or non-negative help text to associate to your form element + * @slot negative-help-text - negative help text to associate to your form element when `invalid` + * + * @fires change - An alteration to the value of the element has been committed by the user. + */ +export class RadioGroup extends FocusVisiblePolyfillMixin(FieldGroup) { + @property({ type: String }) + public name = ''; + + @queryAssignedNodes() + public defaultNodes!: Node[]; + + public get buttons(): Radio[] { + return this.defaultNodes.filter( + (node) => (node as HTMLElement) instanceof Radio + ) as Radio[]; + } + + rovingTabindexController = new RovingTabindexController(this, { + focusInIndex: (elements: Radio[]) => { + return elements.findIndex((el) => { + return this.selected + ? !el.disabled && el.value === this.selected + : !el.disabled; + }); + }, + elementEnterAction: (el: Radio) => { + this._setSelected(el.value); + }, + elements: () => this.buttons, + isFocusableElement: (el: Radio) => !el.disabled, + }); + + public override focus(): void { + this.rovingTabindexController.focus(); + } + + private _setSelected(value: string): void { + if (value === this.selected) { + return; + } + const oldValue = this.selected; + const radio = value + ? (this.querySelector(`sp-radio[value="${value}"]`) as Radio) + : undefined; + + // If no matching radio, selected is reset to empty string + this.selected = radio ? value : ''; + const applyDefault = this.dispatchEvent( + new Event('change', { + cancelable: true, + bubbles: true, + composed: true, + }) + ); + if (!applyDefault) { + this.selected = oldValue; + return; + } + this.validateRadios(); + } + + @property({ reflect: true }) + public selected = ''; + + protected override willUpdate(changes: PropertyValues): void { + if (!this.hasUpdated) { + this.setAttribute('role', 'radiogroup'); + const checkedRadio = this.querySelector( + 'sp-radio[checked]' + ) as Radio; + const checkedRadioValue = checkedRadio ? checkedRadio.value : ''; + // Prefer the checked item over the selected value + this.selected = checkedRadioValue || this.selected; + // Validate the selected value is actual a radio option + if (this.selected && this.selected !== checkedRadioValue) { + const selectedRadio = this.querySelector( + `sp-radio[value="${this.selected}"]` + ) as Radio; + if (selectedRadio) { + selectedRadio.checked = true; + } + } + + this.shadowRoot.addEventListener('change', (event: Event) => { + event.stopPropagation(); + const target = event.target as Radio; + this._setSelected(target.value); + }); + } + + if (changes.has('selected')) { + this.validateRadios(); + } + } + + private async validateRadios(): Promise { + let validSelection = false; + if (!this.hasUpdated) { + // Initial validation has to happen after the initial render to allow + // the buttons to be queries from the rendered element + await this.updateComplete; + } + this.buttons.map((button) => { + button.checked = this.selected === button.value; + validSelection = validSelection || button.checked; + }); + if (!validSelection) { + this.selected = ''; + } + } + + protected override handleSlotchange(): void { + this.rovingTabindexController.clearElementCache(); + } +} diff --git a/1st-gen/packages/radio/src/index.ts b/1st-gen/packages/radio/src/index.ts new file mode 100644 index 00000000000..131a3065680 --- /dev/null +++ b/1st-gen/packages/radio/src/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Radio.js'; +export * from './RadioGroup.js'; diff --git a/1st-gen/packages/radio/src/radio-overrides.css b/1st-gen/packages/radio/src/radio-overrides.css new file mode 100644 index 00000000000..49dcb2a38ca --- /dev/null +++ b/1st-gen/packages/radio/src/radio-overrides.css @@ -0,0 +1,105 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-radio-button-border-color-default: var(--system-radio-button-border-color-default); + --spectrum-radio-button-border-color-hover: var(--system-radio-button-border-color-hover); + --spectrum-radio-button-border-color-down: var(--system-radio-button-border-color-down); + --spectrum-radio-button-border-color-focus: var(--system-radio-button-border-color-focus); + --spectrum-radio-neutral-content-color: var(--system-radio-neutral-content-color); + --spectrum-radio-neutral-content-color-hover: var(--system-radio-neutral-content-color-hover); + --spectrum-radio-neutral-content-color-down: var(--system-radio-neutral-content-color-down); + --spectrum-radio-neutral-content-color-focus: var(--system-radio-neutral-content-color-focus); + --spectrum-radio-focus-indicator-thickness: var(--system-radio-focus-indicator-thickness); + --spectrum-radio-focus-indicator-gap: var(--system-radio-focus-indicator-gap); + --spectrum-radio-focus-indicator-color: var(--system-radio-focus-indicator-color); + --spectrum-radio-disabled-content-color: var(--system-radio-disabled-content-color); + --spectrum-radio-disabled-border-color: var(--system-radio-disabled-border-color); + --spectrum-radio-emphasized-accent-color: var(--system-radio-emphasized-accent-color); + --spectrum-radio-emphasized-accent-color-hover: var(--system-radio-emphasized-accent-color-hover); + --spectrum-radio-emphasized-accent-color-down: var(--system-radio-emphasized-accent-color-down); + --spectrum-radio-emphasized-accent-color-focus: var(--system-radio-emphasized-accent-color-focus); + --spectrum-radio-border-width: var(--system-radio-border-width); + --spectrum-radio-button-background-color: var(--system-radio-button-background-color); + --spectrum-radio-button-checked-border-color-default: var(--system-radio-button-checked-border-color-default); + --spectrum-radio-button-checked-border-color-hover: var(--system-radio-button-checked-border-color-hover); + --spectrum-radio-button-checked-border-color-down: var(--system-radio-button-checked-border-color-down); + --spectrum-radio-button-checked-border-color-focus: var(--system-radio-button-checked-border-color-focus); + --spectrum-radio-line-height: var(--system-radio-line-height); + --spectrum-radio-animation-duration: var(--system-radio-animation-duration); + --spectrum-radio-height: var(--system-radio-height); + --spectrum-radio-button-control-size: var(--system-radio-button-control-size); + --spectrum-radio-text-to-control: var(--system-radio-text-to-control); + --spectrum-radio-label-top-to-text: var(--system-radio-label-top-to-text); + --spectrum-radio-label-bottom-to-text: var(--system-radio-label-bottom-to-text); + --spectrum-radio-button-top-to-control: var(--system-radio-button-top-to-control); + --spectrum-radio-font-size: var(--system-radio-font-size); +} + +:host(:lang(ja)) { + --spectrum-radio-line-height-cjk: var(--system-radio-lang-ja-line-height-cjk); +} + +:host(:lang(zh)) { + --spectrum-radio-line-height-cjk: var(--system-radio-lang-zh-line-height-cjk); +} + +:host(:lang(ko)) { + --spectrum-radio-line-height-cjk: var(--system-radio-lang-ko-line-height-cjk); +} + +:host { + --spectrum-radio-height: var(--system-radio-size-m-height); + --spectrum-radio-button-control-size: var(--system-radio-size-m-button-control-size); + --spectrum-radio-text-to-control: var(--system-radio-size-m-text-to-control); + --spectrum-radio-label-top-to-text: var(--system-radio-size-m-label-top-to-text); + --spectrum-radio-label-bottom-to-text: var(--system-radio-size-m-label-bottom-to-text); + --spectrum-radio-button-top-to-control: var(--system-radio-size-m-button-top-to-control); + --spectrum-radio-font-size: var(--system-radio-size-m-font-size); +} + +:host([size="s"]) { + --spectrum-radio-height: var(--system-radio-size-s-height); + --spectrum-radio-button-control-size: var(--system-radio-size-s-button-control-size); + --spectrum-radio-text-to-control: var(--system-radio-size-s-text-to-control); + --spectrum-radio-label-top-to-text: var(--system-radio-size-s-label-top-to-text); + --spectrum-radio-label-bottom-to-text: var(--system-radio-size-s-label-bottom-to-text); + --spectrum-radio-button-top-to-control: var(--system-radio-size-s-button-top-to-control); + --spectrum-radio-font-size: var(--system-radio-size-s-font-size); +} + +:host([size="l"]) { + --spectrum-radio-height: var(--system-radio-size-l-height); + --spectrum-radio-button-control-size: var(--system-radio-size-l-button-control-size); + --spectrum-radio-text-to-control: var(--system-radio-size-l-text-to-control); + --spectrum-radio-label-top-to-text: var(--system-radio-size-l-label-top-to-text); + --spectrum-radio-label-bottom-to-text: var(--system-radio-size-l-label-bottom-to-text); + --spectrum-radio-button-top-to-control: var(--system-radio-size-l-button-top-to-control); + --spectrum-radio-font-size: var(--system-radio-size-l-font-size); +} + +:host([size="xl"]) { + --spectrum-radio-height: var(--system-radio-size-xl-height); + --spectrum-radio-button-control-size: var(--system-radio-size-xl-button-control-size); + --spectrum-radio-text-to-control: var(--system-radio-size-xl-text-to-control); + --spectrum-radio-label-top-to-text: var(--system-radio-size-xl-label-top-to-text); + --spectrum-radio-label-bottom-to-text: var(--system-radio-size-xl-label-bottom-to-text); + --spectrum-radio-button-top-to-control: var(--system-radio-size-xl-button-top-to-control); + --spectrum-radio-font-size: var(--system-radio-size-xl-font-size); +} + +:host([emphasized]) { + --spectrum-radio-button-checked-border-color-default: var(--system-radio-emphasized-button-checked-border-color-default); + --spectrum-radio-button-checked-border-color-hover: var(--system-radio-emphasized-button-checked-border-color-hover); + --spectrum-radio-button-checked-border-color-down: var(--system-radio-emphasized-button-checked-border-color-down); + --spectrum-radio-button-checked-border-color-focus: var(--system-radio-emphasized-button-checked-border-color-focus); +} diff --git a/1st-gen/packages/radio/src/radio.css b/1st-gen/packages/radio/src/radio.css new file mode 100644 index 00000000000..892d6fd2353 --- /dev/null +++ b/1st-gen/packages/radio/src/radio.css @@ -0,0 +1,33 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-radio.css"); +@import url("./radio-overrides.css"); + +:host(:focus) { + outline: none; +} + +:host([disabled]) { + pointer-events: none; +} + +/** + * Work around for https://github.com/adobe/spectrum-css/issues/2251 + **/ +:host([dir="rtl"]) #button:after { + transform: translateX(50%) translateY(-50%); +} + +/** + * End workaround + **/ diff --git a/1st-gen/packages/radio/src/spectrum-radio.css b/1st-gen/packages/radio/src/spectrum-radio.css new file mode 100644 index 00000000000..9bffd22f1e1 --- /dev/null +++ b/1st-gen/packages/radio/src/spectrum-radio.css @@ -0,0 +1,235 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@media (forced-colors: active) { + :host { + --highcontrast-radio-neutral-content-color: CanvasText; + --highcontrast-radio-neutral-content-color-hover: CanvasText; + --highcontrast-radio-neutral-content-color-down: CanvasText; + --highcontrast-radio-neutral-content-color-focus: CanvasText; + --highcontrast-radio-button-border-color-default: ButtonText; + --highcontrast-radio-button-border-color-hover: Highlight; + --highcontrast-radio-button-border-color-down: ButtonText; + --highcontrast-radio-button-border-color-focus: Highlight; + --highcontrast-radio-emphasized-accent-color: ButtonText; + --highcontrast-radio-emphasized-accent-color-hover: Highlight; + --highcontrast-radio-emphasized-accent-color-down: ButtonText; + --highcontrast-radio-emphasized-accent-color-focus: Highlight; + --highcontrast-radio-button-checked-border-color-default: Highlight; + --highcontrast-radio-button-checked-border-color-hover: Highlight; + --highcontrast-radio-button-checked-border-color-down: Highlight; + --highcontrast-radio-button-checked-border-color-focus: Highlight; + --highcontrast-radio-disabled-content-color: GrayText; + --highcontrast-radio-disabled-border-color: GrayText; + --highcontrast-radio-focus-indicator-color: CanvasText; + } + + #button:after { + forced-color-adjust: none; + } +} + +:host { + vertical-align: top; + min-block-size: var(--mod-radio-height, var(--spectrum-radio-height)); + max-inline-size: 100%; + align-items: flex-start; + display: inline-flex; + position: relative; +} + +:host(:active) #button:before { + border-color: var(--highcontrast-radio-button-border-color-down, var(--mod-radio-button-border-color-down, var(--spectrum-radio-button-border-color-down))); +} + +:host(:active[checked]) #input + #button:before { + border-color: var(--highcontrast-radio-button-checked-border-color-down, var(--mod-radio-button-checked-border-color-down, var(--spectrum-radio-button-checked-border-color-down))); +} + +:host(:active) #label { + color: var(--highcontrast-radio-neutral-content-color-down, var(--mod-radio-neutral-content-color-down, var(--spectrum-radio-neutral-content-color-down))); +} + +:host(:focus-visible) #button:before { + border-color: var(--highcontrast-radio-button-border-color-focus, var(--mod-radio-button-border-color-focus, var(--spectrum-radio-button-border-color-focus))); +} + +:host(:focus-visible) #button:after { + border-style: solid; + border-color: var(--highcontrast-radio-focus-indicator-color, var(--mod-radio-focus-indicator-color, var(--spectrum-radio-focus-indicator-color))); + border-width: var(--mod-radio-focus-indicator-thickness, var(--spectrum-radio-focus-indicator-thickness)); + inline-size: calc(var(--spectrum-radio-button-control-size) + var(--spectrum-radio-focus-indicator-gap) * 2); + block-size: calc(var(--spectrum-radio-button-control-size) + var(--spectrum-radio-focus-indicator-gap) * 2); +} + +:host(:focus-visible[checked]) #input + #button:before { + border-color: var(--highcontrast-radio-button-checked-border-color-focus, var(--mod-radio-button-checked-border-color-focus, var(--spectrum-radio-button-checked-border-color-focus))); +} + +:host(:focus-visible) #label { + color: var(--highcontrast-radio-neutral-content-color-focus, var(--mod-radio-neutral-content-color-focus, var(--spectrum-radio-neutral-content-color-focus))); +} + +:host([readonly]) #input:read-only { + cursor: auto; +} + +:host([readonly]) #button { + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(50%); + position: fixed; + inset-block-end: 100%; + inset-inline-end: 100%; +} + +:host([readonly][checked][disabled]) #input ~ #label, +:host([readonly][disabled]) #input ~ #label, +:host([readonly]) #label { + color: var(--highcontrast-radio-neutral-content-color, var(--mod-radio-neutral-content-color, var(--spectrum-radio-neutral-content-color))); + margin-inline-start: 0; +} + +:host([emphasized][checked]) #input + #button:before { + border-color: var(--highcontrast-radio-emphasized-accent-color, var(--mod-radio-emphasized-accent-color, var(--spectrum-radio-emphasized-accent-color))); +} + +@media (hover: hover) { + :host(:hover) #button:before { + border-color: var(--highcontrast-radio-button-border-color-hover, var(--mod-radio-button-border-color-hover, var(--spectrum-radio-button-border-color-hover))); + } + + :host([checked]:hover) #input + #button:before { + border-color: var(--highcontrast-radio-button-checked-border-color-hover, var(--mod-radio-button-checked-border-color-hover, var(--spectrum-radio-button-checked-border-color-hover))); + } + + :host(:hover) #label { + color: var(--highcontrast-radio-neutral-content-color-hover, var(--mod-radio-neutral-content-color-hover, var(--spectrum-radio-neutral-content-color-hover))); + } + + :host([emphasized][checked]:hover) #input + #button:before { + border-color: var(--highcontrast-radio-emphasized-accent-color-hover, var(--mod-radio-emphasized-accent-color-hover, var(--spectrum-radio-emphasized-accent-color-hover))); + } +} + +:host([emphasized]:active[checked]) #input + #button:before { + border-color: var(--highcontrast-radio-emphasized-accent-color-down, var(--mod-radio-emphasized-accent-color-down, var(--spectrum-radio-emphasized-accent-color-down))); +} + +:host([emphasized]:focus-visible[checked]) #input + #button:before { + border-color: var(--highcontrast-radio-emphasized-accent-color-focus, var(--mod-radio-emphasized-accent-color-focus, var(--spectrum-radio-emphasized-accent-color-focus))); +} + +:host([checked][disabled]) #input + #button:before, +:host([disabled]) #input + #button:before { + border-color: var(--highcontrast-radio-disabled-border-color, var(--mod-radio-disabled-border-color, var(--spectrum-radio-disabled-border-color))); +} + +:host([checked][disabled]) #input ~ #label, +:host([disabled]) #input ~ #label { + color: var(--highcontrast-radio-disabled-content-color, var(--mod-radio-disabled-content-color, var(--spectrum-radio-disabled-content-color))); +} + +#input { + font-family: inherit; + font-size: 100%; + line-height: var(--mod-radio-line-height, var(--spectrum-radio-line-height)); + box-sizing: border-box; + inline-size: 100%; + block-size: 100%; + opacity: 0; + z-index: 1; + cursor: pointer; + margin: 0; + padding: 0; + position: absolute; + overflow: visible; +} + +:host([disabled]) #input { + cursor: default; +} + +:host([checked]) #input + #button:before { + border-width: calc(var(--spectrum-radio-button-control-size) / 2 - var(--spectrum-radio-button-selection-indicator) / 2); + border-color: var(--highcontrast-radio-button-checked-border-color-default, var(--mod-radio-button-checked-border-color-default, var(--spectrum-radio-button-checked-border-color-default))); +} + +#input:focus-visible + #button:after { + border-width: var(--mod-radio-focus-indicator-thickness, var(--spectrum-radio-focus-indicator-thickness)); + border-color: var(--highcontrast-radio-focus-indicator-color, var(--mod-radio-focus-indicator-color, var(--spectrum-radio-focus-indicator-color))); + inline-size: calc(var(--spectrum-radio-button-control-size) + var(--spectrum-radio-focus-indicator-gap) * 2); + block-size: calc(var(--spectrum-radio-button-control-size) + var(--spectrum-radio-focus-indicator-gap) * 2); + border-style: solid; +} + +#label { + text-align: start; + font-size: var(--mod-radio-font-size, var(--spectrum-radio-font-size)); + color: var(--highcontrast-radio-neutral-content-color, var(--mod-radio-neutral-content-color, var(--spectrum-radio-neutral-content-color))); + line-height: var(--mod-radio-line-height, var(--spectrum-radio-line-height)); + transition: color var(--mod-radio-animation-duration, var(--spectrum-radio-animation-duration)) ease-in-out; + margin-block-start: var(--spectrum-radio-label-top-to-text); + margin-block-end: var(--spectrum-radio-label-bottom-to-text); + margin-inline-start: var(--mod-radio-text-to-control, var(--spectrum-radio-text-to-control)); +} + +#label:lang(ja), +#label:lang(ko), +#label:lang(zh) { + line-height: var(--mod-radio-line-height-cjk, var(--spectrum-radio-line-height-cjk)); +} + +#button { + box-sizing: border-box; + inline-size: var(--mod-radio-button-control-size, var(--spectrum-radio-button-control-size)); + block-size: var(--mod-radio-button-control-size, var(--spectrum-radio-button-control-size)); + flex-grow: 0; + flex-shrink: 0; + margin-block-start: var(--mod-radio-button-top-to-control, var(--spectrum-radio-button-top-to-control)); + position: relative; +} + +#button:before { + z-index: 0; + content: ""; + box-sizing: border-box; + inline-size: var(--mod-radio-button-control-size, var(--spectrum-radio-button-control-size)); + block-size: var(--mod-radio-button-control-size, var(--spectrum-radio-button-control-size)); + background-color: var(--highcontrast-radio-button-background-color, var(--mod-radio-button-background-color, var(--spectrum-radio-button-background-color))); + border-width: var(--mod-radio-border-width, var(--spectrum-radio-border-width)); + border-color: var(--highcontrast-radio-button-border-color-default, var(--mod-radio-button-border-color-default, var(--spectrum-radio-button-border-color-default))); + transition: + border var(--mod-radio-animation-duration, var(--spectrum-radio-animation-duration)) ease-in-out, + box-shadow var(--mod-radio-animation-duration, var(--spectrum-radio-animation-duration)) ease-in-out; + border-style: solid; + border-radius: 50%; + display: block; + position: absolute; +} + +#button:after { + content: ""; + transition: + opacity var(--mod-radio-animation-duration, var(--spectrum-radio-animation-duration)) ease-out, + margin var(--mod-radio-animation-duration, var(--spectrum-radio-animation-duration)) ease-out; + border-radius: 50%; + display: block; + position: absolute; + inset-block-start: 50%; + inset-inline-start: 50%; + transform: translateX(-50%) translateY(-50%); +} + +:host:dir(rtl) #button:after, +:host([dir="rtl"]) #button:after { + transform: translateX(50%) translateY(-50%); +} diff --git a/1st-gen/packages/radio/stories/radio-sizes.stories.ts b/1st-gen/packages/radio/stories/radio-sizes.stories.ts new file mode 100644 index 00000000000..3b37729080a --- /dev/null +++ b/1st-gen/packages/radio/stories/radio-sizes.stories.ts @@ -0,0 +1,92 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { TemplateResult } from '@spectrum-web-components/base'; +import { Default, StoryArgs } from './radio.stories.js'; + +export default { + component: 'sp-radio', + title: 'Radio/Sizes', + argTypes: { + checked: { + name: 'checked', + type: { name: 'boolean', required: false }, + description: 'Represents when the input is checked', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: 'boolean', + }, + disabled: { + name: 'disabled', + type: { name: 'boolean', required: false }, + description: + 'Disable this control. It will not receive focus or events.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + emphasized: { + name: 'emphasized', + type: { name: 'boolean', required: false }, + description: "Set the button's state to emphasized.", + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + invalid: { + name: 'invalid', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + }, + args: { + checked: false, + disabled: false, + emphasized: false, + invalid: false, + }, +}; + +export const s = (args: StoryArgs): TemplateResult => Default(args); +s.args = { + size: 's', +}; + +export const m = (args: StoryArgs): TemplateResult => Default(args); +m.args = { + size: 'm', +}; + +export const l = (args: StoryArgs): TemplateResult => Default(args); +l.args = { + size: 'l', +}; + +export const XL = (args: StoryArgs): TemplateResult => Default(args); +XL.args = { + size: 'xl', +}; diff --git a/1st-gen/packages/radio/stories/radio.stories.ts b/1st-gen/packages/radio/stories/radio.stories.ts new file mode 100644 index 00000000000..57be13d3997 --- /dev/null +++ b/1st-gen/packages/radio/stories/radio.stories.ts @@ -0,0 +1,183 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/radio/sp-radio.js'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +import { spreadProps } from '../../../test/lit-helpers.js'; + +export default { + component: 'sp-radio', + title: 'Radio', + argTypes: { + checked: { + name: 'checked', + type: { name: 'boolean', required: false }, + description: 'Represents when the input is checked', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: 'boolean', + }, + disabled: { + name: 'disabled', + type: { name: 'boolean', required: false }, + description: + 'Disable this control. It will not receive focus or events.', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + emphasized: { + name: 'emphasized', + type: { name: 'boolean', required: false }, + description: "Set the button's state to emphasized.", + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + invalid: { + name: 'invalid', + type: { name: 'boolean', required: false }, + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + }, + }, + args: { + checked: false, + disabled: false, + emphasized: false, + invalid: false, + }, +}; + +export interface StoryArgs { + checked?: boolean; + disabled?: boolean; + emphasized?: boolean; + invalid?: boolean; + readonly?: boolean; + size?: 's' | 'm' | 'l' | 'xl'; + [prop: string]: unknown; +} + +function renderRadio(args: StoryArgs): TemplateResult { + return html` + Radio + `; +} +export const Default = (args: StoryArgs): TemplateResult => renderRadio(args); + +export const readonly = (args: StoryArgs): TemplateResult => + renderRadio({ + ...args, + readonly: true, + }); +readonly.args = { + checked: true, +}; + +export const Emphasized = (args: StoryArgs): TemplateResult => + renderRadio(args); +Emphasized.args = { + checked: true, + emphasized: true, +}; + +export const Autofocus = (args: StoryArgs): TemplateResult => { + return html` + Radio + `; +}; + +export const Invalid = (args: StoryArgs): TemplateResult => renderRadio(args); +Invalid.args = { + invalid: true, +}; + +export const Disabled = (args: StoryArgs): TemplateResult => renderRadio(args); +Disabled.args = { + disabled: true, +}; + +const values = { + first: 1, + second: 2, + third: 3, + fourth: 4, +}; + +export const groupExample = (): TemplateResult => { + return html` + + Option 1 + Option 2 + Option 3 + Option 4 + + `; +}; + +export const horizontalGroup = (): TemplateResult => { + return html` + + Option 1 + Option 2 + Option 3 + Option 4 + + `; +}; + +export const tabIndexExample = (): TemplateResult => { + return html` + + + Tab Index 0 + + Tab Index 3 + Tab Index 1 + Tab Index 4 + Tab Index 2 + + `; +}; + +export const horizontalTabIndexExample = (): TemplateResult => { + return html` + + + Tab Index 0 + + Tab Index 3 + Tab Index 1 + Tab Index 4 + Tab Index 2 + + `; +}; + +tabIndexExample.storyName = 'Tab index example'; diff --git a/1st-gen/packages/radio/test/benchmark/test-basic.ts b/1st-gen/packages/radio/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..9e61bb2af67 --- /dev/null +++ b/1st-gen/packages/radio/test/benchmark/test-basic.ts @@ -0,0 +1,24 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/radio/sp-radio-group.js'; +import '@spectrum-web-components/radio/sp-radio.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + + Option 1 + Option 2 + Option 3 + +`); diff --git a/1st-gen/packages/radio/test/radio-group.test.ts b/1st-gen/packages/radio/test/radio-group.test.ts new file mode 100644 index 00000000000..13cc1b43f2d --- /dev/null +++ b/1st-gen/packages/radio/test/radio-group.test.ts @@ -0,0 +1,674 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + elementUpdated, + expect, + fixture, + html, + nextFrame, +} from '@open-wc/testing'; +import { Radio, RadioGroup } from '@spectrum-web-components/radio'; +import '@spectrum-web-components/radio/sp-radio-group.js'; +import '@spectrum-web-components/radio/sp-radio.js'; +import { + a11ySnapshot, + findAccessibilityNode, + sendKeys, +} from '@web/test-runner-commands'; +import { spy } from 'sinon'; +import { sendMouse } from '../../../test/plugins/browser.js'; +import { + arrowDownEvent, + arrowLeftEvent, + arrowRightEvent, + arrowUpEvent, + endEvent, + enterEvent, + homeEvent, +} from '../../../test/testing-helpers.js'; + +describe('Radio Group - focus control', () => { + it('does not accept focus when empty', async () => { + const el = await fixture(html` + + `); + + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement === el).to.be.false; + }); + it('focuses selected before first', async () => { + const values = ['first', 'second', 'third']; + const el = await fixture(html` + + Option 1 + Option 2 + Option 3 + + `); + + await elementUpdated(el); + const selected = el.querySelector('[value="second"]') as Radio; + + expect(document.activeElement === el).to.be.false; + + el.focus(); + await elementUpdated(el); + + expect(document.activeElement === selected).to.be.true; + }); + it('focuses the child input not the root when [tabindex=-1]', async () => { + const values = ['first', 'second', 'third']; + const el = await fixture(html` + + Option 1 + Option 2 + Option 3 + + `); + + await elementUpdated(el); + const first = el.querySelector('[value="first"]') as Radio; + const selected = el.querySelector('[value="second"]') as Radio; + expect(selected.tabIndex).to.equal(0); + expect(first.tabIndex).to.equal(-1); + + await sendMouse([ + { + type: 'move', + position: [first, 'top-left'], + }, + { + type: 'down', + }, + ]); + await elementUpdated(el); + + // Safari can have a situation where it thinks the root is focused, but really something inside of the + // element is focused instead, this tests for both no focus on the root or focus inside of the element. + expect( + !first.matches(':focus') || first.matches(':focus-within'), + 'root should not' + ).to.be.true; + }); + it('does not select on focus', async () => { + const el = await fixture(html` + + Options 1 + Options 2 + Options 3 + Options 4 + Options 5 + + `); + + await elementUpdated(el); + + const radio1 = el.querySelector('sp-radio:nth-child(1)') as Radio; + const radio2 = el.querySelector('sp-radio:nth-child(2)') as Radio; + + expect(el.selected).to.equal(''); + + radio1.focus(); + await elementUpdated(el); + + expect(el.selected).to.equal(''); + el.selected = '1'; + await elementUpdated(el); + + expect(el.selected).to.equal('1'); + expect(radio1.checked).to.be.true; + radio2.focus(); + await elementUpdated(el); + + expect(el.selected).to.equal('1'); + expect(radio1.checked).to.be.true; + }); + it('loads accepts keyboard events while focused', async () => { + const el = await fixture(html` + + Options 1 + Options 2 + Options 3 + Options 4 + Options 5 + + `); + + await elementUpdated(el); + + const radio1 = el.querySelector('sp-radio:nth-child(1)') as Radio; + const radio2 = el.querySelector('sp-radio:nth-child(2)') as Radio; + const radio3 = el.querySelector('sp-radio:nth-child(3)') as Radio; + const radio4 = el.querySelector('sp-radio:nth-child(4)') as Radio; + const radio5 = el.querySelector('sp-radio:nth-child(5)') as Radio; + + radio1.focus(); + await elementUpdated(el); + + el.dispatchEvent(arrowRightEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio2).to.be.true; + + el.dispatchEvent(arrowDownEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio3).to.be.true; + + el.dispatchEvent(endEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio5).to.be.true; + + el.dispatchEvent(arrowLeftEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio4).to.be.true; + + el.dispatchEvent(arrowUpEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio3).to.be.true; + + el.dispatchEvent(homeEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio1).to.be.true; + + radio1.blur(); + }); + it('accepts keyboard interactions where `checked` and `calculateFocusInIndex` might conflict', async () => { + const el = await fixture(html` + + Options 1 + Options 2 + Options 3 + Options 4 + Options 5 + + `); + + await elementUpdated(el); + + const radio1 = el.querySelector('sp-radio:nth-child(1)') as Radio; + const radio5 = el.querySelector('sp-radio:nth-child(5)') as Radio; + + radio5.focus(); + await elementUpdated(el); + expect(document.activeElement === radio5).to.be.true; + expect(radio5.checked).to.be.true; + + await sendKeys({ press: 'ArrowRight' }); + await elementUpdated(el); + + expect(document.activeElement === radio1).to.be.true; + expect(radio1.checked).to.be.true; + }); + it('acknowledges `disabled` and accepts keyboard events while focused', async () => { + const el = await fixture(html` + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + + `); + + await elementUpdated(el); + + const radio2 = el.querySelector('sp-radio:nth-child(2)') as Radio; + const radio4 = el.querySelector('sp-radio:nth-child(4)') as Radio; + + radio2.focus(); + await elementUpdated(el); + expect(document.activeElement === radio2, 'start 2').to.be.true; + expect(el.selected).to.equal(''); + + el.dispatchEvent(enterEvent()); + el.dispatchEvent(endEvent()); + await elementUpdated(el); + expect(document.activeElement === radio4, 'first 4').to.be.true; + expect(el.selected).to.equal('4'); + + el.dispatchEvent(homeEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio2, 'second 2').to.be.true; + + el.dispatchEvent(arrowUpEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio4, 'third 4').to.be.true; + + el.dispatchEvent(arrowDownEvent()); + await elementUpdated(el); + + expect(document.activeElement === radio2, 'fourth 2').to.be.true; + }); +}); + +describe('Group Accessibility', () => { + it('created the expected accessibility tree', async () => { + await fixture(html` + + Option 1 + Option 2 + Option 3 + + `); + + type NamedRoledAndCheckedNode = { + name: string; + role: string; + checked: boolean; + }; + const snapshot = (await a11ySnapshot( + {} + )) as unknown as NamedRoledAndCheckedNode & { + children: NamedRoledAndCheckedNode[]; + }; + + expect( + findAccessibilityNode( + snapshot, + ( + node // Firefox uses 'group' instead of 'radiogroup' here. + ) => + (node.role === 'radiogroup' || node.role === 'group') && + node.name === 'Testing Label' + ), + 'Has a "radiogroup" with the supplied name' + ).to.not.be.null; + expect( + findAccessibilityNode( + snapshot, + (node) => + node.role === 'radio' && + node.checked && + node.name === 'Option 2' + ), + 'Has a named and checked "radio" element' + ).to.not.be.null; + expect( + findAccessibilityNode( + snapshot, + (node) => + node.name === 'Option 2' && node.role.startsWith('text') + ), + 'Does not have a text leaf named like the "radio" element' + ).to.be.null; + }); +}); + +describe('Radio Group', () => { + let testDiv!: HTMLDivElement; + + beforeEach(async () => { + testDiv = await fixture(html` +
+ + Option 1 + Option 2 + Option 3 + + + Option 1 + Option 2 + Option 3 + + + Option 1 + Option 2 + + + Option 1 + Option 2 + + + Option 1 + Option 2 + Option 3 + + + Option 1 + Option 2 + Option 3 + + + Option 1 + Option 2 + + + Option 5 + Option 7 + + + Option 1 + Option 2 + Option 3 + +
+ `); + }); + + it('loads', () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-default' + ) as RadioGroup; + const radioChildren = radioGroup.querySelectorAll('sp-radio'); + + expect(radioGroup).to.exist; + expect(radioChildren.length).to.equal(3); + }); + + it('loads accessibly', async () => { + await expect(testDiv).to.be.accessible(); + }); + + it('validates selection', async () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-none-selected' + ) as RadioGroup; + expect(radioGroup.selected).to.equal(''); + + radioGroup.selected = 'missing'; + await elementUpdated(radioGroup); + + expect(radioGroup.selected).to.equal(''); + }); + + it('can have selection prevented', async () => { + const el = testDiv.querySelector( + 'sp-radio-group#test-default' + ) as RadioGroup; + const secondRadio = el.querySelector('sp-radio[value=second]') as Radio; + const thirdRadio = el.querySelector('sp-radio[value=third]') as Radio; + + await elementUpdated(el); + expect(el.selected).to.equal('first'); + + secondRadio.click(); + + await elementUpdated(el); + expect(el.selected).to.equal('second'); + + el.addEventListener('change', (event) => event.preventDefault()); + + thirdRadio.click(); + + await elementUpdated(el); + expect(el.selected).to.equal('second'); + }); + + it('reflects checked radio with selected property', async () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-default' + ) as RadioGroup; + const firstRadio = radioGroup.querySelector( + 'sp-radio[value=first]' + ) as Radio; + const secondRadio = radioGroup.querySelector( + 'sp-radio[value=second]' + ) as Radio; + const thirdRadio = radioGroup.querySelector( + 'sp-radio[value=third]' + ) as Radio; + + expect(firstRadio.checked).to.be.true; + expect(secondRadio.checked).to.be.false; + expect(thirdRadio.checked).to.be.false; + expect(radioGroup.selected).to.equal(firstRadio.value); + + secondRadio.click(); + await elementUpdated(radioGroup); + + expect(firstRadio.checked).to.be.false; + expect(secondRadio.checked).to.be.true; + expect(thirdRadio.checked).to.be.false; + expect(radioGroup.selected).to.equal(secondRadio.value); + + thirdRadio.click(); + await elementUpdated(radioGroup); + + expect(firstRadio.checked).to.be.false; + expect(secondRadio.checked).to.be.false; + expect(thirdRadio.checked).to.be.true; + expect(radioGroup.selected).to.equal(thirdRadio.value); + }); + + it('forces only one radio to be checked', () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-multiple-checked' + ) as RadioGroup; + const checkedRadios = radioGroup.querySelectorAll('sp-radio[checked]'); + + expect(radioGroup.selected).to.equal('first'); + expect(checkedRadios.length).to.equal(1); + }); + + it('respects clicking on disabled attribute causing nothing to happen', async () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-disabled' + ) as RadioGroup; + const checkedRadio = radioGroup.querySelector( + 'sp-radio[checked]' + ) as Radio; + const disabledRadio = radioGroup.querySelector( + 'sp-radio[disabled]' + ) as Radio; + + disabledRadio.click(); + await elementUpdated(radioGroup); + + expect(disabledRadio.checked).to.be.false; + expect(checkedRadio.checked).to.be.true; + expect(radioGroup.selected).to.equal(checkedRadio.value); + }); + + it('de-checks all but first checked radio if multiple checked', () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-multiple-checked' + ) as RadioGroup; + const radio1 = radioGroup.querySelector( + 'sp-radio[value=first]' + ) as Radio; + const radio2 = radioGroup.querySelector( + 'sp-radio[value=second]' + ) as Radio; + + expect(radioGroup.selected).to.equal('first'); + expect(radio1.checked).to.be.true; + expect(radio2.checked).to.be.false; + }); + + it('ensures setting selection updates checked radio', async () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-selected' + ) as RadioGroup; + const radio1 = radioGroup.querySelector( + 'sp-radio[value=first]' + ) as Radio; + const radio2 = radioGroup.querySelector( + 'sp-radio[value=second]' + ) as Radio; + const radio3 = radioGroup.querySelector( + 'sp-radio[value=third]' + ) as Radio; + + expect(radioGroup.selected).to.equal('third'); + expect(radio1.checked).to.be.false; + expect(radio2.checked).to.be.false; + expect(radio3.checked, 'initial').to.be.true; + + radioGroup.selected = 'second'; + await elementUpdated(radioGroup); + + expect(radioGroup.selected).to.equal('second'); + expect(radio1.checked).to.be.false; + expect(radio2.checked, 'second').to.be.true; + expect(radio3.checked).to.be.false; + + radioGroup.selected = 'first'; + await elementUpdated(radioGroup); + + expect(radioGroup.selected).to.equal('first'); + expect(radio1.checked, 'third').to.be.true; + expect(radio2.checked).to.be.false; + expect(radio3.checked).to.be.false; + }); + + it('ensures setting selected and clicking on radio both work together', async () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-selected-click' + ) as RadioGroup; + const radio1 = radioGroup.querySelector( + 'sp-radio[value=first]' + ) as Radio; + const radio2 = radioGroup.querySelector( + 'sp-radio[value=second]' + ) as Radio; + const radio3 = radioGroup.querySelector( + 'sp-radio[value=third]' + ) as Radio; + + expect(radioGroup.selected).to.equal('third'); + radio2.click(); + await elementUpdated(radioGroup); + + expect(radioGroup.selected).to.equal('second'); + expect(radio1.checked).to.be.false; + expect(radio2.checked).to.be.true; + expect(radio3.checked).to.be.false; + + radioGroup.selected = 'first'; + await elementUpdated(radioGroup); + + expect(radioGroup.selected).to.equal('first'); + expect(radio1.checked, 'moved to checked').to.be.true; + expect(radio2.checked).to.be.false; + expect(radio3.checked).to.be.false; + }); + + it('prioritizes checked over selected on initialization when conflicting', () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-checked-prioritized' + ) as RadioGroup; + const radio1 = radioGroup.querySelector( + 'sp-radio[value=first]' + ) as Radio; + const radio2 = radioGroup.querySelector( + 'sp-radio[value=second]' + ) as Radio; + + expect(radioGroup.selected).to.equal('first'); + expect(radio1.checked).to.be.true; + expect(radio2.checked).to.be.false; + }); + + it('handles integer values for radio buttons', () => { + const radioGroup = testDiv.querySelector( + 'sp-radio-group#test-integer-value' + ) as RadioGroup; + expect(radioGroup.selected).to.equal('5'); + }); + + it('prevents `change` events from radio buttons', async () => { + const changeSpy = spy(); + const onChange = (event: Event & { target: RadioGroup }): void => { + changeSpy(event.target.selected); + }; + const el = await fixture(html` + + Bulbasaur + Squirtle + Charmander + + `); + + const bulbasaur = el.querySelector('[value="bulbasaur"]') as Radio; + const charmander = el.querySelector('[value="charmander"]') as Radio; + bulbasaur.click(); + bulbasaur.click(); + charmander.click(); + + expect(changeSpy.calledWith(undefined)).to.be.false; + }); +}); + +describe('Radio Group - late children', () => { + it('accepts frame late children', async () => { + /** + * In some cases (e.g. when wrapped in React components) will cause otherwise standard looking + * DOM structures to add `` children to `` parents in a non-syncronous manner. + * + * This test emulates that render process to ensure that validation will still work as expect in that context. + */ + const test = await fixture(html` +
+ Bulbasaur + Squirtle + Charmander + Other +
+ `); + const group = document.createElement('sp-radio-group'); + const buttons = [...test.querySelectorAll('sp-radio')] as Radio[]; + + test.append(group); + group.selected = 'first'; + Promise.resolve().then(function () { + group.append(...buttons); + }); + await nextFrame(); + await nextFrame(); + + expect(group.buttons.length).to.equal(4); + expect(group.selected).to.equal('first'); + }); + it('emits change events on arrow key events', async () => { + const changeSpy = spy(); + const onChange = (event: Event & { target: RadioGroup }): void => { + changeSpy(event.target.selected); + }; + const el = await fixture(html` + + Bulbasaur + Squirtle + Charmander + + `); + const bulbasaur = el.querySelector('[value="bulbasaur"]') as Radio; + const squirtle = el.querySelector('[value="squirtle"]') as Radio; + + bulbasaur.focus(); + await elementUpdated(el); + expect(changeSpy.callCount).to.equal(0); + + el.dispatchEvent(arrowRightEvent()); + await elementUpdated(el); + expect(changeSpy.callCount).to.equal(1); + expect(document.activeElement === squirtle).to.be.true; + + el.dispatchEvent(arrowLeftEvent()); + await elementUpdated(el); + expect(changeSpy.callCount).to.equal(2); + expect(document.activeElement === bulbasaur).to.be.true; + }); +}); diff --git a/1st-gen/packages/radio/test/radio-memory.test.ts b/1st-gen/packages/radio/test/radio-memory.test.ts new file mode 100644 index 00000000000..9710e03575b --- /dev/null +++ b/1st-gen/packages/radio/test/radio-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/radio/sp-radio.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/radio/test/radio.test.ts b/1st-gen/packages/radio/test/radio.test.ts new file mode 100644 index 00000000000..840131da2eb --- /dev/null +++ b/1st-gen/packages/radio/test/radio.test.ts @@ -0,0 +1,181 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + elementUpdated, + expect, + fixture, + html, + triggerBlurFor, + waitUntil, +} from '@open-wc/testing'; +import { Radio } from '@spectrum-web-components/radio'; +import '@spectrum-web-components/radio/sp-radio.js'; +import { sendKeys } from '@web/test-runner-commands'; +import { sendMouse } from '../../../test/plugins/browser.js'; + +function labelNodeForRadio(radio: Radio): Node { + if (!radio.shadowRoot) throw new Error('No shadowRoot'); + const slotEl = radio.shadowRoot.querySelector('slot') as HTMLSlotElement; + + return slotEl.assignedNodes()[0]; +} + +describe('Radio', () => { + let testDiv!: HTMLDivElement; + + beforeEach(async () => { + testDiv = await fixture(html` +
+ Option 1 + Option 2 + Option 3 + Option 4 +
+ `); + }); + it('loads', async () => { + const el = testDiv.querySelector('sp-radio[value=first]') as Radio; + const textNode = labelNodeForRadio(el as Radio); + + expect(el).to.not.equal(undefined); + expect(el.innerText).to.equal('Option 1'); + expect(textNode.textContent).to.equal('Option 1'); + }); + + it('loads accessibly', async () => { + await expect(testDiv).to.be.accessible(); + }); + + it('respects checked attribute', () => { + const el1 = document.querySelector('[value=first]') as Radio; + const el2 = testDiv.querySelector('[value=second]') as Radio; + + expect(el1.checked).to.be.true; + expect(el2.checked).to.be.false; + }); + + it('handles click events', async () => { + let value = ''; + let checked = false; + const el = testDiv.querySelector('[value=third]') as Radio; + el.addEventListener('change', (event) => { + const target = event.target as Radio; + value = target.value; + checked = target.checked; + }); + + expect(el.checked).to.be.false; + expect(value).to.equal(''); + expect(checked).to.be.false; + + el.click(); + await elementUpdated(el); + + expect(el.checked).to.be.true; + expect(value).to.equal('third'); + expect(checked).to.be.true; + }); + + it('autofocuses', async () => { + const autoElement = testDiv.querySelector( + 'sp-radio[autofocus]' + ) as Radio; + + expect(autoElement).to.exist; + await waitUntil( + () => document.activeElement === autoElement, + 'Autofocused' + ); + + await triggerBlurFor(autoElement); + + expect(document.activeElement).to.not.equal(autoElement); + }); + + it('ensures clicking disabled does not check them', async () => { + const el = testDiv.querySelector('sp-radio[disabled]') as Radio; + + expect(el.checked).to.be.false; + + el.click(); + await elementUpdated(el); + + expect(el.checked).to.be.false; + }); + + it('renders [invalid]', async () => { + const el = await fixture(html` + Component + `); + + expect(el.getAttribute('aria-invalid')).to.equal('true'); + }); + + describe('accepts "clicks"', () => { + let el!: Radio; + beforeEach(async () => { + el = await fixture(html` + Component + `); + }); + it('imperatively', async () => { + el.click(); + await elementUpdated(el); + + expect(el.checked).to.be.true; + }); + it('as events', async () => { + el.dispatchEvent(new Event('click')); + await elementUpdated(el); + + expect(el.checked).to.be.true; + }); + it('from the keyboard', async () => { + el.focus(); + await elementUpdated(el); + await sendKeys({ press: 'Space' }); + await elementUpdated(el); + + expect(el.checked).to.be.true; + }); + it('imperatively', async () => { + await sendMouse([ + { + type: 'move', + position: [el], + }, + { + type: 'down', + }, + { + type: 'up', + }, + ]); + await elementUpdated(el); + + expect(el.checked).to.be.true; + }); + }); + + it('maintains its value when [readonly]', async () => { + const el = await fixture(html` + Component + `); + expect(el.checked).to.be.true; + + el.click(); + await elementUpdated(el); + + expect(el.checked).to.be.true; + }); +}); diff --git a/1st-gen/packages/radio/tsconfig.json b/1st-gen/packages/radio/tsconfig.json new file mode 100644 index 00000000000..16064d9bf28 --- /dev/null +++ b/1st-gen/packages/radio/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../../tools/shared" }, { "path": "../field-group" }] +} diff --git a/1st-gen/packages/search/.npmrc b/1st-gen/packages/search/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/search/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/search/CHANGELOG.md b/1st-gen/packages/search/CHANGELOG.md new file mode 100644 index 00000000000..c577f8f5ede --- /dev/null +++ b/1st-gen/packages/search/CHANGELOG.md @@ -0,0 +1,872 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8), [`bdf54c1`](https://github.com/adobe/spectrum-web-components/commit/bdf54c1bc6d3eb20da1a1bf3b40650e6ab1ba399), [`72d807c`](https://github.com/adobe/spectrum-web-components/commit/72d807c75d04b0fec1794a8d3e68383ca61d9e4c), [`14ebeb9`](https://github.com/adobe/spectrum-web-components/commit/14ebeb9e8a24de9c9a80e7f3f0babd19a34e8179)]: + - @spectrum-web-components/button@1.9.0 + - @spectrum-web-components/icons-workflow@1.9.0 + - @spectrum-web-components/textfield@1.9.0 + - @spectrum-web-components/icon@1.9.0 + - @spectrum-web-components/base@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies [[`15be17d`](https://github.com/adobe/spectrum-web-components/commit/15be17db91f1140ccf3cad52b1f2ed6c4b9e28ba)]: + - @spectrum-web-components/button@1.8.0 + - @spectrum-web-components/icon@1.8.0 + - @spectrum-web-components/icons-workflow@1.8.0 + - @spectrum-web-components/textfield@1.8.0 + - @spectrum-web-components/base@1.8.0 + +## 1.7.0 + +### Patch Changes + +- Updated dependencies [[`cde976d`](https://github.com/adobe/spectrum-web-components/commit/cde976ddfa71f898e2d0404ecc53150db149a861)]: + - @spectrum-web-components/textfield@1.7.0 + - @spectrum-web-components/button@1.7.0 + - @spectrum-web-components/icon@1.7.0 + - @spectrum-web-components/icons-workflow@1.7.0 + - @spectrum-web-components/base@1.7.0 + +## 1.6.0 + +### Patch Changes + +- [#5157](https://github.com/adobe/spectrum-web-components/pull/5157) [`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - # Release Note + + ## Infield Button + + ### 6.1.2 + - [#3615](https://github.com/adobe/spectrum-css/pull/3615) [`f09c84a`](https://github.com/adobe/spectrum-css/commit/f09c84ae9922d67b6fe237d693afee0fab53fa67) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - ### Infield button fast follows + - Updated infield button disabled border color to use `-spectrum-gray-300` for spectrum-two theme and `-spectrum-gray-200` for other themes. + + ### 6.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 6.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/icon@9.1.0 + - @spectrum-css/tokens@16.0.1 + + ## Number Field + + Bump @spectrum-css/stepper to 7.1.3 + + ### 7.1.3 + - [#3621](https://github.com/adobe/spectrum-css/pull/3621) [`3aec28a`](https://github.com/adobe/spectrum-css/commit/3aec28aac60bdf32a585fa8ff38559d80b57ff86) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - Updates `-spectrum-stepper-buttons-border-color-keyboard-focus` from `gray-900` to `gray-800` to match the rest of the border color on keyboardFocus. + + ### 7.1.2 + + 📝 [#3594](https://github.com/adobe/spectrum-css/pull/3594) [`6200a63`](https://github.com/adobe/spectrum-css/commit/6200a63f2c7dc1d2b0481c33b17c86427726c0bd) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updates Stepper's key-focus border color (`-spectrum-stepper-border-color-keyboard-focus`) to `-spectrum-gray-800`. + + ### 7.1.1 + + 📝 [#3536](https://github.com/adobe/spectrum-css/pull/3536) [`f77aa72`](https://github.com/adobe/spectrum-css/commit/f77aa72486f98c7b7d4f449c0d54fb6801881b7e) Thanks [@marissahuysentruyt](https://github.com/marissahuysentruyt)! + - S2 Foundations fixes + - Adjusts the background-color of the infield button components within stepper to use `gray-100` as opposed to `gray-25`. + - This corresponds to the background-color updates picker has for S2. + - Corrects the border color for the default picker for S2 foundations, using `gray-500` (instead of `gray-800`) to align with other field/form components. + - Refactors the `&.is-keyboardFocused&.is-placeholder` selector to `&.is-keyboardFocused.spectrum-Picker-label.is-placeholder` to avoid unexpectedly targeting the nested placeholder class. + + ### 7.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/actionbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/infieldbutton@7.0.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Textfield + + ### 8.1.1 + + 📝 [#3575](https://github.com/adobe/spectrum-css/pull/3575) [`2e17d10`](https://github.com/adobe/spectrum-css/commit/2e17d109ebec3c2745c32a15840af5c636c8dc5d) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + - Updated border color on keyboard focus state for textfield in spectrum-two theme. + + ### 8.1.0 + + 📝 [#3539](https://github.com/adobe/spectrum-css/pull/3539) [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! + - Updates invalid icon spacing to be vertically centered for S2. + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + - Dependency alignment across the project. + + Set component peerDependencies as optional to reduce console warnings on downstream projects. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/helptext@8.0.0 + - @spectrum-css/tokens@16.0.1 + + ## Search + + ### 8.1.2 + - [#3658](https://github.com/adobe/spectrum-css/pull/3658) [`e9fde67`](https://github.com/adobe/spectrum-css/commit/e9fde67bf341798a6ab34f227b2e7a417d1e5da7) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! - Change S2 theme border color to gray-800 on keyfocus per design request in order to align with text field. + + ### 8.1.1 + + 📝 [#3593](https://github.com/adobe/spectrum-css/pull/3593) [`d829abb`](https://github.com/adobe/spectrum-css/commit/d829abb44f1eaa1874090e52caee553d776684e7) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! + + Updated `--spectrum-search-background-color-disabled` to `--spectrum-gray-25` and `--spectrum-search-border-color-disabled` to `--spectrum-gray-300` for the S2 foundations contexts. + + Also defines disabled quiet border and background colors (`--system-search-quiet-background-color-disabled` and `--system-search-quiet-border-color-disabled`) in order to maintain disabled quiet styling. + + ### 8.1.0 + + 📝 [#3541](https://github.com/adobe/spectrum-css/pull/3541) [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d) Thanks [@castastrophe](https://github.com/castastrophe)! + + Dependency alignment across the project. + - Updated dependencies [[`205182b`](https://github.com/adobe/spectrum-css/commit/205182bebcbe82813457aa098d8799b0a23423ee), [`9b108f7`](https://github.com/adobe/spectrum-css/commit/9b108f7e05df1f55ab315dad96736d3ff4757f8c), [`1a3245c`](https://github.com/adobe/spectrum-css/commit/1a3245c3a660bc52ed260f18b6cceab5ee81541d)]: + - @spectrum-css/clearbutton@8.0.0 + - @spectrum-css/icon@9.1.0 + - @spectrum-css/textfield@9.0.0 + - @spectrum-css/tokens@16.0.1 + +- Updated dependencies [[`f6cebbd`](https://github.com/adobe/spectrum-web-components/commit/f6cebbd90008a2abb1232c355ae06e8566086093), [`00eb0a8`](https://github.com/adobe/spectrum-web-components/commit/00eb0a889583dff9d964341d9c1c27048be3d19e), [`9e15a66`](https://github.com/adobe/spectrum-web-components/commit/9e15a66a281745004add414ff977d4a71186aedd)]: + - @spectrum-web-components/icons-workflow@1.6.0 + - @spectrum-web-components/button@1.6.0 + - @spectrum-web-components/textfield@1.6.0 + - @spectrum-web-components/icon@1.6.0 + - @spectrum-web-components/base@1.6.0 + +## 1.5.0 + +### Patch Changes + +- Updated dependencies [[`4e06533`](https://github.com/adobe/spectrum-web-components/commit/4e065332e0236757fc3a050e53747ce82ac40ed5)]: + - @spectrum-web-components/button@1.5.0 + - @spectrum-web-components/textfield@1.5.0 + - @spectrum-web-components/icon@1.5.0 + - @spectrum-web-components/icons-workflow@1.5.0 + - @spectrum-web-components/base@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.4.0 + - @spectrum-web-components/icon@1.4.0 + - @spectrum-web-components/icons-workflow@1.4.0 + - @spectrum-web-components/textfield@1.4.0 + - @spectrum-web-components/base@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/button@1.3.0 + - @spectrum-web-components/icon@1.3.0 + - @spectrum-web-components/icons-workflow@1.3.0 + - @spectrum-web-components/textfield@1.3.0 + - @spectrum-web-components/base@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +### Bug Fixes + +- **search:** clear button ui in express ([#4910](https://github.com/adobe/spectrum-web-components/issues/4910)) ([f88e1e2](https://github.com/adobe/spectrum-web-components/commit/f88e1e2c03ed74f8d3f7924d395a34168afd244c)) + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +### Features + +- **icon:** use core tokens ([a11ef6b](https://github.com/adobe/spectrum-web-components/commit/a11ef6b45141769b4c73a7c79322e780a8a1fa6e)) + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- **search:** add mod to remove clear button padding ([65168fe](https://github.com/adobe/spectrum-web-components/commit/65168fe546ca271cd68722f0c3f4a0be8d4a3253)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **number-field,search,textfield:** add t-shirt sizes ([fda8f96](https://github.com/adobe/spectrum-web-components/commit/fda8f96b71b1447a8281f73d885c1c33ae74cfec)) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +### Features + +- **search:** use core tokens ([c62a7cd](https://github.com/adobe/spectrum-web-components/commit/c62a7cddae81b9767b0ce83117b790d9a7639547)) + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +### Features + +- **search,textfield:** use core tokens ([2ed5135](https://github.com/adobe/spectrum-web-components/commit/2ed51355c2787ac06274e763ea1eee7bfd0c9c72)) + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +**Note:** Version bump only for package @spectrum-web-components/search + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- add tslib as dependency where needed ([78885d9](https://github.com/adobe/spectrum-web-components/commit/78885d9ca7192a053d3b380c338ad5570da474f9)) +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- ensure CCX search visual delivery ([22b90b9](https://github.com/adobe/spectrum-web-components/commit/22b90b901071d8cdbee8a0f6ac2d6fe8acb6dbf0)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- **search:** ensure "reset" surfaces "input" and "change" events ([d8204a9](https://github.com/adobe/spectrum-web-components/commit/d8204a9cf05605696cab02c1e47edb4fad36e9ed)) +- **search:** prevent overflow content from going behind clear button ([956f947](https://github.com/adobe/spectrum-web-components/commit/956f947533fa37cdbd9852ad5ae8eb984e9965f6)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) +- use type="search" for nicer virtual keyboards ([c439eb3](https://github.com/adobe/spectrum-web-components/commit/c439eb3b5d0b9dbc628691a5215d65c936c3939e)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **button:** use synthetic button instead of native ([49e94bc](https://github.com/adobe/spectrum-web-components/commit/49e94bcf79da6ec1ef05f4197042f992922b91ca)) +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- **search:** adds sp-search element ([d484fc2](https://github.com/adobe/spectrum-web-components/commit/d484fc2848a08d52ebb1fc2064202a4288b6b4b3)) +- **search:** introduce API to control form interactions ([42fac00](https://github.com/adobe/spectrum-web-components/commit/42fac00ac071e87f9f80ae45212ea469d4d05fb0)) +- **search:** submit will bubble ([8014345](https://github.com/adobe/spectrum-web-components/commit/801434548576daf4c31dc99eb6972ea140c68943)) +- **search:** support "quiet" variant ([d0f85f1](https://github.com/adobe/spectrum-web-components/commit/d0f85f18887731f80d26eaec84ae601f4e433196)) +- **search:** update spectrum css input ([05d8131](https://github.com/adobe/spectrum-web-components/commit/05d813121075a96652b122c7bb9aafa375dc97ad)) +- **search:** use Spectrum CSS ^3.0.0 ([7830ac0](https://github.com/adobe/spectrum-web-components/commit/7830ac0868e855145cee0922529a0f6d4d3e7f50)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.12.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.15...@spectrum-web-components/search@0.12.16) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.14...@spectrum-web-components/search@0.12.15) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.13...@spectrum-web-components/search@0.12.14) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.12...@spectrum-web-components/search@0.12.13) (2023-03-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.11...@spectrum-web-components/search@0.12.12) (2023-02-13) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.10...@spectrum-web-components/search@0.12.11) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.9...@spectrum-web-components/search@0.12.10) (2023-01-23) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.8...@spectrum-web-components/search@0.12.9) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.7...@spectrum-web-components/search@0.12.8) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.6...@spectrum-web-components/search@0.12.7) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.5...@spectrum-web-components/search@0.12.6) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.4...@spectrum-web-components/search@0.12.5) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.3...@spectrum-web-components/search@0.12.4) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.2...@spectrum-web-components/search@0.12.3) (2022-10-10) + +### Bug Fixes + +- **search:** prevent overflow content from going behind clear button ([956f947](https://github.com/adobe/spectrum-web-components/commit/956f947533fa37cdbd9852ad5ae8eb984e9965f6)) + +## [0.12.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.1...@spectrum-web-components/search@0.12.2) (2022-09-14) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.12.0...@spectrum-web-components/search@0.12.1) (2022-08-24) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.6...@spectrum-web-components/search@0.12.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.11.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.5...@spectrum-web-components/search@0.11.6) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.11.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.4...@spectrum-web-components/search@0.11.5) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.11.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.3...@spectrum-web-components/search@0.11.4) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.11.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.2...@spectrum-web-components/search@0.11.3) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.11.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.1...@spectrum-web-components/search@0.11.2) (2022-05-27) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.11.0...@spectrum-web-components/search@0.11.1) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.7...@spectrum-web-components/search@0.11.0) (2022-04-21) + +### Bug Fixes + +- ensure CCX search visual delivery ([22b90b9](https://github.com/adobe/spectrum-web-components/commit/22b90b901071d8cdbee8a0f6ac2d6fe8acb6dbf0)) + +### Features + +- conditionally load focus-visible polyfill ([6b5e5cf](https://github.com/adobe/spectrum-web-components/commit/6b5e5cf515f02ef14f072b7aee62feed7a83c281)) + +## [0.10.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.6...@spectrum-web-components/search@0.10.7) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.5...@spectrum-web-components/search@0.10.6) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.4...@spectrum-web-components/search@0.10.5) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.3...@spectrum-web-components/search@0.10.4) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.2...@spectrum-web-components/search@0.10.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.1...@spectrum-web-components/search@0.10.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.10.0...@spectrum-web-components/search@0.10.1) (2021-12-13) + +### Bug Fixes + +- apply "HelpTextMixin" to form elements ([a952447](https://github.com/adobe/spectrum-web-components/commit/a952447254d091b99fe9270b2857cddc48df7c73)) + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.9.1...@spectrum-web-components/search@0.10.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.9.0...@spectrum-web-components/search@0.9.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.18...@spectrum-web-components/search@0.9.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.8.18](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.17...@spectrum-web-components/search@0.8.18) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.17](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.16...@spectrum-web-components/search@0.8.17) (2021-10-05) + +### Bug Fixes + +- use type="search" for nicer virtual keyboards ([c439eb3](https://github.com/adobe/spectrum-web-components/commit/c439eb3b5d0b9dbc628691a5215d65c936c3939e)) + +## [0.8.16](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.15...@spectrum-web-components/search@0.8.16) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.14...@spectrum-web-components/search@0.8.15) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.13...@spectrum-web-components/search@0.8.14) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.8.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.12...@spectrum-web-components/search@0.8.13) (2021-08-03) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.11...@spectrum-web-components/search@0.8.12) (2021-07-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.10...@spectrum-web-components/search@0.8.11) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.9...@spectrum-web-components/search@0.8.10) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.8...@spectrum-web-components/search@0.8.9) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.7...@spectrum-web-components/search@0.8.8) (2021-05-24) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.6...@spectrum-web-components/search@0.8.7) (2021-05-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.5...@spectrum-web-components/search@0.8.6) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.4...@spectrum-web-components/search@0.8.5) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.3...@spectrum-web-components/search@0.8.4) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.2...@spectrum-web-components/search@0.8.3) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.1...@spectrum-web-components/search@0.8.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.8.0...@spectrum-web-components/search@0.8.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.7.3...@spectrum-web-components/search@0.8.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.7.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.7.2...@spectrum-web-components/search@0.7.3) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +## [0.7.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.7.1...@spectrum-web-components/search@0.7.2) (2021-02-02) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.7.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.7.0...@spectrum-web-components/search@0.7.1) (2021-01-28) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.4...@spectrum-web-components/search@0.7.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **button:** use synthetic button instead of native ([49e94bc](https://github.com/adobe/spectrum-web-components/commit/49e94bcf79da6ec1ef05f4197042f992922b91ca)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **search:** update spectrum css input ([05d8131](https://github.com/adobe/spectrum-web-components/commit/05d813121075a96652b122c7bb9aafa375dc97ad)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.4...@spectrum-web-components/search@0.6.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use icons without "size" values ([3fc7c91](https://github.com/adobe/spectrum-web-components/commit/3fc7c91713793a928082eae15fc3d9dec638a31a)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **button:** use synthetic button instead of native ([49e94bc](https://github.com/adobe/spectrum-web-components/commit/49e94bcf79da6ec1ef05f4197042f992922b91ca)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **search:** update spectrum css input ([05d8131](https://github.com/adobe/spectrum-web-components/commit/05d813121075a96652b122c7bb9aafa375dc97ad)) + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.3...@spectrum-web-components/search@0.5.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.2...@spectrum-web-components/search@0.5.3) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.1...@spectrum-web-components/search@0.5.2) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.5.0...@spectrum-web-components/search@0.5.1) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.4.4...@spectrum-web-components/search@0.5.0) (2020-08-31) + +### Features + +- **search:** use Spectrum CSS ^3.0.0 ([7830ac0](https://github.com/adobe/spectrum-web-components/commit/7830ac0868e855145cee0922529a0f6d4d3e7f50)) + +## [0.4.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.4.3...@spectrum-web-components/search@0.4.4) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.4.2...@spectrum-web-components/search@0.4.3) (2020-07-27) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.4.1...@spectrum-web-components/search@0.4.2) (2020-07-24) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.4.0...@spectrum-web-components/search@0.4.1) (2020-07-22) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.3.4...@spectrum-web-components/search@0.4.0) (2020-07-17) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.3.3...@spectrum-web-components/search@0.3.4) (2020-06-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.3.2...@spectrum-web-components/search@0.3.3) (2020-05-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.3.1...@spectrum-web-components/search@0.3.2) (2020-05-08) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.3.0...@spectrum-web-components/search@0.3.1) (2020-04-21) + +**Note:** Version bump only for package @spectrum-web-components/search + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.12...@spectrum-web-components/search@0.3.0) (2020-04-16) + +### Features + +- add and use icons-ui package ([d9c3ab2](https://github.com/adobe/spectrum-web-components/commit/d9c3ab212b4f756334e857fc513ccbf0a4dff9cc)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.2.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.11...@spectrum-web-components/search@0.2.12) (2020-04-10) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.10...@spectrum-web-components/search@0.2.11) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.9...@spectrum-web-components/search@0.2.10) (2020-03-25) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.8...@spectrum-web-components/search@0.2.9) (2020-03-11) + +### Bug Fixes + +- **search:** ensure "reset" surfaces "input" and "change" events ([d8204a9](https://github.com/adobe/spectrum-web-components/commit/d8204a9)) + +## [0.2.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.7...@spectrum-web-components/search@0.2.8) (2020-02-05) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.6...@spectrum-web-components/search@0.2.7) (2020-02-01) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.5...@spectrum-web-components/search@0.2.6) (2020-01-30) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.4...@spectrum-web-components/search@0.2.5) (2020-01-06) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.3...@spectrum-web-components/search@0.2.4) (2019-12-12) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.2...@spectrum-web-components/search@0.2.3) (2019-12-09) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.1...@spectrum-web-components/search@0.2.2) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.2.0...@spectrum-web-components/search@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.1.3...@spectrum-web-components/search@0.2.0) (2019-11-19) + +### Features + +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.1.2...@spectrum-web-components/search@0.1.3) (2019-11-01) + +**Note:** Version bump only for package @spectrum-web-components/search + +## [0.1.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.1.1...@spectrum-web-components/search@0.1.2) (2019-10-16) + +### Bug Fixes + +- add tslib as dependency where needed ([78885d9](https://github.com/adobe/spectrum-web-components/commit/78885d9)) + +## [0.1.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/search@0.1.0...@spectrum-web-components/search@0.1.1) (2019-10-16) + +**Note:** Version bump only for package @spectrum-web-components/search + +# 0.1.0 (2019-10-14) + +### Features + +- **search:** adds sp-search element ([d484fc2](https://github.com/adobe/spectrum-web-components/commit/d484fc2)) +- **search:** introduce API to control form interactions ([42fac00](https://github.com/adobe/spectrum-web-components/commit/42fac00)) +- **search:** submit will bubble ([8014345](https://github.com/adobe/spectrum-web-components/commit/8014345)) +- **search:** support "quiet" variant ([d0f85f1](https://github.com/adobe/spectrum-web-components/commit/d0f85f1)) diff --git a/1st-gen/packages/search/README.md b/1st-gen/packages/search/README.md new file mode 100644 index 00000000000..96cee545664 --- /dev/null +++ b/1st-gen/packages/search/README.md @@ -0,0 +1,161 @@ +## Overview + +The `` element is used for searching and filtering items. + +[View the design documentation for this component.](https://spectrum.adobe.com/page/search-field/) + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/search?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/search) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/search?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/search) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-xnfnkgvf) + +```zsh +yarn add @spectrum-web-components/search +``` + +Import the side effectful registration of `` via: + +```js +import '@spectrum-web-components/search/sp-search.js'; +``` + +When looking to leverage the `Search` base class as a type and/or for extension purposes, do so via: + +```js +import { Search } from '@spectrum-web-components/search'; +``` + +### Anatomy + +The search field consists of several key parts: + +- Label/placeholder +- Text field +- In-field button to clear the search term + +### Options + +#### Sizes + +Search fields come in four different sizes for mobile and desktop platform scales: `small`, `medium`, `large`, and `extra-large`. + +The default and most frequently used size is `medium`. + + +Small + + +```html demo + +``` + + +Medium + + +```html demo + +``` + + +Large + + +```html demo + +``` + + +Extra Large + + +```html demo + +``` + + + + +#### Icon + +The search icon is set using the `icon magnifier icon-workflow icon-search` classes in the component. + +```html demo + +``` + +#### Placeholder + +A placeholder is a hint to the user about what to input in the search field. It is displayed when the search field is empty and is removed when the user starts typing. + +```html demo + +``` + +#### Help text + +A search field can have help text below the field to give extra context or instruction about what a user should input. The description communicates a hint or helpful information, such as a search's scope. The component also supports negative help text, which is displayed when the search field is invalid. + +```html demo + + Enter a search term. + Invalid search term. + +``` + +#### Clear button + +A clear button is a button that clears the search term. It is displayed when the search field is not empty. + +```html demo + +``` + +### States + +#### Disabled + +A search field in a disabled state shows that a search option exists, but is not available in that circumstance. This can be used to maintain layout continuity and communicate that it may become available later. + +```html demo + +``` + +### Events + +The `submit` event fires when the `` is submitted. This is a non-`composed` event in line with what you would expect a [`
`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event) to fire. If you choose to prevent the default behavior of this event, the default action for the underlying `` element will also be prevented, allowing you to handle the search action in JavaScript. + +### Accessibility + +#### Include a label + +Every text field should have a label. A field without a label is ambiguous and not accessible. + +The `aria-label` for the search field is set to `Search` by default. The text set in the `label` property is used as the `aria-label` for the search field. + +#### Include help text + +The description in the help text is flexible and encompasses a range of guidance. Sometimes this guidance is about what to input, and sometimes it's about how to input. This includes information such as: + +- An overall description of the input field +- Hints for what kind of information needs to be input +- Specific formatting examples or requirements + +Learn more about [using help text](https://spectrum.adobe.com/page/text-field/#Use-help-text-to-show-hints,-formatting,-and-requirements). + +#### Include negative help text + +Write error messaging in a human-centered way by guiding a user and showing them a solution — don't simply state what's wrong and then leave them guessing as to how to resolve it. Ambiguous error messages can be frustrating and even shame-inducing for users. Also, keep in mind that something that a system may deem an error may not actually be perceived as an error to a user. + +Learn more about [writing error messages](https://spectrum.adobe.com/page/text-field/#Write-error-text-that-shows-a-solution). + +#### Do not use a placeholder as a replacement for a label or help-text + +Putting instructions for how to complete an input, requirements, or any other essential information into placeholder text is not accessible. Once a value is entered, placeholder text is no longer viewable; if someone is using an automatic form filler, they will never get the information in the placeholder text. + +Instead, use the help text description to convey requirements or to show any formatting examples that would help user comprehension. If there's placeholder text and help text at the same time, it becomes redundant and distracting, especially if they're communicating the same thing. + +#### Hold value on Escape key + +The `holdValueOnEscape` attribute controls whether the typed value should be held (i.e., not cleared or reset) when the Escape key is pressed. If set to true, pressing the Escape key will not affect the value in the search field. diff --git a/1st-gen/packages/search/package.json b/1st-gen/packages/search/package.json new file mode 100644 index 00000000000..55d544cf330 --- /dev/null +++ b/1st-gen/packages/search/package.json @@ -0,0 +1,79 @@ +{ + "name": "@spectrum-web-components/search", + "version": "1.9.0", + "publishConfig": { + "access": "public" + }, + "description": "", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/adobe/spectrum-web-components.git", + "directory": "1st-gen/packages/search" + }, + "author": "Adobe", + "homepage": "https://opensource.adobe.com/spectrum-web-components/components/search", + "bugs": { + "url": "https://github.com/adobe/spectrum-web-components/issues" + }, + "main": "./src/index.js", + "module": "./src/index.js", + "type": "module", + "exports": { + ".": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./package.json": "./package.json", + "./src/Search.js": { + "development": "./src/Search.dev.js", + "default": "./src/Search.js" + }, + "./src/index.js": { + "development": "./src/index.dev.js", + "default": "./src/index.js" + }, + "./src/search-overrides.css.js": "./src/search-overrides.css.js", + "./src/search.css.js": "./src/search.css.js", + "./sp-search.js": { + "development": "./sp-search.dev.js", + "default": "./sp-search.js" + } + }, + "scripts": { + "test": "echo \"Error: run tests from mono-repo root.\" && exit 1" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json", + "!stories/", + "!test/" + ], + "keywords": [ + "design-system", + "spectrum", + "adobe", + "adobe-spectrum", + "web components", + "web-components", + "lit-element", + "lit-html", + "component", + "css" + ], + "dependencies": { + "@spectrum-web-components/base": "1.9.0", + "@spectrum-web-components/button": "1.9.0", + "@spectrum-web-components/icon": "1.9.0", + "@spectrum-web-components/icons-workflow": "1.9.0", + "@spectrum-web-components/textfield": "1.9.0" + }, + "types": "./src/index.d.ts", + "customElements": "custom-elements.json", + "sideEffects": [ + "./sp-*.js", + "./**/*.dev.js" + ] +} diff --git a/1st-gen/packages/search/sp-search.ts b/1st-gen/packages/search/sp-search.ts new file mode 100644 index 00000000000..d2616fe28f5 --- /dev/null +++ b/1st-gen/packages/search/sp-search.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { Search } from './src/Search.js'; +import { defineElement } from '@spectrum-web-components/base/src/define-element.js'; + +defineElement('sp-search', Search); + +declare global { + interface HTMLElementTagNameMap { + 'sp-search': Search; + } +} diff --git a/1st-gen/packages/search/src/Search.ts b/1st-gen/packages/search/src/Search.ts new file mode 100644 index 00000000000..7875e50b2c1 --- /dev/null +++ b/1st-gen/packages/search/src/Search.ts @@ -0,0 +1,153 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { + CSSResultArray, + html, + nothing, + PropertyValues, + TemplateResult, +} from '@spectrum-web-components/base'; +import { + property, + query, +} from '@spectrum-web-components/base/src/decorators.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +import { Textfield } from '@spectrum-web-components/textfield'; +import '@spectrum-web-components/button/sp-clear-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-search.js'; + +import searchStyles from './search.css.js'; + +const stopPropagation = (event: Event): void => event.stopPropagation(); + +/** + * @element sp-search + * @slot help-text - default or non-negative help text to associate to your form element + * @slot negative-help-text - negative help text to associate to your form element when `invalid` + * + * @fires submit - The search form has been submitted. + */ +export class Search extends Textfield { + public static override get styles(): CSSResultArray { + return [...super.styles, searchStyles]; + } + + @property() + public action = ''; + + @property() + public override label = 'Search'; + + @property() + public method?: 'get' | 'post' | 'dialog'; + + @property() + public override placeholder = 'Search'; + + /** + * Controls whether the typed value should be held (i.e., not cleared or reset) when the Escape key is pressed. + * If set to true, pressing the Escape key will not affect the value in the search field. + */ + @property({ type: Boolean }) + public holdValueOnEscape!: boolean; + + @query('#form') + public form!: HTMLFormElement; + + private handleSubmit(event: Event): void { + const applyDefault = this.dispatchEvent( + new Event('submit', { + cancelable: true, + bubbles: true, + }) + ); + if (!applyDefault) { + event.preventDefault(); + } + } + + private handleKeydown(event: KeyboardEvent): void { + const { code } = event; + if (code === 'Escape' && this.holdValueOnEscape) { + return; + } + if (!this.value || code !== 'Escape') { + return; + } + this.reset(); + } + + public async reset(): Promise { + this.value = ''; + await this.updateComplete; + this.focusElement.dispatchEvent( + new InputEvent('input', { + bubbles: true, + composed: true, + }) + ); + // The native `change` event on an `input` element is not composed, + // so this synthetic replication of a `change` event must not be + // either as the `Textfield` baseclass should only need to handle + // the native variant of this interaction. + this.focusElement.dispatchEvent( + new InputEvent('change', { + bubbles: true, + }) + ); + } + + protected override renderField(): TemplateResult { + return html` + + + ${super.renderField()} + ${this.value + ? html` + + ` + : nothing} + + `; + } + + public override firstUpdated(changedProperties: PropertyValues): void { + super.firstUpdated(changedProperties); + // if holdValueOnEscape is not set, default to search type + if (!this.hasAttribute('holdValueOnEscape')) { + this.inputElement.setAttribute('type', 'search'); + } + } + + public override willUpdate(): void { + this.multiline = false; + } +} diff --git a/1st-gen/packages/search/src/index.ts b/1st-gen/packages/search/src/index.ts new file mode 100644 index 00000000000..7cd21c89f16 --- /dev/null +++ b/1st-gen/packages/search/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './Search.js'; diff --git a/1st-gen/packages/search/src/search-overrides.css b/1st-gen/packages/search/src/search-overrides.css new file mode 100644 index 00000000000..4f6b7d9c473 --- /dev/null +++ b/1st-gen/packages/search/src/search-overrides.css @@ -0,0 +1,34 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + --spectrum-search-border-color-default: var(--system-search-border-color-default); + --spectrum-search-border-color-hover: var(--system-search-border-color-hover); + --spectrum-search-border-color-focus: var(--system-search-border-color-focus); + --spectrum-search-border-color-focus-hover: var(--system-search-border-color-focus-hover); + --spectrum-search-border-color-key-focus: var(--system-search-border-color-key-focus); + --spectrum-search-background-color: var(--system-search-background-color); + --spectrum-search-background-color-disabled: var(--system-search-background-color-disabled); + --spectrum-search-border-color-disabled: var(--system-search-border-color-disabled); + --spectrum-search-border-radius: var(--system-search-border-radius); + --spectrum-search-edge-to-visual: var(--system-search-edge-to-visual); +} + +:host([size="m"]) #textfield { + --spectrum-search-border-radius: var(--system-search-size-m-border-radius); + --spectrum-search-edge-to-visual: var(--system-search-size-m-edge-to-visual); +} + +:host([quiet]) { + --spectrum-search-background-color-disabled: var(--system-search-quiet-background-color-disabled); + --spectrum-search-border-color-disabled: var(--system-search-quiet-border-color-disabled); +} diff --git a/1st-gen/packages/search/src/search.css b/1st-gen/packages/search/src/search.css new file mode 100644 index 00000000000..33d7969db7a --- /dev/null +++ b/1st-gen/packages/search/src/search.css @@ -0,0 +1,51 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +@import url("./spectrum-search.css"); +@import url("./search-overrides.css"); + +:host { + --mod-textfield-spacing-inline: var(--spectrum-alias-infieldbutton-full-height-m); +} + +input::-webkit-search-cancel-button { + display: none; +} + +:host([size="s"]) #textfield { + --spectrum-search-border-radius: var(--system-search-size-s-border-radius); + --spectrum-search-edge-to-visual: var(--system-search-size-s-edge-to-visual); +} + +:host([size="l"]) #textfield { + --spectrum-search-border-radius: var(--system-search-size-l-border-radius); + --spectrum-search-edge-to-visual: var(--system-search-size-l-edge-to-visual); +} + +:host([size="xl"]) #textfield { + --spectrum-search-border-radius: var(--system-search-size-xl-border-radius); + --spectrum-search-edge-to-visual: var(--system-search-size-xl-edge-to-visual); +} + +/** + * While overriding the need for `size="m"` in SWC, these values correct the + * cascade when attempting to delivery the Clear Button within the Search UI. + **/ +@media (forced-colors: active) { + sp-clear-button { + --spectrum-clearbutton-fill-background-color: transparent; + --spectrum-clearbutton-fill-background-color-disabled: transparent; + --spectrum-clearbutton-fill-background-color-down: transparent; + --spectrum-clearbutton-fill-background-color-hover: transparent; + --spectrum-clearbutton-fill-background-color-key-focus: transparent; + } +} diff --git a/1st-gen/packages/search/src/spectrum-search.css b/1st-gen/packages/search/src/spectrum-search.css new file mode 100644 index 00000000000..91ba2d6eeb9 --- /dev/null +++ b/1st-gen/packages/search/src/spectrum-search.css @@ -0,0 +1,191 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +#textfield { + --spectrum-search-inline-size: var(--spectrum-field-width); + --spectrum-search-block-size: var(--spectrum-component-height-100); + --spectrum-search-button-inline-size: var(--spectrum-search-block-size); + --spectrum-search-min-inline-size: calc(var(--spectrum-search-field-minimum-width-multiplier) * var(--spectrum-search-block-size)); + --spectrum-search-icon-size: var(--spectrum-workflow-icon-size-100); + --spectrum-search-text-to-icon: var(--spectrum-text-to-visual-100); + --spectrum-search-to-help-text: var(--spectrum-help-text-to-component); + --spectrum-search-top-to-text: var(--spectrum-component-top-to-text-100); + --spectrum-search-bottom-to-text: var(--spectrum-component-bottom-to-text-100); + --spectrum-search-focus-indicator-thickness: var(--spectrum-focus-indicator-thickness); + --spectrum-search-focus-indicator-gap: var(--spectrum-focus-indicator-gap); + --spectrum-search-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-search-font-family: var(--spectrum-sans-font-family-stack); + --spectrum-search-font-weight: var(--spectrum-regular-font-weight); + --spectrum-search-font-style: var(--spectrum-default-font-style); + --spectrum-search-line-height: var(--spectrum-line-height-100); + --spectrum-search-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-search-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-search-color-focus: var(--spectrum-neutral-content-color-focus); + --spectrum-search-color-focus-hover: var(--spectrum-neutral-content-color-focus-hover); + --spectrum-search-color-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-search-border-width: var(--spectrum-border-width-100); + --spectrum-search-color-disabled: var(--spectrum-disabled-content-color); + --mod-textfield-font-family: var(--mod-search-font-family, var(--spectrum-search-font-family)); + --mod-textfield-font-weight: var(--mod-search-font-weight, var(--spectrum-search-font-weight)); + --mod-textfield-corner-radius: var(--mod-search-border-radius, var(--spectrum-search-border-radius)); + --mod-textfield-border-width: var(--mod-search-border-width, var(--spectrum-search-border-width)); + --mod-textfield-focus-indicator-gap: var(--mod-search-focus-indicator-gap, var(--spectrum-search-focus-indicator-gap)); + --mod-textfield-focus-indicator-width: var(--mod-search-focus-indicator-thickness, var(--spectrum-search-focus-indicator-thickness)); + --mod-textfield-focus-indicator-color: var(--mod-search-focus-indicator-color, var(--spectrum-search-focus-indicator-color)); + --mod-textfield-text-color-default: var(--mod-search-color-default, var(--spectrum-search-color-default)); + --mod-textfield-text-color-hover: var(--mod-search-color-hover, var(--spectrum-search-color-hover)); + --mod-textfield-text-color-focus: var(--mod-search-color-focus, var(--spectrum-search-color-focus)); + --mod-textfield-text-color-focus-hover: var(--mod-search-color-focus-hover, var(--spectrum-search-color-focus-hover)); + --mod-textfield-text-color-keyboard-focus: var(--mod-search-color-key-focus, var(--spectrum-search-color-key-focus)); + --mod-textfield-text-color-disabled: var(--mod-search-color-disabled, var(--spectrum-search-color-disabled)); + --mod-textfield-border-color: var(--mod-search-border-color-default, var(--spectrum-search-border-color-default)); + --mod-textfield-border-color-hover: var(--mod-search-border-color-hover, var(--spectrum-search-border-color-hover)); + --mod-textfield-border-color-focus: var(--mod-search-border-color-focus, var(--spectrum-search-border-color-focus)); + --mod-textfield-border-color-focus-hover: var(--mod-search-border-color-focus-hover, var(--spectrum-search-border-color-focus-hover)); + --mod-textfield-border-color-keyboard-focus: var(--mod-search-border-color-key-focus, var(--spectrum-search-border-color-key-focus)); + --mod-textfield-border-color-disabled: var(--mod-search-border-color-disabled, var(--spectrum-search-border-color-disabled)); + --mod-textfield-background-color: var(--mod-search-background-color, var(--spectrum-search-background-color)); + --mod-textfield-background-color-disabled: var(--mod-search-background-color-disabled, var(--spectrum-search-background-color-disabled)); + inline-size: var(--mod-search-inline-size, var(--spectrum-search-inline-size)); + min-inline-size: var(--mod-search-min-inline-size, var(--spectrum-search-min-inline-size)); + display: inline-block; + position: relative; +} + +#textfield .spectrum-HelpText { + margin-block-start: var(--mod-search-to-help-text, var(--spectrum-search-to-help-text)); +} + +:host([size="s"]) #textfield { + --spectrum-search-block-size: var(--spectrum-component-height-75); + --spectrum-search-icon-size: var(--spectrum-workflow-icon-size-75); + --spectrum-search-text-to-icon: var(--spectrum-text-to-visual-75); +} + +:host([size="l"]) #textfield { + --spectrum-search-block-size: var(--spectrum-component-height-200); + --spectrum-search-icon-size: var(--spectrum-workflow-icon-size-200); + --spectrum-search-text-to-icon: var(--spectrum-text-to-visual-200); +} + +:host([size="xl"]) #textfield { + --spectrum-search-block-size: var(--spectrum-component-height-300); + --spectrum-search-icon-size: var(--spectrum-workflow-icon-size-300); + --spectrum-search-text-to-icon: var(--spectrum-text-to-visual-300); +} + +@media (forced-colors: active) { + #textfield #textfield, + #textfield #textfield .input { + --highcontrast-search-color-default: CanvasText; + --highcontrast-search-color-hover: CanvasText; + --highcontrast-search-color-focus: CanvasText; + --highcontrast-search-color-disabled: GrayText; + } + + #textfield #button .spectrum-ClearButton-fill { + forced-color-adjust: none; + background-color: initial; + } +} + +#button { + position: absolute; + inset-block-start: 0; + inset-inline-end: 0; +} + +#button, +#button .spectrum-ClearButton-fill { + border-radius: var(--mod-search-border-radius, var(--spectrum-search-border-radius)); +} + +#textfield.is-disabled #button { + display: none; +} + +#textfield { + inline-size: 100%; +} + +.icon-search { + --spectrum-search-color: var(--highcontrast-search-color-default, var(--mod-search-color-default, var(--spectrum-search-color-default))); + color: var(--spectrum-search-color); + margin-block: auto; + display: block; + position: absolute; + inset-block: 0; +} + +#textfield.is-focused .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-focus, var(--mod-search-color-focus, var(--spectrum-search-color-focus))); +} + +#textfield.is-keyboardFocused .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-focus, var(--mod-search-color-key-focus, var(--spectrum-search-color-key-focus))); +} + +#textfield.is-disabled .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-disabled, var(--mod-search-color-disabled, var(--spectrum-search-color-disabled))); +} + +@media (hover: hover) { + #textfield:hover .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-hover, var(--mod-search-color-hover, var(--spectrum-search-color-hover))); + } + + #textfield.is-focused:hover .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-focus, var(--mod-search-color-focus-hover, var(--spectrum-search-color-focus-hover))); + } + + #textfield.is-disabled:hover .icon-search { + --spectrum-search-color: var(--highcontrast-search-color-disabled, var(--mod-search-color-disabled, var(--spectrum-search-color-disabled))); + } +} + +.input { + appearance: none; + block-size: var(--mod-search-block-size, var(--spectrum-search-block-size)); + font-style: var(--mod-search-font-style, var(--spectrum-search-font-style)); + line-height: var(--mod-search-line-height, var(--spectrum-search-line-height)); + padding-block-start: calc(var(--mod-search-top-to-text, var(--spectrum-search-top-to-text)) - var(--mod-search-border-width, var(--spectrum-search-border-width))); + padding-block-end: calc(var(--mod-search-bottom-to-text, var(--spectrum-search-bottom-to-text)) - var(--mod-search-border-width, var(--spectrum-search-border-width))); +} + +.input::-webkit-search-cancel-button, +.input::-webkit-search-decoration { + appearance: none; +} + +:host(:not([quiet])) #textfield .icon-search { + inset-inline-start: var(--mod-search-edge-to-visual, var(--spectrum-search-edge-to-visual)); +} + +:host(:not([quiet])) #textfield .input { + padding-inline-start: calc(var(--mod-search-edge-to-visual, var(--spectrum-search-edge-to-visual)) - var(--mod-search-border-width, var(--spectrum-search-border-width)) + var(--mod-search-icon-size, var(--spectrum-search-icon-size)) + var(--mod-search-text-to-icon, var(--spectrum-search-text-to-icon))); + padding-inline-end: var(--mod-search-button-inline-size, var(--spectrum-search-button-inline-size)); +} + +:host([quiet]) { + --spectrum-search-background-color: transparent; + --spectrum-search-background-color-disabled: transparent; + --spectrum-search-border-color-disabled: var(--spectrum-disabled-border-color); + --mod-search-border-radius: 0; + --mod-search-edge-to-visual: var(--spectrum-field-edge-to-visual-quiet); +} + +:host([quiet]) .input { + border-radius: var(--mod-search-border-radius, var(--spectrum-search-border-radius)); + padding-block-start: var(--mod-search-top-to-text, var(--spectrum-search-top-to-text)); + padding-inline-start: calc(var(--mod-search-edge-to-visual, var(--spectrum-search-edge-to-visual)) + var(--mod-search-icon-size, var(--spectrum-search-icon-size)) + var(--mod-search-text-to-icon, var(--spectrum-search-text-to-icon))); + padding-inline-end: var(--mod-search-button-inline-size, var(--spectrum-search-button-inline-size)); +} diff --git a/1st-gen/packages/search/stories/search-sizes.stories.ts b/1st-gen/packages/search/stories/search-sizes.stories.ts new file mode 100644 index 00000000000..5bf3bcb2d7b --- /dev/null +++ b/1st-gen/packages/search/stories/search-sizes.stories.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from '@spectrum-web-components/base'; + +import '@spectrum-web-components/search/sp-search.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/help-text/sp-help-text.js'; +import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; + +export default { + component: 'sp-search', + title: 'Search/Sizes', +}; + +const template = ({ + size, +}: { + size?: 's' | 'm' | 'l' | 'xl'; +} = {}): TemplateResult => { + return html` + + What would you like to find? + + + + Anything within reason... + + + `; +}; + +export const s = (): TemplateResult => template({ size: 's' }); +export const noSize = (): TemplateResult => template(); +export const m = (): TemplateResult => template({ size: 'm' }); +export const l = (): TemplateResult => template({ size: 'l' }); +export const XL = (): TemplateResult => template({ size: 'xl' }); diff --git a/1st-gen/packages/search/stories/search.stories.ts b/1st-gen/packages/search/stories/search.stories.ts new file mode 100644 index 00000000000..91c4dd7ac44 --- /dev/null +++ b/1st-gen/packages/search/stories/search.stories.ts @@ -0,0 +1,42 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/search/sp-search.js'; +import { html, TemplateResult } from '@spectrum-web-components/base'; + +export default { + component: 'sp-search', + title: 'Search', +}; + +export const Default = (): TemplateResult => html` + + +`; + +export const autofocus = (): TemplateResult => html` + +`; + +export const focusedOverflowing = (): TemplateResult => html` + +`; + +export const Quiet = (): TemplateResult => html` + + +`; + +export const holdValueOnEscape = (): TemplateResult => html` + +`; diff --git a/1st-gen/packages/search/test/benchmark/test-basic.ts b/1st-gen/packages/search/test/benchmark/test-basic.ts new file mode 100644 index 00000000000..b1a07861993 --- /dev/null +++ b/1st-gen/packages/search/test/benchmark/test-basic.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import '@spectrum-web-components/search/sp-search.js'; +import { html } from 'lit'; +import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js'; + +measureFixtureCreation(html` + { + event.preventDefault(); + }} + > +`); diff --git a/1st-gen/packages/search/test/search-memory.test.ts b/1st-gen/packages/search/test/search-memory.test.ts new file mode 100644 index 00000000000..9cc8d9d25ec --- /dev/null +++ b/1st-gen/packages/search/test/search-memory.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from '@open-wc/testing'; +import '@spectrum-web-components/search/sp-search.js'; +import { testForMemoryLeaks } from '../../../test/testing-helpers.js'; + +testForMemoryLeaks(html` + +`); diff --git a/1st-gen/packages/search/test/search.test.ts b/1st-gen/packages/search/test/search.test.ts new file mode 100644 index 00000000000..2cbeef7f25d --- /dev/null +++ b/1st-gen/packages/search/test/search.test.ts @@ -0,0 +1,232 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import '@spectrum-web-components/search/sp-search.js'; +import { Search } from '@spectrum-web-components/search'; +import { elementUpdated, expect, html, litFixture } from '@open-wc/testing'; +import { escapeEvent, spaceEvent } from '../../../test/testing-helpers.js'; +import '@spectrum-web-components/shared/src/focus-visible.js'; +import { spy } from 'sinon'; +import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; + +describe('Search', () => { + testForLitDevWarnings( + async () => + await litFixture(html` + + `) + ); + it('loads accessibly', async () => { + const el = await litFixture(html` + + `); + + await elementUpdated(el); + + await expect(el).to.be.accessible(); + }); + it('can be cleared', async () => { + const el = await litFixture(html` + + `); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + + const root = el.shadowRoot ? el.shadowRoot : el; + const clearButton = root.querySelector('#button') as HTMLButtonElement; + clearButton.click(); + + await elementUpdated(el); + + expect(el.value).to.equal(''); + }); + it('captures keyboard events to the clear button', async () => { + const el = await litFixture(html` + + `); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + + const root = el.shadowRoot ? el.shadowRoot : el; + const clearButton = root.querySelector('#button') as HTMLButtonElement; + clearButton.dispatchEvent(escapeEvent()); + + await elementUpdated(el); + + expect(el.value).to.equal('Test'); + }); + it('dispatches events when using the "clear" button', async () => { + const inputSpy = spy(); + const changeSpy = spy(); + const handleInput = (event: Event): void => { + const target = event.target as HTMLInputElement; + inputSpy(target.value); + }; + const handleChange = (event: Event): void => { + const target = event.target as HTMLInputElement; + changeSpy(target.value); + }; + const el = await litFixture(html` + + `); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + + const root = el.shadowRoot ? el.shadowRoot : el; + const clearButton = root.querySelector('#button') as HTMLButtonElement; + inputSpy.resetHistory(); + changeSpy.resetHistory(); + clearButton.click(); + + await elementUpdated(el); + + expect(el.value).to.equal(''); + expect(inputSpy.calledOnce, 'one input').to.be.true; + expect(inputSpy.calledWith(''), 'was blank').to.be.true; + expect(changeSpy.calledOnce, 'one change').to.be.true; + expect(changeSpy.calledWith(''), 'was blank').to.be.true; + }); + it('can be cleared via "Escape"', async () => { + const inputSpy = spy(); + const changeSpy = spy(); + const handleInput = (event: Event): void => { + const target = event.target as HTMLInputElement; + inputSpy(target.value); + }; + const handleChange = (event: Event): void => { + const target = event.target as HTMLInputElement; + changeSpy(target.value); + }; + const el = await litFixture(html` + + `); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + el.focusElement.dispatchEvent(spaceEvent()); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + + inputSpy.resetHistory(); + changeSpy.resetHistory(); + el.focusElement.dispatchEvent(escapeEvent()); + + await elementUpdated(el); + + expect(el.value).to.equal(''); + expect(inputSpy.calledOnce, 'one input').to.be.true; + expect(inputSpy.calledWith(''), 'was blank').to.be.true; + expect(changeSpy.calledOnce, 'one change').to.be.true; + expect(changeSpy.calledWith(''), 'was blank').to.be.true; + }); + it('cannot be cleared via "Escape" if holdValueOnEscape is true', async () => { + const inputSpy = spy(); + const changeSpy = spy(); + const handleInput = (event: Event): void => { + const target = event.target as HTMLInputElement; + inputSpy(target.value); + }; + const handleChange = (event: Event): void => { + const target = event.target as HTMLInputElement; + changeSpy(target.value); + }; + const el = await litFixture(html` + + `); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + el.focusElement.dispatchEvent(spaceEvent()); + + await elementUpdated(el); + expect(el.value).to.equal('Test'); + + inputSpy.resetHistory(); + changeSpy.resetHistory(); + el.focusElement.dispatchEvent(escapeEvent()); + + await elementUpdated(el); + + expect(el.value).to.equal('Test'); + }); + it('cannot be multiline', async () => { + const el = await litFixture(html` + + `); + + await elementUpdated(el); + + expect(el.multiline).to.be.false; + + el.multiline = true; + + await elementUpdated(el); + + expect(el.multiline).to.be.false; + }); + it('accepts `placeholder` and `label` properties', async () => { + const testString = 'Search for images'; + const el = await litFixture(html` + + `); + + await elementUpdated(el); + el.placeholder = testString; + el.label = testString; + + await elementUpdated(el); + + expect(el.focusElement.placeholder).to.equal(testString); + expect(el.focusElement.getAttribute('aria-label')).to.equal(testString); + }); + it('can have default prevented', async () => { + const el = await litFixture(html` + { + event.preventDefault(); + }} + > + `); + + await elementUpdated(el); + const searchForm = ( + el.shadowRoot + ? el.shadowRoot.querySelector('form') + : el.querySelector('form') + ) as HTMLFormElement; + + const submitEvent = new Event('submit', { + cancelable: true, + bubbles: false, + composed: false, + }); + searchForm.dispatchEvent(submitEvent); + + expect(submitEvent.defaultPrevented).to.be.true; + }); +}); diff --git a/1st-gen/packages/search/tsconfig.json b/1st-gen/packages/search/tsconfig.json new file mode 100644 index 00000000000..e42e970bd27 --- /dev/null +++ b/1st-gen/packages/search/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["*.ts", "src/*.ts"], + "exclude": ["test/*.ts", "stories/*.ts"], + "references": [{ "path": "../textfield" }] +} diff --git a/1st-gen/packages/sidenav/.npmrc b/1st-gen/packages/sidenav/.npmrc new file mode 100644 index 00000000000..43e50704a7f --- /dev/null +++ b/1st-gen/packages/sidenav/.npmrc @@ -0,0 +1,3 @@ +@adobe:registry=https://registry.npmjs.org/ +registry=https://registry.npmjs.org/ + diff --git a/1st-gen/packages/sidenav/CHANGELOG.md b/1st-gen/packages/sidenav/CHANGELOG.md new file mode 100644 index 00000000000..9d5409cec70 --- /dev/null +++ b/1st-gen/packages/sidenav/CHANGELOG.md @@ -0,0 +1,732 @@ +# Change Log + +## 1.9.0 + +### Patch Changes + +- Updated dependencies [[`7d23140`](https://github.com/adobe/spectrum-web-components/commit/7d23140c21f0006ddea8a5cf39478ff36acbfbb8)]: + - @spectrum-web-components/reactive-controllers@1.9.0 + - @spectrum-web-components/base@1.9.0 + - @spectrum-web-components/shared@1.9.0 + +## 1.8.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.8.0 + - @spectrum-web-components/reactive-controllers@1.8.0 + - @spectrum-web-components/shared@1.8.0 + +## 1.7.0 + +### Patch Changes + +- [#5504](https://github.com/adobe/spectrum-web-components/pull/5504) [`cde976d`](https://github.com/adobe/spectrum-web-components/commit/cde976ddfa71f898e2d0404ecc53150db149a861) Thanks [@castastrophe](https://github.com/castastrophe)! - Replace deprecated `word-break: break-word` with `overflow-wrap: break-word` to align with modern CSS standards and improve cross-browser compatibility. This property was deprecated in Chrome 44 (July 2015) in favor of the standardized `overflow-wrap` property. + +- Updated dependencies []: + - @spectrum-web-components/base@1.7.0 + - @spectrum-web-components/reactive-controllers@1.7.0 + - @spectrum-web-components/shared@1.7.0 + +## 1.6.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.6.0 + - @spectrum-web-components/reactive-controllers@1.6.0 + - @spectrum-web-components/shared@1.6.0 + +## 1.5.0 + +### Patch Changes + +- [#5271](https://github.com/adobe/spectrum-web-components/pull/5271) [`165a904`](https://github.com/adobe/spectrum-web-components/commit/165a904bd01fddea922fe87b181bbf41281f81f0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove unnecessary system theme references to reduce complexity for components that don't need the additional mapping layer. + +- Updated dependencies []: + - @spectrum-web-components/base@1.5.0 + - @spectrum-web-components/reactive-controllers@1.5.0 + - @spectrum-web-components/shared@1.5.0 + +## 1.4.0 + +### Patch Changes + +- Updated dependencies []: + - @spectrum-web-components/base@1.4.0 + - @spectrum-web-components/reactive-controllers@1.4.0 + - @spectrum-web-components/shared@1.4.0 + +## 1.3.0 + +### Patch Changes + +- Updated dependencies [[`ea38ef0`](https://github.com/adobe/spectrum-web-components/commit/ea38ef0db33b251a054d50abf5cffc04e32f579f)]: + - @spectrum-web-components/reactive-controllers@1.3.0 + - @spectrum-web-components/base@1.3.0 + - @spectrum-web-components/shared@1.3.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.2.0](https://github.com/adobe/spectrum-web-components/compare/v1.1.2...v1.2.0) (2025-02-27) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [1.1.2](https://github.com/adobe/spectrum-web-components/compare/v1.1.1...v1.1.2) (2025-02-12) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [1.1.1](https://github.com/adobe/spectrum-web-components/compare/v1.1.0...v1.1.1) (2025-01-29) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [1.1.0](https://github.com/adobe/spectrum-web-components/compare/v1.0.3...v1.1.0) (2025-01-29) + +### Bug Fixes + +- lock prerelease versions for Spectrum CSS ([#5014](https://github.com/adobe/spectrum-web-components/issues/5014)) ([8aa7734](https://github.com/adobe/spectrum-web-components/commit/8aa77342f169b75ecbd1c07a2a1050860b182822)) + +## [1.0.3](https://github.com/adobe/spectrum-web-components/compare/v1.0.1...v1.0.3) (2024-12-09) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [1.0.1](https://github.com/adobe/spectrum-web-components/compare/v1.0.0...v1.0.1) (2024-11-11) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [1.0.0](https://github.com/adobe/spectrum-web-components/compare/v0.49.0...v1.0.0) (2024-10-31) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.49.0](https://github.com/adobe/spectrum-web-components/compare/v0.48.1...v0.49.0) (2024-10-15) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.48.1](https://github.com/adobe/spectrum-web-components/compare/v0.48.0...v0.48.1) (2024-10-01) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.48.0](https://github.com/adobe/spectrum-web-components/compare/v0.47.2...v0.48.0) (2024-09-17) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.47.2](https://github.com/adobe/spectrum-web-components/compare/v0.47.1...v0.47.2) (2024-09-03) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.47.1](https://github.com/adobe/spectrum-web-components/compare/v0.47.0...v0.47.1) (2024-08-27) + +### Bug Fixes + +- **reactive-controllers:** update focusable element's tab-index to 0 on accepting focus ([#4630](https://github.com/adobe/spectrum-web-components/issues/4630)) ([d359e84](https://github.com/adobe/spectrum-web-components/commit/d359e844fb00ff3a52f7f4346038aa8d5b620025)) + +# [0.47.0](https://github.com/adobe/spectrum-web-components/compare/v0.46.0...v0.47.0) (2024-08-20) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.46.0](https://github.com/adobe/spectrum-web-components/compare/v0.45.0...v0.46.0) (2024-08-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.45.0](https://github.com/adobe/spectrum-web-components/compare/v0.44.0...v0.45.0) (2024-07-30) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.44.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.44.0) (2024-07-15) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.43.0](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.43.0) (2024-06-11) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.42.5](https://github.com/adobe/spectrum-web-components/compare/v0.42.4...v0.42.5) (2024-05-24) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.42.4](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.4) (2024-05-14) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.42.3](https://github.com/adobe/spectrum-web-components/compare/v0.42.2...v0.42.3) (2024-05-01) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.42.2](https://github.com/adobe/spectrum-web-components/compare/v0.42.1...v0.42.2) (2024-04-03) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.42.1](https://github.com/adobe/spectrum-web-components/compare/v0.42.0...v0.42.1) (2024-04-02) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.42.0](https://github.com/adobe/spectrum-web-components/compare/v0.41.2...v0.42.0) (2024-03-19) + +### Features + +- **asset:** use core tokens ([99e76f4](https://github.com/adobe/spectrum-web-components/commit/99e76f4d32e990960b7fa2f0613ed4144adc4f6e)) + +## [0.41.2](https://github.com/adobe/spectrum-web-components/compare/v0.41.1...v0.41.2) (2024-03-05) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.41.1](https://github.com/adobe/spectrum-web-components/compare/v0.41.0...v0.41.1) (2024-02-22) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.41.0](https://github.com/adobe/spectrum-web-components/compare/v0.40.5...v0.41.0) (2024-02-13) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.40.5](https://github.com/adobe/spectrum-web-components/compare/v0.40.4...v0.40.5) (2024-02-05) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.40.4](https://github.com/adobe/spectrum-web-components/compare/v0.40.3...v0.40.4) (2024-01-29) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.40.3](https://github.com/adobe/spectrum-web-components/compare/v0.40.2...v0.40.3) (2024-01-11) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.40.2](https://github.com/adobe/spectrum-web-components/compare/v0.40.1...v0.40.2) (2023-12-18) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.40.1](https://github.com/adobe/spectrum-web-components/compare/v0.40.0...v0.40.1) (2023-12-05) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.40.0](https://github.com/adobe/spectrum-web-components/compare/v0.39.4...v0.40.0) (2023-11-16) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.39.4](https://github.com/adobe/spectrum-web-components/compare/v0.39.3...v0.39.4) (2023-11-02) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.39.3](https://github.com/adobe/spectrum-web-components/compare/v0.39.2...v0.39.3) (2023-10-18) + +### Bug Fixes + +- update deps graph, fix imports ([f633005](https://github.com/adobe/spectrum-web-components/commit/f633005e26bff640615f157b54830bfb0677d682)) + +## [0.39.2](https://github.com/adobe/spectrum-web-components/compare/v0.39.1...v0.39.2) (2023-10-13) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.39.1](https://github.com/adobe/spectrum-web-components/compare/v0.39.0...v0.39.1) (2023-10-06) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.39.0](https://github.com/adobe/spectrum-web-components/compare/v0.38.0...v0.39.0) (2023-09-25) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.38.0](https://github.com/adobe/spectrum-web-components/compare/v0.37.0...v0.38.0) (2023-09-05) + +### Bug Fixes + +- **sidenav:** reintroduce support for slotted label content ([26c7e6e](https://github.com/adobe/spectrum-web-components/commit/26c7e6e5c6065e7e8e44700fb03092b12d267a94)) + +# [0.37.0](https://github.com/adobe/spectrum-web-components/compare/v0.36.0...v0.37.0) (2023-08-18) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.36.0](https://github.com/adobe/spectrum-web-components/compare/v0.35.0...v0.36.0) (2023-08-18) + +### Features + +- **sidenav:** migrate to core tokens ([1846aa3](https://github.com/adobe/spectrum-web-components/commit/1846aa30d763b1f88801b9e26c16d2c20d5b4a6a)) + +# [0.35.0](https://github.com/adobe/spectrum-web-components/compare/v0.34.0...v0.35.0) (2023-07-31) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.34.0](https://github.com/adobe/spectrum-web-components/compare/v0.33.2...v0.34.0) (2023-07-11) + +### Bug Fixes + +- **sidenav:** express hierarchy using list and listitem ([f9019d7](https://github.com/adobe/spectrum-web-components/commit/f9019d7f5a37c81b61395d5329b251317497a685)), closes [#3348](https://github.com/adobe/spectrum-web-components/issues/3348) [#3348](https://github.com/adobe/spectrum-web-components/issues/3348) + +## [0.33.2](https://github.com/adobe/spectrum-web-components/compare/v0.33.1...v0.33.2) (2023-06-14) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.33.0](https://github.com/adobe/spectrum-web-components/compare/v0.32.0...v0.33.0) (2023-06-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.32.0](https://github.com/adobe/spectrum-web-components/compare/v0.31.0...v0.32.0) (2023-06-01) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.31.0](https://github.com/adobe/spectrum-web-components/compare/v0.30.0...v0.31.0) (2023-05-17) + +### Bug Fixes + +- generate react/picker and pass react TS checks ([101b88c](https://github.com/adobe/spectrum-web-components/commit/101b88c9d1607023e073a985a2b46d2dce2c9c82)) + +# 0.30.0 (2023-05-03) + +### Bug Fixes + +- [#2933](https://github.com/adobe/spectrum-web-components/issues/2933) by adding optional variant property to SideNav ([9c45c33](https://github.com/adobe/spectrum-web-components/commit/9c45c337e0434045729de2acafa2218817890261)) +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) +- correct a11y tree ([f7e54e5](https://github.com/adobe/spectrum-web-components/commit/f7e54e5b07c7f374952ad1558ab44880b08f5e7d)) +- correctly track "activeElement" across shadow boundaries ([8b9f93a](https://github.com/adobe/spectrum-web-components/commit/8b9f93ad5a66515f95053f559bc9e04d96063f0a)) +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) +- ensure item exists when attempting to acquire next item to focus ([fb52cea](https://github.com/adobe/spectrum-web-components/commit/fb52ceac75f76943788411b206fd39739ff66a54)) +- fix expanding sidenav item that has no value ([b28cdac](https://github.com/adobe/spectrum-web-components/commit/b28cdacf3b8a5d5676af57a47f3d9d8c6d4b876e)) +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716f2f787deb8d868a78bd28c8e62fe90e21)) +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cdac98282c886f23c4a8d6cf4910c4a606c)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- prevent tabindex=-1 elements from placing focus on their host ([1ac1293](https://github.com/adobe/spectrum-web-components/commit/1ac12931771c6d5fdbc99f5d214702ed644cb81a)) +- **sidenav:** add aria-current when using href with sidenav-item ([9172639](https://github.com/adobe/spectrum-web-components/commit/9172639f54cad57111d3ced348a747e8ea5a285a)) +- **sidenav:** add support for icons and document icons/headlines ([9ddb363](https://github.com/adobe/spectrum-web-components/commit/9ddb3630020b2ea669411b73fc4ecc9cee917014)) +- **sidenav:** manage tabindex when interacting with keyboard ([ea977cf](https://github.com/adobe/spectrum-web-components/commit/ea977cf1ceac9b74fb1789bf8f72bfe1d3c72b03)) +- **sidenav:** prevent items with hrefs from toggling expanded or selection ([7ff4920](https://github.com/adobe/spectrum-web-components/commit/7ff4920bc14aac7709f1c588078730aa9054bae3)) +- **sidenav:** tighten Spectrum adherence and sharpen docs delivery ([d4c70cd](https://github.com/adobe/spectrum-web-components/commit/d4c70cd73b506cec103ef47bd2ec6f6bacebf9c7)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- style clean up ([49e1537](https://github.com/adobe/spectrum-web-components/commit/49e15377f3a839d0ed5dc2504dd71396aa156eb5)) +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) +- update slotting in "sp-sidenav-item" to allow for labelling in HTML ([928c476](https://github.com/adobe/spectrum-web-components/commit/928c476294c482f1d3acf1b787ef995f960edcbb)) +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- implement [#2964](https://github.com/adobe/spectrum-web-components/issues/2964) for sidenav component ([99afac9](https://github.com/adobe/spectrum-web-components/commit/99afac986f1ddf45cc6d0486306cdac246f8764a)) +- implement [#2964](https://github.com/adobe/spectrum-web-components/issues/2964) for sidenav component ([5bf36e5](https://github.com/adobe/spectrum-web-components/commit/5bf36e56c132781b62a28eeb5a01c523aa6633bb)) +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) +- shared pkg versions, devmode define warning, registry-conflicts docs ([6e49565](https://github.com/adobe/spectrum-web-components/commit/6e4956519b845fa8127f8032948b625c252ef7a6)) +- **sidenav:** add a "change" event to track the "value" property ([8d3a0bd](https://github.com/adobe/spectrum-web-components/commit/8d3a0bd93bdd9dbad66df0b895ff8101128776fa)) +- **sidenav:** add keyboard accessibility ([6ff622b](https://github.com/adobe/spectrum-web-components/commit/6ff622bf89ad319a7d464fbdd2477c7b55b65cdd)) +- **sidenav:** update spectrum css input ([bd43201](https://github.com/adobe/spectrum-web-components/commit/bd43201749948479216400af6c320c1c6dd269cd)) +- support rel attribute for sidenav item ([90522e7](https://github.com/adobe/spectrum-web-components/commit/90522e79f57df974b3610877143d32d6885c4c41)) +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc77960de8e57dd9c49bb7669df689f0ebaa)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/39188887afad9bec52ef48d4e22596f9b757a9fe)) +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0accd643c2f35cbf1ba809b54f52c25628d)) + +### Reverts + +- Revert "chore: release new versions" ([a6d655d](https://github.com/adobe/spectrum-web-components/commit/a6d655d1435ee6427a3778b89f1a6cf9fe4beb9d)) + +## [0.14.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.14.2...@spectrum-web-components/sidenav@0.14.3) (2023-04-24) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.14.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.14.1...@spectrum-web-components/sidenav@0.14.2) (2023-04-05) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.14.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.14.0...@spectrum-web-components/sidenav@0.14.1) (2023-03-22) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.14.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.10...@spectrum-web-components/sidenav@0.14.0) (2023-03-08) + +### Features + +- implement [#2964](https://github.com/adobe/spectrum-web-components/issues/2964) for sidenav component ([99afac9](https://github.com/adobe/spectrum-web-components/commit/99afac986f1ddf45cc6d0486306cdac246f8764a)) +- implement [#2964](https://github.com/adobe/spectrum-web-components/issues/2964) for sidenav component ([5bf36e5](https://github.com/adobe/spectrum-web-components/commit/5bf36e56c132781b62a28eeb5a01c523aa6633bb)) + +## [0.13.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.9...@spectrum-web-components/sidenav@0.13.10) (2023-02-21) + +### Bug Fixes + +- [#2933](https://github.com/adobe/spectrum-web-components/issues/2933) by adding optional variant property to SideNav ([9c45c33](https://github.com/adobe/spectrum-web-components/commit/9c45c337e0434045729de2acafa2218817890261)) + +## [0.13.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.8...@spectrum-web-components/sidenav@0.13.9) (2023-02-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.7...@spectrum-web-components/sidenav@0.13.8) (2023-01-23) + +### Bug Fixes + +- **sidenav:** prevent items with hrefs from toggling expanded or selection ([7ff4920](https://github.com/adobe/spectrum-web-components/commit/7ff4920bc14aac7709f1c588078730aa9054bae3)) + +## [0.13.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.6...@spectrum-web-components/sidenav@0.13.7) (2023-01-09) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.5...@spectrum-web-components/sidenav@0.13.6) (2022-12-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.4...@spectrum-web-components/sidenav@0.13.5) (2022-11-21) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.3...@spectrum-web-components/sidenav@0.13.4) (2022-11-14) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.2...@spectrum-web-components/sidenav@0.13.3) (2022-10-28) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.1...@spectrum-web-components/sidenav@0.13.2) (2022-10-17) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.13.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.13.0...@spectrum-web-components/sidenav@0.13.1) (2022-10-10) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.13.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.15...@spectrum-web-components/sidenav@0.13.0) (2022-08-09) + +### Features + +- include all Dev Mode files in side effects ([f70817c](https://github.com/adobe/spectrum-web-components/commit/f70817cc15db6dcf5cc1de2d82b4f7b0c80b1251)) + +## [0.12.15](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.14...@spectrum-web-components/sidenav@0.12.15) (2022-08-04) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.14](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.13...@spectrum-web-components/sidenav@0.12.14) (2022-07-18) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.13](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.12...@spectrum-web-components/sidenav@0.12.13) (2022-06-29) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.12](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.11...@spectrum-web-components/sidenav@0.12.12) (2022-06-07) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.11](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.10...@spectrum-web-components/sidenav@0.12.11) (2022-05-27) + +### Bug Fixes + +- update consumption of Spectrum CSS for latest version ([ed2305b](https://github.com/adobe/spectrum-web-components/commit/ed2305b7334c973ea5c8299cbbce33a365896329)) + +## [0.12.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.9...@spectrum-web-components/sidenav@0.12.10) (2022-05-12) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.8...@spectrum-web-components/sidenav@0.12.9) (2022-04-21) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.7...@spectrum-web-components/sidenav@0.12.8) (2022-03-30) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.6...@spectrum-web-components/sidenav@0.12.7) (2022-03-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.5...@spectrum-web-components/sidenav@0.12.6) (2022-03-04) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.4...@spectrum-web-components/sidenav@0.12.5) (2022-02-22) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.3...@spectrum-web-components/sidenav@0.12.4) (2022-02-02) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.2...@spectrum-web-components/sidenav@0.12.3) (2022-01-26) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.1...@spectrum-web-components/sidenav@0.12.2) (2022-01-07) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.12.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.12.0...@spectrum-web-components/sidenav@0.12.1) (2021-12-13) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.12.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.11.1...@spectrum-web-components/sidenav@0.12.0) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.11.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.11.0...@spectrum-web-components/sidenav@0.11.1) (2021-11-08) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.11.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.10...@spectrum-web-components/sidenav@0.11.0) (2021-11-02) + +### Features + +- adopt DNA@7 base Spectrum CSS ([e08cafd](https://github.com/adobe/spectrum-web-components/commit/e08cafda9f1b33b0163fbe5ba66754806be8f9e4)) + +## [0.10.10](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.9...@spectrum-web-components/sidenav@0.10.10) (2021-10-12) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.9](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.8...@spectrum-web-components/sidenav@0.10.9) (2021-09-20) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.7...@spectrum-web-components/sidenav@0.10.8) (2021-09-13) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.6...@spectrum-web-components/sidenav@0.10.7) (2021-08-24) + +### Bug Fixes + +- correct [@element](https://github.com/element) jsDoc listing across library ([c97a632](https://github.com/adobe/spectrum-web-components/commit/c97a6320c16a2b3053637e22bca0d56ce0cd5ae5)) + +## [0.10.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.5...@spectrum-web-components/sidenav@0.10.6) (2021-08-17) + +### Bug Fixes + +- update slotting in "sp-sidenav-item" to allow for labelling in HTML ([928c476](https://github.com/adobe/spectrum-web-components/commit/928c476294c482f1d3acf1b787ef995f960edcbb)) + +## [0.10.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.4...@spectrum-web-components/sidenav@0.10.5) (2021-07-22) + +### Bug Fixes + +- style clean up ([49e1537](https://github.com/adobe/spectrum-web-components/commit/49e15377f3a839d0ed5dc2504dd71396aa156eb5)) + +## [0.10.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.3...@spectrum-web-components/sidenav@0.10.4) (2021-07-01) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.2...@spectrum-web-components/sidenav@0.10.3) (2021-06-16) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.1...@spectrum-web-components/sidenav@0.10.2) (2021-06-07) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.10.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.10.0...@spectrum-web-components/sidenav@0.10.1) (2021-05-24) + +### Bug Fixes + +- prevent tabindex=-1 elements from placing focus on their host ([1ac1293](https://github.com/adobe/spectrum-web-components/commit/1ac12931771c6d5fdbc99f5d214702ed644cb81a)) + +# [0.10.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.5...@spectrum-web-components/sidenav@0.10.0) (2021-05-12) + +### Bug Fixes + +- ensure item exists when attempting to acquire next item to focus ([fb52cea](https://github.com/adobe/spectrum-web-components/commit/fb52ceac75f76943788411b206fd39739ff66a54)) + +### Features + +- **sidenav:** add a "change" event to track the "value" property ([8d3a0bd](https://github.com/adobe/spectrum-web-components/commit/8d3a0bd93bdd9dbad66df0b895ff8101128776fa)) + +## [0.9.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.4...@spectrum-web-components/sidenav@0.9.5) (2021-04-15) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.9.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.3...@spectrum-web-components/sidenav@0.9.4) (2021-04-09) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.9.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.2...@spectrum-web-components/sidenav@0.9.3) (2021-03-29) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.9.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.1...@spectrum-web-components/sidenav@0.9.2) (2021-03-22) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.9.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.9.0...@spectrum-web-components/sidenav@0.9.1) (2021-03-05) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.9.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.8.1...@spectrum-web-components/sidenav@0.9.0) (2021-03-04) + +### Features + +- use latest exports specification ([a7ecf4b](https://github.com/adobe/spectrum-web-components/commit/a7ecf4b6da7996f36a8a89f62cc2384709497008)) + +## [0.8.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.8.0...@spectrum-web-components/sidenav@0.8.1) (2021-02-11) + +### Bug Fixes + +- update to latest spectrum-css packages ([a5ca19f](https://github.com/adobe/spectrum-web-components/commit/a5ca19f67d5b3f0951667c4441d4d977bf1e0937)) + +# [0.8.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.6.0...@spectrum-web-components/sidenav@0.8.0) (2021-01-21) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled] ([2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **sidenav:** update spectrum css input ([bd43201](https://github.com/adobe/spectrum-web-components/commit/bd43201749948479216400af6c320c1c6dd269cd)) + +# [0.7.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.6.0...@spectrum-web-components/sidenav@0.7.0) (2021-01-13) + +### Bug Fixes + +- include the "types" entry in package.json files ([b432f59](https://github.com/adobe/spectrum-web-components/commit/b432f5982b3b79f80af12f6d0312cbe2285e608b)) +- prevent infinite loops when all children are [disabled](<[2deac3d](https://github.com/adobe/spectrum-web-components/commit/2deac3d88ea7f2f27e74d60793e253952d0d765f)>) +- stop merging selectors in a way that alters the cascade ([369388f](https://github.com/adobe/spectrum-web-components/commit/369388f8cc147543891087991c569f849ddb9b38)) +- update latest Spectrum CSS beta releases ([d8d3acc](https://github.com/adobe/spectrum-web-components/commit/d8d3acc86de31e58219db6ba2a9d045b83cbe103)) +- use latest @spectrum-css/\* versions ([c35eb86](https://github.com/adobe/spectrum-web-components/commit/c35eb86defd89a0c36b5ea186f6d40f20851b5e5)) + +### Features + +- **action-button:** add action button pattern ([03ac00a](https://github.com/adobe/spectrum-web-components/commit/03ac00a710290e6a78340f206d88385a4f8ae8c2)) +- **icons-workflow:** vend fully registered icon components ([941f3a4](https://github.com/adobe/spectrum-web-components/commit/941f3a41486fbd49eca0805fb63383f63313e71e)) +- **sidenav:** update spectrum css input ([bd43201](https://github.com/adobe/spectrum-web-components/commit/bd43201749948479216400af6c320c1c6dd269cd)) + +# [0.6.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.5.4...@spectrum-web-components/sidenav@0.6.0) (2020-11-20) + +### Features + +- support rel attribute for sidenav item ([90522e7](https://github.com/adobe/spectrum-web-components/commit/90522e79f57df974b3610877143d32d6885c4c41)) + +## [0.5.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.5.3...@spectrum-web-components/sidenav@0.5.4) (2020-10-12) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.5.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.5.2...@spectrum-web-components/sidenav@0.5.3) (2020-10-12) + +### Bug Fixes + +- include default export in the "exports" fields ([f32407d](https://github.com/adobe/spectrum-web-components/commit/f32407d7bbfd18e72c35b6f27740549e79957858)) + +## [0.5.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.5.1...@spectrum-web-components/sidenav@0.5.2) (2020-09-25) + +### Bug Fixes + +- update side effect listings ([8160d3a](https://github.com/adobe/spectrum-web-components/commit/8160d3ab2c4f5ea11ac40897a5cf1fdaa357f4a8)) + +## [0.5.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.5.0...@spectrum-web-components/sidenav@0.5.1) (2020-09-14) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.5.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.4.3...@spectrum-web-components/sidenav@0.5.0) (2020-08-31) + +### Features + +- update to Spectrum CSS v3.0.0 ([e8b3d8f](https://github.com/adobe/spectrum-web-components/commit/e8b3d8f75c77c04b4d7af126b91b0f6ad2a40742)) + +## [0.4.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.4.2...@spectrum-web-components/sidenav@0.4.3) (2020-08-19) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.4.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.4.1...@spectrum-web-components/sidenav@0.4.2) (2020-07-27) + +### Bug Fixes + +- ensure browser understandable extensions ([f4e59f7](https://github.com/adobe/spectrum-web-components/commit/f4e59f76f86369593810463c6406565e28ad97e9)) + +## [0.4.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.4.0...@spectrum-web-components/sidenav@0.4.1) (2020-07-22) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +# [0.4.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.8...@spectrum-web-components/sidenav@0.4.0) (2020-07-17) + +### Bug Fixes + +- **sidenav:** add aria-current when using href with sidenav-item ([9172639](https://github.com/adobe/spectrum-web-components/commit/9172639f54cad57111d3ced348a747e8ea5a285a)) +- **sidenav:** manage tabindex when interacting with keyboard ([ea977cf](https://github.com/adobe/spectrum-web-components/commit/ea977cf1ceac9b74fb1789bf8f72bfe1d3c72b03)) + +### Features + +- leverage "exports" field in package.json ([321abd7](https://github.com/adobe/spectrum-web-components/commit/321abd7b7e78ccd9157cff75a1fa3dbd06e81f79)) + +## [0.3.8](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.7...@spectrum-web-components/sidenav@0.3.8) (2020-06-08) + +### Bug Fixes + +- **sidenav:** add support for icons and document icons/headlines ([9ddb363](https://github.com/adobe/spectrum-web-components/commit/9ddb3630020b2ea669411b73fc4ecc9cee917014)) +- **sidenav:** tighten Spectrum adherence and sharpen docs delivery ([d4c70cd](https://github.com/adobe/spectrum-web-components/commit/d4c70cd73b506cec103ef47bd2ec6f6bacebf9c7)) + +## [0.3.7](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.6...@spectrum-web-components/sidenav@0.3.7) (2020-04-16) + +### Performance Improvements + +- use "sideEffects" listing in package.json ([7271614](https://github.com/adobe/spectrum-web-components/commit/7271614c0ca3ccf3566583bb59467eb15a6199cd)) + +## [0.3.6](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.5...@spectrum-web-components/sidenav@0.3.6) (2020-04-10) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.3.5](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.4...@spectrum-web-components/sidenav@0.3.5) (2020-04-07) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.3.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.3...@spectrum-web-components/sidenav@0.3.4) (2020-03-11) + +### Bug Fixes + +- correct a11y tree ([f7e54e5](https://github.com/adobe/spectrum-web-components/commit/f7e54e5)) + +## [0.3.3](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.2...@spectrum-web-components/sidenav@0.3.3) (2020-02-05) + +### Bug Fixes + +- correctly track "activeElement" across shadow boundaries ([8b9f93a](https://github.com/adobe/spectrum-web-components/commit/8b9f93a)) + +## [0.3.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.1...@spectrum-web-components/sidenav@0.3.2) (2020-02-01) + +**Note:** Version bump only for package @spectrum-web-components/sidenav + +## [0.3.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.3.0...@spectrum-web-components/sidenav@0.3.1) (2020-01-30) + +### Bug Fixes + +- fix expanding sidenav item that has no value ([b28cdac](https://github.com/adobe/spectrum-web-components/commit/b28cdac)) + +# [0.3.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.2.2...@spectrum-web-components/sidenav@0.3.0) (2020-01-06) + +### Features + +- **sidenav:** add keyboard accessibility ([6ff622b](https://github.com/adobe/spectrum-web-components/commit/6ff622b)) + +## [0.2.2](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.2.1...@spectrum-web-components/sidenav@0.2.2) (2019-12-02) + +### Bug Fixes + +- normalize "event" and "error" argument names ([8d382cd](https://github.com/adobe/spectrum-web-components/commit/8d382cd)) + +## [0.2.1](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.2.0...@spectrum-web-components/sidenav@0.2.1) (2019-11-27) + +### Bug Fixes + +- include "type" in package.json, generate custom-elements.json ([1a8d716](https://github.com/adobe/spectrum-web-components/commit/1a8d716)) + +# [0.2.0](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.1.4...@spectrum-web-components/sidenav@0.2.0) (2019-11-19) + +### Features + +- use :focus-visable (via polyfill) instead of :focus ([11c6fc7](https://github.com/adobe/spectrum-web-components/commit/11c6fc7)) +- use @adobe/spectrum-css@2.15.1 ([3918888](https://github.com/adobe/spectrum-web-components/commit/3918888)) + +## [0.1.4](https://github.com/adobe/spectrum-web-components/compare/@spectrum-web-components/sidenav@0.1.3...@spectrum-web-components/sidenav@0.1.4) (2019-10-14) + +### Performance Improvements + +- use imported TypeScript helpers instead of inlining them ([cc2bd0a](https://github.com/adobe/spectrum-web-components/commit/cc2bd0a)) + +## 0.1.3 (2019-10-03) + +**Note:** Version bump only for package @spectrum-web-components/sidenav diff --git a/1st-gen/packages/sidenav/README.md b/1st-gen/packages/sidenav/README.md new file mode 100644 index 00000000000..005468534ca --- /dev/null +++ b/1st-gen/packages/sidenav/README.md @@ -0,0 +1,254 @@ +## Overview + +Side navigation allows users to locate information and features within the UI. +It can be used for either hierarchical or flat navigation, and gives the ability +to group navigable items categorically. Side navigation is an opportunity to +prioritize content or features based on your users’ needs in a way that +maintains clear, persistent visibility. Use side navigation within the context +of larger elements and mechanisms within the app frame. + +`` elements accept both `` and `` elements as children in order to construct a hierarchy of navigation elements. [``](/components/sidenav-item/) elements will place themselves as a togglable child of their `` element parent. [``](/components/sidenav-heading/) elements will create visible structure by grouping their `` children under a non-interactive heading. + +[View the design documentation for this component.](https://spectrum.adobe.com/page/side-navigation/) + +### Usage + +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/sidenav?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/sidenav) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/sidenav?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/sidenav) +[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-q3w6kjxv) + +```bash +yarn add @spectrum-web-components/sidenav +``` + +Import the side effectful registration of ``, ``, or `` via: + +```js +import '@spectrum-web-components/sidenav/sp-sidenav.js'; +import '@spectrum-web-components/sidenav/sp-sidenav-heading.js'; +import '@spectrum-web-components/sidenav/sp-sidenav-item.js'; +``` + +When looking to leverage the `Sidenav`, `SidenavHeading`, or `SidenavItem` base classes as a type and/or for extension purposes, do so via: + +```js +import { + Sidenav, + SidenavHeading, + SidenavItem, +} from '@spectrum-web-components/sidenav'; +``` + +### Anatomy + +The side navigation consists of several key parts: + +- A container element that manages the side navigation behavior +- Individual side navigation items that may or may not be expandable +- Children side navigation items that are revealed when a parent item is expanded +- Optional heading with a label + +```html live-demo + + + + + + +``` + +### Options + + +Default (single-level) + + +Make sure to use the right option for the context and user needs. Don’t mix behavior, styles, or variations together in a single navigation menu. Follow these guidelines: + +- When navigation is simple, use the single level side navigation. +- When navigation is simple but categorical, use the single level side navigation with headers. +- When navigation is expansive, hierarchical, and/or you need progressive disclosure in the menu behavior, use the multi-level side navigation. Up to three levels of navigation are supported. + +```html + + + + + + + + +``` + + +Single-level with icons + + +In single-level side navigation, do not mix icon usage between side nav items. Either all side nav items have icons, or no items have icons. In cases where the navigation content might be user-generated, stick to text-only navigation items. + +```html + + + + + + + + + + + +``` + + +With headings + + +Use headings in single level side navigation when it's beneficial to group navigation items into categories. The headings are not interactive. If items don’t fall into a category, place them at the top. When using the heading variation, an entire category should either all have icons or all be text-only. + +Although headings can be used in multi-level side navigation, they can only be used as first-level items, and are not to be nested. + +```html + + + + + + + + + + + + +``` + + +Multi-level + + +Use `variant="multilevel"` when you have multiple layers of hierarchical navigation. +In the instances where a top-level navigation item has no children, clicking +will send the user to the location of the item. Additionally, headings can be used +in multi-level side navigation, but they can only be used as first-level items, and are not to be nested. + +Up to three levels of navigation are supported. + +```html + + + + + + + + + + + + + +``` + + +Multi-level with icons + + +In multi-level side navigation, icon and text-only navigation items can be used in combination, but only the first-level items can have icons to maintain visual clarity and hierarchy. Icons only appear on first-level items, and sublevels (second and third) should not include icons. In cases where the navigation content might be user-generated, stick to text-only navigation items. + +#### Multi-level side navigation icon usage + +- All icons: all items have icons +- No icons: no items have icons +- Mixed icons: only first-level items have icons; second and third-level items do not + +```html + + + + + + + + + + + + + + + + + +``` + + + + +### Behaviors + +When an side navigation item is programmatically selected in `variant="multilevel"`, all of its parent items automatically expand to reveal the selection path. + +### Accessibility + +When the `manage-tab-index` attribute is set on an `` element, it will present its `` children with a single tab-stop. This will leave items beyond the selected item (or when there is no focusable selected item), accessible via the up and down arrow keys. Items with expanded children that aren't selected lose focus when `manage-tab-index` is active. + +#### Roles and ARIA attributes + +- `` renders a `