@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.
Files changed (136) hide show
  1. package/CHANGELOG.md +75 -9
  2. package/dist/components/accordion/Accordion.base.js +28 -22
  3. package/dist/components/accordion/Accordion.base.js.map +1 -1
  4. package/dist/components/accordion/AccordionItem.base.d.ts +16 -6
  5. package/dist/components/accordion/AccordionItem.base.js +6 -3
  6. package/dist/components/accordion/AccordionItem.base.js.map +1 -1
  7. package/dist/components/action-group/ActionGroup.base.d.ts +108 -0
  8. package/dist/components/action-group/ActionGroup.base.js +53 -0
  9. package/dist/components/action-group/ActionGroup.base.js.map +1 -0
  10. package/dist/components/action-group/ActionGroup.types.d.ts +17 -0
  11. package/dist/components/action-group/ActionGroup.types.js +12 -0
  12. package/dist/components/action-group/ActionGroup.types.js.map +1 -0
  13. package/dist/components/action-group/index.d.ts +13 -0
  14. package/dist/components/action-group/index.js +3 -0
  15. package/dist/components/alert-banner/AlertBanner.base.js +11 -10
  16. package/dist/components/alert-banner/AlertBanner.base.js.map +1 -1
  17. package/dist/components/asset/Asset.base.d.ts +1 -1
  18. package/dist/components/asset/Asset.base.js +14 -8
  19. package/dist/components/asset/Asset.base.js.map +1 -1
  20. package/dist/components/avatar/Avatar.base.js +18 -22
  21. package/dist/components/avatar/Avatar.base.js.map +1 -1
  22. package/dist/components/badge/Badge.base.d.ts +24 -8
  23. package/dist/components/badge/Badge.base.js +22 -17
  24. package/dist/components/badge/Badge.base.js.map +1 -1
  25. package/dist/components/button/Button.base.d.ts +20 -10
  26. package/dist/components/button/Button.base.js +17 -12
  27. package/dist/components/button/Button.base.js.map +1 -1
  28. package/dist/components/button-group/ButtonGroup.base.js +19 -12
  29. package/dist/components/button-group/ButtonGroup.base.js.map +1 -1
  30. package/dist/components/card/Card.base.d.ts +95 -46
  31. package/dist/components/card/Card.base.js +71 -23
  32. package/dist/components/card/Card.base.js.map +1 -1
  33. package/dist/components/card/Card.types.d.ts +1 -0
  34. package/dist/components/card/Card.types.js +2 -2
  35. package/dist/components/card/Card.types.js.map +1 -1
  36. package/dist/components/card/index.js +3 -3
  37. package/dist/components/divider/Divider.base.js +13 -8
  38. package/dist/components/divider/Divider.base.js.map +1 -1
  39. package/dist/components/dropzone/Dropzone.base.d.ts +74 -0
  40. package/dist/components/dropzone/Dropzone.base.js +82 -0
  41. package/dist/components/dropzone/Dropzone.base.js.map +1 -0
  42. package/dist/components/dropzone/Dropzone.types.d.ts +43 -0
  43. package/dist/components/dropzone/Dropzone.types.js +15 -0
  44. package/dist/components/dropzone/Dropzone.types.js.map +1 -0
  45. package/dist/components/dropzone/index.d.ts +13 -0
  46. package/dist/components/dropzone/index.js +3 -0
  47. package/dist/components/icon/Icon.base.d.ts +11 -7
  48. package/dist/components/icon/Icon.base.js +13 -20
  49. package/dist/components/icon/Icon.base.js.map +1 -1
  50. package/dist/components/illustrated-message/IllustratedMessage.base.d.ts +22 -8
  51. package/dist/components/illustrated-message/IllustratedMessage.base.js +33 -20
  52. package/dist/components/illustrated-message/IllustratedMessage.base.js.map +1 -1
  53. package/dist/components/infield-button/InfieldButton.base.d.ts +28 -0
  54. package/dist/components/infield-button/InfieldButton.base.js +22 -0
  55. package/dist/components/infield-button/InfieldButton.base.js.map +1 -0
  56. package/dist/components/infield-button/InfieldButton.types.d.ts +13 -0
  57. package/dist/components/infield-button/InfieldButton.types.js +11 -0
  58. package/dist/components/infield-button/InfieldButton.types.js.map +1 -0
  59. package/dist/components/infield-button/index.d.ts +13 -0
  60. package/dist/components/infield-button/index.js +3 -0
  61. package/dist/components/meter/Meter.base.js +11 -9
  62. package/dist/components/meter/Meter.base.js.map +1 -1
  63. package/dist/components/popover/Popover.base.js +46 -42
  64. package/dist/components/popover/Popover.base.js.map +1 -1
  65. package/dist/components/progress-circle/ProgressCircle.base.d.ts +0 -1
  66. package/dist/components/progress-circle/ProgressCircle.base.js +26 -22
  67. package/dist/components/progress-circle/ProgressCircle.base.js.map +1 -1
  68. package/dist/components/status-light/StatusLight.base.d.ts +1 -1
  69. package/dist/components/status-light/StatusLight.base.js +12 -9
  70. package/dist/components/status-light/StatusLight.base.js.map +1 -1
  71. package/dist/components/tabs/Tabs.base.js +44 -32
  72. package/dist/components/tabs/Tabs.base.js.map +1 -1
  73. package/dist/components/tooltip/Tooltip.base.js +57 -22
  74. package/dist/components/tooltip/Tooltip.base.js.map +1 -1
  75. package/dist/controllers/color-controller/src/color-controller.js +45 -44
  76. package/dist/controllers/color-controller/src/color-controller.js.map +1 -1
  77. package/dist/controllers/drag-and-drop-controller/index.d.ts +12 -0
  78. package/dist/controllers/drag-and-drop-controller/index.js +2 -0
  79. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.d.ts +68 -0
  80. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js +56 -0
  81. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js.map +1 -0
  82. package/dist/controllers/index.d.ts +4 -1
  83. package/dist/controllers/index.js +14 -11
  84. package/dist/controllers/page-scroll-lock-controller/index.d.ts +12 -0
  85. package/dist/controllers/page-scroll-lock-controller/index.js +2 -0
  86. package/dist/controllers/{page-scroll-lock.js → page-scroll-lock-controller/src/page-scroll-lock.js} +1 -1
  87. package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.js.map +1 -0
  88. package/dist/controllers/slot-presence-controller/index.d.ts +12 -0
  89. package/dist/controllers/slot-presence-controller/index.js +2 -0
  90. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.d.ts +57 -0
  91. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js +44 -0
  92. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js.map +1 -0
  93. package/dist/controllers/slot-text-controller/index.d.ts +12 -0
  94. package/dist/controllers/slot-text-controller/index.js +2 -0
  95. package/dist/controllers/slot-text-controller/src/slot-text-controller.d.ts +92 -0
  96. package/dist/controllers/slot-text-controller/src/slot-text-controller.js +53 -0
  97. package/dist/controllers/slot-text-controller/src/slot-text-controller.js.map +1 -0
  98. package/dist/element/index.d.ts +1 -1
  99. package/dist/element/index.js +2 -2
  100. package/dist/element/spectrum-element.d.ts +58 -15
  101. package/dist/element/spectrum-element.js +55 -36
  102. package/dist/element/spectrum-element.js.map +1 -1
  103. package/dist/element/version.d.ts +2 -2
  104. package/dist/element/version.js +1 -1
  105. package/dist/element/version.js.map +1 -1
  106. package/dist/mixins/index.d.ts +0 -2
  107. package/dist/mixins/index.js +4 -6
  108. package/dist/mixins/linear-progress-mixin.d.ts +1 -2
  109. package/dist/mixins/linear-progress-mixin.js +35 -34
  110. package/dist/mixins/linear-progress-mixin.js.map +1 -1
  111. package/dist/mixins/pending-mixin.js +12 -11
  112. package/dist/mixins/pending-mixin.js.map +1 -1
  113. package/dist/mixins/sized-mixin.d.ts +28 -0
  114. package/dist/mixins/sized-mixin.js +6 -6
  115. package/dist/mixins/sized-mixin.js.map +1 -1
  116. package/dist/utils/dev-validation.d.ts +88 -0
  117. package/dist/utils/dev-validation.js +33 -0
  118. package/dist/utils/dev-validation.js.map +1 -0
  119. package/dist/utils/index.d.ts +2 -0
  120. package/dist/utils/index.js +12 -10
  121. package/dist/utils/is-focus-visible-in-tree.d.ts +33 -0
  122. package/dist/utils/is-focus-visible-in-tree.js +11 -0
  123. package/dist/utils/is-focus-visible-in-tree.js.map +1 -0
  124. package/package.json +68 -15
  125. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/defineProperty.js +0 -12
  126. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPrimitive.js +0 -14
  127. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPropertyKey.js +0 -9
  128. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/typeof.js +0 -11
  129. package/dist/controllers/page-scroll-lock.js.map +0 -1
  130. package/dist/mixins/observe-slot-presence.d.ts +0 -12
  131. package/dist/mixins/observe-slot-presence.js +0 -40
  132. package/dist/mixins/observe-slot-presence.js.map +0 -1
  133. package/dist/mixins/observe-slot-text.d.ts +0 -11
  134. package/dist/mixins/observe-slot-text.js +0 -60
  135. package/dist/mixins/observe-slot-text.js.map +0 -1
  136. /package/dist/controllers/{page-scroll-lock.d.ts → page-scroll-lock-controller/src/page-scroll-lock.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Button.base.js","names":[],"sources":["../../../components/button/Button.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 { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport {\n ObserveSlotPresence,\n ObserveSlotText,\n SizedMixin,\n} from '@adobe/spectrum-wc-core/mixins/index.js';\n\nimport { BUTTON_VALID_SIZES, type ButtonSize } from './Button.types.js';\n\n/**\n * Abstract base class for all button-like components. Owns shared semantic\n * concerns: interaction state, sizing, slot-derived icon/label state,\n * accessible-name resolution, and host-to-internal-button attribute forwarding.\n *\n * Visual API specific to `sp-button` (`variant`, `fill-style`, `static-color`)\n * is intentionally absent so that ActionButton, ClearButton, CloseButton,\n * PickerButton, and InfieldButton can extend this base without inheriting\n * the `swc-button` visual surface.\n *\n * @attribute {ElementSize} size - The size of the button.\n *\n * @todo We currently have 3 levels of mixins on this class, but the mixin\n * composition guide recommends a maximum of 2. Explore reducing after milestone 2.\n */\nexport abstract class ButtonBase extends SizedMixin(\n ObserveSlotText(ObserveSlotPresence(SpectrumElement, '[slot=\"icon\"]'), ''),\n { validSizes: BUTTON_VALID_SIZES }\n) {\n static override shadowRootOptions: ShadowRootInit = {\n ...SpectrumElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * The size of the button.\n *\n * @default m\n */\n declare public size: ButtonSize;\n\n /**\n * Whether the button is disabled. Removes focusability and prevents\n * interaction.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n /**\n * Accessible label forwarded to the internal `<button>` element as\n * `aria-label`. Required for icon-only buttons, which have no visible text.\n */\n @property({ type: String, attribute: 'accessible-label' })\n public accessibleLabel?: string;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n protected get hasIcon(): boolean {\n return this.slotContentIsPresent;\n }\n\n protected get hasLabel(): boolean {\n return this.slotHasContent;\n }\n\n /**\n * Returns the set of attributes that should be forwarded to the internal\n * semantic `<button>` element, if not otherwise directly managed.\n *\n * @internal\n */\n protected getForwardedButtonAttributes(): Record<\n string,\n string | boolean | undefined\n > {\n return {\n disabled: this.disabled,\n };\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n // Capture phase so slotted light-DOM clicks are suppressed before host\n // listeners (e.g. Storybook actions) run.\n this.addEventListener('click', this.handleClick, true);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('click', this.handleClick, true);\n super.disconnectedCallback();\n }\n\n /**\n * Suppresses click activation while the button is `disabled`.\n *\n * Slotted icon content lives in the light DOM, so pointer clicks on icons\n * bypass the disabled inner `<button>` and bubble on the host. The host\n * listener (capture) and inner `@click` binding both call this handler.\n */\n protected readonly handleClick = (event: Event): void => {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n\n protected override update(changedProperties: PropertyValues): void {\n super.update(changedProperties);\n if (window.__swc?.DEBUG) {\n if (this.hasIcon && !this.hasLabel && !this.accessibleLabel) {\n window.__swc.warn(\n this,\n `<${this.localName}> with an icon and no label must have an \"accessible-label\" attribute to be accessible.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/button/#icon-only',\n { issues: ['accessible-label'] }\n );\n }\n }\n }\n}\n"],"mappings":";;;;;;OAuCsB,IAAtB,cAAyC,EACvC,EAAgB,EAAoB,GAAiB,kBAAgB,EAAE,GAAG,EAC1E,EAAE,YAAY,GAAoB,CACnC,CAAC;;+BAsB2B,wBAuDO,MAAuB;AACvD,GAAI,KAAK,aACP,EAAM,gBAAgB,EACtB,EAAM,0BAA0B;;;CA7CpC,IAAc,UAAmB;AAC/B,SAAO,KAAK;;CAGd,IAAc,WAAoB;AAChC,SAAO,KAAK;;CASd,+BAGE;AACA,SAAO,EACL,UAAU,KAAK,UAChB;;CAGH,oBAA0C;AAIxC,EAHA,MAAM,mBAAmB,EAGzB,KAAK,iBAAiB,SAAS,KAAK,aAAa,GAAK;;CAGxD,uBAA6C;AAE3C,EADA,KAAK,oBAAoB,SAAS,KAAK,aAAa,GAAK,EACzD,MAAM,sBAAsB;;CAiB9B,OAA0B,GAAyC;;AAEjE,EADA,MAAM,OAAO,EAAkB,GAC/B,IAAI,OAAO,UAAA,QAAA,EAAO,SACZ,KAAK,WAAW,CAAC,KAAK,YAAY,CAAC,KAAK,mBAC1C,OAAO,MAAM,KACX,MACA,IAAI,KAAK,UAAU,0FACnB,qFACA,EAAE,QAAQ,CAAC,mBAAmB,EAAE,CACjC;;;6BA5F6C;CAClD,GAAG,EAAgB;CACnB,gBAAgB;CACjB,KAiBA,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAO1C,EAAS;CAAE,MAAM;CAAQ,WAAW;CAAoB,CAAC,CAAA,EAAA,EAAA,WAAA,mBAAA,KAAA,EAAA"}
1
+ {"version":3,"file":"Button.base.js","names":[],"sources":["../../../components/button/Button.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 { SlotPresenceController } from '@adobe/spectrum-wc-core/controllers/slot-presence-controller/index.js';\nimport { SlotTextController } from '@adobe/spectrum-wc-core/controllers/slot-text-controller/index.js';\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\nimport { warnIf } from '@adobe/spectrum-wc-core/utils/index.js';\n\nimport { BUTTON_VALID_SIZES, type ButtonSize } from './Button.types.js';\n\n/**\n * Abstract base class for all button-like components. Owns shared semantic\n * concerns: interaction state, sizing, slot-derived icon/label state,\n * accessible-name resolution, and host-to-internal-button attribute forwarding.\n *\n * Visual API specific to `sp-button` (`variant`, `fill-style`, `static-color`)\n * is intentionally absent so that ActionButton, ClearButton, CloseButton,\n * PickerButton, and InfieldButton can extend this base without inheriting\n * the `swc-button` visual surface.\n *\n * @attribute {ElementSize} size - The size of the button.\n */\nexport abstract class ButtonBase extends SizedMixin(SpectrumElement, {\n validSizes: BUTTON_VALID_SIZES,\n}) {\n static override shadowRootOptions: ShadowRootInit = {\n ...SpectrumElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * The size of the button.\n *\n * @default m\n */\n declare public size: ButtonSize;\n\n /**\n * Whether the button is disabled. Removes focusability and prevents\n * interaction.\n */\n @property({ type: Boolean, reflect: true })\n public disabled: boolean = false;\n\n /**\n * Accessible label forwarded to the internal `<button>` element as\n * `aria-label`. Required for icon-only buttons, which have no visible text.\n */\n @property({ type: String, attribute: 'accessible-label' })\n public accessibleLabel?: string;\n\n // ──────────────────────\n // CONTROLLERS\n // ──────────────────────\n\n /**\n * Observes whether an icon is slotted into `[slot=\"icon\"]`.\n *\n * @internal\n */\n protected slotPresence = new SlotPresenceController(this, '[slot=\"icon\"]');\n\n /**\n * Observes whether the default slot has a meaningful text label. The default\n * slot must bind `@slotchange=${this.slotText.handleSlotChange}` for changes\n * after the first render to be tracked.\n *\n * @internal\n */\n protected slotText = new SlotTextController(this);\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n protected get hasIcon(): boolean {\n return this.slotPresence.isPresent;\n }\n\n protected get hasLabel(): boolean {\n return this.slotText.hasContent;\n }\n\n /**\n * Returns the set of attributes that should be forwarded to the internal\n * semantic `<button>` element, if not otherwise directly managed.\n *\n * @internal\n */\n protected getForwardedButtonAttributes(): Record<\n string,\n string | boolean | undefined\n > {\n return {\n disabled: this.disabled,\n };\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n // Capture phase so slotted light-DOM clicks are suppressed before host\n // listeners (e.g. Storybook actions) run.\n this.addEventListener('click', this.handleClick, true);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('click', this.handleClick, true);\n super.disconnectedCallback();\n }\n\n /**\n * Suppresses click activation while the button is `disabled`, or externally\n * marked `aria-disabled` (e.g. by a disabled parent `swc-action-group`,\n * which uses `aria-disabled` instead of native `disabled` so children\n * remain keyboard-reachable).\n *\n * Slotted icon content lives in the light DOM, so pointer clicks on icons\n * bypass the disabled inner `<button>` and bubble on the host. The host\n * listener (capture) and inner `@click` binding both call this handler.\n */\n protected readonly handleClick = (event: Event): void => {\n if (this.disabled || this.getAttribute('aria-disabled') === 'true') {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n\n protected override update(changedProperties: PropertyValues): void {\n super.update(changedProperties);\n warnIf(\n this,\n this.hasIcon && !this.hasLabel && !this.accessibleLabel,\n `<${this.localName}> with an icon and no label must have an \"accessible-label\" attribute to be accessible.`,\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-button--docs',\n { type: 'accessibility', issues: ['accessible-label'] }\n );\n }\n}\n"],"mappings":";;;;;;;;;OAmCsB,IAAtB,cAAyC,EAAW,GAAiB,EACnE,YAAY,GACb,CAAC,CAAC;;+BAsB0B,wBAkBF,IAAI,EAAuB,MAAM,kBAAgB,kBASrD,IAAI,EAAmB,KAAK,sBAmDf,MAAuB;AACvD,IAAI,KAAK,YAAY,KAAK,aAAa,gBAAgB,KAAK,YAC1D,EAAM,gBAAgB,EACtB,EAAM,0BAA0B;;;CAhDpC,IAAc,UAAmB;AAC/B,SAAO,KAAK,aAAa;;CAG3B,IAAc,WAAoB;AAChC,SAAO,KAAK,SAAS;;CASvB,+BAGE;AACA,SAAO,EACL,UAAU,KAAK,UAChB;;CAGH,oBAA0C;AAIxC,EAHA,MAAM,mBAAmB,EAGzB,KAAK,iBAAiB,SAAS,KAAK,aAAa,GAAK;;CAGxD,uBAA6C;AAE3C,EADA,KAAK,oBAAoB,SAAS,KAAK,aAAa,GAAK,EACzD,MAAM,sBAAsB;;CAoB9B,OAA0B,GAAyC;AAEjE,EADA,MAAM,OAAO,EAAkB,EAC/B,EACE,MACA,KAAK,WAAW,CAAC,KAAK,YAAY,CAAC,KAAK,iBACxC,IAAI,KAAK,UAAU,0FACnB,iFACA;GAAE,MAAM;GAAiB,QAAQ,CAAC,mBAAmB;GAAE,CACxD;;;6BAlHiD;CAClD,GAAG,EAAgB;CACnB,gBAAgB;CACjB,KAiBA,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAO1C,EAAS;CAAE,MAAM;CAAQ,WAAW;CAAoB,CAAC,CAAA,EAAA,EAAA,WAAA,mBAAA,KAAA,EAAA"}
@@ -4,8 +4,9 @@ import { BUTTON_GROUP_ALIGNMENTS as n, BUTTON_GROUP_ORIENTATIONS as r, BUTTON_GR
4
4
  import { property as a, queryAssignedElements as o } from "lit/decorators.js";
5
5
  import { SpectrumElement as s } from "@adobe/spectrum-wc-core/element/index.js";
6
6
  import { SizedMixin as c } from "@adobe/spectrum-wc-core/mixins/index.js";
7
+ import { validateEnum as l } from "@adobe/spectrum-wc-core/utils/index.js";
7
8
  //#region components/button-group/ButtonGroup.base.ts
8
- var l, u = class extends c(s, { validSizes: i }) {
9
+ var u, d = class extends c(s, { validSizes: i }) {
9
10
  constructor(...e) {
10
11
  super(...e), this.orientation = "horizontal", this.disabled = !1, this.align = "start", this.individuallyDisabled = /* @__PURE__ */ new WeakSet(), this._sizePropagation = new t(this, {
11
12
  attribute: "size",
@@ -16,12 +17,18 @@ var l, u = class extends c(s, { validSizes: i }) {
16
17
  super.firstUpdated(e), this.setAttribute("role", "group");
17
18
  }
18
19
  update(e) {
19
- var t;
20
- if ((t = window.__swc) != null && t.DEBUG) {
21
- let e = this.constructor;
22
- e.ORIENTATIONS.includes(this.orientation) || window.__swc.warn(this, `<${this.localName}> element expects the "orientation" attribute to be one of the following:`, "https://opensource.adobe.com/spectrum-web-components/components/button-group/", { issues: [...e.ORIENTATIONS] }), e.ALIGNMENTS.includes(this.align) || window.__swc.warn(this, `<${this.localName}> element expects the "align" attribute to be one of the following:`, "https://opensource.adobe.com/spectrum-web-components/components/button-group/", { issues: [...e.ALIGNMENTS] });
23
- }
24
- super.update(e);
20
+ let t = this.constructor;
21
+ l(this, {
22
+ prop: "orientation",
23
+ value: this.orientation,
24
+ valid: t.ORIENTATIONS,
25
+ url: "https://spectrum-web-components.adobe.com/?path=/docs/components-button-group--docs"
26
+ }), l(this, {
27
+ prop: "align",
28
+ value: this.align,
29
+ valid: t.ALIGNMENTS,
30
+ url: "https://spectrum-web-components.adobe.com/?path=/docs/components-button-group--docs"
31
+ }), super.update(e);
25
32
  }
26
33
  updated(e) {
27
34
  if (super.updated(e), e.has("disabled")) {
@@ -37,17 +44,17 @@ var l, u = class extends c(s, { validSizes: i }) {
37
44
  this.disabled || (this.individuallyDisabled = /* @__PURE__ */ new WeakSet());
38
45
  }
39
46
  };
40
- l = u, l.ORIENTATIONS = r, l.ALIGNMENTS = n, e([a({
47
+ u = d, u.ORIENTATIONS = r, u.ALIGNMENTS = n, e([a({
41
48
  type: String,
42
49
  reflect: !0
43
- })], u.prototype, "orientation", void 0), e([a({
50
+ })], d.prototype, "orientation", void 0), e([a({
44
51
  type: Boolean,
45
52
  reflect: !0
46
- })], u.prototype, "disabled", void 0), e([a({
53
+ })], d.prototype, "disabled", void 0), e([a({
47
54
  type: String,
48
55
  reflect: !0
49
- })], u.prototype, "align", void 0), e([o({ flatten: !0 })], u.prototype, "buttons", void 0);
56
+ })], d.prototype, "align", void 0), e([o({ flatten: !0 })], d.prototype, "buttons", void 0);
50
57
  //#endregion
51
- export { u as ButtonGroupBase };
58
+ export { d as ButtonGroupBase };
52
59
 
53
60
  //# sourceMappingURL=ButtonGroup.base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonGroup.base.js","names":[],"sources":["../../../components/button-group/ButtonGroup.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 type { ButtonBase } from '@adobe/spectrum-wc-core/components/button';\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\n\nimport { SlotAttributePropagationController } from '../../controllers/slot-attribute-propagation-controller/index.js';\nimport {\n BUTTON_GROUP_ALIGNMENTS,\n BUTTON_GROUP_ORIENTATIONS,\n BUTTON_GROUP_SIZES,\n type ButtonGroupAlignment,\n type ButtonGroupOrientation,\n type ButtonGroupSize,\n} from './ButtonGroup.types.js';\n\n/**\n * A button group clusters related actions together, providing consistent\n * spacing, sizing, and orientation. The host exposes `role=\"group\"` and\n * propagates `size` and `disabled` to slotted button children.\n *\n * This base class owns shared logic and accessibility semantics. Rendering\n * and styling live in the concrete SWC subclass.\n *\n * @slot - One or more `swc-button` elements.\n *\n * @attribute {ElementSize} size - The size of the button group and its children.\n */\nexport abstract class ButtonGroupBase extends SizedMixin(SpectrumElement, {\n validSizes: BUTTON_GROUP_SIZES,\n}) {\n /**\n * The size of the button group. Propagated to all slotted button children.\n *\n * @default m\n */\n declare public size: ButtonGroupSize;\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * @internal\n *\n * Valid orientation values for validation.\n */\n static readonly ORIENTATIONS: readonly string[] = BUTTON_GROUP_ORIENTATIONS;\n\n /**\n * @internal\n *\n * Valid alignment values for validation.\n */\n static readonly ALIGNMENTS: readonly string[] = BUTTON_GROUP_ALIGNMENTS;\n\n /**\n * The layout direction of the button group.\n *\n * Note: this property does NOT set `aria-orientation` on the host because\n * `aria-orientation` is only meaningful for roles that manage arrow-key\n * navigation (e.g. `toolbar`, `listbox`). Since button-group uses\n * sequential Tab navigation (not roving tabindex), the attribute would\n * be invalid.\n */\n @property({ type: String, reflect: true })\n public orientation: ButtonGroupOrientation = 'horizontal';\n\n /**\n * Whether all buttons in the group are disabled. When `true`, forces\n * every slotted button child to `disabled`. When `false`, children\n * retain their individual disabled state — a button slotted with\n * `disabled` remains disabled even when the group is enabled.\n */\n @property({ type: Boolean, reflect: true })\n public disabled = false;\n\n /**\n * The alignment of buttons within the group along the main axis.\n */\n @property({ type: String, reflect: true })\n public align: ButtonGroupAlignment = 'start';\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n @queryAssignedElements({ flatten: true })\n private buttons!: ButtonBase[];\n\n /**\n * Tracks buttons that were individually disabled before the group\n * forced all children disabled. Used to restore their state when\n * the group becomes enabled again.\n */\n private individuallyDisabled = new WeakSet<ButtonBase>();\n\n private readonly _sizePropagation = new SlotAttributePropagationController(\n this,\n {\n attribute: 'size',\n getValue: () => this.size,\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 update(changedProperties: PropertyValues): void {\n if (window.__swc?.DEBUG) {\n const constructor = this.constructor as typeof ButtonGroupBase;\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:`,\n 'https://opensource.adobe.com/spectrum-web-components/components/button-group/',\n { issues: [...constructor.ORIENTATIONS] }\n );\n }\n if (!constructor.ALIGNMENTS.includes(this.align)) {\n window.__swc.warn(\n this,\n `<${this.localName}> element expects the \"align\" attribute to be one of the following:`,\n 'https://opensource.adobe.com/spectrum-web-components/components/button-group/',\n { issues: [...constructor.ALIGNMENTS] }\n );\n }\n }\n super.update(changedProperties);\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n\n if (changed.has('disabled')) {\n const wasDisabled = changed.get('disabled');\n if (this.disabled || wasDisabled) {\n this.propagateDisabledToChildren();\n }\n }\n }\n\n /**\n * Handles slotchange events from the default slot. Ensures newly slotted\n * children receive the current size and disabled state.\n */\n protected handleSlotchange(): void {\n this._sizePropagation.propagate();\n\n if (this.disabled) {\n this.propagateDisabledToChildren();\n }\n }\n\n /**\n * Propagates disabled state to slotted button children.\n *\n * Uses a one-directional model: when the group is disabled, all children\n * are forced disabled (tracking which were already individually disabled).\n * When the group is enabled, children are restored to their individual\n * disabled state — a button slotted with `disabled` remains disabled.\n *\n * On slotchange when the group is enabled, buttons are not touched so\n * their declarative `disabled` attribute is preserved.\n */\n private propagateDisabledToChildren(): void {\n for (const button of this.buttons) {\n if (this.disabled) {\n if (button.disabled) {\n this.individuallyDisabled.add(button);\n }\n button.disabled = true;\n } else {\n button.disabled = this.individuallyDisabled.has(button);\n }\n }\n\n if (!this.disabled) {\n this.individuallyDisabled = new WeakSet();\n }\n }\n}\n"],"mappings":";;;;;;;OAyCsB,IAAtB,cAA8C,EAAW,GAAiB,EACxE,YAAY,GACb,CAAC,CAAC;;kCAoC4C,8BAS3B,iBAMmB,qDAcN,IAAI,SAAqB,0BAEpB,IAAI,EACtC,MACA;GACE,WAAW;GACX,gBAAgB,KAAK;GACtB,CACF;;CAED,aAAgC,GAAqC;AAEnE,EADA,MAAM,aAAa,EAAQ,EAC3B,KAAK,aAAa,QAAQ,QAAQ;;CAGpC,OAA0B,GAAyC;;AACjE,OAAA,IAAI,OAAO,UAAA,QAAA,EAAO,OAAO;GACvB,IAAM,IAAc,KAAK;AASzB,GARK,EAAY,aAAa,SAAS,KAAK,YAAY,IACtD,OAAO,MAAM,KACX,MACA,IAAI,KAAK,UAAU,4EACnB,iFACA,EAAE,QAAQ,CAAC,GAAG,EAAY,aAAa,EAAE,CAC1C,EAEE,EAAY,WAAW,SAAS,KAAK,MAAM,IAC9C,OAAO,MAAM,KACX,MACA,IAAI,KAAK,UAAU,sEACnB,iFACA,EAAE,QAAQ,CAAC,GAAG,EAAY,WAAW,EAAE,CACxC;;AAGL,QAAM,OAAO,EAAkB;;CAGjC,QAA2B,GAAqC;AAG9D,MAFA,MAAM,QAAQ,EAAQ,EAElB,EAAQ,IAAI,WAAW,EAAE;GAC3B,IAAM,IAAc,EAAQ,IAAI,WAAW;AAC3C,IAAI,KAAK,YAAY,MACnB,KAAK,6BAA6B;;;CASxC,mBAAmC;AAGjC,EAFA,KAAK,iBAAiB,WAAW,EAE7B,KAAK,YACP,KAAK,6BAA6B;;CAetC,8BAA4C;AAC1C,OAAK,IAAM,KAAU,KAAK,QACxB,CAAI,KAAK,YACH,EAAO,YACT,KAAK,qBAAqB,IAAI,EAAO,EAEvC,EAAO,WAAW,MAElB,EAAO,WAAW,KAAK,qBAAqB,IAAI,EAAO;AAI3D,EAAK,KAAK,aACR,KAAK,uCAAuB,IAAI,SAAS;;;wBArIK,kBAOF,MAW/C,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,eAAA,KAAA,EAAA,KASzC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAM1C,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,SAAA,KAAA,EAAA,KAOzC,EAAsB,EAAE,SAAS,IAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA"}
1
+ {"version":3,"file":"ButtonGroup.base.js","names":[],"sources":["../../../components/button-group/ButtonGroup.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 type { ButtonBase } from '@adobe/spectrum-wc-core/components/button';\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 { SlotAttributePropagationController } from '../../controllers/slot-attribute-propagation-controller/index.js';\nimport {\n BUTTON_GROUP_ALIGNMENTS,\n BUTTON_GROUP_ORIENTATIONS,\n BUTTON_GROUP_SIZES,\n type ButtonGroupAlignment,\n type ButtonGroupOrientation,\n type ButtonGroupSize,\n} from './ButtonGroup.types.js';\n\n/**\n * A button group clusters related actions together, providing consistent\n * spacing, sizing, and orientation. The host exposes `role=\"group\"` and\n * propagates `size` and `disabled` to slotted button children.\n *\n * This base class owns shared logic and accessibility semantics. Rendering\n * and styling live in the concrete SWC subclass.\n *\n * @slot - One or more `swc-button` elements.\n *\n * @attribute {ElementSize} size - The size of the button group and its children.\n */\nexport abstract class ButtonGroupBase extends SizedMixin(SpectrumElement, {\n validSizes: BUTTON_GROUP_SIZES,\n}) {\n /**\n * The size of the button group. Propagated to all slotted button children.\n *\n * @default m\n */\n declare public size: ButtonGroupSize;\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * @internal\n *\n * Valid orientation values for validation.\n */\n static readonly ORIENTATIONS: readonly string[] = BUTTON_GROUP_ORIENTATIONS;\n\n /**\n * @internal\n *\n * Valid alignment values for validation.\n */\n static readonly ALIGNMENTS: readonly string[] = BUTTON_GROUP_ALIGNMENTS;\n\n /**\n * The layout direction of the button group.\n *\n * Note: this property does NOT set `aria-orientation` on the host because\n * `aria-orientation` is only meaningful for roles that manage arrow-key\n * navigation (e.g. `toolbar`, `listbox`). Since button-group uses\n * sequential Tab navigation (not roving tabindex), the attribute would\n * be invalid.\n */\n @property({ type: String, reflect: true })\n public orientation: ButtonGroupOrientation = 'horizontal';\n\n /**\n * Whether all buttons in the group are disabled. When `true`, forces\n * every slotted button child to `disabled`. When `false`, children\n * retain their individual disabled state — a button slotted with\n * `disabled` remains disabled even when the group is enabled.\n */\n @property({ type: Boolean, reflect: true })\n public disabled = false;\n\n /**\n * The alignment of buttons within the group along the main axis.\n */\n @property({ type: String, reflect: true })\n public align: ButtonGroupAlignment = 'start';\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n @queryAssignedElements({ flatten: true })\n private buttons!: ButtonBase[];\n\n /**\n * Tracks buttons that were individually disabled before the group\n * forced all children disabled. Used to restore their state when\n * the group becomes enabled again.\n */\n private individuallyDisabled = new WeakSet<ButtonBase>();\n\n private readonly _sizePropagation = new SlotAttributePropagationController(\n this,\n {\n attribute: 'size',\n getValue: () => this.size,\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 update(changedProperties: PropertyValues): void {\n const constructor = this.constructor as typeof ButtonGroupBase;\n validateEnum(this, {\n prop: 'orientation',\n value: this.orientation,\n valid: constructor.ORIENTATIONS,\n url: 'https://spectrum-web-components.adobe.com/?path=/docs/components-button-group--docs',\n });\n validateEnum(this, {\n prop: 'align',\n value: this.align,\n valid: constructor.ALIGNMENTS,\n url: 'https://spectrum-web-components.adobe.com/?path=/docs/components-button-group--docs',\n });\n super.update(changedProperties);\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n\n if (changed.has('disabled')) {\n const wasDisabled = changed.get('disabled');\n if (this.disabled || wasDisabled) {\n this.propagateDisabledToChildren();\n }\n }\n }\n\n /**\n * Handles slotchange events from the default slot. Ensures newly slotted\n * children receive the current size and disabled state.\n */\n protected handleSlotchange(): void {\n this._sizePropagation.propagate();\n\n if (this.disabled) {\n this.propagateDisabledToChildren();\n }\n }\n\n /**\n * Propagates disabled state to slotted button children.\n *\n * Uses a one-directional model: when the group is disabled, all children\n * are forced disabled (tracking which were already individually disabled).\n * When the group is enabled, children are restored to their individual\n * disabled state — a button slotted with `disabled` remains disabled.\n *\n * On slotchange when the group is enabled, buttons are not touched so\n * their declarative `disabled` attribute is preserved.\n */\n private propagateDisabledToChildren(): void {\n for (const button of this.buttons) {\n if (this.disabled) {\n if (button.disabled) {\n this.individuallyDisabled.add(button);\n }\n button.disabled = true;\n } else {\n button.disabled = this.individuallyDisabled.has(button);\n }\n }\n\n if (!this.disabled) {\n this.individuallyDisabled = new WeakSet();\n }\n }\n}\n"],"mappings":";;;;;;;;OA0CsB,IAAtB,cAA8C,EAAW,GAAiB,EACxE,YAAY,GACb,CAAC,CAAC;;kCAoC4C,8BAS3B,iBAMmB,qDAcN,IAAI,SAAqB,0BAEpB,IAAI,EACtC,MACA;GACE,WAAW;GACX,gBAAgB,KAAK;GACtB,CACF;;CAED,aAAgC,GAAqC;AAEnE,EADA,MAAM,aAAa,EAAQ,EAC3B,KAAK,aAAa,QAAQ,QAAQ;;CAGpC,OAA0B,GAAyC;EACjE,IAAM,IAAc,KAAK;AAazB,EAZA,EAAa,MAAM;GACjB,MAAM;GACN,OAAO,KAAK;GACZ,OAAO,EAAY;GACnB,KAAK;GACN,CAAC,EACF,EAAa,MAAM;GACjB,MAAM;GACN,OAAO,KAAK;GACZ,OAAO,EAAY;GACnB,KAAK;GACN,CAAC,EACF,MAAM,OAAO,EAAkB;;CAGjC,QAA2B,GAAqC;AAG9D,MAFA,MAAM,QAAQ,EAAQ,EAElB,EAAQ,IAAI,WAAW,EAAE;GAC3B,IAAM,IAAc,EAAQ,IAAI,WAAW;AAC3C,IAAI,KAAK,YAAY,MACnB,KAAK,6BAA6B;;;CASxC,mBAAmC;AAGjC,EAFA,KAAK,iBAAiB,WAAW,EAE7B,KAAK,YACP,KAAK,6BAA6B;;CAetC,8BAA4C;AAC1C,OAAK,IAAM,KAAU,KAAK,QACxB,CAAI,KAAK,YACH,EAAO,YACT,KAAK,qBAAqB,IAAI,EAAO,EAEvC,EAAO,WAAW,MAElB,EAAO,WAAW,KAAK,qBAAqB,IAAI,EAAO;AAI3D,EAAK,KAAK,aACR,KAAK,uCAAuB,IAAI,SAAS;;;wBA/HK,kBAOF,MAW/C,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,eAAA,KAAA,EAAA,KASzC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAM1C,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,SAAA,KAAA,EAAA,KAOzC,EAAsB,EAAE,SAAS,IAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA"}
@@ -1,5 +1,6 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { SpectrumElement } from '../../element/index.js';
3
+ import { SlotTextController } from '../../controllers/slot-text-controller/index.js';
3
4
  import { CardDensity, CardVariant } from './Card.types.js';
4
5
  declare const CardBase_base: typeof SpectrumElement & {
5
6
  new (...args: any[]): import('../../mixins/index.js').SizedElementInterface;
@@ -9,20 +10,31 @@ declare const CardBase_base: typeof SpectrumElement & {
9
10
  * Abstract base class for all card-family components. Owns the semantics
10
11
  * shared across every card type: sizing, visual variant, and density.
11
12
  *
12
- * `swc-card`, `swc-user-card`, and `swc-product-card` each extend this base
13
- * directly and render the shared anatomy via `renderCardTemplate()` in
14
- * `swc/components/card/card-template.ts`. That template also carries a
15
- * collection placeholder and an avatar/thumbnail glyph, each supplied
16
- * per-component via `renderCollection`/`renderGlyph`.
17
- *
18
13
  * @attribute {ElementSize} size - The size of the card.
19
14
  *
15
+ * @fires swc-card-click - Dispatched when a `selectable` card is activated (click, Enter, or Space).
16
+ *
20
17
  * @slot preview - Primary preview content
21
18
  * @slot title - Card title
22
19
  * @slot actions - Optional action controls
23
20
  * @slot description - Supporting description text
24
21
  * @slot footer - Optional footer content
25
22
  * @slot - Additional body content
23
+ *
24
+ * @cssprop --swc-card-base-max-inline-size - Maximum inline size of the card. Defaults to 280px, overridden per size.
25
+ * @cssprop --swc-card-base-border-radius - Corner radius of the card. Defaults to the extra-large corner-radius token, overridden per size.
26
+ * @cssprop --swc-card-base-box-shadow - Box shadow (elevation) of the card. Defaults to the emphasized drop-shadow token; overridden by the tertiary variant, selectable focus, and title-as-link/selectable hover.
27
+ * @cssprop --swc-card-base-background-color - Background color of the card. Defaults to the layer-2 background token; overridden by the secondary, tertiary, and quiet variants.
28
+ * @cssprop --swc-card-base-preview-aspect-ratio - Aspect ratio of the preview slot. Defaults to 3/2.
29
+ * @cssprop --swc-card-base-title-font-size - Font size of the title slot. Defaults to the medium font-size token, overridden per size.
30
+ * @cssprop --swc-card-base-title-line-height - Line height of the title slot. Defaults to the medium line-height token, overridden per size.
31
+ * @cssprop --swc-card-base-description-font-size - Font size of the description slot and default slot content. Defaults to a smaller font-size token, overridden per size.
32
+ * @cssprop --swc-card-base-action-component-height - Height used to vertically balance slotted actions content. Defaults to the smallest component-height token, overridden per size.
33
+ * @cssprop --swc-card-base-content-header-gap - Column gap between the title and actions slots. Defaults to the medium base-gap token, overridden per size.
34
+ * @cssprop --swc-card-base-content-padding - Padding of the content region. Defaults to the medium container-padding token; overridden by density.
35
+ * @cssprop --swc-card-base-content-padding-regular - Content padding used at the default (regular) density, per size.
36
+ * @cssprop --swc-card-base-content-padding-compact - Content padding used at compact density, per size.
37
+ * @cssprop --swc-card-base-content-padding-spacious - Content padding used at spacious density, per size.
26
38
  */
27
39
  export declare abstract class CardBase extends CardBase_base {
28
40
  /**
@@ -48,75 +60,112 @@ export declare abstract class CardBase extends CardBase_base {
48
60
  /**
49
61
  * Indicates the consumer has wrapped their `title` slot content in a real
50
62
  * link. Extends that link's hit area to cover the card surface while
51
- * leaving navigation entirely consumer-owned Card accepts no `href`.
52
- *
53
- * @todo Naming, and the `::slotted(a)::after` vs. click-proxy mechanism,
54
- * are still open. See the card family plan, A11y-3 / Q2.
63
+ * leaving navigation entirely consumer-owned; Card accepts no `href`.
55
64
  */
56
65
  titleAsLink: boolean;
57
66
  /**
58
67
  * Makes the card focusable and captures surface clicks (excluding nested
59
68
  * interactive targets) to dispatch a `swc-card-click` event, independent
60
- * of `titleAsLink`. Lays groundwork for a future `CardView` selection
61
- * model without Card owning selected-state UI itself.
69
+ * of `titleAsLink`.
62
70
  *
63
- * @todo Event name and `tabindex` management details are still open. See
64
- * the card family plan, A11y-3 / Q3.
65
- * @todo No `role` is set when `selectable` is true — deferred rather than
66
- * defaulting to `role="button"`, since the eventual `CardView` selection
67
- * model may call for a different role (e.g. `option`/`gridcell`) that
68
- * `role="button"` would be wrong to have committed to today. See the card
69
- * family plan, A11y-3 / Q8.
71
+ * @todo No ARIA role is set yet; deferred until a future `CardView`
72
+ * selection model determines the appropriate role.
70
73
  */
71
74
  selectable: boolean;
75
+ /**
76
+ * Keeps a slotted action control's `size` one step smaller than the
77
+ * card's own `size`.
78
+ */
79
+ private readonly _sizePropagation;
80
+ /**
81
+ * Observes whether the default slot has meaningful content. Each concrete
82
+ * card's `render()` must bind `@slotchange=${this.slotText.handleSlotChange}`
83
+ * on the default slot (via `renderCardTemplate`'s `onDefaultSlotChange`) for
84
+ * changes after the first render to be tracked.
85
+ *
86
+ * @internal
87
+ */
88
+ protected slotText: SlotTextController;
89
+ /**
90
+ * Whether the default slot has meaningful content. Consumed by each concrete
91
+ * card's `render()` (through `renderCardTemplate`'s `hasDefaultSlotContent`)
92
+ * to toggle the `--hasDefault` class.
93
+ *
94
+ * @internal
95
+ */
96
+ protected get slotHasContent(): boolean;
72
97
  connectedCallback(): void;
73
98
  disconnectedCallback(): void;
99
+ protected firstUpdated(changedProperties: PropertyValues): void;
100
+ protected update(changedProperties: PropertyValues): void;
74
101
  protected updated(changedProperties: PropertyValues): void;
75
102
  /**
76
103
  * @internal
77
- * The card's own `title` slot element, or `null` before the concrete
78
- * class's `renderCardTemplate()` call has rendered.
104
+ *
105
+ * The card's own `title` slot element.
79
106
  */
80
107
  protected getTitleSlotElement(): HTMLSlotElement | null;
81
108
  /**
82
109
  * @internal
83
- * The `title` slot's link, supporting both forms consumers reasonably
84
- * use: the assigned element itself is the anchor (`<a slot="title"
85
- * href="...">`), or the anchor is nested inside a wrapper (`<span
86
- * slot="title"><a href="...">`). Requires `href` — a link with no
87
- * destination can't usefully be clicked-through.
110
+ *
111
+ * The card's own `actions` slot element.
112
+ */
113
+ protected getActionsSlotElement(): HTMLSlotElement | null;
114
+ /**
115
+ * Whether the `actions` slot is supported for this card's current state.
116
+ * `xs` cards don't have room for it. Concrete classes may override this
117
+ * to exclude the slot for other reasons, independent of size.
118
+ */
119
+ protected get actionsSupported(): boolean;
120
+ /**
121
+ * @internal
122
+ *
123
+ * Warns in dev mode when the `actions` slot has content but isn't
124
+ * supported for the current state. Visual suppression is handled in
125
+ * CSS, not here.
126
+ */
127
+ private checkActionsSupport;
128
+ /**
129
+ * @internal
130
+ *
131
+ * The `title` slot's link: either the assigned element itself
132
+ * (`<a slot="title" href="...">`) or an anchor nested inside a wrapper
133
+ * (`<span slot="title"><a href="...">`). Requires `href`.
88
134
  */
89
135
  protected getTitleLinkElement(): HTMLAnchorElement | null;
90
136
  /**
91
137
  * @internal
92
- * Whether `node` provides its own interaction/focus semantics. Checking
93
- * the `tabIndex` IDL property (rather than the `tabindex` attribute or a
94
- * tag-name list) correctly covers natively-interactive elements
95
- * (`button`, `input`, `select`, `textarea`, `a[href]`) with no explicit
96
- * attribute, excludes `tabindex="-1"` (focusable for scripting, not a
97
- * click target) and disabled controls, and works for a custom element's
98
- * internal shadow-DOM control too — `composedPath()` already traverses
99
- * into other elements' shadow roots for composed events like `click`, so
100
- * an internal `<button>` inside e.g. `<swc-button>` is inspected directly
101
- * regardless of which shadow tree it belongs to.
138
+ *
139
+ * Whether `node` has its own interaction/focus semantics, via the
140
+ * `tabIndex` IDL property rather than the `tabindex` attribute; this
141
+ * also correctly excludes `tabindex="-1"` and disabled controls.
102
142
  */
103
143
  private static isFocusable;
144
+ /**
145
+ * @internal
146
+ *
147
+ * The size one step below `size` in `CARD_VALID_SIZES`, clamped at the
148
+ * smallest size.
149
+ */
150
+ private static getSmallerSize;
151
+ /**
152
+ * Re-propagates the `actions` slot's `size` for elements assigned after
153
+ * the initial render, wired to the slot's `slotchange` in
154
+ * `firstUpdated()`.
155
+ */
156
+ protected readonly handleActionsSlotChange: () => void;
104
157
  /**
105
158
  * Proxies a qualifying surface click to `titleAsLink`'s link and/or
106
159
  * dispatches `swc-card-click` for `selectable`, after filtering out
107
- * clicks that landed on a nested interactive target (see `isFocusable()`
108
- * and the `actions`-slot exclusion above).
160
+ * clicks that landed on a nested interactive target or followed a
161
+ * text-selection drag.
109
162
  */
110
163
  protected readonly handleSurfaceClick: (event: Event) => void;
111
164
  /**
112
- * `tabindex` is only ever added alongside this listener (see `updated()`)
113
- * and removed alongside its removal a focusable card is never left
114
- * without keyboard activation. Enter and Space are treated identically
115
- * and both proxy to `titleAsLink`'s link when set, even though a bare
116
- * link conventionally responds to Enter only: the card's own activation
117
- * contract (Enter+Space, more button-like) is authoritative once
118
- * `selectable` makes the card itself the focused target, regardless of
119
- * what that activation happens to proxy to.
165
+ * Enter and Space both activate the card, even though a bare link
166
+ * conventionally responds to Enter only; the card's own activation
167
+ * contract takes precedence once `selectable` makes it the focused
168
+ * target.
120
169
  */
121
170
  protected readonly handleSelectableKeydown: (event: KeyboardEvent) => void;
122
171
  }
@@ -1,21 +1,30 @@
1
1
  import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
2
- import { CARD_DENSITIES as t, CARD_VALID_SIZES as n, CARD_VARIANTS as r } from "./Card.types.js";
3
- import { property as i } from "lit/decorators.js";
4
- import { SpectrumElement as a } from "@adobe/spectrum-wc-core/element/index.js";
5
- import { SizedMixin as o } from "@adobe/spectrum-wc-core/mixins/index.js";
2
+ import { SlotAttributePropagationController as t } from "../../controllers/slot-attribute-propagation-controller/src/slot-attribute-propagation-controller.js";
3
+ import { SlotTextController as n } from "../../controllers/slot-text-controller/src/slot-text-controller.js";
4
+ import { CARD_DENSITIES as r, CARD_VALID_SIZES as i, CARD_VARIANTS as a, SWC_CARD_CLICK_EVENT as o } from "./Card.types.js";
5
+ import { property as s } from "lit/decorators.js";
6
+ import { SpectrumElement as c } from "@adobe/spectrum-wc-core/element/index.js";
7
+ import { SizedMixin as l } from "@adobe/spectrum-wc-core/mixins/index.js";
8
+ import { isDebug as u, validateEnum as d, warnIf as f } from "@adobe/spectrum-wc-core/utils/index.js";
6
9
  //#region components/card/Card.base.ts
7
- var s, c = class e extends o(a, { validSizes: n }) {
8
- constructor(...t) {
9
- super(...t), this.variant = "primary", this.density = "regular", this.titleAsLink = !1, this.selectable = !1, this.handleSurfaceClick = (t) => {
10
+ var p, m = class e extends l(c, { validSizes: i }) {
11
+ constructor(...r) {
12
+ super(...r), this.variant = "primary", this.density = "regular", this.titleAsLink = !1, this.selectable = !1, this._sizePropagation = new t(this, {
13
+ attribute: "size",
14
+ getValue: () => e.getSmallerSize(this.size),
15
+ slotName: "actions"
16
+ }), this.slotText = new n(this), this.handleActionsSlotChange = () => {
17
+ this._sizePropagation.propagate(), this.checkActionsSupport();
18
+ }, this.handleSurfaceClick = (t) => {
10
19
  var n;
11
- if (!this.titleAsLink && !this.selectable) return;
12
- let r = t.composedPath(), i = r.slice(0, r.indexOf(this)), a = (n = this.renderRoot) == null ? void 0 : n.querySelector("slot[name=\"actions\"]");
20
+ if (!this.titleAsLink && !this.selectable || t instanceof MouseEvent && ((n = document.getSelection()) == null ? void 0 : n.isCollapsed) === !1) return;
21
+ let r = t.composedPath(), i = r.slice(0, r.indexOf(this)), a = this.getActionsSlotElement();
13
22
  if (!(a && i.includes(a) || i.some(e.isFocusable))) {
14
23
  if (this.titleAsLink) {
15
- var o;
16
- (o = this.getTitleLinkElement()) == null || o.click();
24
+ var s;
25
+ (s = this.getTitleLinkElement()) == null || s.click();
17
26
  }
18
- this.selectable && this.dispatchEvent(new Event("swc-card-click", {
27
+ this.selectable && this.dispatchEvent(new Event(o, {
19
28
  bubbles: !0,
20
29
  composed: !0
21
30
  }));
@@ -24,23 +33,58 @@ var s, c = class e extends o(a, { validSizes: n }) {
24
33
  (e.code === "Enter" || e.code === "Space") && (e.preventDefault(), this.handleSurfaceClick(e));
25
34
  };
26
35
  }
36
+ get slotHasContent() {
37
+ return this.slotText.hasContent;
38
+ }
27
39
  connectedCallback() {
28
40
  super.connectedCallback(), this.addEventListener("click", this.handleSurfaceClick);
29
41
  }
30
42
  disconnectedCallback() {
31
43
  this.removeEventListener("click", this.handleSurfaceClick), this.removeEventListener("keydown", this.handleSelectableKeydown), super.disconnectedCallback();
32
44
  }
33
- updated(e) {
45
+ firstUpdated(e) {
34
46
  var t;
35
- if (super.updated(e), e.has("selectable") && (this.selectable ? (this.setAttribute("tabindex", "0"), this.addEventListener("keydown", this.handleSelectableKeydown)) : (this.removeAttribute("tabindex"), this.removeEventListener("keydown", this.handleSelectableKeydown))), (t = window.__swc) != null && t.DEBUG) {
36
- let { VARIANTS: t, DENSITIES: n } = this.constructor;
37
- e.has("variant") && !t.includes(this.variant) && window.__swc.warn(this, `<${this.localName}> received an invalid "variant" value of "${this.variant}". Valid values are ${t.join(", ")}.`, "https://opensource.adobe.com/spectrum-web-components/components/card/", { issues: [`variant="${this.variant}"`] }), e.has("density") && !n.includes(this.density) && window.__swc.warn(this, `<${this.localName}> received an invalid "density" value of "${this.density}". Valid values are ${n.join(", ")}.`, "https://opensource.adobe.com/spectrum-web-components/components/card/", { issues: [`density="${this.density}"`] }), e.has("titleAsLink") && this.titleAsLink && !this.getTitleLinkElement() && window.__swc.warn(this, `<${this.localName}> has "title-as-link" set but no link element was found in the "title" slot.`, "https://opensource.adobe.com/spectrum-web-components/components/card/", { issues: ["title-as-link"] });
38
- }
47
+ super.firstUpdated(e), (t = this.renderRoot) == null || (t = t.querySelector("slot[name=\"actions\"]")) == null || t.addEventListener("slotchange", this.handleActionsSlotChange);
48
+ }
49
+ update(e) {
50
+ let { VARIANTS: t, DENSITIES: n } = this.constructor;
51
+ e.has("variant") && d(this, {
52
+ prop: "variant",
53
+ value: this.variant,
54
+ valid: t,
55
+ url: "https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs"
56
+ }), e.has("density") && d(this, {
57
+ prop: "density",
58
+ value: this.density,
59
+ valid: n,
60
+ url: "https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs",
61
+ options: { level: "low" }
62
+ }), super.update(e);
63
+ }
64
+ updated(e) {
65
+ super.updated(e), e.has("selectable") && (this.selectable ? (this.setAttribute("tabindex", "0"), this.addEventListener("keydown", this.handleSelectableKeydown)) : (this.removeAttribute("tabindex"), this.removeEventListener("keydown", this.handleSelectableKeydown))), f(this, e.has("titleAsLink") && this.titleAsLink && !this.getTitleLinkElement(), `<${this.localName}> has "title-as-link" set but no link element was found in the "title" slot.`, "https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs", {
66
+ level: "high",
67
+ issues: ["title-as-link"]
68
+ }), e.has("size") && this.checkActionsSupport();
39
69
  }
40
70
  getTitleSlotElement() {
41
71
  var e, t;
42
72
  return (e = (t = this.renderRoot) == null ? void 0 : t.querySelector("slot[name=\"title\"]")) == null ? null : e;
43
73
  }
74
+ getActionsSlotElement() {
75
+ var e, t;
76
+ return (e = (t = this.renderRoot) == null ? void 0 : t.querySelector("slot[name=\"actions\"]")) == null ? null : e;
77
+ }
78
+ get actionsSupported() {
79
+ return this.size !== "xs";
80
+ }
81
+ checkActionsSupport() {
82
+ var e, t;
83
+ u() && f(this, !this.actionsSupported && ((e = (t = this.getActionsSlotElement()) == null ? void 0 : t.assignedElements({ flatten: !0 }).length) == null ? 0 : e) > 0, `<${this.localName}> has content in the "actions" slot, but actions are not supported for this card (size="${this.size}").`, "https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs", {
84
+ level: "medium",
85
+ issues: ["actions"]
86
+ });
87
+ }
44
88
  getTitleLinkElement() {
45
89
  var e;
46
90
  let t = (e = this.getTitleSlotElement()) == null ? void 0 : e.assignedElements({ flatten: !0 });
@@ -54,22 +98,26 @@ var s, c = class e extends o(a, { validSizes: n }) {
54
98
  static isFocusable(e) {
55
99
  return e instanceof HTMLElement && e.tabIndex >= 0;
56
100
  }
101
+ static getSmallerSize(e) {
102
+ let t = i.indexOf(e);
103
+ return i[Math.max(t - 1, 0)];
104
+ }
57
105
  };
58
- s = c, s.VARIANTS = r, s.DENSITIES = t, e([i({
106
+ p = m, p.VARIANTS = a, p.DENSITIES = r, e([s({
59
107
  type: String,
60
108
  reflect: !0
61
- })], c.prototype, "variant", void 0), e([i({
109
+ })], m.prototype, "variant", void 0), e([s({
62
110
  type: String,
63
111
  reflect: !0
64
- })], c.prototype, "density", void 0), e([i({
112
+ })], m.prototype, "density", void 0), e([s({
65
113
  type: Boolean,
66
114
  reflect: !0,
67
115
  attribute: "title-as-link"
68
- })], c.prototype, "titleAsLink", void 0), e([i({
116
+ })], m.prototype, "titleAsLink", void 0), e([s({
69
117
  type: Boolean,
70
118
  reflect: !0
71
- })], c.prototype, "selectable", void 0);
119
+ })], m.prototype, "selectable", void 0);
72
120
  //#endregion
73
- export { c as CardBase };
121
+ export { m as CardBase };
74
122
 
75
123
  //# sourceMappingURL=Card.base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.base.js","names":[],"sources":["../../../components/card/Card.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 { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { SizedMixin } from '@adobe/spectrum-wc-core/mixins/index.js';\n\nimport {\n CARD_DENSITIES,\n CARD_VALID_SIZES,\n CARD_VARIANTS,\n type CardDensity,\n type CardVariant,\n} from './Card.types.js';\n\n/**\n * Abstract base class for all card-family components. Owns the semantics\n * shared across every card type: sizing, visual variant, and density.\n *\n * `swc-card`, `swc-user-card`, and `swc-product-card` each extend this base\n * directly and render the shared anatomy via `renderCardTemplate()` in\n * `swc/components/card/card-template.ts`. That template also carries a\n * collection placeholder and an avatar/thumbnail glyph, each supplied\n * per-component via `renderCollection`/`renderGlyph`.\n *\n * @attribute {ElementSize} size - The size of the card.\n *\n * @slot preview - Primary preview content\n * @slot title - Card title\n * @slot actions - Optional action controls\n * @slot description - Supporting description text\n * @slot footer - Optional footer content\n * @slot - Additional body content\n */\nexport abstract class CardBase extends SizedMixin(SpectrumElement, {\n validSizes: CARD_VALID_SIZES,\n}) {\n // ─────────────────────────\n // API TO OVERRIDE\n // ─────────────────────────\n\n /**\n * @internal\n */\n static readonly VARIANTS: readonly CardVariant[] = CARD_VARIANTS;\n\n /**\n * @internal\n */\n static readonly DENSITIES: readonly CardDensity[] = CARD_DENSITIES;\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * The visual variant of the card.\n *\n * @default primary\n */\n @property({ type: String, reflect: true })\n public variant: CardVariant = 'primary';\n\n /**\n * The density of the card, controlling internal spacing and gaps.\n *\n * @default regular\n */\n @property({ type: String, reflect: true })\n public density: CardDensity = 'regular';\n\n /**\n * Indicates the consumer has wrapped their `title` slot content in a real\n * link. Extends that link's hit area to cover the card surface while\n * leaving navigation entirely consumer-owned — Card accepts no `href`.\n *\n * @todo Naming, and the `::slotted(a)::after` vs. click-proxy mechanism,\n * are still open. See the card family plan, A11y-3 / Q2.\n */\n @property({ type: Boolean, reflect: true, attribute: 'title-as-link' })\n public titleAsLink = false;\n\n /**\n * Makes the card focusable and captures surface clicks (excluding nested\n * interactive targets) to dispatch a `swc-card-click` event, independent\n * of `titleAsLink`. Lays groundwork for a future `CardView` selection\n * model without Card owning selected-state UI itself.\n *\n * @todo Event name and `tabindex` management details are still open. See\n * the card family plan, A11y-3 / Q3.\n * @todo No `role` is set when `selectable` is true — deferred rather than\n * defaulting to `role=\"button\"`, since the eventual `CardView` selection\n * model may call for a different role (e.g. `option`/`gridcell`) that\n * `role=\"button\"` would be wrong to have committed to today. See the card\n * family plan, A11y-3 / Q8.\n */\n @property({ type: Boolean, reflect: true })\n public selectable = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this.handleSurfaceClick);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('click', this.handleSurfaceClick);\n this.removeEventListener('keydown', this.handleSelectableKeydown);\n super.disconnectedCallback();\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n super.updated(changedProperties);\n\n if (changedProperties.has('selectable')) {\n if (this.selectable) {\n this.setAttribute('tabindex', '0');\n this.addEventListener('keydown', this.handleSelectableKeydown);\n } else {\n this.removeAttribute('tabindex');\n this.removeEventListener('keydown', this.handleSelectableKeydown);\n }\n }\n\n if (window.__swc?.DEBUG) {\n const { VARIANTS, DENSITIES } = this.constructor as typeof CardBase;\n\n if (\n changedProperties.has('variant') &&\n !VARIANTS.includes(this.variant)\n ) {\n window.__swc.warn(\n this,\n `<${this.localName}> received an invalid \"variant\" value of \"${this.variant}\". Valid values are ${VARIANTS.join(', ')}.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/card/',\n { issues: [`variant=\"${this.variant}\"`] }\n );\n }\n\n if (\n changedProperties.has('density') &&\n !DENSITIES.includes(this.density)\n ) {\n window.__swc.warn(\n this,\n `<${this.localName}> received an invalid \"density\" value of \"${this.density}\". Valid values are ${DENSITIES.join(', ')}.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/card/',\n { issues: [`density=\"${this.density}\"`] }\n );\n }\n\n if (\n changedProperties.has('titleAsLink') &&\n this.titleAsLink &&\n !this.getTitleLinkElement()\n ) {\n window.__swc.warn(\n this,\n `<${this.localName}> has \"title-as-link\" set but no link element was found in the \"title\" slot.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/card/',\n { issues: ['title-as-link'] }\n );\n }\n }\n }\n\n /**\n * @internal\n * The card's own `title` slot element, or `null` before the concrete\n * class's `renderCardTemplate()` call has rendered.\n */\n protected getTitleSlotElement(): HTMLSlotElement | null {\n return this.renderRoot?.querySelector('slot[name=\"title\"]') ?? null;\n }\n\n /**\n * @internal\n * The `title` slot's link, supporting both forms consumers reasonably\n * use: the assigned element itself is the anchor (`<a slot=\"title\"\n * href=\"...\">`), or the anchor is nested inside a wrapper (`<span\n * slot=\"title\"><a href=\"...\">`). Requires `href` — a link with no\n * destination can't usefully be clicked-through.\n */\n protected getTitleLinkElement(): HTMLAnchorElement | null {\n const assigned = this.getTitleSlotElement()?.assignedElements({\n flatten: true,\n });\n for (const element of assigned ?? []) {\n if (element instanceof HTMLAnchorElement && element.href) {\n return element;\n }\n const nested = element.querySelector<HTMLAnchorElement>('a[href]');\n if (nested) {\n return nested;\n }\n }\n return null;\n }\n\n /**\n * @internal\n * Whether `node` provides its own interaction/focus semantics. Checking\n * the `tabIndex` IDL property (rather than the `tabindex` attribute or a\n * tag-name list) correctly covers natively-interactive elements\n * (`button`, `input`, `select`, `textarea`, `a[href]`) with no explicit\n * attribute, excludes `tabindex=\"-1\"` (focusable for scripting, not a\n * click target) and disabled controls, and works for a custom element's\n * internal shadow-DOM control too — `composedPath()` already traverses\n * into other elements' shadow roots for composed events like `click`, so\n * an internal `<button>` inside e.g. `<swc-button>` is inspected directly\n * regardless of which shadow tree it belongs to.\n */\n private static isFocusable(node: EventTarget): boolean {\n return node instanceof HTMLElement && node.tabIndex >= 0;\n }\n\n /**\n * Proxies a qualifying surface click to `titleAsLink`'s link and/or\n * dispatches `swc-card-click` for `selectable`, after filtering out\n * clicks that landed on a nested interactive target (see `isFocusable()`\n * and the `actions`-slot exclusion above).\n */\n protected readonly handleSurfaceClick = (event: Event): void => {\n if (!this.titleAsLink && !this.selectable) {\n return;\n }\n const path = event.composedPath();\n const precedingPath = path.slice(0, path.indexOf(this));\n const actionsSlot = this.renderRoot?.querySelector('slot[name=\"actions\"]');\n const hitInteractiveTarget =\n // The `actions` slot is unconditionally excluded, defense-in-depth,\n // since it's contractually for interactive content regardless of\n // whether a given control correctly reflects focusability.\n (actionsSlot && precedingPath.includes(actionsSlot)) ||\n precedingPath.some(CardBase.isFocusable);\n if (hitInteractiveTarget) {\n return;\n }\n if (this.titleAsLink) {\n this.getTitleLinkElement()?.click();\n }\n if (this.selectable) {\n this.dispatchEvent(\n new Event('swc-card-click', { bubbles: true, composed: true })\n );\n }\n };\n\n /**\n * `tabindex` is only ever added alongside this listener (see `updated()`)\n * and removed alongside its removal — a focusable card is never left\n * without keyboard activation. Enter and Space are treated identically\n * and both proxy to `titleAsLink`'s link when set, even though a bare\n * link conventionally responds to Enter only: the card's own activation\n * contract (Enter+Space, more button-like) is authoritative once\n * `selectable` makes the card itself the focused target, regardless of\n * what that activation happens to proxy to.\n */\n protected readonly handleSelectableKeydown = (event: KeyboardEvent): void => {\n if (event.code === 'Enter' || event.code === 'Space') {\n event.preventDefault();\n this.handleSurfaceClick(event);\n }\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Card.base.js","names":[],"sources":["../../../components/card/Card.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 { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport {\n type ElementSize,\n SizedMixin,\n} from '@adobe/spectrum-wc-core/mixins/index.js';\nimport {\n isDebug,\n validateEnum,\n warnIf,\n} from '@adobe/spectrum-wc-core/utils/index.js';\n\nimport { SlotAttributePropagationController } from '../../controllers/slot-attribute-propagation-controller/index.js';\nimport { SlotTextController } from '../../controllers/slot-text-controller/index.js';\nimport {\n CARD_DENSITIES,\n CARD_VALID_SIZES,\n CARD_VARIANTS,\n type CardDensity,\n type CardSize,\n type CardVariant,\n SWC_CARD_CLICK_EVENT,\n} from './Card.types.js';\n\n/**\n * Abstract base class for all card-family components. Owns the semantics\n * shared across every card type: sizing, visual variant, and density.\n *\n * @attribute {ElementSize} size - The size of the card.\n *\n * @fires swc-card-click - Dispatched when a `selectable` card is activated (click, Enter, or Space).\n *\n * @slot preview - Primary preview content\n * @slot title - Card title\n * @slot actions - Optional action controls\n * @slot description - Supporting description text\n * @slot footer - Optional footer content\n * @slot - Additional body content\n *\n * @cssprop --swc-card-base-max-inline-size - Maximum inline size of the card. Defaults to 280px, overridden per size.\n * @cssprop --swc-card-base-border-radius - Corner radius of the card. Defaults to the extra-large corner-radius token, overridden per size.\n * @cssprop --swc-card-base-box-shadow - Box shadow (elevation) of the card. Defaults to the emphasized drop-shadow token; overridden by the tertiary variant, selectable focus, and title-as-link/selectable hover.\n * @cssprop --swc-card-base-background-color - Background color of the card. Defaults to the layer-2 background token; overridden by the secondary, tertiary, and quiet variants.\n * @cssprop --swc-card-base-preview-aspect-ratio - Aspect ratio of the preview slot. Defaults to 3/2.\n * @cssprop --swc-card-base-title-font-size - Font size of the title slot. Defaults to the medium font-size token, overridden per size.\n * @cssprop --swc-card-base-title-line-height - Line height of the title slot. Defaults to the medium line-height token, overridden per size.\n * @cssprop --swc-card-base-description-font-size - Font size of the description slot and default slot content. Defaults to a smaller font-size token, overridden per size.\n * @cssprop --swc-card-base-action-component-height - Height used to vertically balance slotted actions content. Defaults to the smallest component-height token, overridden per size.\n * @cssprop --swc-card-base-content-header-gap - Column gap between the title and actions slots. Defaults to the medium base-gap token, overridden per size.\n * @cssprop --swc-card-base-content-padding - Padding of the content region. Defaults to the medium container-padding token; overridden by density.\n * @cssprop --swc-card-base-content-padding-regular - Content padding used at the default (regular) density, per size.\n * @cssprop --swc-card-base-content-padding-compact - Content padding used at compact density, per size.\n * @cssprop --swc-card-base-content-padding-spacious - Content padding used at spacious density, per size.\n */\nexport abstract class CardBase extends SizedMixin(SpectrumElement, {\n validSizes: CARD_VALID_SIZES,\n}) {\n // ─────────────────────────\n // API TO OVERRIDE\n // ─────────────────────────\n\n /**\n * @internal\n */\n static readonly VARIANTS: readonly CardVariant[] = CARD_VARIANTS;\n\n /**\n * @internal\n */\n static readonly DENSITIES: readonly CardDensity[] = CARD_DENSITIES;\n\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n /**\n * The visual variant of the card.\n *\n * @default primary\n */\n @property({ type: String, reflect: true })\n public variant: CardVariant = 'primary';\n\n /**\n * The density of the card, controlling internal spacing and gaps.\n *\n * @default regular\n */\n @property({ type: String, reflect: true })\n public density: CardDensity = 'regular';\n\n /**\n * Indicates the consumer has wrapped their `title` slot content in a real\n * link. Extends that link's hit area to cover the card surface while\n * leaving navigation entirely consumer-owned; Card accepts no `href`.\n */\n @property({ type: Boolean, reflect: true, attribute: 'title-as-link' })\n public titleAsLink = false;\n\n /**\n * Makes the card focusable and captures surface clicks (excluding nested\n * interactive targets) to dispatch a `swc-card-click` event, independent\n * of `titleAsLink`.\n *\n * @todo No ARIA role is set yet; deferred until a future `CardView`\n * selection model determines the appropriate role.\n */\n @property({ type: Boolean, reflect: true })\n public selectable = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n /**\n * Keeps a slotted action control's `size` one step smaller than the\n * card's own `size`.\n */\n private readonly _sizePropagation = new SlotAttributePropagationController(\n this,\n {\n attribute: 'size',\n getValue: () => CardBase.getSmallerSize(this.size),\n slotName: 'actions',\n }\n );\n\n /**\n * Observes whether the default slot has meaningful content. Each concrete\n * card's `render()` must bind `@slotchange=${this.slotText.handleSlotChange}`\n * on the default slot (via `renderCardTemplate`'s `onDefaultSlotChange`) for\n * changes after the first render to be tracked.\n *\n * @internal\n */\n protected slotText = new SlotTextController(this);\n\n /**\n * Whether the default slot has meaningful content. Consumed by each concrete\n * card's `render()` (through `renderCardTemplate`'s `hasDefaultSlotContent`)\n * to toggle the `--hasDefault` class.\n *\n * @internal\n */\n protected get slotHasContent(): boolean {\n return this.slotText.hasContent;\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this.handleSurfaceClick);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('click', this.handleSurfaceClick);\n this.removeEventListener('keydown', this.handleSelectableKeydown);\n super.disconnectedCallback();\n }\n\n protected override firstUpdated(changedProperties: PropertyValues): void {\n super.firstUpdated(changedProperties);\n // renderCardTemplate() doesn't take a slotchange callback, so the\n // listener is attached imperatively rather than declaratively in the\n // template; the slot node itself persists across re-renders.\n this.renderRoot\n ?.querySelector('slot[name=\"actions\"]')\n ?.addEventListener('slotchange', this.handleActionsSlotChange);\n }\n\n protected override update(changedProperties: PropertyValues): void {\n const { VARIANTS, DENSITIES } = this.constructor as typeof CardBase;\n\n if (changedProperties.has('variant')) {\n validateEnum(this, {\n prop: 'variant',\n value: this.variant,\n valid: VARIANTS,\n url: 'https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs',\n });\n }\n\n if (changedProperties.has('density')) {\n validateEnum(this, {\n prop: 'density',\n value: this.density,\n valid: DENSITIES,\n url: 'https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs',\n options: { level: 'low' },\n });\n }\n\n super.update(changedProperties);\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n super.updated(changedProperties);\n\n if (changedProperties.has('selectable')) {\n if (this.selectable) {\n this.setAttribute('tabindex', '0');\n this.addEventListener('keydown', this.handleSelectableKeydown);\n } else {\n this.removeAttribute('tabindex');\n this.removeEventListener('keydown', this.handleSelectableKeydown);\n }\n }\n\n warnIf(\n this,\n changedProperties.has('titleAsLink') &&\n this.titleAsLink &&\n !this.getTitleLinkElement(),\n `<${this.localName}> has \"title-as-link\" set but no link element was found in the \"title\" slot.`,\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs',\n { level: 'high', issues: ['title-as-link'] }\n );\n\n if (changedProperties.has('size')) {\n this.checkActionsSupport();\n }\n }\n\n /**\n * @internal\n *\n * The card's own `title` slot element.\n */\n protected getTitleSlotElement(): HTMLSlotElement | null {\n return this.renderRoot?.querySelector('slot[name=\"title\"]') ?? null;\n }\n\n /**\n * @internal\n *\n * The card's own `actions` slot element.\n */\n protected getActionsSlotElement(): HTMLSlotElement | null {\n return this.renderRoot?.querySelector('slot[name=\"actions\"]') ?? null;\n }\n\n /**\n * Whether the `actions` slot is supported for this card's current state.\n * `xs` cards don't have room for it. Concrete classes may override this\n * to exclude the slot for other reasons, independent of size.\n */\n protected get actionsSupported(): boolean {\n return this.size !== 'xs';\n }\n\n /**\n * @internal\n *\n * Warns in dev mode when the `actions` slot has content but isn't\n * supported for the current state. Visual suppression is handled in\n * CSS, not here.\n */\n private checkActionsSupport(): void {\n if (!isDebug()) {\n return;\n }\n warnIf(\n this,\n !this.actionsSupported &&\n (this.getActionsSlotElement()?.assignedElements({ flatten: true })\n .length ?? 0) > 0,\n `<${this.localName}> has content in the \"actions\" slot, but actions are not supported for this card (size=\"${this.size}\").`,\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-card--docs',\n { level: 'medium', issues: ['actions'] }\n );\n }\n\n /**\n * @internal\n *\n * The `title` slot's link: either the assigned element itself\n * (`<a slot=\"title\" href=\"...\">`) or an anchor nested inside a wrapper\n * (`<span slot=\"title\"><a href=\"...\">`). Requires `href`.\n */\n protected getTitleLinkElement(): HTMLAnchorElement | null {\n const assigned = this.getTitleSlotElement()?.assignedElements({\n flatten: true,\n });\n for (const element of assigned ?? []) {\n if (element instanceof HTMLAnchorElement && element.href) {\n return element;\n }\n const nested = element.querySelector<HTMLAnchorElement>('a[href]');\n if (nested) {\n return nested;\n }\n }\n return null;\n }\n\n /**\n * @internal\n *\n * Whether `node` has its own interaction/focus semantics, via the\n * `tabIndex` IDL property rather than the `tabindex` attribute; this\n * also correctly excludes `tabindex=\"-1\"` and disabled controls.\n */\n private static isFocusable(node: EventTarget): boolean {\n return node instanceof HTMLElement && node.tabIndex >= 0;\n }\n\n /**\n * @internal\n *\n * The size one step below `size` in `CARD_VALID_SIZES`, clamped at the\n * smallest size.\n */\n private static getSmallerSize(size: ElementSize): CardSize {\n const index = CARD_VALID_SIZES.indexOf(size as CardSize);\n return CARD_VALID_SIZES[Math.max(index - 1, 0)];\n }\n\n /**\n * Re-propagates the `actions` slot's `size` for elements assigned after\n * the initial render, wired to the slot's `slotchange` in\n * `firstUpdated()`.\n */\n protected readonly handleActionsSlotChange = (): void => {\n this._sizePropagation.propagate();\n this.checkActionsSupport();\n };\n\n /**\n * Proxies a qualifying surface click to `titleAsLink`'s link and/or\n * dispatches `swc-card-click` for `selectable`, after filtering out\n * clicks that landed on a nested interactive target or followed a\n * text-selection drag.\n */\n protected readonly handleSurfaceClick = (event: Event): void => {\n if (!this.titleAsLink && !this.selectable) {\n return;\n }\n // A text-selection drag still fires `click` on mouseup; a non-collapsed\n // selection at that point means the user was selecting text, not\n // clicking through the card.\n if (\n event instanceof MouseEvent &&\n document.getSelection()?.isCollapsed === false\n ) {\n return;\n }\n const path = event.composedPath();\n const precedingPath = path.slice(0, path.indexOf(this));\n const actionsSlot = this.getActionsSlotElement();\n const hitInteractiveTarget =\n // The actions slot is always excluded, since it's contractually\n // for interactive content regardless of whether a control reflects\n // focusability correctly.\n (actionsSlot && precedingPath.includes(actionsSlot)) ||\n precedingPath.some(CardBase.isFocusable);\n if (hitInteractiveTarget) {\n return;\n }\n if (this.titleAsLink) {\n this.getTitleLinkElement()?.click();\n }\n if (this.selectable) {\n this.dispatchEvent(\n new Event(SWC_CARD_CLICK_EVENT, { bubbles: true, composed: true })\n );\n }\n };\n\n /**\n * Enter and Space both activate the card, even though a bare link\n * conventionally responds to Enter only; the card's own activation\n * contract takes precedence once `selectable` makes it the focused\n * target.\n */\n protected readonly handleSelectableKeydown = (event: KeyboardEvent): void => {\n if (event.code === 'Enter' || event.code === 'Space') {\n event.preventDefault();\n this.handleSurfaceClick(event);\n }\n };\n}\n"],"mappings":"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"}
@@ -12,6 +12,7 @@
12
12
  export declare const CARD_VALID_SIZES: readonly ["xs", "s", "m", "l", "xl"];
13
13
  export declare const CARD_VARIANTS: readonly ["primary", "secondary", "tertiary", "quiet"];
14
14
  export declare const CARD_DENSITIES: readonly ["compact", "regular", "spacious"];
15
+ export declare const SWC_CARD_CLICK_EVENT: "swc-card-click";
15
16
  export type CardSize = (typeof CARD_VALID_SIZES)[number];
16
17
  export type CardVariant = (typeof CARD_VARIANTS)[number];
17
18
  export type CardDensity = (typeof CARD_DENSITIES)[number];
@@ -14,8 +14,8 @@ var e = [
14
14
  "compact",
15
15
  "regular",
16
16
  "spacious"
17
- ];
17
+ ], r = "swc-card-click";
18
18
  //#endregion
19
- export { n as CARD_DENSITIES, e as CARD_VALID_SIZES, t as CARD_VARIANTS };
19
+ export { n as CARD_DENSITIES, e as CARD_VALID_SIZES, t as CARD_VARIANTS, r as SWC_CARD_CLICK_EVENT };
20
20
 
21
21
  //# sourceMappingURL=Card.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.types.js","names":[],"sources":["../../../components/card/Card.types.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 type { ElementSize } from '@adobe/spectrum-wc-core/mixins/index.js';\n\n// ──────────────────\n// SHARED\n// ──────────────────\n\nexport const CARD_VALID_SIZES = [\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n] as const satisfies readonly ElementSize[];\n\nexport const CARD_VARIANTS = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'quiet',\n] as const;\n\nexport const CARD_DENSITIES = ['compact', 'regular', 'spacious'] as const;\n\n// ──────────────────\n// TYPES\n// ──────────────────\n\nexport type CardSize = (typeof CARD_VALID_SIZES)[number];\nexport type CardVariant = (typeof CARD_VARIANTS)[number];\nexport type CardDensity = (typeof CARD_DENSITIES)[number];\n"],"mappings":";AAkBA,IAAa,IAAmB;CAC9B;CACA;CACA;CACA;CACA;CACD,EAEY,IAAgB;CAC3B;CACA;CACA;CACA;CACD,EAEY,IAAiB;CAAC;CAAW;CAAW;CAAW"}
1
+ {"version":3,"file":"Card.types.js","names":[],"sources":["../../../components/card/Card.types.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 type { ElementSize } from '@adobe/spectrum-wc-core/mixins/index.js';\n\n// ──────────────────\n// SHARED\n// ──────────────────\n\nexport const CARD_VALID_SIZES = [\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n] as const satisfies readonly ElementSize[];\n\nexport const CARD_VARIANTS = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'quiet',\n] as const;\n\nexport const CARD_DENSITIES = ['compact', 'regular', 'spacious'] as const;\n\nexport const SWC_CARD_CLICK_EVENT = 'swc-card-click' as const;\n\n// ──────────────────\n// TYPES\n// ──────────────────\n\nexport type CardSize = (typeof CARD_VALID_SIZES)[number];\nexport type CardVariant = (typeof CARD_VARIANTS)[number];\nexport type CardDensity = (typeof CARD_DENSITIES)[number];\n"],"mappings":";AAkBA,IAAa,IAAmB;CAC9B;CACA;CACA;CACA;CACA;CACD,EAEY,IAAgB;CAC3B;CACA;CACA;CACA;CACD,EAEY,IAAiB;CAAC;CAAW;CAAW;CAAW,EAEnD,IAAuB"}
@@ -1,3 +1,3 @@
1
- import { CARD_DENSITIES as e, CARD_VALID_SIZES as t, CARD_VARIANTS as n } from "./Card.types.js";
2
- import { CardBase as r } from "./Card.base.js";
3
- export { e as CARD_DENSITIES, t as CARD_VALID_SIZES, n as CARD_VARIANTS, r as CardBase };
1
+ import { CARD_DENSITIES as e, CARD_VALID_SIZES as t, CARD_VARIANTS as n, SWC_CARD_CLICK_EVENT as r } from "./Card.types.js";
2
+ import { CardBase as i } from "./Card.base.js";
3
+ export { e as CARD_DENSITIES, t as CARD_VALID_SIZES, n as CARD_VARIANTS, i as CardBase, r as SWC_CARD_CLICK_EVENT };