@adobe/spectrum-wc-core 2.0.0-beta.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -9
- package/dist/components/accordion/Accordion.base.js +28 -22
- package/dist/components/accordion/Accordion.base.js.map +1 -1
- package/dist/components/accordion/AccordionItem.base.d.ts +16 -6
- package/dist/components/accordion/AccordionItem.base.js +6 -3
- package/dist/components/accordion/AccordionItem.base.js.map +1 -1
- package/dist/components/action-group/ActionGroup.base.d.ts +108 -0
- package/dist/components/action-group/ActionGroup.base.js +53 -0
- package/dist/components/action-group/ActionGroup.base.js.map +1 -0
- package/dist/components/action-group/ActionGroup.types.d.ts +17 -0
- package/dist/components/action-group/ActionGroup.types.js +12 -0
- package/dist/components/action-group/ActionGroup.types.js.map +1 -0
- package/dist/components/action-group/index.d.ts +13 -0
- package/dist/components/action-group/index.js +3 -0
- package/dist/components/alert-banner/AlertBanner.base.js +11 -10
- package/dist/components/alert-banner/AlertBanner.base.js.map +1 -1
- package/dist/components/asset/Asset.base.d.ts +1 -1
- package/dist/components/asset/Asset.base.js +14 -8
- package/dist/components/asset/Asset.base.js.map +1 -1
- package/dist/components/avatar/Avatar.base.js +18 -22
- package/dist/components/avatar/Avatar.base.js.map +1 -1
- package/dist/components/badge/Badge.base.d.ts +24 -8
- package/dist/components/badge/Badge.base.js +22 -17
- package/dist/components/badge/Badge.base.js.map +1 -1
- package/dist/components/button/Button.base.d.ts +20 -10
- package/dist/components/button/Button.base.js +17 -12
- package/dist/components/button/Button.base.js.map +1 -1
- package/dist/components/button-group/ButtonGroup.base.js +19 -12
- package/dist/components/button-group/ButtonGroup.base.js.map +1 -1
- package/dist/components/card/Card.base.d.ts +95 -46
- package/dist/components/card/Card.base.js +71 -23
- package/dist/components/card/Card.base.js.map +1 -1
- package/dist/components/card/Card.types.d.ts +1 -0
- package/dist/components/card/Card.types.js +2 -2
- package/dist/components/card/Card.types.js.map +1 -1
- package/dist/components/card/index.js +3 -3
- package/dist/components/divider/Divider.base.js +13 -8
- package/dist/components/divider/Divider.base.js.map +1 -1
- package/dist/components/dropzone/Dropzone.base.d.ts +74 -0
- package/dist/components/dropzone/Dropzone.base.js +82 -0
- package/dist/components/dropzone/Dropzone.base.js.map +1 -0
- package/dist/components/dropzone/Dropzone.types.d.ts +43 -0
- package/dist/components/dropzone/Dropzone.types.js +15 -0
- package/dist/components/dropzone/Dropzone.types.js.map +1 -0
- package/dist/components/dropzone/index.d.ts +13 -0
- package/dist/components/dropzone/index.js +3 -0
- package/dist/components/icon/Icon.base.d.ts +11 -7
- package/dist/components/icon/Icon.base.js +13 -20
- package/dist/components/icon/Icon.base.js.map +1 -1
- package/dist/components/illustrated-message/IllustratedMessage.base.d.ts +22 -8
- package/dist/components/illustrated-message/IllustratedMessage.base.js +33 -20
- package/dist/components/illustrated-message/IllustratedMessage.base.js.map +1 -1
- package/dist/components/infield-button/InfieldButton.base.d.ts +28 -0
- package/dist/components/infield-button/InfieldButton.base.js +22 -0
- package/dist/components/infield-button/InfieldButton.base.js.map +1 -0
- package/dist/components/infield-button/InfieldButton.types.d.ts +13 -0
- package/dist/components/infield-button/InfieldButton.types.js +11 -0
- package/dist/components/infield-button/InfieldButton.types.js.map +1 -0
- package/dist/components/infield-button/index.d.ts +13 -0
- package/dist/components/infield-button/index.js +3 -0
- package/dist/components/meter/Meter.base.js +11 -9
- package/dist/components/meter/Meter.base.js.map +1 -1
- package/dist/components/popover/Popover.base.js +46 -42
- package/dist/components/popover/Popover.base.js.map +1 -1
- package/dist/components/progress-circle/ProgressCircle.base.d.ts +0 -1
- package/dist/components/progress-circle/ProgressCircle.base.js +26 -22
- package/dist/components/progress-circle/ProgressCircle.base.js.map +1 -1
- package/dist/components/status-light/StatusLight.base.d.ts +1 -1
- package/dist/components/status-light/StatusLight.base.js +12 -9
- package/dist/components/status-light/StatusLight.base.js.map +1 -1
- package/dist/components/tabs/Tabs.base.js +44 -32
- package/dist/components/tabs/Tabs.base.js.map +1 -1
- package/dist/components/tooltip/Tooltip.base.js +57 -22
- package/dist/components/tooltip/Tooltip.base.js.map +1 -1
- package/dist/controllers/color-controller/src/color-controller.js +45 -44
- package/dist/controllers/color-controller/src/color-controller.js.map +1 -1
- package/dist/controllers/drag-and-drop-controller/index.d.ts +12 -0
- package/dist/controllers/drag-and-drop-controller/index.js +2 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.d.ts +68 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js +56 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js.map +1 -0
- package/dist/controllers/index.d.ts +4 -1
- package/dist/controllers/index.js +14 -11
- package/dist/controllers/page-scroll-lock-controller/index.d.ts +12 -0
- package/dist/controllers/page-scroll-lock-controller/index.js +2 -0
- package/dist/controllers/{page-scroll-lock.js → page-scroll-lock-controller/src/page-scroll-lock.js} +1 -1
- package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.js.map +1 -0
- package/dist/controllers/slot-presence-controller/index.d.ts +12 -0
- package/dist/controllers/slot-presence-controller/index.js +2 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.d.ts +57 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js +44 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js.map +1 -0
- package/dist/controllers/slot-text-controller/index.d.ts +12 -0
- package/dist/controllers/slot-text-controller/index.js +2 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.d.ts +92 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.js +53 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.js.map +1 -0
- package/dist/element/index.d.ts +1 -1
- package/dist/element/index.js +2 -2
- package/dist/element/spectrum-element.d.ts +58 -15
- package/dist/element/spectrum-element.js +55 -36
- package/dist/element/spectrum-element.js.map +1 -1
- package/dist/element/version.d.ts +2 -2
- package/dist/element/version.js +1 -1
- package/dist/element/version.js.map +1 -1
- package/dist/mixins/index.d.ts +0 -2
- package/dist/mixins/index.js +4 -6
- package/dist/mixins/linear-progress-mixin.d.ts +1 -2
- package/dist/mixins/linear-progress-mixin.js +35 -34
- package/dist/mixins/linear-progress-mixin.js.map +1 -1
- package/dist/mixins/pending-mixin.js +12 -11
- package/dist/mixins/pending-mixin.js.map +1 -1
- package/dist/mixins/sized-mixin.d.ts +28 -0
- package/dist/mixins/sized-mixin.js +6 -6
- package/dist/mixins/sized-mixin.js.map +1 -1
- package/dist/utils/dev-validation.d.ts +88 -0
- package/dist/utils/dev-validation.js +33 -0
- package/dist/utils/dev-validation.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +12 -10
- package/dist/utils/is-focus-visible-in-tree.d.ts +33 -0
- package/dist/utils/is-focus-visible-in-tree.js +11 -0
- package/dist/utils/is-focus-visible-in-tree.js.map +1 -0
- package/package.json +68 -15
- package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/defineProperty.js +0 -12
- package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPrimitive.js +0 -14
- package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPropertyKey.js +0 -9
- package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/typeof.js +0 -11
- package/dist/controllers/page-scroll-lock.js.map +0 -1
- package/dist/mixins/observe-slot-presence.d.ts +0 -12
- package/dist/mixins/observe-slot-presence.js +0 -40
- package/dist/mixins/observe-slot-presence.js.map +0 -1
- package/dist/mixins/observe-slot-text.d.ts +0 -11
- package/dist/mixins/observe-slot-text.js +0 -60
- package/dist/mixins/observe-slot-text.js.map +0 -1
- /package/dist/controllers/{page-scroll-lock.d.ts → page-scroll-lock-controller/src/page-scroll-lock.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,51 +1,117 @@
|
|
|
1
1
|
# @spectrum-web-components/core
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#6444](https://github.com/adobe/spectrum-web-components/pull/6444) [`2b26e0b`](https://github.com/adobe/spectrum-web-components/commit/2b26e0b3b6e25d4852e9984472737bd3caa2dfae) Thanks [@rise-erpelding](https://github.com/rise-erpelding)! - Add the 2nd-gen `<swc-action-group>` file structure, API, accessibility semantics, and Spectrum 2 styling, migrated from the Spectrum 1 `<sp-action-group>`.
|
|
8
|
+
- **API**: `accessible-label`, `disabled`, `orientation` (`horizontal` / `vertical`), `compact`, `quiet`, `justified`, `size`, `static-color`; children are collected via the default slot (`swc-action-button` / `swc-action-menu`).
|
|
9
|
+
- **Accessibility**: host always `role="group"` (never `toolbar` or `radiogroup`); `accessible-label` reflects to `aria-label`; no `aria-orientation` on the host in either layout, matching `swc-button-group`; group `disabled` sets `aria-disabled="true"` on the host and propagates `aria-disabled` (not native `disabled`) to all children so they remain keyboard-reachable and discoverable per [APG: Focusability of disabled controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols); `FocusgroupNavigationController` wired with `skipDisabled: false` so `aria-disabled` children stay in the arrow-key sequence. A focused child's focus ring is no longer hidden behind an adjacent child's border in `compact` mode.
|
|
10
|
+
- **Styling**: full Spectrum 2 token-based CSS — sizes `xs`–`xl`, `orientation`, `justified` (equal-width children), and `compact` (shared-border join with correct corner rounding at the strip's outer edges only, in both orientations); `compact` has no visual effect when `quiet` is also set. Exposes `--swc-action-group-gap` for overriding the spacing between children. `vertical` orientation groups shrink-to-fit the longest child's label by default and stretch to fill an ancestor-imposed width when present (for example, multiple `swc-action-group` elements sharing a toolbar wrapper), so all children and sibling groups end up the same width without an explicit `inline-size`.
|
|
11
|
+
- **`ButtonBase` (core)**: click activation is now suppressed for any button whose host carries `aria-disabled="true"`, matching the existing suppression for `disabled` and `pending`. This is shared behavior for every `ButtonBase` subclass, not just `swc-action-button`.
|
|
12
|
+
- **`swc-action-button`**: added disabled-appearance CSS for the externally-set `aria-disabled` case (e.g. when disabled via a parent `swc-action-group`), including forced-colors system-color overrides. Exposes four logical corner-radius custom properties (`--swc-action-button-border-start-start-radius`, `-start-end-radius`, `-end-start-radius`, `-end-end-radius`), each falling back to the existing `--swc-action-button-border-radius`, so a parent `swc-action-group` can override individual corners in `compact` mode without affecting standalone usage. The button's `inline-size: 100%` (needed so it fills a stretched vertical `swc-action-group` parent) is excluded from the generated global stylesheet, so consumers using global action-button classes outside a component context are not forced full-width.
|
|
13
|
+
- **1st-gen `sp-action-group`**: added `@deprecated` JSDoc to `vertical`, `selects`, `selected`, and `emphasized`, plus a runtime `window.__swc.warn()` deprecation notice on the `selected` setter, ahead of removal in 2nd-gen.
|
|
14
|
+
|
|
15
|
+
- [#6644](https://github.com/adobe/spectrum-web-components/pull/6644) [`346746c`](https://github.com/adobe/spectrum-web-components/commit/346746cacd405fa1cd58b7fae3f164457968dec7) Thanks [@TarunAdobe](https://github.com/TarunAdobe)! - **feat(prompt-field):** Accept file drops anywhere over `swc-prompt-field` with a high-intensity solid-fill drop target and blue focus ring. The new `DragAndDropController` is exported for reuse by other components.
|
|
16
|
+
|
|
17
|
+
- [#6555](https://github.com/adobe/spectrum-web-components/pull/6555) [`3110850`](https://github.com/adobe/spectrum-web-components/commit/31108509505dcaf485e4d2582074ea5fa8189922) Thanks [@5t3ph](https://github.com/5t3ph)! - Add the 2nd-gen `<swc-card>`, the Spectrum 2 successor to `<sp-card>`.
|
|
18
|
+
- **API**: `variant` (`primary`/`secondary`/`tertiary`/`quiet`), `size` (`xs`–`xl`), `density`, and the `title-as-link` and `selectable` attributes. Content is slot-only (`preview`, `collection`, `media`, `title`, `actions`, `description`, default, `footer`); regular, collection, and gallery layouts are driven by slot presence. `selectable` dispatches `swc-card-click`.
|
|
19
|
+
- **Accessibility**: whole-card linking uses a consumer `<a>` in the `title` slot (Card takes no `href`); `selectable` makes the card focusable without setting an ARIA role; nested controls keep their own activation.
|
|
20
|
+
- **Styling**: shared CSS Grid layout with the `--swc-card-*` custom-property surface.
|
|
21
|
+
- **Core**: `CardBase` and the shared `renderCardTemplate` gain the card behavior and the `collection`/`media`/glyph rendering hooks.
|
|
22
|
+
|
|
23
|
+
`<swc-user-card>` and `<swc-product-card>` are not part of this release.
|
|
24
|
+
|
|
25
|
+
- [#6508](https://github.com/adobe/spectrum-web-components/pull/6508) [`d429a49`](https://github.com/adobe/spectrum-web-components/commit/d429a4991a51339b5325f726bd39d0d3c4ef447e) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - **feat(dev-validation):** Added reusable dev-mode validation helpers (`validateEnum`, `warnIf`, `validateRequiredSlot`, `validateAllowedChildren`) in `@adobe/spectrum-wc-core/utils`, and fixed `window.__swc.warn`'s dedup key so two distinct warnings on the same component no longer suppress each other.
|
|
26
|
+
|
|
27
|
+
Component authors should use these helpers instead of hand-rolled `includes()` + `window.__swc.warn()` checks for union/enum values, required and conditionally required properties, mutually exclusive/no-effect combinations, required slots, and allowed slotted children. See the "Reusable validation helpers" and "Slot validation" sections of the [Debug and validation style guide](https://github.com/adobe/spectrum-web-components/blob/main/CONTRIBUTOR-DOCS/02_style-guide/02_typescript/17_debug-validation.md).
|
|
28
|
+
|
|
29
|
+
- [#6437](https://github.com/adobe/spectrum-web-components/pull/6437) [`afe0beb`](https://github.com/adobe/spectrum-web-components/commit/afe0beb9e487d3f2838bb1ec7e98f131f53606af) Thanks [@cdransf](https://github.com/cdransf)! - Add the 2nd-gen `<swc-dropzone>`, migrated from the Spectrum 1 `<sp-dropzone>`.
|
|
30
|
+
- **API**: `dropEffect`, `dragged`, `filled`, `size` (new), and localizable `dragged-message`/`filled-message`/`replace-message` status text. Renames `isDragged`/`isFilled` to `dragged`/`filled` and events to the `swc-dropzone-*` prefix; adds a dedicated `filled-content` slot instead of restyling the default slot in place.
|
|
31
|
+
- **Accessibility**: fixed `role="group"` host requiring an accessible name, a visually-hidden `role="status"` region announcing drag and drop state changes, and no host `tabindex` (the slotted browse control owns the tab stop).
|
|
32
|
+
- **Styling**: SVG stroke border matching Spectrum 2's dashed-corner treatment, three sizes, and a small `--swc-dropzone-*` custom-property surface.
|
|
33
|
+
- **Docs and tests**: includes Storybook docs, a consumer migration guide, unit and accessibility tests, and dedicated VRT coverage.
|
|
34
|
+
|
|
35
|
+
**fix(illustrated-message):** `<swc-illustrated-message>`'s default slot is now reactive to content added after first render. It previously only re-evaluated on `characterData` mutations, missing element insertions such as a dynamically added illustration.
|
|
36
|
+
|
|
37
|
+
1st-gen `<sp-dropzone>` gains `@deprecated` JSDoc for `isDragged`/`isFilled`, `onDragOver`/`onDragLeave`/`onDrop`, and the removed `DropzoneEventDetail` type, plus matching development-mode console warnings for the upcoming `swc-dropzone-*` event rename and overriding the drag handler methods. `isDragged`/`isFilled` have no runtime warning: both attributes (`dragged`/`filled`) are unchanged and still valid, so Lit's attribute-to-property sync and (for `isDragged`) the component's own internal drag handling route through the same reactive properties a consumer's JS assignment would use, and a warning there would fire for ordinary, unmigrated attribute/template-binding usage the migration plan explicitly promises is unaffected.
|
|
38
|
+
|
|
39
|
+
- [#6563](https://github.com/adobe/spectrum-web-components/pull/6563) [`74a0c56`](https://github.com/adobe/spectrum-web-components/commit/74a0c56e25be120309a40c540ad750b7f1081f4b) Thanks [@Rajdeepc](https://github.com/Rajdeepc)! - Add the 2nd-gen `<swc-infield-button>`, the Spectrum 2 net-new icon button for form fields.
|
|
40
|
+
- **API**: `accessible-label` (required, maps to `aria-label` on the inner `<button>`), `size` (`s`/`m`/`l`/`xl`), `quiet`, and `disabled`. Does not inherit the 1st-gen link attributes (`href`, `target`, etc.) or position attributes (`block`, `inline`). Accepts icon content via the named `icon` slot.
|
|
41
|
+
- **Accessibility**: button is set to `tabindex="-1"` (not in the tab order); the parent field owns keyboard behavior and the visible focus ring. Missing `accessible-label` fires a dev-mode console warning.
|
|
42
|
+
- **Styling**: `--swc-infield-button-*` custom-property surface covering background-color and icon-color per interactive state. Quiet treatment removes the background.
|
|
43
|
+
- **Docs and tests**: includes Storybook docs, a consumer migration guide, unit and Playwright accessibility tests.
|
|
44
|
+
|
|
45
|
+
- [#6522](https://github.com/adobe/spectrum-web-components/pull/6522) [`735a6df`](https://github.com/adobe/spectrum-web-components/commit/735a6dfbd16767af716c5b3fe9a89b09714874a4) Thanks [@caseyisonit](https://github.com/caseyisonit)! - **refactor(core):** Replace the `ObserveSlotPresence` and `ObserveSlotText` mixins with reactive controllers, following the mixin-composition guidance to prefer controllers over deep mixin chains.
|
|
46
|
+
- **`@adobe/spectrum-wc-core`**: adds `SlotPresenceController` (`/controllers/slot-presence-controller`), which tracks whether slotted content matching one or more CSS selectors is present in the light DOM, and `SlotTextController` (`/controllers/slot-text-controller`), which tracks whether a slot has meaningful text or element content. Both are documented in the Controllers section of Storybook with stories and tests. The `ObserveSlotPresence` and `ObserveSlotText` mixins and their subpath exports (`/mixins/observe-slot-presence.js`, `/mixins/observe-slot-text.js`) are **removed**; consumers should construct the corresponding controller instead. `SlotTextController` requires binding `handleSlotChange` to the observed slot's `@slotchange` event.
|
|
47
|
+
- **`@adobe/spectrum-wc`**: `swc-badge`, `swc-button` (and its subclasses), `swc-accordion-item`, and the linear-progress components (`swc-progress-bar`, `swc-meter`) now derive their icon/label/actions/slot state from these controllers. No public API or behavioral change — the controllers reproduce the mixins' behavior.
|
|
48
|
+
|
|
49
|
+
- [#6523](https://github.com/adobe/spectrum-web-components/pull/6523) [`86f40a1`](https://github.com/adobe/spectrum-web-components/commit/86f40a1e0bc46d74c796e712f47d3428e0e4c7e5) Thanks [@caseyisonit](https://github.com/caseyisonit)! - **refactor(core):** Leaned out `SpectrumElement`.
|
|
50
|
+
- Removed `hasVisibleFocusInTree()` from `SpectrumMixin` / `SpectrumInterface`. The same behavior is now the standalone `isFocusVisibleInTree(root)` utility exported from `@adobe/spectrum-wc-core/utils`. Call `isFocusVisibleInTree(this.getRootNode() as Document | ShadowRoot)` where a component previously used `this.hasVisibleFocusInTree()`.
|
|
51
|
+
- Removed the `get dir()` override from `SpectrumElement`; `element.dir` now resolves to the standard DOM attribute instead of the computed direction. No 2nd-gen component read this property (2nd-gen resolves direction via `getComputedStyle(...).direction` at each call site).
|
|
52
|
+
- Removed the `SpectrumMixin` and `SpectrumInterface` exports. With `hasVisibleFocusInTree` gone, the mixin only re-typed `shadowRoot` as non-null, which nothing relied on (all reads use `?.`). `SpectrumElement` now extends `LitElement` directly, and `shadowRoot` is `ShadowRoot | null` again as in Lit.
|
|
53
|
+
|
|
54
|
+
- [#6552](https://github.com/adobe/spectrum-web-components/pull/6552) [`bd6c017`](https://github.com/adobe/spectrum-web-components/commit/bd6c017708de0b362c0504ad8b28a7f37a3b17da) Thanks [@caseyisonit](https://github.com/caseyisonit)! - Add the internal 2nd-gen UI icon system: the `<swc-ui-icon>` element plus a build-time generator for the S2 UI icon set.
|
|
55
|
+
- **`<swc-ui-icon>`** (internal): `icon` selects the icon-set, `size` selects the matching optical step, and `accessible-label` drives host-owned accessibility; renders generated Lit templates with no `unsafeSVG` in consuming components.
|
|
56
|
+
- **Generator** (`yarn generate:ui-icons`): converts downloaded A4U source SVGs into per-logical-icon template bundles under `components/ui-icons/icon-set/`, rewriting fills to `var(--swc-icon-color, currentColor)`.
|
|
57
|
+
- **`IconBase`**: refactored to a behavior-only base (`size` + `accessible-label` + host-owned accessibility, with no render or styles); the `<swc-icon>` frame and `<swc-ui-icon>` both extend it and share `stylesheets/_lit-styles/icon-base.css`. The frame uses `accessible-label` for host-owned accessibility (`role="img"` plus `aria-label` when labeled, `aria-hidden` when decorative).
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- [#6587](https://github.com/adobe/spectrum-web-components/pull/6587) [`4a30997`](https://github.com/adobe/spectrum-web-components/commit/4a309978f86b9d050cb54ed03db7418e40cb464a) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - **fix(slot-text-controller):** `SlotTextController` no longer counts comment nodes as label content. A `${cond ? nothing : label}` binding leaves a Lit child-part marker (a comment node with non-empty data) in the default slot; its data was previously misread as label text during the controller's initial `host.childNodes` scan.
|
|
62
|
+
|
|
63
|
+
For a consumer whose default slot does not bind `@slotchange` (for example an icon-only `<swc-action-button>` with a conditional label), this made `hasContent` stay `true`, so the icon-only presentation was never applied. Only real text nodes now count.
|
|
64
|
+
|
|
65
|
+
- [#6594](https://github.com/adobe/spectrum-web-components/pull/6594) [`9b9695a`](https://github.com/adobe/spectrum-web-components/commit/9b9695a1e157ac300234d56882a4923d81dbf724) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - Fix `swc-popover` scrolling the page when closing a light-dismiss popover whose trigger has been scrolled out of view. On close, focus is restored to the trigger with `preventScroll` so the browser no longer scrolls the off-screen trigger back into view. This surfaced on touch devices (e.g. iPad), where tapping outside on non-interactive content does not blur the popover, so focus is still inside when it closes and restoration runs.
|
|
66
|
+
|
|
67
|
+
- [#6595](https://github.com/adobe/spectrum-web-components/pull/6595) [`1f85e54`](https://github.com/adobe/spectrum-web-components/commit/1f85e545d6cf3cff80888995f3184fbaea7fd154) Thanks [@rubencarvalho](https://github.com/rubencarvalho)! - Tooltip now uses `popover="manual"` instead of `popover="auto"`. Opening a tooltip on hover no longer light-dismisses an open `<swc-popover>` (or menu, picker, or select); a hover tooltip and an open popover coexist in both directions. Escape and close-on-leave are handled internally, so no dismissal behavior is lost. Tooltip also joins the shared dismissible stack, so when a tooltip is open on top of a popover, Escape closes only the tooltip first and leaves the popover open; a second Escape closes the popover.
|
|
68
|
+
|
|
3
69
|
## 2.0.0-beta.2
|
|
4
70
|
|
|
5
71
|
### Minor Changes
|
|
6
72
|
|
|
7
|
-
- [#
|
|
73
|
+
- [#6410](https://github.com/adobe/spectrum-web-components/pull/6410) [`b0c6e37`](https://github.com/adobe/spectrum-web-components/commit/b0c6e375760ccc1ec6c1773ed1aa4015aa3b0f03) - Add the 2nd-gen `<swc-close-button>`, migrated from the Spectrum 1 `<sp-close-button>`.
|
|
8
74
|
- **API**: `size`, `disabled`, `accessible-label`, and `static-color`; omits the legacy `variant` surface in favor of `static-color`.
|
|
9
75
|
- **Accessibility**: renders a real inner `<button type="button">` with delegated focus; requires `accessible-label` for its icon-only name; the cross icon remains decorative.
|
|
10
76
|
- **Styling**: ships Spectrum 2 sizing and static-color treatments plus the `--swc-close-button-*` custom-property surface for token-aligned overrides.
|
|
11
77
|
- **Docs and tests**: includes Storybook docs, consumer migration guidance, unit coverage, and Playwright accessibility and keyboard tests.
|
|
12
78
|
|
|
13
|
-
- [#
|
|
79
|
+
- [#6480](https://github.com/adobe/spectrum-web-components/pull/6480) [`f27f690`](https://github.com/adobe/spectrum-web-components/commit/f27f6906f142f824dcc28f588e205271a36ec04a) - **feat(color-handle):** Added `<swc-color-handle>`, the Spectrum 2 migration of `sp-color-handle`.
|
|
14
80
|
|
|
15
81
|
A non-interactive color-picker primitive exposing `color`, `disabled`, `focused`, `open`, and the new `fill` property, with a built-in `<swc-color-loupe>` and an adaptive white-first dual border that meets WCAG 1.4.11 non-text contrast across the color spectrum. The `--mod-colorhandle-*` custom properties are removed; see the migration guide.
|
|
16
82
|
|
|
17
|
-
- [#6439](https://github.com/adobe/spectrum-web-components/pull/6439) [`7f0c3e9`](https://github.com/adobe/spectrum-web-components/commit/7f0c3e937e697e3e1d5d3973ce4f709542f1bbef)
|
|
83
|
+
- [#6439](https://github.com/adobe/spectrum-web-components/pull/6439) [`7f0c3e9`](https://github.com/adobe/spectrum-web-components/commit/7f0c3e937e697e3e1d5d3973ce4f709542f1bbef) - Extract the pending (busy) state into reusable, decoupled 2nd-gen core primitives so any pending-capable component can adopt it.
|
|
18
84
|
- **`@adobe/spectrum-wc-core`**: adds `PendingController` (`/controllers/pending-controller`) for the pending state (delayed activation, inline-size freeze, derived busy accessible name), the render-only `renderPendingSpinner` directive (`/directives/pending-spinner`), and `PendingMixin` (`/mixins`) which wires the controller, the `pending` / `pending-label` properties, and click suppression. `ButtonBase` no longer owns pending state.
|
|
19
85
|
- **`@adobe/spectrum-wc`**: `swc-button` and `swc-action-button` now consume these primitives via `PendingMixin`. No public API change — `pending` / `pending-label` and the busy behavior are unchanged.
|
|
20
86
|
|
|
21
|
-
- [#
|
|
87
|
+
- [#6494](https://github.com/adobe/spectrum-web-components/pull/6494) [`9e7995a`](https://github.com/adobe/spectrum-web-components/commit/9e7995ad8189970d6788a7872007d611af247663) - **refactor(tabs):** Migrate `<swc-tabs>` keyboard navigation to `FocusgroupNavigationController`.
|
|
22
88
|
|
|
23
89
|
Arrow-key, Home, and End navigation is now handled by the controller rather than by manually computed deltas in `handleKeyDown`. The `handleKeyDown` method retains only Enter/Space activation; all roving-tabindex management is delegated to the controller. In automatic activation mode, `focusgroupNavigationActiveChange` events with `source: 'keyboard'` drive selection-follows-focus; events with `source: 'refresh'` or `source: 'programmatic'` are intentionally ignored so that mounting or toggling `disabled` cannot trigger spurious `change` events.
|
|
24
90
|
|
|
25
91
|
### Patch Changes
|
|
26
92
|
|
|
27
|
-
- [#6518](https://github.com/adobe/spectrum-web-components/pull/6518) [`36052f3`](https://github.com/adobe/spectrum-web-components/commit/36052f305622ad8f46b44bf5d71e2b02ebd8229c)
|
|
93
|
+
- [#6518](https://github.com/adobe/spectrum-web-components/pull/6518) [`36052f3`](https://github.com/adobe/spectrum-web-components/commit/36052f305622ad8f46b44bf5d71e2b02ebd8229c) - Fix inaccurate API reference tables for several 2nd-gen components by documenting CSS custom properties and JSDoc property descriptions that were missing from the generated Custom Elements Manifest.
|
|
28
94
|
- Added missing `@cssprop` entries: `swc-tabs`/`swc-tab` (5 props), `swc-action-button` and `swc-button` (down-state transform, button also gets `max-inline-size`), `swc-illustrated-message` (10 props covering illustration sizing/color and heading/description typography).
|
|
29
95
|
- Added missing `size`/`variant` property descriptions for `swc-button`, `swc-action-button`, `swc-close-button`, `swc-status-light`, and `swc-badge`.
|
|
30
96
|
- Fixed the Tabs docs page rendering only `swc-tabs`'s API table; `swc-tab` and `swc-tab-panel` (the other two elements of the three-element component) now get their own API tables too, matching the pattern already used by Accordion.
|
|
31
97
|
|
|
32
98
|
No component runtime changes; documentation and Storybook docs-page rendering only.
|
|
33
99
|
|
|
34
|
-
- [#6513](https://github.com/adobe/spectrum-web-components/pull/6513) [`41e0483`](https://github.com/adobe/spectrum-web-components/commit/41e0483f59d3956ce973bbe50b2d54a1d8c73e9f)
|
|
100
|
+
- [#6513](https://github.com/adobe/spectrum-web-components/pull/6513) [`41e0483`](https://github.com/adobe/spectrum-web-components/commit/41e0483f59d3956ce973bbe50b2d54a1d8c73e9f) - **fix(color-loupe):** Added an adaptive white-first inner border to `<swc-color-loupe>` so its chrome meets WCAG 1.4.11 non-text contrast (≥3:1) across the color spectrum.
|
|
35
101
|
|
|
36
102
|
The inner border's opacity now escalates above its default floor only when the white outer halo can't itself carry 3:1 contrast against the loupe's color. The outer border, shape, and sizing are unchanged, and there is no public API change. This supersedes the prior practical-limits exception, matching the adaptive dual-border approach already shipped for `<swc-color-handle>`.
|
|
37
103
|
|
|
38
|
-
- [#
|
|
104
|
+
- [#6506](https://github.com/adobe/spectrum-web-components/pull/6506) [`6049706`](https://github.com/adobe/spectrum-web-components/commit/6049706e5d08bb92cd6531cbf7661c282b3ab409) - **fix(popover):** Fixed `swc-popover` staying dismissed on the next unrelated outside click after a trigger press was dragged off and released elsewhere.
|
|
39
105
|
|
|
40
106
|
A `pointerdown` on the trigger followed by a drag off the trigger and a release elsewhere never dispatches a `click`, so the internal reopen-guard flag was left stuck `true`, misattributing the next unrelated outside light-dismiss to that stale press and swallowing the following legitimate trigger click.
|
|
41
107
|
|
|
42
|
-
- [#6490](https://github.com/adobe/spectrum-web-components/pull/6490) [`1e053fe`](https://github.com/adobe/spectrum-web-components/commit/1e053fe761c20b1df70c842cb3f9dcee94e02d8d)
|
|
108
|
+
- [#6490](https://github.com/adobe/spectrum-web-components/pull/6490) [`1e053fe`](https://github.com/adobe/spectrum-web-components/commit/1e053fe761c20b1df70c842cb3f9dcee94e02d8d) - **fix(slot-attribute-propagation-controller):** Fixed `SlotAttributePropagationController` permanently skipping re-propagation when a repeated value was recorded before its target slot had resolved, and added support for propagating attributes that are only sometimes present on the host.
|
|
43
109
|
|
|
44
110
|
`getValue` may now return `null` to remove the propagated attribute from assigned elements instead of setting it to an empty string. The `hostUpdated()` no-op guard now only records a value as applied once the slot actually resolves, so a slot that resolves after an earlier unsuccessful attempt with the same value is no longer skipped forever.
|
|
45
111
|
|
|
46
112
|
`SlotAttributePropagationController` is also now a public export of `@adobe/spectrum-wc-core` (`@spectrum-web-components/core/controllers/slot-attribute-propagation-controller.js`), alongside dedicated tests and a Storybook controller docs page. Existing consumers (`<swc-button-group>`, `<swc-illustrated-message>`) are unaffected aside from benefiting from the propagation-guard fix.
|
|
47
113
|
|
|
48
|
-
- [#6533](https://github.com/adobe/spectrum-web-components/pull/6533) [`5da5474`](https://github.com/adobe/spectrum-web-components/commit/5da54741eadcf61d60fd37d700ff457419a4d2ca)
|
|
114
|
+
- [#6533](https://github.com/adobe/spectrum-web-components/pull/6533) [`5da5474`](https://github.com/adobe/spectrum-web-components/commit/5da54741eadcf61d60fd37d700ff457419a4d2ca) - **fix(progress-circle):** Replaced the `animation: none` reduced-motion override on `<swc-progress-circle>`'s indeterminate state with a slowed, single-rotation animation driven by custom properties (`--swc-progress-circle-rotate-start`, `--swc-progress-circle-rotate-end`, `--swc-progress-circle-dashoffset-30`), so `prefers-reduced-motion: reduce` still conveys progress without the distracting spin.
|
|
49
115
|
|
|
50
116
|
## 2.0.0-beta.1
|
|
51
117
|
|
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { __decorate as
|
|
3
|
-
import { AccordionItemBase as
|
|
4
|
-
import { property as
|
|
5
|
-
import { LiveSelectionController as
|
|
6
|
-
import { SpectrumElement as
|
|
7
|
-
import { SizedMixin as
|
|
1
|
+
import { ACCORDION_DENSITIES as e, ACCORDION_VALID_SIZES as t, SWC_ACCORDION_ITEM_TOGGLE_EVENT as n } from "./Accordion.types.js";
|
|
2
|
+
import { __decorate as r } from "../../_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
|
|
3
|
+
import { AccordionItemBase as i } from "./AccordionItem.base.js";
|
|
4
|
+
import { property as a } from "lit/decorators.js";
|
|
5
|
+
import { LiveSelectionController as o } from "@adobe/spectrum-wc-core/controllers/index.js";
|
|
6
|
+
import { SpectrumElement as s } from "@adobe/spectrum-wc-core/element/index.js";
|
|
7
|
+
import { SizedMixin as c } from "@adobe/spectrum-wc-core/mixins/index.js";
|
|
8
|
+
import { validateEnum as l } from "@adobe/spectrum-wc-core/utils/index.js";
|
|
8
9
|
//#region components/accordion/Accordion.base.ts
|
|
9
|
-
var
|
|
10
|
-
validSizes:
|
|
10
|
+
var u = class extends c(s, {
|
|
11
|
+
validSizes: t,
|
|
11
12
|
defaultSize: "m"
|
|
12
13
|
}) {
|
|
13
14
|
constructor(...e) {
|
|
14
|
-
super(...e), this.allowMultiple = !1, this.level = 3, this.density = "regular", this.quiet = !1, this.disabled = !1, this.selectionController = new
|
|
15
|
+
super(...e), this.allowMultiple = !1, this.level = 3, this.density = "regular", this.quiet = !1, this.disabled = !1, this.selectionController = new o(this, {
|
|
15
16
|
getItems: () => this.assignedItems(),
|
|
16
17
|
readSelected: (e) => e.open,
|
|
17
18
|
deselect: (e) => {
|
|
18
19
|
e.open = !1;
|
|
19
20
|
},
|
|
20
|
-
observeEvent:
|
|
21
|
+
observeEvent: n,
|
|
21
22
|
mode: () => this.allowMultiple ? "multiple" : "single"
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
assignedItems() {
|
|
25
26
|
var e;
|
|
26
27
|
let t = (e = this.renderRoot) == null ? void 0 : e.querySelector("slot");
|
|
27
|
-
return t ? t.assignedElements({ flatten: !0 }).filter((e) => e instanceof
|
|
28
|
+
return t ? t.assignedElements({ flatten: !0 }).filter((e) => e instanceof i) : [];
|
|
28
29
|
}
|
|
29
30
|
firstUpdated(e) {
|
|
30
31
|
super.firstUpdated(e), this.selectionController.refresh();
|
|
@@ -32,32 +33,37 @@ var c = class extends s(o, {
|
|
|
32
33
|
syncAccordionItems() {
|
|
33
34
|
for (let e of this.assignedItems()) e.setManagedHeading(this.level), e.size = this.size, e.setManagedParentDisabled(this.disabled);
|
|
34
35
|
}
|
|
35
|
-
update(
|
|
36
|
-
if (
|
|
36
|
+
update(t) {
|
|
37
|
+
if (t.has("density") && l(this, {
|
|
38
|
+
prop: "density",
|
|
39
|
+
value: this.density,
|
|
40
|
+
valid: e,
|
|
41
|
+
url: "https://spectrum-web-components.adobe.com/?path=/docs/components-accordion--docs"
|
|
42
|
+
}), t.has("level")) {
|
|
37
43
|
let e = Math.min(6, Math.max(2, this.level));
|
|
38
44
|
this.level !== e && (this.level = e);
|
|
39
45
|
}
|
|
40
|
-
(
|
|
46
|
+
(t.has("level") || t.has("size") || t.has("disabled")) && this.syncAccordionItems(), t.has("allowMultiple") && t.get("allowMultiple") === !0 && !this.allowMultiple && this.selectionController.refresh(), t.has("disabled") && t.get("disabled") === !0 && !this.disabled && !this.allowMultiple && this.selectionController.refresh(), super.update(t);
|
|
41
47
|
}
|
|
42
48
|
};
|
|
43
|
-
|
|
49
|
+
r([a({
|
|
44
50
|
type: Boolean,
|
|
45
51
|
reflect: !0,
|
|
46
52
|
attribute: "allow-multiple"
|
|
47
|
-
})],
|
|
53
|
+
})], u.prototype, "allowMultiple", void 0), r([a({
|
|
48
54
|
type: Number,
|
|
49
55
|
reflect: !0
|
|
50
|
-
})],
|
|
56
|
+
})], u.prototype, "level", void 0), r([a({
|
|
51
57
|
type: String,
|
|
52
58
|
reflect: !0
|
|
53
|
-
})],
|
|
59
|
+
})], u.prototype, "density", void 0), r([a({
|
|
54
60
|
type: Boolean,
|
|
55
61
|
reflect: !0
|
|
56
|
-
})],
|
|
62
|
+
})], u.prototype, "quiet", void 0), r([a({
|
|
57
63
|
type: Boolean,
|
|
58
64
|
reflect: !0
|
|
59
|
-
})],
|
|
65
|
+
})], u.prototype, "disabled", void 0);
|
|
60
66
|
//#endregion
|
|
61
|
-
export {
|
|
67
|
+
export { u as AccordionBase };
|
|
62
68
|
|
|
63
69
|
//# sourceMappingURL=Accordion.base.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.base.js","names":[],"sources":["../../../components/accordion/Accordion.base.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { LiveSelectionController } from '@adobe/spectrum-wc-core/controllers/index.js';\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\n\nimport {\n ACCORDION_VALID_SIZES,\n type AccordionDensity,\n type AccordionHeadingLevel,\n type AccordionSize,\n SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n} from './Accordion.types.js';\nimport { AccordionItemBase } from './AccordionItem.base.js';\n\n/**\n * Base class for accordion components. Manages item propagation, heading\n * level, density, and the exclusive-open constraint.\n *\n * @attribute {boolean} allowMultiple - Reflected as `allow-multiple`. When set,\n * multiple items may be open at the same time.\n * @attribute {number} level - Heading level (2–6) applied to every item header.\n * Values outside that range are clamped.\n * @attribute {AccordionSize} size - Size applied to all items.\n * @attribute {AccordionDensity} density - Vertical spacing between items.\n * @attribute {boolean} quiet - Renders the accordion in its quiet visual variant.\n * @attribute {boolean} disabled - Disables all items in the accordion.\n *\n * @slot - One or more `swc-accordion-item` elements.\n */\nexport abstract class AccordionBase extends SizedMixin(SpectrumElement, {\n validSizes: ACCORDION_VALID_SIZES,\n defaultSize: 'm',\n}) {\n // ──────────────────\n // PUBLIC API\n // ──────────────────\n\n /**\n * When set, multiple items may be open at the same time. By default only\n * one item can be open.\n */\n @property({ type: Boolean, reflect: true, attribute: 'allow-multiple' })\n public allowMultiple: boolean = false;\n\n /**\n * Heading level applied to every item header (2–6). Defaults to 3.\n * Values outside that range are clamped.\n */\n @property({ type: Number, reflect: true })\n public level: AccordionHeadingLevel = 3;\n\n /**\n * Size applied to all items. Defaults to `m`.\n */\n declare public size: AccordionSize;\n\n /**\n * Controls vertical spacing between items.\n *\n * @default regular\n */\n @property({ type: String, reflect: true })\n public density: AccordionDensity = 'regular';\n\n /**\n * Renders the accordion in its quiet (no-border) visual variant.\n */\n @property({ type: Boolean, reflect: true })\n public quiet: boolean = false;\n\n /**\n * Disables all items in the accordion. Individual items may also be\n * disabled independently.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n private assignedItems(): AccordionItemBase[] {\n const slot = this.renderRoot?.querySelector('slot');\n if (!slot) {\n return [];\n }\n return slot\n .assignedElements({ flatten: true })\n .filter((el): el is AccordionItemBase => el instanceof AccordionItemBase);\n }\n\n // LiveSelectionController observes swc-accordion-item-toggle events and\n // enforces the exclusive-open constraint when allowMultiple is false. Items\n // own their own open state; the controller only closes siblings.\n private readonly selectionController = new LiveSelectionController(this, {\n getItems: () => this.assignedItems(),\n readSelected: (item) => item.open,\n deselect: (item) => {\n item.open = false;\n },\n observeEvent: SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n mode: () => (this.allowMultiple ? 'multiple' : 'single'),\n });\n\n protected override firstUpdated(changedProperties: PropertyValues): void {\n super.firstUpdated(changedProperties);\n // The controller is event-driven and won't catch items that start open via\n // HTML attributes; read the initial DOM state and enforce the constraint now.\n this.selectionController.refresh();\n }\n\n protected syncAccordionItems(): void {\n for (const item of this.assignedItems()) {\n item.setManagedHeading(this.level);\n item.size = this.size;\n item.setManagedParentDisabled(this.disabled);\n }\n }\n\n protected override update(changedProperties: PropertyValues): void {\n if (changedProperties.has('level')) {\n const clamped = Math.min(\n 6,\n Math.max(2, this.level)\n ) as AccordionHeadingLevel;\n if (this.level !== clamped) {\n this.level = clamped;\n }\n }\n if (\n changedProperties.has('level') ||\n changedProperties.has('size') ||\n changedProperties.has('disabled')\n ) {\n this.syncAccordionItems();\n }\n // When allow-multiple is removed, enforce the stricter single-select\n // constraint over the current DOM state.\n if (\n changedProperties.has('allowMultiple') &&\n changedProperties.get('allowMultiple') === true &&\n !this.allowMultiple\n ) {\n this.selectionController.refresh();\n }\n // When the accordion is re-enabled after being disabled, enforce\n // exclusive-open so items that were opened while disabled are corrected.\n if (\n changedProperties.has('disabled') &&\n changedProperties.get('disabled') === true &&\n !this.disabled &&\n !this.allowMultiple\n ) {\n this.selectionController.refresh();\n }\n super.update(changedProperties);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Accordion.base.js","names":[],"sources":["../../../components/accordion/Accordion.base.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { LiveSelectionController } from '@adobe/spectrum-wc-core/controllers/index.js';\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\nimport { validateEnum } from '@adobe/spectrum-wc-core/utils/index.js';\n\nimport {\n ACCORDION_DENSITIES,\n ACCORDION_VALID_SIZES,\n type AccordionDensity,\n type AccordionHeadingLevel,\n type AccordionSize,\n SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n} from './Accordion.types.js';\nimport { AccordionItemBase } from './AccordionItem.base.js';\n\n/**\n * Base class for accordion components. Manages item propagation, heading\n * level, density, and the exclusive-open constraint.\n *\n * @attribute {boolean} allowMultiple - Reflected as `allow-multiple`. When set,\n * multiple items may be open at the same time.\n * @attribute {number} level - Heading level (2–6) applied to every item header.\n * Values outside that range are clamped.\n * @attribute {AccordionSize} size - Size applied to all items.\n * @attribute {AccordionDensity} density - Vertical spacing between items.\n * @attribute {boolean} quiet - Renders the accordion in its quiet visual variant.\n * @attribute {boolean} disabled - Disables all items in the accordion.\n *\n * @slot - One or more `swc-accordion-item` elements.\n */\nexport abstract class AccordionBase extends SizedMixin(SpectrumElement, {\n validSizes: ACCORDION_VALID_SIZES,\n defaultSize: 'm',\n}) {\n // ──────────────────\n // PUBLIC API\n // ──────────────────\n\n /**\n * When set, multiple items may be open at the same time. By default only\n * one item can be open.\n */\n @property({ type: Boolean, reflect: true, attribute: 'allow-multiple' })\n public allowMultiple: boolean = false;\n\n /**\n * Heading level applied to every item header (2–6). Defaults to 3.\n * Values outside that range are clamped.\n */\n @property({ type: Number, reflect: true })\n public level: AccordionHeadingLevel = 3;\n\n /**\n * Size applied to all items. Defaults to `m`.\n */\n declare public size: AccordionSize;\n\n /**\n * Controls vertical spacing between items.\n *\n * @default regular\n */\n @property({ type: String, reflect: true })\n public density: AccordionDensity = 'regular';\n\n /**\n * Renders the accordion in its quiet (no-border) visual variant.\n */\n @property({ type: Boolean, reflect: true })\n public quiet: boolean = false;\n\n /**\n * Disables all items in the accordion. Individual items may also be\n * disabled independently.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n private assignedItems(): AccordionItemBase[] {\n const slot = this.renderRoot?.querySelector('slot');\n if (!slot) {\n return [];\n }\n return slot\n .assignedElements({ flatten: true })\n .filter((el): el is AccordionItemBase => el instanceof AccordionItemBase);\n }\n\n // LiveSelectionController observes swc-accordion-item-toggle events and\n // enforces the exclusive-open constraint when allowMultiple is false. Items\n // own their own open state; the controller only closes siblings.\n private readonly selectionController = new LiveSelectionController(this, {\n getItems: () => this.assignedItems(),\n readSelected: (item) => item.open,\n deselect: (item) => {\n item.open = false;\n },\n observeEvent: SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n mode: () => (this.allowMultiple ? 'multiple' : 'single'),\n });\n\n protected override firstUpdated(changedProperties: PropertyValues): void {\n super.firstUpdated(changedProperties);\n // The controller is event-driven and won't catch items that start open via\n // HTML attributes; read the initial DOM state and enforce the constraint now.\n this.selectionController.refresh();\n }\n\n protected syncAccordionItems(): void {\n for (const item of this.assignedItems()) {\n item.setManagedHeading(this.level);\n item.size = this.size;\n item.setManagedParentDisabled(this.disabled);\n }\n }\n\n protected override update(changedProperties: PropertyValues): void {\n if (changedProperties.has('density')) {\n validateEnum(this, {\n prop: 'density',\n value: this.density,\n valid: ACCORDION_DENSITIES,\n url: 'https://spectrum-web-components.adobe.com/?path=/docs/components-accordion--docs',\n });\n }\n if (changedProperties.has('level')) {\n const clamped = Math.min(\n 6,\n Math.max(2, this.level)\n ) as AccordionHeadingLevel;\n if (this.level !== clamped) {\n this.level = clamped;\n }\n }\n if (\n changedProperties.has('level') ||\n changedProperties.has('size') ||\n changedProperties.has('disabled')\n ) {\n this.syncAccordionItems();\n }\n // When allow-multiple is removed, enforce the stricter single-select\n // constraint over the current DOM state.\n if (\n changedProperties.has('allowMultiple') &&\n changedProperties.get('allowMultiple') === true &&\n !this.allowMultiple\n ) {\n this.selectionController.refresh();\n }\n // When the accordion is re-enabled after being disabled, enforce\n // exclusive-open so items that were opened while disabled are corrected.\n if (\n changedProperties.has('disabled') &&\n changedProperties.get('disabled') === true &&\n !this.disabled &&\n !this.allowMultiple\n ) {\n this.selectionController.refresh();\n }\n super.update(changedProperties);\n }\n}\n"],"mappings":";;;;;;;;;AA6CA,IAAsB,IAAtB,cAA4C,EAAW,GAAiB;CACtE,YAAY;CACZ,aAAa;CACd,CAAC,CAAC;;oCAU+B,iBAOM,kBAaH,wBAMX,oBAOG,+BAmBY,IAAI,EAAwB,MAAM;GACvE,gBAAgB,KAAK,eAAe;GACpC,eAAe,MAAS,EAAK;GAC7B,WAAW,MAAS;AAClB,MAAK,OAAO;;GAEd,cAAc;GACd,YAAa,KAAK,gBAAgB,aAAa;GAChD,CAAC;;CArBF,gBAA6C;;EAC3C,IAAM,KAAA,IAAO,KAAK,eAAA,OAAA,KAAA,IAAA,EAAY,cAAc,OAAO;AAInD,SAHK,IAGE,EACJ,iBAAiB,EAAE,SAAS,IAAM,CAAC,CACnC,QAAQ,MAAgC,aAAc,EAAkB,GAJlE,EAAE;;CAoBb,aAAgC,GAAyC;AAIvE,EAHA,MAAM,aAAa,EAAkB,EAGrC,KAAK,oBAAoB,SAAS;;CAGpC,qBAAqC;AACnC,OAAK,IAAM,KAAQ,KAAK,eAAe,CAGrC,CAFA,EAAK,kBAAkB,KAAK,MAAM,EAClC,EAAK,OAAO,KAAK,MACjB,EAAK,yBAAyB,KAAK,SAAS;;CAIhD,OAA0B,GAAyC;AASjE,MARI,EAAkB,IAAI,UAAU,IAClC,EAAa,MAAM;GACjB,MAAM;GACN,OAAO,KAAK;GACZ,OAAO;GACP,KAAK;GACN,CAAC,EAEA,EAAkB,IAAI,QAAQ,EAAE;GAClC,IAAM,IAAU,KAAK,IACnB,GACA,KAAK,IAAI,GAAG,KAAK,MAAM,CACxB;AACD,GAAI,KAAK,UAAU,MACjB,KAAK,QAAQ;;AA6BjB,GAzBE,EAAkB,IAAI,QAAQ,IAC9B,EAAkB,IAAI,OAAO,IAC7B,EAAkB,IAAI,WAAW,KAEjC,KAAK,oBAAoB,EAKzB,EAAkB,IAAI,gBAAgB,IACtC,EAAkB,IAAI,gBAAgB,KAAK,MAC3C,CAAC,KAAK,iBAEN,KAAK,oBAAoB,SAAS,EAKlC,EAAkB,IAAI,WAAW,IACjC,EAAkB,IAAI,WAAW,KAAK,MACtC,CAAC,KAAK,YACN,CAAC,KAAK,iBAEN,KAAK,oBAAoB,SAAS,EAEpC,MAAM,OAAO,EAAkB;;;GA1HhC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,WAAW;CAAkB,CAAC,CAAA,EAAA,EAAA,WAAA,iBAAA,KAAA,EAAA,KAOvE,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,SAAA,KAAA,EAAA,KAazC,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA,KAMzC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,SAAA,KAAA,EAAA,KAO1C,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { PropertyValues } from 'lit';
|
|
2
|
+
import { SlotPresenceController } from '../../controllers/slot-presence-controller/index.js';
|
|
2
3
|
import { SpectrumElement } from '../../element/index.js';
|
|
3
4
|
import { AccordionHeadingLevel, AccordionSize } from './Accordion.types.js';
|
|
4
|
-
declare const AccordionItemBase_base: typeof SpectrumElement & {
|
|
5
|
-
new (...args: any[]): import('../../mixins/observe-slot-presence.js').SlotPresenceObservingInterface;
|
|
6
|
-
prototype: import('../../mixins/observe-slot-presence.js').SlotPresenceObservingInterface;
|
|
7
|
-
};
|
|
8
5
|
/**
|
|
9
6
|
* Base class for accordion item components. Manages open/disabled state,
|
|
10
7
|
* heading level (set by the parent accordion), and the toggle event.
|
|
@@ -19,7 +16,14 @@ declare const AccordionItemBase_base: typeof SpectrumElement & {
|
|
|
19
16
|
* the toggle button so they remain independently interactive.
|
|
20
17
|
* @slot - The panel content revealed when the item is open.
|
|
21
18
|
*/
|
|
22
|
-
export declare abstract class AccordionItemBase extends
|
|
19
|
+
export declare abstract class AccordionItemBase extends SpectrumElement {
|
|
20
|
+
/**
|
|
21
|
+
* Observes whether content is slotted into `[slot="actions"]` so the header
|
|
22
|
+
* can conditionally render the actions container.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
protected slotPresence: SlotPresenceController;
|
|
23
27
|
/**
|
|
24
28
|
* Whether the accordion item panel is expanded.
|
|
25
29
|
*/
|
|
@@ -50,6 +54,13 @@ export declare abstract class AccordionItemBase extends AccordionItemBase_base {
|
|
|
50
54
|
* when the accordion is re-enabled.
|
|
51
55
|
*/
|
|
52
56
|
protected parentDisabled: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
* Whether content is slotted into `[slot="actions"]`. Consumed by the
|
|
60
|
+
* concrete element's `render()` to conditionally render the actions
|
|
61
|
+
* container.
|
|
62
|
+
*/
|
|
63
|
+
protected get hasActions(): boolean;
|
|
53
64
|
/**
|
|
54
65
|
* @internal
|
|
55
66
|
* Whether the item may change `open` (expand or collapse). When false, the
|
|
@@ -83,4 +94,3 @@ export declare abstract class AccordionItemBase extends AccordionItemBase_base {
|
|
|
83
94
|
connectedCallback(): void;
|
|
84
95
|
disconnectedCallback(): void;
|
|
85
96
|
}
|
|
86
|
-
export {};
|
|
@@ -2,11 +2,11 @@ import { SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT as e, SWC_ACCORDION_ITEM_AFTER_OPE
|
|
|
2
2
|
import { __decorate as a } from "../../_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
|
|
3
3
|
import { property as o, state as s } from "lit/decorators.js";
|
|
4
4
|
import { SpectrumElement as c } from "@adobe/spectrum-wc-core/element/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { SlotPresenceController as l } from "@adobe/spectrum-wc-core/controllers/slot-presence-controller/index.js";
|
|
6
6
|
//#region components/accordion/AccordionItem.base.ts
|
|
7
|
-
var u = class extends
|
|
7
|
+
var u = class extends c {
|
|
8
8
|
constructor(...e) {
|
|
9
|
-
super(...e), this.disabled = !1, this._open = !1, this.headingLevel = 3, this.parentDisabled = !1, this.afterEventPending = !1, this.handleTransitionEnd = (e) => {
|
|
9
|
+
super(...e), this.slotPresence = new l(this, "[slot=\"actions\"]"), this.disabled = !1, this._open = !1, this.headingLevel = 3, this.parentDisabled = !1, this.afterEventPending = !1, this.handleTransitionEnd = (e) => {
|
|
10
10
|
e.target !== this.contentPanel || e.propertyName !== "height" || !this.afterEventPending || (this.afterEventPending = !1, this.dispatchAfterEvent(this.open));
|
|
11
11
|
}, this.handleTransitionCancel = (e) => {
|
|
12
12
|
e.target !== this.contentPanel || e.propertyName !== "height" || !this.afterEventPending || (this.afterEventPending = !1, this.dispatchAfterEvent(this.open));
|
|
@@ -20,6 +20,9 @@ var u = class extends l(c, "[slot=\"actions\"]") {
|
|
|
20
20
|
let t = this._open;
|
|
21
21
|
this._open = e, e ? this.setAttribute("open", "") : this.removeAttribute("open"), this.requestUpdate("open", t);
|
|
22
22
|
}
|
|
23
|
+
get hasActions() {
|
|
24
|
+
return this.slotPresence.isPresent;
|
|
25
|
+
}
|
|
23
26
|
mayExpand() {
|
|
24
27
|
return !this.disabled && !this.parentDisabled;
|
|
25
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccordionItem.base.js","names":[],"sources":["../../../components/accordion/AccordionItem.base.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { ObserveSlotPresence } from '@adobe/spectrum-wc-core/mixins/observe-slot-presence.js';\n\nimport {\n type AccordionHeadingLevel,\n type AccordionSize,\n SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,\n SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT,\n SWC_ACCORDION_ITEM_CLOSE_EVENT,\n SWC_ACCORDION_ITEM_OPEN_EVENT,\n SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n} from './Accordion.types.js';\n\n/**\n * Base class for accordion item components. Manages open/disabled state,\n * heading level (set by the parent accordion), and the toggle event.\n *\n * @attribute {boolean} open - Whether the accordion item panel is expanded.\n * @attribute {boolean} disabled - Whether the accordion item is disabled.\n * @attribute {AccordionSize} size - Size of the item. Inherited from the parent\n * accordion when slotted; controls the chevron icon when used standalone.\n *\n * @slot label - The heading text for this accordion item.\n * @slot actions - Optional actions rendered adjacent to the heading, outside\n * the toggle button so they remain independently interactive.\n * @slot - The panel content revealed when the item is open.\n */\nexport abstract class AccordionItemBase extends ObserveSlotPresence(\n SpectrumElement,\n '[slot=\"actions\"]'\n) {\n // ──────────────────\n // PUBLIC API\n // ──────────────────\n\n /**\n * Whether the accordion item panel is expanded.\n */\n @property({ type: Boolean, reflect: true })\n public get open(): boolean {\n return this._open;\n }\n\n public set open(value: boolean) {\n if (this.hasUpdated && !this.mayExpand() && value !== this._open) {\n return;\n }\n if (value === this._open) {\n return;\n }\n const oldValue = this._open;\n this._open = value;\n if (value) {\n this.setAttribute('open', '');\n } else {\n this.removeAttribute('open');\n }\n this.requestUpdate('open', oldValue);\n }\n\n /**\n * Whether the accordion item is disabled. A disabled item keeps its header\n * in the tab order but blocks toggling.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n /**\n * The size of the item. Inherited from the parent accordion; controls which\n * chevron icon is displayed. Has no effect when the item is used standalone.\n */\n @property({ type: String, reflect: true })\n public size?: AccordionSize;\n\n private _open = false;\n\n // ──────────────────────\n // INTERNAL STATE\n // ──────────────────────\n\n /**\n * @internal\n * Heading level (2–6) propagated by the parent accordion. Defaults to 3\n * for standalone items.\n */\n @state()\n protected headingLevel: AccordionHeadingLevel = 3;\n\n /**\n * @internal\n * Set by the parent accordion when its own `disabled` is true. Causes the\n * item to render as disabled (aria-disabled + inert panel) without clobbering\n * the item's own `disabled` property, so the per-item state is preserved\n * when the accordion is re-enabled.\n */\n @state()\n protected parentDisabled: boolean = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n /**\n * @internal\n * Whether the item may change `open` (expand or collapse). When false, the\n * `open` setter and `toggle()` leave state unchanged.\n */\n protected mayExpand(): boolean {\n return !this.disabled && !this.parentDisabled;\n }\n\n private get contentPanel(): HTMLElement | null {\n return this.shadowRoot?.getElementById('content') ?? null;\n }\n\n private dispatchAfterEvent(isOpen: boolean): void {\n this.dispatchEvent(\n new Event(\n isOpen\n ? SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT\n : SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,\n { bubbles: true, composed: true }\n )\n );\n }\n\n // Guards dispatchAfterEvent so only one after-event fires per open/close\n // cycle. transitionend fires once per CSS property; height is the only match.\n private afterEventPending = false;\n\n private readonly handleTransitionEnd = (event: TransitionEvent): void => {\n if (\n event.target !== this.contentPanel ||\n event.propertyName !== 'height' ||\n !this.afterEventPending\n ) {\n return;\n }\n this.afterEventPending = false;\n this.dispatchAfterEvent(this.open);\n };\n\n // Reused for transitioncancel: an externally interrupted transition must still\n // resolve afterEventPending so the after-event is not silently lost.\n private readonly handleTransitionCancel = (event: TransitionEvent): void => {\n if (\n event.target !== this.contentPanel ||\n event.propertyName !== 'height' ||\n !this.afterEventPending\n ) {\n return;\n }\n this.afterEventPending = false;\n this.dispatchAfterEvent(this.open);\n };\n\n /**\n * @internal\n * Toggles the item open state. Guards for disabled, flips `open`, dispatches\n * the toggle event, and reverts if the event is canceled. On success, dispatches\n * `swc-after-open` or `swc-after-close` after the panel height transition ends,\n * or immediately if no transition is active.\n */\n protected toggle(): void {\n if (!this.mayExpand()) {\n return;\n }\n this.open = !this.open;\n const toggleEvent = new Event(SWC_ACCORDION_ITEM_TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n if (!this.dispatchEvent(toggleEvent)) {\n this.open = !this.open;\n return;\n }\n const isOpen = this.open;\n this.dispatchEvent(\n new Event(\n isOpen ? SWC_ACCORDION_ITEM_OPEN_EVENT : SWC_ACCORDION_ITEM_CLOSE_EVENT,\n {\n bubbles: true,\n composed: true,\n }\n )\n );\n const panel = this.contentPanel;\n if (!panel || getComputedStyle(panel).transitionDuration === '0s') {\n this.dispatchAfterEvent(isOpen);\n } else {\n this.afterEventPending = true;\n }\n }\n\n /**\n * @internal\n * Synchronizes parent-managed heading level onto the item.\n */\n public setManagedHeading(heading: AccordionHeadingLevel): void {\n this.headingLevel = heading;\n }\n\n /**\n * @internal\n * Synchronizes parent-managed disabled state onto the item.\n */\n public setManagedParentDisabled(disabled: boolean): void {\n this.parentDisabled = disabled;\n }\n\n protected override firstUpdated(changedProperties: PropertyValues): void {\n super.firstUpdated(changedProperties);\n this.contentPanel?.addEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.addEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (this.hasUpdated) {\n this.contentPanel?.addEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.addEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n }\n\n public override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.contentPanel?.removeEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.removeEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AccordionItem.base.js","names":[],"sources":["../../../components/accordion/AccordionItem.base.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { SlotPresenceController } from '@adobe/spectrum-wc-core/controllers/slot-presence-controller/index.js';\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\n\nimport {\n type AccordionHeadingLevel,\n type AccordionSize,\n SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,\n SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT,\n SWC_ACCORDION_ITEM_CLOSE_EVENT,\n SWC_ACCORDION_ITEM_OPEN_EVENT,\n SWC_ACCORDION_ITEM_TOGGLE_EVENT,\n} from './Accordion.types.js';\n\n/**\n * Base class for accordion item components. Manages open/disabled state,\n * heading level (set by the parent accordion), and the toggle event.\n *\n * @attribute {boolean} open - Whether the accordion item panel is expanded.\n * @attribute {boolean} disabled - Whether the accordion item is disabled.\n * @attribute {AccordionSize} size - Size of the item. Inherited from the parent\n * accordion when slotted; controls the chevron icon when used standalone.\n *\n * @slot label - The heading text for this accordion item.\n * @slot actions - Optional actions rendered adjacent to the heading, outside\n * the toggle button so they remain independently interactive.\n * @slot - The panel content revealed when the item is open.\n */\nexport abstract class AccordionItemBase extends SpectrumElement {\n // ──────────────────────\n // CONTROLLERS\n // ──────────────────────\n\n /**\n * Observes whether content is slotted into `[slot=\"actions\"]` so the header\n * can conditionally render the actions container.\n *\n * @internal\n */\n protected slotPresence = new SlotPresenceController(this, '[slot=\"actions\"]');\n\n // ──────────────────\n // PUBLIC API\n // ──────────────────\n\n /**\n * Whether the accordion item panel is expanded.\n */\n @property({ type: Boolean, reflect: true })\n public get open(): boolean {\n return this._open;\n }\n\n public set open(value: boolean) {\n if (this.hasUpdated && !this.mayExpand() && value !== this._open) {\n return;\n }\n if (value === this._open) {\n return;\n }\n const oldValue = this._open;\n this._open = value;\n if (value) {\n this.setAttribute('open', '');\n } else {\n this.removeAttribute('open');\n }\n this.requestUpdate('open', oldValue);\n }\n\n /**\n * Whether the accordion item is disabled. A disabled item keeps its header\n * in the tab order but blocks toggling.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n /**\n * The size of the item. Inherited from the parent accordion; controls which\n * chevron icon is displayed. Has no effect when the item is used standalone.\n */\n @property({ type: String, reflect: true })\n public size?: AccordionSize;\n\n private _open = false;\n\n // ──────────────────────\n // INTERNAL STATE\n // ──────────────────────\n\n /**\n * @internal\n * Heading level (2–6) propagated by the parent accordion. Defaults to 3\n * for standalone items.\n */\n @state()\n protected headingLevel: AccordionHeadingLevel = 3;\n\n /**\n * @internal\n * Set by the parent accordion when its own `disabled` is true. Causes the\n * item to render as disabled (aria-disabled + inert panel) without clobbering\n * the item's own `disabled` property, so the per-item state is preserved\n * when the accordion is re-enabled.\n */\n @state()\n protected parentDisabled: boolean = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n /**\n * @internal\n * Whether content is slotted into `[slot=\"actions\"]`. Consumed by the\n * concrete element's `render()` to conditionally render the actions\n * container.\n */\n protected get hasActions(): boolean {\n return this.slotPresence.isPresent;\n }\n\n /**\n * @internal\n * Whether the item may change `open` (expand or collapse). When false, the\n * `open` setter and `toggle()` leave state unchanged.\n */\n protected mayExpand(): boolean {\n return !this.disabled && !this.parentDisabled;\n }\n\n private get contentPanel(): HTMLElement | null {\n return this.shadowRoot?.getElementById('content') ?? null;\n }\n\n private dispatchAfterEvent(isOpen: boolean): void {\n this.dispatchEvent(\n new Event(\n isOpen\n ? SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT\n : SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,\n { bubbles: true, composed: true }\n )\n );\n }\n\n // Guards dispatchAfterEvent so only one after-event fires per open/close\n // cycle. transitionend fires once per CSS property; height is the only match.\n private afterEventPending = false;\n\n private readonly handleTransitionEnd = (event: TransitionEvent): void => {\n if (\n event.target !== this.contentPanel ||\n event.propertyName !== 'height' ||\n !this.afterEventPending\n ) {\n return;\n }\n this.afterEventPending = false;\n this.dispatchAfterEvent(this.open);\n };\n\n // Reused for transitioncancel: an externally interrupted transition must still\n // resolve afterEventPending so the after-event is not silently lost.\n private readonly handleTransitionCancel = (event: TransitionEvent): void => {\n if (\n event.target !== this.contentPanel ||\n event.propertyName !== 'height' ||\n !this.afterEventPending\n ) {\n return;\n }\n this.afterEventPending = false;\n this.dispatchAfterEvent(this.open);\n };\n\n /**\n * @internal\n * Toggles the item open state. Guards for disabled, flips `open`, dispatches\n * the toggle event, and reverts if the event is canceled. On success, dispatches\n * `swc-after-open` or `swc-after-close` after the panel height transition ends,\n * or immediately if no transition is active.\n */\n protected toggle(): void {\n if (!this.mayExpand()) {\n return;\n }\n this.open = !this.open;\n const toggleEvent = new Event(SWC_ACCORDION_ITEM_TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n if (!this.dispatchEvent(toggleEvent)) {\n this.open = !this.open;\n return;\n }\n const isOpen = this.open;\n this.dispatchEvent(\n new Event(\n isOpen ? SWC_ACCORDION_ITEM_OPEN_EVENT : SWC_ACCORDION_ITEM_CLOSE_EVENT,\n {\n bubbles: true,\n composed: true,\n }\n )\n );\n const panel = this.contentPanel;\n if (!panel || getComputedStyle(panel).transitionDuration === '0s') {\n this.dispatchAfterEvent(isOpen);\n } else {\n this.afterEventPending = true;\n }\n }\n\n /**\n * @internal\n * Synchronizes parent-managed heading level onto the item.\n */\n public setManagedHeading(heading: AccordionHeadingLevel): void {\n this.headingLevel = heading;\n }\n\n /**\n * @internal\n * Synchronizes parent-managed disabled state onto the item.\n */\n public setManagedParentDisabled(disabled: boolean): void {\n this.parentDisabled = disabled;\n }\n\n protected override firstUpdated(changedProperties: PropertyValues): void {\n super.firstUpdated(changedProperties);\n this.contentPanel?.addEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.addEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (this.hasUpdated) {\n this.contentPanel?.addEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.addEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n }\n\n public override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.contentPanel?.removeEventListener(\n 'transitionend',\n this.handleTransitionEnd\n );\n this.contentPanel?.removeEventListener(\n 'transitioncancel',\n this.handleTransitionCancel\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
import { SpectrumElement } from '../../element/index.js';
|
|
3
|
+
import { ActionGroupOrientation, ActionGroupSize } from './ActionGroup.types.js';
|
|
4
|
+
declare const ActionGroupBase_base: typeof SpectrumElement & {
|
|
5
|
+
new (...args: any[]): import('../../mixins/index.js').SizedElementInterface;
|
|
6
|
+
prototype: import('../../mixins/index.js').SizedElementInterface;
|
|
7
|
+
} & import('../../mixins/index.js').SizedElementConstructor;
|
|
8
|
+
/**
|
|
9
|
+
* An action group clusters related actions together with consistent
|
|
10
|
+
* spacing, sizing, and orientation. It treats the whole strip as a single
|
|
11
|
+
* stop in the keyboard sequence, with arrow keys moving between children.
|
|
12
|
+
*
|
|
13
|
+
* This base class owns the accessibility semantics, `accessible-label` →
|
|
14
|
+
* `aria-label` management, `disabled` state contract, and child collection logic.
|
|
15
|
+
* Rendering and styling live in the concrete SWC subclass.
|
|
16
|
+
*
|
|
17
|
+
* @slot - One or more `swc-action-button` or `swc-action-menu` elements.
|
|
18
|
+
*
|
|
19
|
+
* @attribute {ActionGroupSize} size - The size of the group and its children.
|
|
20
|
+
*/
|
|
21
|
+
export declare abstract class ActionGroupBase extends ActionGroupBase_base {
|
|
22
|
+
static shadowRootOptions: {
|
|
23
|
+
delegatesFocus: boolean;
|
|
24
|
+
clonable?: boolean;
|
|
25
|
+
customElementRegistry?: CustomElementRegistry;
|
|
26
|
+
mode: ShadowRootMode;
|
|
27
|
+
serializable?: boolean;
|
|
28
|
+
slotAssignment?: SlotAssignmentMode;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The size of the action group. Propagated to all slotted children.
|
|
32
|
+
*/
|
|
33
|
+
size: ActionGroupSize;
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*
|
|
37
|
+
* Valid orientation values for validation.
|
|
38
|
+
*/
|
|
39
|
+
static readonly ORIENTATIONS: readonly string[];
|
|
40
|
+
/**
|
|
41
|
+
* @internal
|
|
42
|
+
*
|
|
43
|
+
* Valid static-color values for validation.
|
|
44
|
+
*/
|
|
45
|
+
static readonly STATIC_COLORS: readonly string[];
|
|
46
|
+
/**
|
|
47
|
+
* The layout direction of the action group.
|
|
48
|
+
*
|
|
49
|
+
* When set to `"vertical"`, the group stacks children vertically and
|
|
50
|
+
* `FocusgroupNavigationController` moves focus with the Up/Down arrow
|
|
51
|
+
* keys instead of Left/Right.
|
|
52
|
+
*
|
|
53
|
+
* Note: this property does NOT set `aria-orientation` on the host. The
|
|
54
|
+
* host's role is fixed to `role="group"`, and `aria-orientation` is only
|
|
55
|
+
* a supported ARIA attribute on roles that expose it (`toolbar`,
|
|
56
|
+
* `listbox`, `menu`, etc.), not `group`, regardless of this component's
|
|
57
|
+
* roving-tabindex keyboard model. Setting it anyway fails axe's
|
|
58
|
+
* `aria-allowed-attr` rule.
|
|
59
|
+
*
|
|
60
|
+
* @default horizontal
|
|
61
|
+
*/
|
|
62
|
+
orientation: ActionGroupOrientation;
|
|
63
|
+
/**
|
|
64
|
+
* Accessible label for the group. Reflected to `aria-label` on the host.
|
|
65
|
+
*
|
|
66
|
+
* Providing a label is recommended whenever the strip has a distinct
|
|
67
|
+
* purpose (e.g., "Image adjustments" or "Edit"). An empty value removes
|
|
68
|
+
* the `aria-label` attribute.
|
|
69
|
+
*/
|
|
70
|
+
accessibleLabel: string;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the group and all of its children are disabled.
|
|
73
|
+
*
|
|
74
|
+
* Sets `aria-disabled="true"` on the host and propagates `aria-disabled`
|
|
75
|
+
* to each managed child. Children remain keyboard-reachable so that screen
|
|
76
|
+
* reader users can still discover the group. Native `disabled` is not
|
|
77
|
+
* applied to children.
|
|
78
|
+
*/
|
|
79
|
+
disabled: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* @internal
|
|
82
|
+
*
|
|
83
|
+
* The managed children: all `swc-action-button` and `swc-action-menu`
|
|
84
|
+
* elements assigned to the default slot. Populated by the concrete
|
|
85
|
+
* subclass via `@queryAssignedElements`.
|
|
86
|
+
*/
|
|
87
|
+
protected managedChildren: HTMLElement[];
|
|
88
|
+
/**
|
|
89
|
+
* Focuses the first enabled child in the group.
|
|
90
|
+
*
|
|
91
|
+
* The SWC concrete class overrides this with `FocusgroupNavigationController`,
|
|
92
|
+
* restoring focus to the last active item when memory is enabled. This
|
|
93
|
+
* implementation serves as a fallback for non-SWC subclasses.
|
|
94
|
+
*/
|
|
95
|
+
focus(options?: FocusOptions): void;
|
|
96
|
+
/**
|
|
97
|
+
* @internal
|
|
98
|
+
*
|
|
99
|
+
* Handles slot-change events. Propagates `aria-disabled` to newly slotted
|
|
100
|
+
* children when the group is disabled. Concrete subclasses call
|
|
101
|
+
* `super.handleSlotchange()` and then propagate visual attributes.
|
|
102
|
+
*/
|
|
103
|
+
protected handleSlotchange(): void;
|
|
104
|
+
protected firstUpdated(changed: PropertyValues<this>): void;
|
|
105
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
106
|
+
private propagateDisabledToChildren;
|
|
107
|
+
}
|
|
108
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
|
|
2
|
+
import { ACTION_GROUP_ORIENTATIONS as t, ACTION_GROUP_STATIC_COLORS as n, ACTION_GROUP_VALID_SIZES as r } from "./ActionGroup.types.js";
|
|
3
|
+
import { property as i, queryAssignedElements as a } from "lit/decorators.js";
|
|
4
|
+
import { SpectrumElement as o } from "@adobe/spectrum-wc-core/element/index.js";
|
|
5
|
+
import { SizedMixin as s } from "@adobe/spectrum-wc-core/mixins/index.js";
|
|
6
|
+
//#region components/action-group/ActionGroup.base.ts
|
|
7
|
+
var c, l = class extends s(o, {
|
|
8
|
+
validSizes: r,
|
|
9
|
+
noDefaultSize: !0
|
|
10
|
+
}) {
|
|
11
|
+
constructor(...e) {
|
|
12
|
+
super(...e), this.orientation = "horizontal", this.accessibleLabel = "", this.disabled = !1;
|
|
13
|
+
}
|
|
14
|
+
focus(e) {
|
|
15
|
+
var t;
|
|
16
|
+
let n = (t = this.managedChildren) == null ? void 0 : t.find((e) => !e.hasAttribute("disabled") && e.getAttribute("aria-disabled") !== "true");
|
|
17
|
+
n == null || n.focus(e);
|
|
18
|
+
}
|
|
19
|
+
handleSlotchange() {
|
|
20
|
+
this.disabled && this.propagateDisabledToChildren();
|
|
21
|
+
}
|
|
22
|
+
firstUpdated(e) {
|
|
23
|
+
super.firstUpdated(e), this.setAttribute("role", "group");
|
|
24
|
+
}
|
|
25
|
+
updated(e) {
|
|
26
|
+
var t;
|
|
27
|
+
if (super.updated(e), e.has("accessibleLabel") && (this.accessibleLabel ? this.setAttribute("aria-label", this.accessibleLabel) : this.removeAttribute("aria-label")), e.has("disabled") && (this.disabled ? this.setAttribute("aria-disabled", "true") : this.removeAttribute("aria-disabled"), this.propagateDisabledToChildren()), (t = window.__swc) != null && t.DEBUG) {
|
|
28
|
+
let e = this.constructor;
|
|
29
|
+
e.ORIENTATIONS.includes(this.orientation) || window.__swc.warn(this, `<${this.localName}> element expects the "orientation" attribute to be one of the following: ${e.ORIENTATIONS.join(", ")}.`, "https://opensource.adobe.com/spectrum-web-components/components/action-group/", { issues: [...e.ORIENTATIONS] });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
propagateDisabledToChildren() {
|
|
33
|
+
var e;
|
|
34
|
+
for (let t of (e = this.managedChildren) == null ? [] : e) this.disabled ? t.setAttribute("aria-disabled", "true") : t.removeAttribute("aria-disabled");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
c = l, c.shadowRootOptions = {
|
|
38
|
+
...o.shadowRootOptions,
|
|
39
|
+
delegatesFocus: !0
|
|
40
|
+
}, c.ORIENTATIONS = t, c.STATIC_COLORS = n, e([i({
|
|
41
|
+
type: String,
|
|
42
|
+
reflect: !0
|
|
43
|
+
})], l.prototype, "orientation", void 0), e([i({
|
|
44
|
+
type: String,
|
|
45
|
+
attribute: "accessible-label"
|
|
46
|
+
})], l.prototype, "accessibleLabel", void 0), e([i({
|
|
47
|
+
type: Boolean,
|
|
48
|
+
reflect: !0
|
|
49
|
+
})], l.prototype, "disabled", void 0), e([a({ flatten: !0 })], l.prototype, "managedChildren", void 0);
|
|
50
|
+
//#endregion
|
|
51
|
+
export { l as ActionGroupBase };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=ActionGroup.base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionGroup.base.js","names":[],"sources":["../../../components/action-group/ActionGroup.base.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { PropertyValues } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\n\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\n\nimport {\n ACTION_GROUP_ORIENTATIONS,\n ACTION_GROUP_STATIC_COLORS,\n ACTION_GROUP_VALID_SIZES,\n type ActionGroupOrientation,\n type ActionGroupSize,\n} from './ActionGroup.types.js';\n\n/**\n * An action group clusters related actions together with consistent\n * spacing, sizing, and orientation. It treats the whole strip as a single\n * stop in the keyboard sequence, with arrow keys moving between children.\n *\n * This base class owns the accessibility semantics, `accessible-label` →\n * `aria-label` management, `disabled` state contract, and child collection logic.\n * Rendering and styling live in the concrete SWC subclass.\n *\n * @slot - One or more `swc-action-button` or `swc-action-menu` elements.\n *\n * @attribute {ActionGroupSize} size - The size of the group and its children.\n */\nexport abstract class ActionGroupBase extends SizedMixin(SpectrumElement, {\n validSizes: ACTION_GROUP_VALID_SIZES,\n noDefaultSize: true,\n}) {\n static override shadowRootOptions = {\n ...SpectrumElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n /**\n * The size of the action group. Propagated to all slotted children.\n */\n declare public size: ActionGroupSize;\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * @internal\n *\n * Valid orientation values for validation.\n */\n static readonly ORIENTATIONS: readonly string[] = ACTION_GROUP_ORIENTATIONS;\n\n /**\n * @internal\n *\n * Valid static-color values for validation.\n */\n static readonly STATIC_COLORS: readonly string[] = ACTION_GROUP_STATIC_COLORS;\n\n /**\n * The layout direction of the action group.\n *\n * When set to `\"vertical\"`, the group stacks children vertically and\n * `FocusgroupNavigationController` moves focus with the Up/Down arrow\n * keys instead of Left/Right.\n *\n * Note: this property does NOT set `aria-orientation` on the host. The\n * host's role is fixed to `role=\"group\"`, and `aria-orientation` is only\n * a supported ARIA attribute on roles that expose it (`toolbar`,\n * `listbox`, `menu`, etc.), not `group`, regardless of this component's\n * roving-tabindex keyboard model. Setting it anyway fails axe's\n * `aria-allowed-attr` rule.\n *\n * @default horizontal\n */\n @property({ type: String, reflect: true })\n public orientation: ActionGroupOrientation = 'horizontal';\n\n /**\n * Accessible label for the group. Reflected to `aria-label` on the host.\n *\n * Providing a label is recommended whenever the strip has a distinct\n * purpose (e.g., \"Image adjustments\" or \"Edit\"). An empty value removes\n * the `aria-label` attribute.\n */\n @property({ type: String, attribute: 'accessible-label' })\n public accessibleLabel = '';\n\n /**\n * Whether the group and all of its children are disabled.\n *\n * Sets `aria-disabled=\"true\"` on the host and propagates `aria-disabled`\n * to each managed child. Children remain keyboard-reachable so that screen\n * reader users can still discover the group. Native `disabled` is not\n * applied to children.\n */\n @property({ type: Boolean, reflect: true })\n public disabled = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n /**\n * @internal\n *\n * The managed children: all `swc-action-button` and `swc-action-menu`\n * elements assigned to the default slot. Populated by the concrete\n * subclass via `@queryAssignedElements`.\n */\n @queryAssignedElements({ flatten: true })\n protected managedChildren!: HTMLElement[];\n\n /**\n * Focuses the first enabled child in the group.\n *\n * The SWC concrete class overrides this with `FocusgroupNavigationController`,\n * restoring focus to the last active item when memory is enabled. This\n * implementation serves as a fallback for non-SWC subclasses.\n */\n public override focus(options?: FocusOptions): void {\n const firstEnabled = this.managedChildren?.find(\n (el) =>\n !el.hasAttribute('disabled') &&\n el.getAttribute('aria-disabled') !== 'true'\n );\n firstEnabled?.focus(options);\n }\n\n /**\n * @internal\n *\n * Handles slot-change events. Propagates `aria-disabled` to newly slotted\n * children when the group is disabled. Concrete subclasses call\n * `super.handleSlotchange()` and then propagate visual attributes.\n */\n protected handleSlotchange(): void {\n if (this.disabled) {\n this.propagateDisabledToChildren();\n }\n }\n\n protected override firstUpdated(changed: PropertyValues<this>): void {\n super.firstUpdated(changed);\n this.setAttribute('role', 'group');\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n\n if (changed.has('accessibleLabel')) {\n if (this.accessibleLabel) {\n this.setAttribute('aria-label', this.accessibleLabel);\n } else {\n this.removeAttribute('aria-label');\n }\n }\n\n if (changed.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.removeAttribute('aria-disabled');\n }\n this.propagateDisabledToChildren();\n }\n\n if (window.__swc?.DEBUG) {\n const constructor = this.constructor as typeof ActionGroupBase;\n if (!constructor.ORIENTATIONS.includes(this.orientation)) {\n window.__swc.warn(\n this,\n `<${this.localName}> element expects the \"orientation\" attribute to be one of the following: ${constructor.ORIENTATIONS.join(', ')}.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/action-group/',\n { issues: [...constructor.ORIENTATIONS] }\n );\n }\n }\n }\n\n private propagateDisabledToChildren(): void {\n // `aria-disabled` is set on the child host element. For AT to announce the\n // child as disabled, each child component must forward the host attribute to\n // its inner interactive element. `swc-action-button` already does this\n // (observes `aria-disabled` and forwards to its inner <button>).\n // `swc-action-menu` will need the same treatment when it is built — it must\n // forward `aria-disabled` from its host to its inner trigger element and\n // apply disabled appearance via :host([aria-disabled=\"true\"]) CSS.\n for (const child of this.managedChildren ?? []) {\n if (this.disabled) {\n child.setAttribute('aria-disabled', 'true');\n } else {\n child.removeAttribute('aria-disabled');\n }\n }\n }\n}\n"],"mappings":";;;;;;OAuCsB,IAAtB,cAA8C,EAAW,GAAiB;CACxE,YAAY;CACZ,eAAe;CAChB,CAAC,CAAC;;kCA8C4C,qCAUpB,oBAWP;;CAuBlB,MAAsB,GAA8B;;EAClD,IAAM,KAAA,IAAe,KAAK,oBAAA,OAAA,KAAA,IAAA,EAAiB,MACxC,MACC,CAAC,EAAG,aAAa,WAAW,IAC5B,EAAG,aAAa,gBAAgB,KAAK,OACxC;AACD,OAAA,QAAA,EAAc,MAAM,EAAQ;;CAU9B,mBAAmC;AACjC,EAAI,KAAK,YACP,KAAK,6BAA6B;;CAItC,aAAgC,GAAqC;AAEnE,EADA,MAAM,aAAa,EAAQ,EAC3B,KAAK,aAAa,QAAQ,QAAQ;;CAGpC,QAA2B,GAAqC;;AAoB9D,MAnBA,MAAM,QAAQ,EAAQ,EAElB,EAAQ,IAAI,kBAAkB,KAC5B,KAAK,kBACP,KAAK,aAAa,cAAc,KAAK,gBAAgB,GAErD,KAAK,gBAAgB,aAAa,GAIlC,EAAQ,IAAI,WAAW,KACrB,KAAK,WACP,KAAK,aAAa,iBAAiB,OAAO,GAE1C,KAAK,gBAAgB,gBAAgB,EAEvC,KAAK,6BAA6B,IAGpC,IAAI,OAAO,UAAA,QAAA,EAAO,OAAO;GACvB,IAAM,IAAc,KAAK;AACzB,GAAK,EAAY,aAAa,SAAS,KAAK,YAAY,IACtD,OAAO,MAAM,KACX,MACA,IAAI,KAAK,UAAU,4EAA4E,EAAY,aAAa,KAAK,KAAK,CAAC,IACnI,iFACA,EAAE,QAAQ,CAAC,GAAG,EAAY,aAAa,EAAE,CAC1C;;;CAKP,8BAA4C;;AAQ1C,OAAK,IAAM,MAAA,IAAS,KAAK,oBAAA,OAAmB,EAAE,GAArB,EACvB,CAAI,KAAK,WACP,EAAM,aAAa,iBAAiB,OAAO,GAE3C,EAAM,gBAAgB,gBAAgB;;;6BAjKR;CAClC,GAAG,EAAgB;CACnB,gBAAgB;CACjB,mBAgBiD,qBAOC,MAkBlD,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,eAAA,KAAA,EAAA,KAUzC,EAAS;CAAE,MAAM;CAAQ,WAAW;CAAoB,CAAC,CAAA,EAAA,EAAA,WAAA,mBAAA,KAAA,EAAA,KAWzD,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAc1C,EAAsB,EAAE,SAAS,IAAM,CAAC,CAAA,EAAA,EAAA,WAAA,mBAAA,KAAA,EAAA"}
|