@adobe/spectrum-wc-core 2.0.0-beta.2 → 2.0.0-beta.4

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 (157) hide show
  1. package/README.md +1 -1
  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 +89 -10
  18. package/dist/components/asset/Asset.base.js +117 -12
  19. package/dist/components/asset/Asset.base.js.map +1 -1
  20. package/dist/components/asset/Asset.types.d.ts +20 -2
  21. package/dist/components/asset/Asset.types.js +10 -2
  22. package/dist/components/asset/Asset.types.js.map +1 -1
  23. package/dist/components/asset/index.js +3 -3
  24. package/dist/components/avatar/Avatar.base.js +18 -22
  25. package/dist/components/avatar/Avatar.base.js.map +1 -1
  26. package/dist/components/badge/Badge.base.d.ts +24 -8
  27. package/dist/components/badge/Badge.base.js +22 -17
  28. package/dist/components/badge/Badge.base.js.map +1 -1
  29. package/dist/components/button/Button.base.d.ts +20 -10
  30. package/dist/components/button/Button.base.js +17 -12
  31. package/dist/components/button/Button.base.js.map +1 -1
  32. package/dist/components/button-group/ButtonGroup.base.js +19 -12
  33. package/dist/components/button-group/ButtonGroup.base.js.map +1 -1
  34. package/dist/components/card/Card.base.d.ts +95 -46
  35. package/dist/components/card/Card.base.js +71 -23
  36. package/dist/components/card/Card.base.js.map +1 -1
  37. package/dist/components/card/Card.types.d.ts +1 -0
  38. package/dist/components/card/Card.types.js +2 -2
  39. package/dist/components/card/Card.types.js.map +1 -1
  40. package/dist/components/card/index.js +3 -3
  41. package/dist/components/divider/Divider.base.js +13 -8
  42. package/dist/components/divider/Divider.base.js.map +1 -1
  43. package/dist/components/dropzone/Dropzone.base.d.ts +74 -0
  44. package/dist/components/dropzone/Dropzone.base.js +82 -0
  45. package/dist/components/dropzone/Dropzone.base.js.map +1 -0
  46. package/dist/components/dropzone/Dropzone.types.d.ts +43 -0
  47. package/dist/components/dropzone/Dropzone.types.js +15 -0
  48. package/dist/components/dropzone/Dropzone.types.js.map +1 -0
  49. package/dist/components/dropzone/index.d.ts +13 -0
  50. package/dist/components/dropzone/index.js +3 -0
  51. package/dist/components/icon/Icon.base.d.ts +11 -7
  52. package/dist/components/icon/Icon.base.js +13 -20
  53. package/dist/components/icon/Icon.base.js.map +1 -1
  54. package/dist/components/illustrated-message/IllustratedMessage.base.d.ts +22 -8
  55. package/dist/components/illustrated-message/IllustratedMessage.base.js +33 -20
  56. package/dist/components/illustrated-message/IllustratedMessage.base.js.map +1 -1
  57. package/dist/components/infield-button/InfieldButton.base.d.ts +28 -0
  58. package/dist/components/infield-button/InfieldButton.base.js +22 -0
  59. package/dist/components/infield-button/InfieldButton.base.js.map +1 -0
  60. package/dist/components/infield-button/InfieldButton.types.d.ts +13 -0
  61. package/dist/components/infield-button/InfieldButton.types.js +11 -0
  62. package/dist/components/infield-button/InfieldButton.types.js.map +1 -0
  63. package/dist/components/infield-button/index.d.ts +13 -0
  64. package/dist/components/infield-button/index.js +3 -0
  65. package/dist/components/meter/Meter.base.js +11 -9
  66. package/dist/components/meter/Meter.base.js.map +1 -1
  67. package/dist/components/popover/Popover.base.d.ts +1 -21
  68. package/dist/components/popover/Popover.base.js +57 -77
  69. package/dist/components/popover/Popover.base.js.map +1 -1
  70. package/dist/components/progress-circle/ProgressCircle.base.d.ts +0 -1
  71. package/dist/components/progress-circle/ProgressCircle.base.js +26 -22
  72. package/dist/components/progress-circle/ProgressCircle.base.js.map +1 -1
  73. package/dist/components/status-light/StatusLight.base.d.ts +1 -1
  74. package/dist/components/status-light/StatusLight.base.js +12 -9
  75. package/dist/components/status-light/StatusLight.base.js.map +1 -1
  76. package/dist/components/tabs/TabPanel.base.d.ts +1 -1
  77. package/dist/components/tabs/TabPanel.base.js.map +1 -1
  78. package/dist/components/tabs/Tabs.base.js +44 -32
  79. package/dist/components/tabs/Tabs.base.js.map +1 -1
  80. package/dist/components/tooltip/Tooltip.base.js +57 -22
  81. package/dist/components/tooltip/Tooltip.base.js.map +1 -1
  82. package/dist/controllers/color-controller/src/color-controller.js +45 -44
  83. package/dist/controllers/color-controller/src/color-controller.js.map +1 -1
  84. package/dist/controllers/drag-and-drop-controller/index.d.ts +12 -0
  85. package/dist/controllers/drag-and-drop-controller/index.js +2 -0
  86. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.d.ts +68 -0
  87. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js +56 -0
  88. package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js.map +1 -0
  89. package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.d.ts +1 -1
  90. package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.js.map +1 -1
  91. package/dist/controllers/index.d.ts +6 -2
  92. package/dist/controllers/index.js +15 -11
  93. package/dist/controllers/language-resolution.d.ts +1 -1
  94. package/dist/controllers/language-resolution.js.map +1 -1
  95. package/dist/controllers/page-scroll-lock-controller/index.d.ts +12 -0
  96. package/dist/controllers/page-scroll-lock-controller/index.js +2 -0
  97. package/dist/controllers/{page-scroll-lock.js → page-scroll-lock-controller/src/page-scroll-lock.js} +1 -1
  98. package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.js.map +1 -0
  99. package/dist/controllers/slot-presence-controller/index.d.ts +12 -0
  100. package/dist/controllers/slot-presence-controller/index.js +2 -0
  101. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.d.ts +57 -0
  102. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js +44 -0
  103. package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js.map +1 -0
  104. package/dist/controllers/slot-text-controller/index.d.ts +12 -0
  105. package/dist/controllers/slot-text-controller/index.js +2 -0
  106. package/dist/controllers/slot-text-controller/src/slot-text-controller.d.ts +92 -0
  107. package/dist/controllers/slot-text-controller/src/slot-text-controller.js +53 -0
  108. package/dist/controllers/slot-text-controller/src/slot-text-controller.js.map +1 -0
  109. package/dist/controllers/trigger-press-controller/index.d.ts +12 -0
  110. package/dist/controllers/trigger-press-controller/index.js +2 -0
  111. package/dist/controllers/trigger-press-controller/src/trigger-press-controller.d.ts +149 -0
  112. package/dist/controllers/trigger-press-controller/src/trigger-press-controller.js +43 -0
  113. package/dist/controllers/trigger-press-controller/src/trigger-press-controller.js.map +1 -0
  114. package/dist/directives/index.d.ts +1 -1
  115. package/dist/element/define-element.js +1 -1
  116. package/dist/element/define-element.js.map +1 -1
  117. package/dist/element/index.d.ts +1 -1
  118. package/dist/element/index.js +2 -2
  119. package/dist/element/spectrum-element.d.ts +58 -15
  120. package/dist/element/spectrum-element.js +56 -37
  121. package/dist/element/spectrum-element.js.map +1 -1
  122. package/dist/element/version.d.ts +3 -3
  123. package/dist/element/version.js +1 -1
  124. package/dist/element/version.js.map +1 -1
  125. package/dist/mixins/index.d.ts +0 -2
  126. package/dist/mixins/index.js +4 -6
  127. package/dist/mixins/linear-progress-mixin.d.ts +1 -2
  128. package/dist/mixins/linear-progress-mixin.js +35 -34
  129. package/dist/mixins/linear-progress-mixin.js.map +1 -1
  130. package/dist/mixins/pending-mixin.js +12 -11
  131. package/dist/mixins/pending-mixin.js.map +1 -1
  132. package/dist/mixins/sized-mixin.d.ts +28 -0
  133. package/dist/mixins/sized-mixin.js +6 -6
  134. package/dist/mixins/sized-mixin.js.map +1 -1
  135. package/dist/utils/dev-validation.d.ts +88 -0
  136. package/dist/utils/dev-validation.js +33 -0
  137. package/dist/utils/dev-validation.js.map +1 -0
  138. package/dist/utils/index.d.ts +2 -0
  139. package/dist/utils/index.js +12 -10
  140. package/dist/utils/is-focus-visible-in-tree.d.ts +33 -0
  141. package/dist/utils/is-focus-visible-in-tree.js +11 -0
  142. package/dist/utils/is-focus-visible-in-tree.js.map +1 -0
  143. package/dist/utils/resolve-trigger.js.map +1 -1
  144. package/package.json +213 -18
  145. package/CHANGELOG.md +0 -125
  146. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/defineProperty.js +0 -12
  147. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPrimitive.js +0 -14
  148. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/toPropertyKey.js +0 -9
  149. package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/typeof.js +0 -11
  150. package/dist/controllers/page-scroll-lock.js.map +0 -1
  151. package/dist/mixins/observe-slot-presence.d.ts +0 -12
  152. package/dist/mixins/observe-slot-presence.js +0 -40
  153. package/dist/mixins/observe-slot-presence.js.map +0 -1
  154. package/dist/mixins/observe-slot-text.d.ts +0 -11
  155. package/dist/mixins/observe-slot-text.js +0 -60
  156. package/dist/mixins/observe-slot-text.js.map +0 -1
  157. /package/dist/controllers/{page-scroll-lock.d.ts → page-scroll-lock-controller/src/page-scroll-lock.d.ts} +0 -0
@@ -1,22 +1,101 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { SpectrumElement } from '../../element/index.js';
3
- import { AssetVariant } from './Asset.types.js';
3
+ import { AssetBackground, AssetFit, AssetLoadState } from './Asset.types.js';
4
+ /**
5
+ * Base class for the `<swc-asset>` general image/media primitive.
6
+ *
7
+ * @slot - a single `<img>` or `<svg>` element to display
8
+ */
4
9
  export declare abstract class AssetBase extends SpectrumElement {
10
+ private _aspectRatio;
11
+ private _rawAspectRatio;
5
12
  /**
6
- * @internal
13
+ * The aspect ratio to apply to the asset, in CSS `<ratio>` syntax (e.g.
14
+ * `"16/9"`), plus the `square` keyword. `:`-separated ratios (e.g.
15
+ * `"16:9"`) are normalized to `/`. Falls through to an ancestor-supplied
16
+ * default, else `auto`, when unset. Has no effect when both `width` and
17
+ * `height` are also set.
18
+ */
19
+ get aspectRatio(): string | undefined;
20
+ set aspectRatio(value: string | undefined);
21
+ /**
22
+ * An explicit width, as a CSS `<length-percentage>` (e.g. `"100px"`,
23
+ * `"90%"`). An alternative to `aspectRatio` for sizing the asset.
24
+ */
25
+ width: string | undefined;
26
+ /**
27
+ * An explicit height, as a CSS `<length-percentage>` (e.g. `"100px"`,
28
+ * `"90%"`). An alternative to `aspectRatio` for sizing the asset.
29
+ */
30
+ height: string | undefined;
31
+ /**
32
+ * How slotted image/SVG content fits within the asset's box.
7
33
  *
8
- * A readonly array of all valid variants for the asset.
34
+ * @default cover
35
+ */
36
+ fit: AssetFit;
37
+ /**
38
+ * Marks the asset as decorative, removing it from the accessibility tree
39
+ * (`aria-hidden="true"` on the host) regardless of slotted content or
40
+ * `accessibleLabel`.
41
+ */
42
+ decorative: boolean;
43
+ /**
44
+ * A fallback accessible name, applied to the slotted `<img>` or `<svg>`
45
+ * only when it doesn't already carry its own accessible name.
46
+ */
47
+ accessibleLabel: string | undefined;
48
+ /**
49
+ * The background shown behind slotted content: `transparent` (no
50
+ * background), a `solid` color, or an opacity `checkerboard`.
9
51
  *
10
- * This is an actual internal property, intended not for customer use
52
+ * @default transparent
53
+ */
54
+ background: AssetBackground;
55
+ /**
56
+ * The load status of the slotted `<img>`: `'loading'` while its request is
57
+ * in flight, `'loaded'` on success, `'error'` on failure. Immediately
58
+ * `'loaded'` for a slotted `<svg>` or no slotted content, since there's
59
+ * nothing asynchronous to wait for. Set internally by Asset; a consumer
60
+ * influences it only by changing what's slotted, not by setting it
61
+ * directly.
62
+ */
63
+ loadState: AssetLoadState;
64
+ private _appliedAriaHidden;
65
+ private _trackedImg;
66
+ private _preserveAspectRatioAppliedTo;
67
+ private _appliedAccessibleLabelTo;
68
+ protected update(changes: PropertyValues): void;
69
+ /**
70
+ * Warns when the default slot receives more than one child, or a child
71
+ * that isn't an `<img>` or `<svg>`. There is exactly one (default) slot,
72
+ * so its assigned elements are the host's own light DOM children.
73
+ */
74
+ private validateSlottedContent;
75
+ /**
76
+ * Implements `decorative` and the `accessibleLabel` fallback, in priority
77
+ * order: `decorative` > the child's own name (self-healing a missing
78
+ * `role="img"` on a named `<svg>`) > `accessibleLabel` > warn.
79
+ */
80
+ private resolveAccessibleName;
81
+ /**
82
+ * Whether `child` already has its own accessible name. The `<svg>` branch
83
+ * doesn't require `role="img"` — `resolveAccessibleName` self-heals a
84
+ * missing role separately.
11
85
  */
12
- static readonly VARIANTS: readonly AssetVariant[];
86
+ private hasOwnAccessibleName;
13
87
  /**
14
- * The variant of the asset. When not provided, slot content is rendered (e.g., an image).
88
+ * Applies `fit` to a slotted `<svg>` via `preserveAspectRatio`, without
89
+ * overwriting a consumer-set value or writing on every update.
15
90
  */
16
- variant: AssetVariant | undefined;
91
+ private applyFitToSvg;
17
92
  /**
18
- * Accessible label for the asset’s file or folder variant.
93
+ * Tracks `loadState` against the slotted `<img>`, re-wiring listeners only
94
+ * when the tracked element actually changes (a no-op on every other
95
+ * property update, since re-running this for the same `<img>` would
96
+ * incorrectly reset an already-resolved `loadState` back to `'loading'`).
19
97
  */
20
- label: string;
21
- protected updated(changes: PropertyValues): void;
98
+ private updateLoadState;
99
+ private readonly handleImgLoad;
100
+ private readonly handleImgError;
22
101
  }
@@ -1,25 +1,130 @@
1
1
  import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
2
- import { ASSET_VARIANTS as t } from "./Asset.types.js";
3
- import { property as n } from "lit/decorators.js";
4
- import { SpectrumElement as r } from "@adobe/spectrum-wc-core/element/index.js";
2
+ import { ASSET_BACKGROUND_VALUES as t, ASSET_FIT_VALUES as n, ASSET_LOAD_STATE_VALUES as r, SWC_ASSET_ERROR_EVENT as i, SWC_ASSET_LOAD_EVENT as a } from "./Asset.types.js";
3
+ import { property as o } from "lit/decorators.js";
4
+ import { SpectrumElement as s } from "@adobe/spectrum-wc-core/element/index.js";
5
+ import { isDebug as c, validateEnum as l, warnIf as u } from "@adobe/spectrum-wc-core/utils/index.js";
5
6
  //#region components/asset/Asset.base.ts
6
- var i, a = class extends r {
7
+ var d = "https://spectrum-web-components.adobe.com/?path=/docs/components-asset--docs", f = String.raw`(?:\d+\.?\d*|\.\d+)`, p = String.raw`${f}(?:\s*\/\s*${f})?`, m = RegExp(`^(?:auto|${p}|auto\\s+${p}|${p}\\s+auto)$`), h = {
8
+ cover: "xMidYMid slice",
9
+ contain: "xMidYMid meet"
10
+ };
11
+ function g(e) {
12
+ return e && (e === "square" ? "1/1" : e.replace(":", "/"));
13
+ }
14
+ var _ = class extends s {
7
15
  constructor(...e) {
8
- super(...e), this.label = "";
16
+ super(...e), this.fit = "cover", this.decorative = !1, this.background = "transparent", this.loadState = "loading", this._appliedAriaHidden = !1, this._trackedImg = void 0, this._preserveAspectRatioAppliedTo = null, this._appliedAccessibleLabelTo = null, this.handleImgLoad = () => {
17
+ this.loadState = "loaded", this.dispatchEvent(new CustomEvent(a, {
18
+ bubbles: !0,
19
+ composed: !0
20
+ }));
21
+ }, this.handleImgError = () => {
22
+ var e, t;
23
+ this.loadState = "error", this.dispatchEvent(new CustomEvent(i, {
24
+ bubbles: !0,
25
+ composed: !0,
26
+ detail: { src: (e = (t = this._trackedImg) == null ? void 0 : t.currentSrc) == null ? "" : e }
27
+ }));
28
+ };
29
+ }
30
+ get aspectRatio() {
31
+ return this._aspectRatio;
32
+ }
33
+ set aspectRatio(e) {
34
+ let t = this._aspectRatio;
35
+ this._rawAspectRatio = e, this._aspectRatio = g(e), this.requestUpdate("aspectRatio", t);
36
+ }
37
+ update(e) {
38
+ e.has("fit") && l(this, {
39
+ prop: "fit",
40
+ value: this.fit,
41
+ valid: n,
42
+ url: d
43
+ }), e.has("background") && l(this, {
44
+ prop: "background",
45
+ value: this.background,
46
+ valid: t,
47
+ url: d
48
+ }), e.has("loadState") && l(this, {
49
+ prop: "load-state",
50
+ value: this.loadState,
51
+ valid: r,
52
+ url: d
53
+ }), (e.has("aspectRatio") || e.has("width") || e.has("height")) && (u(this, this.aspectRatio !== void 0 && !m.test(this.aspectRatio), `<${this.localName}> expects "aspect-ratio" to be a CSS <ratio> (e.g. "16/9"), the "square" keyword, or a ":"-separated ratio (e.g. "16:9"). Received "${this._rawAspectRatio}".`, d), u(this, this.aspectRatio !== void 0 && this.width !== void 0 && this.height !== void 0, `<${this.localName}> "aspect-ratio" has no effect when both "width" and "height" are set.`, d));
54
+ let i = Array.from(this.children);
55
+ c() && this.validateSlottedContent(i), this.resolveAccessibleName(i), this.applyFitToSvg(i), this.updateLoadState(i), super.update(e);
56
+ }
57
+ validateSlottedContent(e) {
58
+ u(this, e.length > 1, `<${this.localName}> only supports a single slotted <img> or <svg> element. Received ${e.length} children.`, d);
59
+ let [t] = e;
60
+ if (t) {
61
+ let e = t.tagName.toLowerCase();
62
+ u(this, e !== "img" && e !== "svg", `<${this.localName}> expects its slotted content to be an <img> or <svg> element. Received <${e}>.`, d);
63
+ }
64
+ }
65
+ resolveAccessibleName(e) {
66
+ if (this.decorative) {
67
+ this.hasAttribute("aria-hidden") || (this._appliedAriaHidden = !0, this.setAttribute("aria-hidden", "true"));
68
+ return;
69
+ }
70
+ this._appliedAriaHidden && (this.removeAttribute("aria-hidden"), this._appliedAriaHidden = !1);
71
+ let [t] = e, n = t == null ? void 0 : t.tagName.toLowerCase();
72
+ if (t && n !== "img" && n !== "svg") return;
73
+ let r = !!t && this._appliedAccessibleLabelTo === t, i = !!t && !r && this.hasOwnAccessibleName(t, n);
74
+ t && (i ? n === "svg" && !t.hasAttribute("role") && t.setAttribute("role", "img") : this.accessibleLabel ? (n === "img" ? t.alt = this.accessibleLabel : (t.setAttribute("role", "img"), t.setAttribute("aria-label", this.accessibleLabel)), this._appliedAccessibleLabelTo = t) : r && (n === "img" ? t.removeAttribute("alt") : (t.removeAttribute("role"), t.removeAttribute("aria-label")), this._appliedAccessibleLabelTo = null)), u(this, !i && !this.accessibleLabel, `<${this.localName}> requires an accessible name: set "alt" on the slotted <img> (or "aria-label"/"aria-labelledby"/a child <title> on the slotted <svg>), set "accessible-label" on <${this.localName}>, or set "decorative".`, d);
9
75
  }
10
- updated(e) {
76
+ hasOwnAccessibleName(e, t) {
77
+ let n = e.hasAttribute("aria-label") || e.hasAttribute("aria-labelledby");
78
+ if (t === "img") return n || e.hasAttribute("alt");
79
+ let r = !!e.querySelector(":scope > title");
80
+ return n || r;
81
+ }
82
+ applyFitToSvg(e) {
11
83
  var t;
12
- if (super.updated(e), (t = window.__swc) != null && t.DEBUG) {
13
- let e = this.constructor;
14
- this.variant !== void 0 && !e.VARIANTS.includes(this.variant) && window.__swc.warn(this, `<${this.localName}> element expects the "variant" attribute to be one of the following:`, "https://opensource.adobe.com/spectrum-web-components/components/asset/", { issues: [...e.VARIANTS] });
84
+ let [n] = e;
85
+ if ((n == null ? void 0 : n.tagName.toLowerCase()) !== "svg") {
86
+ this._preserveAspectRatioAppliedTo = null;
87
+ return;
88
+ }
89
+ let r = this._preserveAspectRatioAppliedTo === n;
90
+ if (n.hasAttribute("preserveAspectRatio") && !r) return;
91
+ let i = (t = h[this.fit]) == null ? h.cover : t;
92
+ n.getAttribute("preserveAspectRatio") !== i && n.setAttribute("preserveAspectRatio", i), this._preserveAspectRatioAppliedTo = n;
93
+ }
94
+ updateLoadState(e) {
95
+ let [t] = e, n = (t == null ? void 0 : t.tagName.toLowerCase()) === "img" ? t : null;
96
+ if (n !== this._trackedImg) {
97
+ if (this._trackedImg && (this._trackedImg.removeEventListener("load", this.handleImgLoad), this._trackedImg.removeEventListener("error", this.handleImgError)), this._trackedImg = n, !n) {
98
+ this.loadState = "loaded";
99
+ return;
100
+ }
101
+ if (this.loadState = "loading", n.addEventListener("load", this.handleImgLoad), n.addEventListener("error", this.handleImgError), n.complete && n.currentSrc) {
102
+ let e = n.naturalWidth > 0;
103
+ queueMicrotask(() => {
104
+ this._trackedImg === n && (e ? this.handleImgLoad() : this.handleImgError());
105
+ });
106
+ }
15
107
  }
16
108
  }
17
109
  };
18
- i = a, i.VARIANTS = t, e([n({
110
+ e([o({ attribute: "aspect-ratio" })], _.prototype, "aspectRatio", null), e([o({ type: String })], _.prototype, "width", void 0), e([o({ type: String })], _.prototype, "height", void 0), e([o({
111
+ type: String,
112
+ reflect: !0
113
+ })], _.prototype, "fit", void 0), e([o({
114
+ type: Boolean,
115
+ reflect: !0
116
+ })], _.prototype, "decorative", void 0), e([o({
117
+ type: String,
118
+ attribute: "accessible-label"
119
+ })], _.prototype, "accessibleLabel", void 0), e([o({
19
120
  type: String,
20
121
  reflect: !0
21
- })], a.prototype, "variant", void 0), e([n({ type: String })], a.prototype, "label", void 0);
122
+ })], _.prototype, "background", void 0), e([o({
123
+ type: String,
124
+ reflect: !0,
125
+ attribute: "load-state"
126
+ })], _.prototype, "loadState", void 0);
22
127
  //#endregion
23
- export { a as AssetBase };
128
+ export { _ as AssetBase };
24
129
 
25
130
  //# sourceMappingURL=Asset.base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Asset.base.js","names":[],"sources":["../../../components/asset/Asset.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';\n\nimport { ASSET_VARIANTS, type AssetVariant } from './Asset.types.js';\n\nexport abstract class AssetBase extends SpectrumElement {\n // ─────────────────────────\n // API TO OVERRIDE\n // ─────────────────────────\n\n /**\n * @internal\n *\n * A readonly array of all valid variants for the asset.\n *\n * This is an actual internal property, intended not for customer use\n */\n static readonly VARIANTS: readonly AssetVariant[] = ASSET_VARIANTS;\n\n // ─────────────────\n // SHARED API\n // ─────────────────\n\n /**\n * The variant of the asset. When not provided, slot content is rendered (e.g., an image).\n */\n @property({ type: String, reflect: true })\n public variant: AssetVariant | undefined;\n\n /**\n * Accessible label for the asset’s file or folder variant.\n */\n @property({ type: String })\n public label = '';\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n protected override updated(changes: PropertyValues): void {\n super.updated(changes);\n if (window.__swc?.DEBUG) {\n const constructor = this.constructor as typeof AssetBase;\n if (\n typeof this.variant !== 'undefined' &&\n !constructor.VARIANTS.includes(this.variant)\n ) {\n window.__swc.warn(\n this,\n `<${this.localName}> element expects the \"variant\" attribute to be one of the following:`,\n 'https://opensource.adobe.com/spectrum-web-components/components/asset/',\n {\n issues: [...constructor.VARIANTS],\n }\n );\n }\n }\n }\n}\n"],"mappings":";;;;;OAmBsB,IAAtB,cAAwC,EAAgB;;4BA4BvC;;CAMf,QAA2B,GAA+B;;AAExD,MADA,MAAM,QAAQ,EAAQ,GACtB,IAAI,OAAO,UAAA,QAAA,EAAO,OAAO;GACvB,IAAM,IAAc,KAAK;AACzB,GACS,KAAK,YAAY,UACxB,CAAC,EAAY,SAAS,SAAS,KAAK,QAAQ,IAE5C,OAAO,MAAM,KACX,MACA,IAAI,KAAK,UAAU,wEACnB,0EACA,EACE,QAAQ,CAAC,GAAG,EAAY,SAAS,EAClC,CACF;;;;oBArC6C,MASnD,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA,KAMzC,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,EAAA,WAAA,SAAA,KAAA,EAAA"}
1
+ {"version":3,"file":"Asset.base.js","names":[],"sources":["../../../components/asset/Asset.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 isDebug,\n validateEnum,\n warnIf,\n} from '@adobe/spectrum-wc-core/utils/index.js';\n\nimport {\n ASSET_BACKGROUND_VALUES,\n ASSET_FIT_VALUES,\n ASSET_LOAD_STATE_VALUES,\n type AssetBackground,\n type AssetErrorEventDetail,\n type AssetFit,\n type AssetLoadState,\n SWC_ASSET_ERROR_EVENT,\n SWC_ASSET_LOAD_EVENT,\n} from './Asset.types.js';\n\nconst DOCS_URL =\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-asset--docs';\n\n// A plain CSS <number>: \"16\", \"1.5\", or \".5\".\nconst NUMBER = String.raw`(?:\\d+\\.?\\d*|\\.\\d+)`;\n// A CSS <ratio>, optionally paired with `auto` on either side (both orders\n// are valid, e.g. \"auto 16/9\" or \"16/9 auto\").\nconst RATIO = String.raw`${NUMBER}(?:\\s*\\/\\s*${NUMBER})?`;\nconst ASPECT_RATIO_PATTERN = new RegExp(\n `^(?:auto|${RATIO}|auto\\\\s+${RATIO}|${RATIO}\\\\s+auto)$`\n);\n\n// object-fit doesn't apply to inline <svg>, so `fit` drives\n// `preserveAspectRatio` instead.\nconst SVG_PRESERVE_ASPECT_RATIO: Record<AssetFit, string> = {\n cover: 'xMidYMid slice',\n contain: 'xMidYMid meet',\n};\n\n/**\n * Normalizes an `aspectRatio` value: maps the `square` keyword to `1/1`, and\n * `:`-separated ratios (e.g. `16:9`) to the CSS `<ratio>` separator (`16/9`).\n */\nfunction normalizeAspectRatio(value: string | undefined): string | undefined {\n if (!value) {\n return value;\n }\n if (value === 'square') {\n return '1/1';\n }\n return value.replace(':', '/');\n}\n\n/**\n * Base class for the `<swc-asset>` general image/media primitive.\n *\n * @slot - a single `<img>` or `<svg>` element to display\n */\nexport abstract class AssetBase extends SpectrumElement {\n // ──────────────────\n // SHARED API\n // ──────────────────\n\n private _aspectRatio: string | undefined;\n\n // The pre-normalization value, kept for the malformed-ratio warning\n private _rawAspectRatio: string | undefined;\n\n /**\n * The aspect ratio to apply to the asset, in CSS `<ratio>` syntax (e.g.\n * `\"16/9\"`), plus the `square` keyword. `:`-separated ratios (e.g.\n * `\"16:9\"`) are normalized to `/`. Falls through to an ancestor-supplied\n * default, else `auto`, when unset. Has no effect when both `width` and\n * `height` are also set.\n */\n @property({ attribute: 'aspect-ratio' })\n public get aspectRatio(): string | undefined {\n return this._aspectRatio;\n }\n\n public set aspectRatio(value: string | undefined) {\n const oldValue = this._aspectRatio;\n this._rawAspectRatio = value;\n this._aspectRatio = normalizeAspectRatio(value);\n this.requestUpdate('aspectRatio', oldValue);\n }\n\n /**\n * An explicit width, as a CSS `<length-percentage>` (e.g. `\"100px\"`,\n * `\"90%\"`). An alternative to `aspectRatio` for sizing the asset.\n */\n @property({ type: String })\n public width: string | undefined;\n\n /**\n * An explicit height, as a CSS `<length-percentage>` (e.g. `\"100px\"`,\n * `\"90%\"`). An alternative to `aspectRatio` for sizing the asset.\n */\n @property({ type: String })\n public height: string | undefined;\n\n /**\n * How slotted image/SVG content fits within the asset's box.\n *\n * @default cover\n */\n @property({ type: String, reflect: true })\n public fit: AssetFit = 'cover';\n\n /**\n * Marks the asset as decorative, removing it from the accessibility tree\n * (`aria-hidden=\"true\"` on the host) regardless of slotted content or\n * `accessibleLabel`.\n */\n @property({ type: Boolean, reflect: true })\n public decorative = false;\n\n /**\n * A fallback accessible name, applied to the slotted `<img>` or `<svg>`\n * only when it doesn't already carry its own accessible name.\n */\n @property({ type: String, attribute: 'accessible-label' })\n public accessibleLabel: string | undefined;\n\n /**\n * The background shown behind slotted content: `transparent` (no\n * background), a `solid` color, or an opacity `checkerboard`.\n *\n * @default transparent\n */\n @property({ type: String, reflect: true })\n public background: AssetBackground = 'transparent';\n\n /**\n * The load status of the slotted `<img>`: `'loading'` while its request is\n * in flight, `'loaded'` on success, `'error'` on failure. Immediately\n * `'loaded'` for a slotted `<svg>` or no slotted content, since there's\n * nothing asynchronous to wait for. Set internally by Asset; a consumer\n * influences it only by changing what's slotted, not by setting it\n * directly.\n */\n @property({ type: String, reflect: true, attribute: 'load-state' })\n public loadState: AssetLoadState = 'loading';\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n // Only clear `aria-hidden` if this instance set it, so a consumer's own\n // attribute survives.\n private _appliedAriaHidden = false;\n\n // `undefined` means \"not yet determined\" (distinct from `null`, \"confirmed\n // no `<img>` child\"), so the first resolution to \"no `<img>`\" isn't\n // mistaken for an already-processed steady state. See `updateLoadState`.\n private _trackedImg: HTMLImageElement | null | undefined = undefined;\n\n // The <svg> this instance owns `preserveAspectRatio` on, so a\n // consumer-set value is left alone until this instance takes over.\n private _preserveAspectRatioAppliedTo: Element | null = null;\n\n // The child this instance applied `accessibleLabel` to, so a later\n // change or clearing it updates/removes our own value instead of being\n // mistaken for the child's own name.\n private _appliedAccessibleLabelTo: Element | null = null;\n\n protected override update(changes: PropertyValues): void {\n if (changes.has('fit')) {\n validateEnum(this, {\n prop: 'fit',\n value: this.fit,\n valid: ASSET_FIT_VALUES,\n url: DOCS_URL,\n });\n }\n if (changes.has('background')) {\n validateEnum(this, {\n prop: 'background',\n value: this.background,\n valid: ASSET_BACKGROUND_VALUES,\n url: DOCS_URL,\n });\n }\n if (changes.has('loadState')) {\n validateEnum(this, {\n prop: 'load-state',\n value: this.loadState,\n valid: ASSET_LOAD_STATE_VALUES,\n url: DOCS_URL,\n });\n }\n if (\n changes.has('aspectRatio') ||\n changes.has('width') ||\n changes.has('height')\n ) {\n warnIf(\n this,\n typeof this.aspectRatio !== 'undefined' &&\n !ASPECT_RATIO_PATTERN.test(this.aspectRatio),\n `<${this.localName}> expects \"aspect-ratio\" to be a CSS <ratio> (e.g. \"16/9\"), the \"square\" keyword, or a \":\"-separated ratio (e.g. \"16:9\"). Received \"${this._rawAspectRatio}\".`,\n DOCS_URL\n );\n warnIf(\n this,\n typeof this.aspectRatio !== 'undefined' &&\n typeof this.width !== 'undefined' &&\n typeof this.height !== 'undefined',\n `<${this.localName}> \"aspect-ratio\" has no effect when both \"width\" and \"height\" are set.`,\n DOCS_URL\n );\n }\n\n const children = Array.from(this.children);\n if (isDebug()) {\n this.validateSlottedContent(children);\n }\n this.resolveAccessibleName(children);\n this.applyFitToSvg(children);\n this.updateLoadState(children);\n super.update(changes);\n }\n\n /**\n * Warns when the default slot receives more than one child, or a child\n * that isn't an `<img>` or `<svg>`. There is exactly one (default) slot,\n * so its assigned elements are the host's own light DOM children.\n */\n private validateSlottedContent(children: Element[]): void {\n warnIf(\n this,\n children.length > 1,\n `<${this.localName}> only supports a single slotted <img> or <svg> element. Received ${children.length} children.`,\n DOCS_URL\n );\n const [child] = children;\n if (child) {\n const tagName = child.tagName.toLowerCase();\n warnIf(\n this,\n tagName !== 'img' && tagName !== 'svg',\n `<${this.localName}> expects its slotted content to be an <img> or <svg> element. Received <${tagName}>.`,\n DOCS_URL\n );\n }\n }\n\n /**\n * Implements `decorative` and the `accessibleLabel` fallback, in priority\n * order: `decorative` > the child's own name (self-healing a missing\n * `role=\"img\"` on a named `<svg>`) > `accessibleLabel` > warn.\n */\n private resolveAccessibleName(children: Element[]): void {\n if (this.decorative) {\n // Only claim ownership (and write the attribute) when it isn't\n // already present, to avoid redundant attribute writes.\n if (!this.hasAttribute('aria-hidden')) {\n this._appliedAriaHidden = true;\n this.setAttribute('aria-hidden', 'true');\n }\n return;\n }\n if (this._appliedAriaHidden) {\n this.removeAttribute('aria-hidden');\n this._appliedAriaHidden = false;\n }\n\n const [child] = children;\n const tagName = child?.tagName.toLowerCase();\n if (child && tagName !== 'img' && tagName !== 'svg') {\n // Already warned about by validateSlottedContent.\n return;\n }\n\n // Excludes a name this instance applied itself from counting as the\n // child's own.\n const ownsAppliedName = !!child && this._appliedAccessibleLabelTo === child;\n const hasOwnName =\n !!child &&\n !ownsAppliedName &&\n this.hasOwnAccessibleName(child, tagName as 'img' | 'svg');\n\n if (child) {\n if (hasOwnName) {\n if (tagName === 'svg' && !child.hasAttribute('role')) {\n child.setAttribute('role', 'img');\n }\n } else if (this.accessibleLabel) {\n if (tagName === 'img') {\n (child as HTMLImageElement).alt = this.accessibleLabel;\n } else {\n child.setAttribute('role', 'img');\n child.setAttribute('aria-label', this.accessibleLabel);\n }\n this._appliedAccessibleLabelTo = child;\n } else if (ownsAppliedName) {\n // accessibleLabel cleared; remove the name we applied instead of\n // leaving it stale.\n if (tagName === 'img') {\n (child as HTMLImageElement).removeAttribute('alt');\n } else {\n child.removeAttribute('role');\n child.removeAttribute('aria-label');\n }\n this._appliedAccessibleLabelTo = null;\n }\n }\n\n warnIf(\n this,\n !hasOwnName && !this.accessibleLabel,\n `<${this.localName}> requires an accessible name: set \"alt\" on the slotted <img> (or \"aria-label\"/\"aria-labelledby\"/a child <title> on the slotted <svg>), set \"accessible-label\" on <${this.localName}>, or set \"decorative\".`,\n DOCS_URL\n );\n }\n\n /**\n * Whether `child` already has its own accessible name. The `<svg>` branch\n * doesn't require `role=\"img\"` — `resolveAccessibleName` self-heals a\n * missing role separately.\n */\n private hasOwnAccessibleName(\n child: Element,\n tagName: 'img' | 'svg'\n ): boolean {\n const hasAriaName =\n child.hasAttribute('aria-label') || child.hasAttribute('aria-labelledby');\n if (tagName === 'img') {\n return hasAriaName || child.hasAttribute('alt');\n }\n const hasTitleChild = !!child.querySelector(':scope > title');\n return hasAriaName || hasTitleChild;\n }\n\n /**\n * Applies `fit` to a slotted `<svg>` via `preserveAspectRatio`, without\n * overwriting a consumer-set value or writing on every update.\n */\n private applyFitToSvg(children: Element[]): void {\n const [child] = children;\n if (child?.tagName.toLowerCase() !== 'svg') {\n this._preserveAspectRatioAppliedTo = null;\n return;\n }\n const alreadyOwned = this._preserveAspectRatioAppliedTo === child;\n if (child.hasAttribute('preserveAspectRatio') && !alreadyOwned) {\n return;\n }\n const value =\n SVG_PRESERVE_ASPECT_RATIO[this.fit] ?? SVG_PRESERVE_ASPECT_RATIO.cover;\n if (child.getAttribute('preserveAspectRatio') !== value) {\n child.setAttribute('preserveAspectRatio', value);\n }\n this._preserveAspectRatioAppliedTo = child;\n }\n\n /**\n * Tracks `loadState` against the slotted `<img>`, re-wiring listeners only\n * when the tracked element actually changes (a no-op on every other\n * property update, since re-running this for the same `<img>` would\n * incorrectly reset an already-resolved `loadState` back to `'loading'`).\n */\n private updateLoadState(children: Element[]): void {\n const [child] = children;\n const img =\n child?.tagName.toLowerCase() === 'img'\n ? (child as HTMLImageElement)\n : null;\n\n if (img === this._trackedImg) {\n return;\n }\n\n if (this._trackedImg) {\n this._trackedImg.removeEventListener('load', this.handleImgLoad);\n this._trackedImg.removeEventListener('error', this.handleImgError);\n }\n this._trackedImg = img;\n\n if (!img) {\n // No <img> to wait for: a slotted <svg>, an unsupported child, or\n // nothing slotted at all.\n this.loadState = 'loaded';\n return;\n }\n\n this.loadState = 'loading';\n img.addEventListener('load', this.handleImgLoad);\n img.addEventListener('error', this.handleImgError);\n\n // An already-complete `<img>` (e.g. cached) already fired its native\n // `load`/`error` before these listeners attached, so schedule the\n // equivalent transition instead of skipping it - a consumer can always\n // just listen for the events without special-casing the cache case.\n // An `<img>` with no `src` yet is also `complete` but has nothing to\n // report, hence the `currentSrc` check.\n if (img.complete && img.currentSrc) {\n const succeeded = img.naturalWidth > 0;\n queueMicrotask(() => {\n if (this._trackedImg !== img) {\n return;\n }\n if (succeeded) {\n this.handleImgLoad();\n } else {\n this.handleImgError();\n }\n });\n }\n }\n\n private readonly handleImgLoad = (): void => {\n this.loadState = 'loaded';\n this.dispatchEvent(\n new CustomEvent(SWC_ASSET_LOAD_EVENT, {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private readonly handleImgError = (): void => {\n this.loadState = 'error';\n this.dispatchEvent(\n new CustomEvent<AssetErrorEventDetail>(SWC_ASSET_ERROR_EVENT, {\n bubbles: true,\n composed: true,\n detail: { src: this._trackedImg?.currentSrc ?? '' },\n })\n );\n };\n}\n"],"mappings":"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"}
@@ -9,5 +9,23 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- export declare const ASSET_VARIANTS: readonly ["file", "folder"];
13
- export type AssetVariant = (typeof ASSET_VARIANTS)[number];
12
+ export declare const ASSET_FIT_VALUES: readonly ["cover", "contain"];
13
+ export type AssetFit = (typeof ASSET_FIT_VALUES)[number];
14
+ export declare const ASSET_BACKGROUND_VALUES: readonly ["transparent", "solid", "checkerboard"];
15
+ export type AssetBackground = (typeof ASSET_BACKGROUND_VALUES)[number];
16
+ export declare const ASSET_LOAD_STATE_VALUES: readonly ["loading", "loaded", "error"];
17
+ export type AssetLoadState = (typeof ASSET_LOAD_STATE_VALUES)[number];
18
+ /** Fired when the slotted `<img>` finishes loading successfully. */
19
+ export declare const SWC_ASSET_LOAD_EVENT = "swc-asset-load";
20
+ /** Fired when the slotted `<img>` fails to load. */
21
+ export declare const SWC_ASSET_ERROR_EVENT = "swc-asset-error";
22
+ /** Detail emitted with `swc-asset-error`. */
23
+ export interface AssetErrorEventDetail {
24
+ src: string;
25
+ }
26
+ declare global {
27
+ interface GlobalEventHandlersEventMap {
28
+ [SWC_ASSET_LOAD_EVENT]: CustomEvent<undefined>;
29
+ [SWC_ASSET_ERROR_EVENT]: CustomEvent<AssetErrorEventDetail>;
30
+ }
31
+ }
@@ -1,6 +1,14 @@
1
1
  //#region components/asset/Asset.types.ts
2
- var e = ["file", "folder"];
2
+ var e = ["cover", "contain"], t = [
3
+ "transparent",
4
+ "solid",
5
+ "checkerboard"
6
+ ], n = [
7
+ "loading",
8
+ "loaded",
9
+ "error"
10
+ ], r = "swc-asset-load", i = "swc-asset-error";
3
11
  //#endregion
4
- export { e as ASSET_VARIANTS };
12
+ export { t as ASSET_BACKGROUND_VALUES, e as ASSET_FIT_VALUES, n as ASSET_LOAD_STATE_VALUES, i as SWC_ASSET_ERROR_EVENT, r as SWC_ASSET_LOAD_EVENT };
5
13
 
6
14
  //# sourceMappingURL=Asset.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Asset.types.js","names":[],"sources":["../../../components/asset/Asset.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\nexport const ASSET_VARIANTS = [\n 'file',\n 'folder',\n] as const satisfies readonly string[];\n\nexport type AssetVariant = (typeof ASSET_VARIANTS)[number];\n"],"mappings":";AAYA,IAAa,IAAiB,CAC5B,QACA,SACD"}
1
+ {"version":3,"file":"Asset.types.js","names":[],"sources":["../../../components/asset/Asset.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\nexport const ASSET_FIT_VALUES = [\n 'cover',\n 'contain',\n] as const satisfies readonly string[];\n\nexport type AssetFit = (typeof ASSET_FIT_VALUES)[number];\n\nexport const ASSET_BACKGROUND_VALUES = [\n 'transparent',\n 'solid',\n 'checkerboard',\n] as const satisfies readonly string[];\n\nexport type AssetBackground = (typeof ASSET_BACKGROUND_VALUES)[number];\n\nexport const ASSET_LOAD_STATE_VALUES = [\n 'loading',\n 'loaded',\n 'error',\n] as const satisfies readonly string[];\n\nexport type AssetLoadState = (typeof ASSET_LOAD_STATE_VALUES)[number];\n\n// ──────────────────\n// EVENTS\n// ──────────────────\n\n/** Fired when the slotted `<img>` finishes loading successfully. */\nexport const SWC_ASSET_LOAD_EVENT = 'swc-asset-load';\n\n/** Fired when the slotted `<img>` fails to load. */\nexport const SWC_ASSET_ERROR_EVENT = 'swc-asset-error';\n\n/** Detail emitted with `swc-asset-error`. */\nexport interface AssetErrorEventDetail {\n src: string;\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n [SWC_ASSET_LOAD_EVENT]: CustomEvent<undefined>;\n [SWC_ASSET_ERROR_EVENT]: CustomEvent<AssetErrorEventDetail>;\n }\n}\n"],"mappings":";AAYA,IAAa,IAAmB,CAC9B,SACA,UACD,EAIY,IAA0B;CACrC;CACA;CACA;CACD,EAIY,IAA0B;CACrC;CACA;CACA;CACD,EASY,IAAuB,kBAGvB,IAAwB"}
@@ -1,3 +1,3 @@
1
- import { ASSET_VARIANTS as e } from "./Asset.types.js";
2
- import { AssetBase as t } from "./Asset.base.js";
3
- export { e as ASSET_VARIANTS, t as AssetBase };
1
+ import { ASSET_BACKGROUND_VALUES as e, ASSET_FIT_VALUES as t, ASSET_LOAD_STATE_VALUES as n, SWC_ASSET_ERROR_EVENT as r, SWC_ASSET_LOAD_EVENT as i } from "./Asset.types.js";
2
+ import { AssetBase as a } from "./Asset.base.js";
3
+ export { e as ASSET_BACKGROUND_VALUES, t as ASSET_FIT_VALUES, n as ASSET_LOAD_STATE_VALUES, a as AssetBase, r as SWC_ASSET_ERROR_EVENT, i as SWC_ASSET_LOAD_EVENT };
@@ -2,8 +2,9 @@ import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.124.0/he
2
2
  import { AVATAR_VALID_SIZES as t } from "./Avatar.types.js";
3
3
  import { property as n } from "lit/decorators.js";
4
4
  import { SpectrumElement as r } from "@adobe/spectrum-wc-core/element/index.js";
5
+ import { warnIf as i } from "@adobe/spectrum-wc-core/utils/index.js";
5
6
  //#region components/avatar/Avatar.base.ts
6
- var i, a = class extends r {
7
+ var a, o = class extends r {
7
8
  constructor(...e) {
8
9
  super(...e), this.src = "", this._size = 500, this.outline = !1, this.disabled = !1, this.decorative = !1;
9
10
  }
@@ -11,46 +12,41 @@ var i, a = class extends r {
11
12
  return this._size;
12
13
  }
13
14
  set size(e) {
14
- let n = t.includes(Number(e)) ? Number(e) : 500;
15
- if (this._size === n) return;
16
- let r = this._size;
17
- this._size = n, this.requestUpdate("size", r);
15
+ let n = t.includes(Number(e)), r = n ? Number(e) : 500;
16
+ if (i(this, !n, `<${this.localName}> expects "size" to be one of: ${t.join(", ")}. Received "${e}".`, "https://spectrum-web-components.adobe.com/?path=/docs/components-avatar--docs", { issues: [`size="${e}"`] }), this._size === r) return;
17
+ let a = this._size;
18
+ this._size = r, this.requestUpdate("size", a);
18
19
  }
19
20
  firstUpdated(e) {
20
- var t;
21
- super.firstUpdated(e), this.hasAttribute("size") || this.setAttribute("size", String(this.size)), this._syncAriaHidden(), (t = window.__swc) != null && t.DEBUG && this._warnMissingAlt();
21
+ super.firstUpdated(e), this.hasAttribute("size") || this.setAttribute("size", String(this.size)), this._syncAriaHidden(), this._warnMissingAlt();
22
22
  }
23
23
  updated(e) {
24
- var t;
25
- super.updated(e), e.has("decorative") && this._syncAriaHidden(), e.has("alt") && (t = window.__swc) != null && t.DEBUG && this._warnMissingAlt();
24
+ super.updated(e), e.has("decorative") && this._syncAriaHidden(), e.has("alt") && this._warnMissingAlt();
26
25
  }
27
26
  _syncAriaHidden() {
28
27
  this.decorative ? this.setAttribute("aria-hidden", "true") : this.removeAttribute("aria-hidden");
29
28
  }
30
29
  _warnMissingAlt() {
31
- if (this.alt === void 0 && !this.decorative) {
32
- var e;
33
- (e = window.__swc) == null || e.warn(this, `<${this.localName}> is missing an \`alt\` attribute. Provide a text description or pass \`alt=""\` and mark it as \`decorative\`.`, "https://opensource.adobe.com/spectrum-web-components/components/avatar/#accessibility", {
34
- type: "accessibility",
35
- issues: ["Provide an `alt` attribute with meaningful alternative text, or", "Set `alt=\"\"` and mark the image as `decorative` (hidden from screen readers)."]
36
- });
37
- }
30
+ i(this, this.alt === void 0 && !this.decorative, `<${this.localName}> is missing an \`alt\` attribute. Provide a text description or pass \`alt=""\` and mark it as \`decorative\`.`, "https://spectrum-web-components.adobe.com/?path=/docs/components-avatar--docs", {
31
+ type: "accessibility",
32
+ issues: ["Provide an `alt` attribute with meaningful alternative text, or", "Set `alt=\"\"` and mark the image as `decorative` (hidden from screen readers)."]
33
+ });
38
34
  }
39
35
  };
40
- i = a, i.VALID_SIZES = t, e([n({ type: String })], a.prototype, "src", void 0), e([n({ type: String })], a.prototype, "alt", void 0), e([n({
36
+ a = o, a.VALID_SIZES = t, e([n({ type: String })], o.prototype, "src", void 0), e([n({ type: String })], o.prototype, "alt", void 0), e([n({
41
37
  type: Number,
42
38
  reflect: !0
43
- })], a.prototype, "size", null), e([n({
39
+ })], o.prototype, "size", null), e([n({
44
40
  type: Boolean,
45
41
  reflect: !0
46
- })], a.prototype, "outline", void 0), e([n({
42
+ })], o.prototype, "outline", void 0), e([n({
47
43
  type: Boolean,
48
44
  reflect: !0
49
- })], a.prototype, "disabled", void 0), e([n({
45
+ })], o.prototype, "disabled", void 0), e([n({
50
46
  type: Boolean,
51
47
  reflect: !0
52
- })], a.prototype, "decorative", void 0);
48
+ })], o.prototype, "decorative", void 0);
53
49
  //#endregion
54
- export { a as AvatarBase };
50
+ export { o as AvatarBase };
55
51
 
56
52
  //# sourceMappingURL=Avatar.base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.base.js","names":[],"sources":["../../../components/avatar/Avatar.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 */\nimport { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\n\nimport {\n AVATAR_DEFAULT_SIZE,\n AVATAR_VALID_SIZES,\n type AvatarSize,\n} from './Avatar.types.js';\n\n/**\n * Base class for the avatar component.\n *\n * Provides the core API for displaying a circular profile image. Concrete\n * classes supply the stylesheet and render template.\n */\nexport abstract class AvatarBase extends SpectrumElement {\n // ─────────────────────────\n // STATIC\n // ─────────────────────────\n\n /**\n * @internal\n *\n * The set of valid numeric size values for the avatar.\n *\n * This is an internal property not intended for consumer use, but used in\n * internal validation logic, stories, and tests to keep them in sync with\n * the canonical type definition in `Avatar.types.ts`.\n */\n static readonly VALID_SIZES: readonly AvatarSize[] = AVATAR_VALID_SIZES;\n\n // ──────────────────\n // CORE API\n // ──────────────────\n\n /**\n * URL of the profile image to display.\n */\n @property({ type: String })\n public src = '';\n\n /**\n * Text description of the avatar image.\n */\n @property({ type: String })\n public alt: string | undefined;\n\n // ───────────────────\n // SIZE API\n // ───────────────────\n\n /**\n * The size of the avatar. Invalid values fall back to the default (500).\n *\n * @default 500\n */\n @property({ type: Number, reflect: true })\n public get size(): AvatarSize {\n return this._size;\n }\n\n public set size(value: AvatarSize) {\n const validSize = (AVATAR_VALID_SIZES as readonly number[]).includes(\n Number(value)\n )\n ? (Number(value) as AvatarSize)\n : AVATAR_DEFAULT_SIZE;\n\n if (this._size === validSize) {\n return;\n }\n\n const oldSize = this._size;\n this._size = validSize;\n this.requestUpdate('size', oldSize);\n }\n\n private _size: AvatarSize = AVATAR_DEFAULT_SIZE;\n\n // ───────────────────────\n // VISUAL API\n // ───────────────────────\n\n /**\n * Renders a visual outline around the avatar image.\n */\n @property({ type: Boolean, reflect: true })\n public outline = false;\n\n /**\n * Renders the avatar at reduced opacity, indicating the entity is inactive or unavailable.\n */\n @property({ type: Boolean, reflect: true })\n public disabled = false;\n\n // ───────────────────────────\n // ACCESSIBILITY API\n // ───────────────────────────\n\n /**\n * Marks the avatar as decorative, hiding it from assistive technology.\n */\n @property({ type: Boolean, reflect: true })\n public decorative = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n protected override firstUpdated(changes: PropertyValues): void {\n super.firstUpdated(changes);\n if (!this.hasAttribute('size')) {\n this.setAttribute('size', String(this.size));\n }\n this._syncAriaHidden();\n if (window.__swc?.DEBUG) {\n this._warnMissingAlt();\n }\n }\n\n protected override updated(changes: PropertyValues): void {\n super.updated(changes);\n if (changes.has('decorative')) {\n this._syncAriaHidden();\n }\n if (changes.has('alt') && window.__swc?.DEBUG) {\n this._warnMissingAlt();\n }\n }\n\n private _syncAriaHidden(): void {\n if (this.decorative) {\n this.setAttribute('aria-hidden', 'true');\n } else {\n this.removeAttribute('aria-hidden');\n }\n }\n\n private _warnMissingAlt(): void {\n if (this.alt === undefined && !this.decorative) {\n window.__swc?.warn(\n this,\n `<${this.localName}> is missing an \\`alt\\` attribute. Provide a text description or pass \\`alt=\"\"\\` and mark it as \\`decorative\\`.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/avatar/#accessibility',\n {\n type: 'accessibility',\n issues: [\n 'Provide an `alt` attribute with meaningful alternative text, or',\n 'Set `alt=\"\"` and mark the image as `decorative` (hidden from screen readers).',\n ],\n }\n );\n }\n }\n}\n"],"mappings":";;;;;OA4BsB,IAAtB,cAAyC,EAAgB;;0BAwB1C,qCAgDI,oBAMC,sBAUE;;CA/CpB,IACW,OAAmB;AAC5B,SAAO,KAAK;;CAGd,IAAW,KAAK,GAAmB;EACjC,IAAM,IAAa,EAAyC,SAC1D,OAAO,EAAM,CACd,GACI,OAAO,EAAM,GAAA;AAGlB,MAAI,KAAK,UAAU,EACjB;EAGF,IAAM,IAAU,KAAK;AAErB,EADA,KAAK,QAAQ,GACb,KAAK,cAAc,QAAQ,EAAQ;;CAmCrC,aAAgC,GAA+B;;AAM7D,EALA,MAAM,aAAa,EAAQ,EACtB,KAAK,aAAa,OAAO,IAC5B,KAAK,aAAa,QAAQ,OAAO,KAAK,KAAK,CAAC,EAE9C,KAAK,iBAAiB,GACtB,IAAI,OAAO,UAAA,QAAA,EAAO,SAChB,KAAK,iBAAiB;;CAI1B,QAA2B,GAA+B;;AAKxD,EAJA,MAAM,QAAQ,EAAQ,EAClB,EAAQ,IAAI,aAAa,IAC3B,KAAK,iBAAiB,EAEpB,EAAQ,IAAI,MAAM,KAAA,IAAI,OAAO,UAAA,QAAA,EAAO,SACtC,KAAK,iBAAiB;;CAI1B,kBAAgC;AAC9B,EAAI,KAAK,aACP,KAAK,aAAa,eAAe,OAAO,GAExC,KAAK,gBAAgB,cAAc;;CAIvC,kBAAgC;AAC9B,MAAI,KAAK,QAAQ,KAAA,KAAa,CAAC,KAAK,YAAY;;AAC9C,IAAA,IAAA,OAAO,UAAA,QAAA,EAAO,KACZ,MACA,IAAI,KAAK,UAAU,kHACnB,yFACA;IACE,MAAM;IACN,QAAQ,CACN,mEACA,kFACD;IACF,CACF;;;;uBA1HgD,MASpD,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,EAAA,WAAA,OAAA,KAAA,EAAA,KAM1B,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,EAAA,WAAA,OAAA,KAAA,EAAA,KAY1B,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,QAAA,KAAA,KA8BzC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA,KAM1C,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAU1C,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,cAAA,KAAA,EAAA"}
1
+ {"version":3,"file":"Avatar.base.js","names":[],"sources":["../../../components/avatar/Avatar.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 */\nimport { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { SpectrumElement } from '@adobe/spectrum-wc-core/element/index.js';\nimport { warnIf } from '@adobe/spectrum-wc-core/utils/index.js';\n\nimport {\n AVATAR_DEFAULT_SIZE,\n AVATAR_VALID_SIZES,\n type AvatarSize,\n} from './Avatar.types.js';\n\n/**\n * Base class for the avatar component.\n *\n * Provides the core API for displaying a circular profile image. Concrete\n * classes supply the stylesheet and render template.\n */\nexport abstract class AvatarBase extends SpectrumElement {\n // ─────────────────────────\n // STATIC\n // ─────────────────────────\n\n /**\n * @internal\n *\n * The set of valid numeric size values for the avatar.\n *\n * This is an internal property not intended for consumer use, but used in\n * internal validation logic, stories, and tests to keep them in sync with\n * the canonical type definition in `Avatar.types.ts`.\n */\n static readonly VALID_SIZES: readonly AvatarSize[] = AVATAR_VALID_SIZES;\n\n // ──────────────────\n // CORE API\n // ──────────────────\n\n /**\n * URL of the profile image to display.\n */\n @property({ type: String })\n public src = '';\n\n /**\n * Text description of the avatar image.\n */\n @property({ type: String })\n public alt: string | undefined;\n\n // ───────────────────\n // SIZE API\n // ───────────────────\n\n /**\n * The size of the avatar. Invalid values fall back to the default (500).\n *\n * @default 500\n */\n @property({ type: Number, reflect: true })\n public get size(): AvatarSize {\n return this._size;\n }\n\n public set size(value: AvatarSize) {\n const isValid = (AVATAR_VALID_SIZES as readonly number[]).includes(\n Number(value)\n );\n const validSize = isValid\n ? (Number(value) as AvatarSize)\n : AVATAR_DEFAULT_SIZE;\n\n warnIf(\n this,\n !isValid,\n `<${this.localName}> expects \"size\" to be one of: ${AVATAR_VALID_SIZES.join(', ')}. Received \"${value}\".`,\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-avatar--docs',\n { issues: [`size=\"${value}\"`] }\n );\n\n if (this._size === validSize) {\n return;\n }\n\n const oldSize = this._size;\n this._size = validSize;\n this.requestUpdate('size', oldSize);\n }\n\n private _size: AvatarSize = AVATAR_DEFAULT_SIZE;\n\n // ───────────────────────\n // VISUAL API\n // ───────────────────────\n\n /**\n * Renders a visual outline around the avatar image.\n */\n @property({ type: Boolean, reflect: true })\n public outline = false;\n\n /**\n * Renders the avatar at reduced opacity, indicating the entity is inactive or unavailable.\n */\n @property({ type: Boolean, reflect: true })\n public disabled = false;\n\n // ───────────────────────────\n // ACCESSIBILITY API\n // ───────────────────────────\n\n /**\n * Marks the avatar as decorative, hiding it from assistive technology.\n */\n @property({ type: Boolean, reflect: true })\n public decorative = false;\n\n // ──────────────────────\n // IMPLEMENTATION\n // ──────────────────────\n\n protected override firstUpdated(changes: PropertyValues): void {\n super.firstUpdated(changes);\n if (!this.hasAttribute('size')) {\n this.setAttribute('size', String(this.size));\n }\n this._syncAriaHidden();\n this._warnMissingAlt();\n }\n\n protected override updated(changes: PropertyValues): void {\n super.updated(changes);\n if (changes.has('decorative')) {\n this._syncAriaHidden();\n }\n if (changes.has('alt')) {\n this._warnMissingAlt();\n }\n }\n\n private _syncAriaHidden(): void {\n if (this.decorative) {\n this.setAttribute('aria-hidden', 'true');\n } else {\n this.removeAttribute('aria-hidden');\n }\n }\n\n private _warnMissingAlt(): void {\n warnIf(\n this,\n this.alt === undefined && !this.decorative,\n `<${this.localName}> is missing an \\`alt\\` attribute. Provide a text description or pass \\`alt=\"\"\\` and mark it as \\`decorative\\`.`,\n 'https://spectrum-web-components.adobe.com/?path=/docs/components-avatar--docs',\n {\n type: 'accessibility',\n issues: [\n 'Provide an `alt` attribute with meaningful alternative text, or',\n 'Set `alt=\"\"` and mark the image as `decorative` (hidden from screen readers).',\n ],\n }\n );\n }\n}\n"],"mappings":";;;;;;OA6BsB,IAAtB,cAAyC,EAAgB;;0BAwB1C,qCAyDI,oBAMC,sBAUE;;CAxDpB,IACW,OAAmB;AAC5B,SAAO,KAAK;;CAGd,IAAW,KAAK,GAAmB;EACjC,IAAM,IAAW,EAAyC,SACxD,OAAO,EAAM,CACd,EACK,IAAY,IACb,OAAO,EAAM,GAAA;AAWlB,MARA,EACE,MACA,CAAC,GACD,IAAI,KAAK,UAAU,iCAAiC,EAAmB,KAAK,KAAK,CAAC,cAAc,EAAM,KACtG,iFACA,EAAE,QAAQ,CAAC,SAAS,EAAM,GAAG,EAAE,CAChC,EAEG,KAAK,UAAU,EACjB;EAGF,IAAM,IAAU,KAAK;AAErB,EADA,KAAK,QAAQ,GACb,KAAK,cAAc,QAAQ,EAAQ;;CAmCrC,aAAgC,GAA+B;AAM7D,EALA,MAAM,aAAa,EAAQ,EACtB,KAAK,aAAa,OAAO,IAC5B,KAAK,aAAa,QAAQ,OAAO,KAAK,KAAK,CAAC,EAE9C,KAAK,iBAAiB,EACtB,KAAK,iBAAiB;;CAGxB,QAA2B,GAA+B;AAKxD,EAJA,MAAM,QAAQ,EAAQ,EAClB,EAAQ,IAAI,aAAa,IAC3B,KAAK,iBAAiB,EAEpB,EAAQ,IAAI,MAAM,IACpB,KAAK,iBAAiB;;CAI1B,kBAAgC;AAC9B,EAAI,KAAK,aACP,KAAK,aAAa,eAAe,OAAO,GAExC,KAAK,gBAAgB,cAAc;;CAIvC,kBAAgC;AAC9B,IACE,MACA,KAAK,QAAQ,KAAA,KAAa,CAAC,KAAK,YAChC,IAAI,KAAK,UAAU,kHACnB,iFACA;GACE,MAAM;GACN,QAAQ,CACN,mEACA,kFACD;GACF,CACF;;;uBAjIkD,MASpD,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,EAAA,WAAA,OAAA,KAAA,EAAA,KAM1B,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,EAAA,WAAA,OAAA,KAAA,EAAA,KAY1B,EAAS;CAAE,MAAM;CAAQ,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,QAAA,KAAA,KAuCzC,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,WAAA,KAAA,EAAA,KAM1C,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,YAAA,KAAA,EAAA,KAU1C,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,EAAA,WAAA,cAAA,KAAA,EAAA"}
@@ -1,13 +1,9 @@
1
1
  import { PropertyValues } from 'lit';
2
+ import { SlotPresenceController } from '../../controllers/slot-presence-controller/index.js';
3
+ import { SlotTextController } from '../../controllers/slot-text-controller/index.js';
2
4
  import { SpectrumElement } from '../../element/index.js';
3
5
  import { BadgeSize, BadgeVariant, FixedValues } from './Badge.types.js';
4
6
  declare const BadgeBase_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
- new (...args: any[]): import('../../mixins/observe-slot-text.js').SlotTextObservingInterface;
9
- prototype: import('../../mixins/observe-slot-text.js').SlotTextObservingInterface;
10
- } & {
11
7
  new (...args: any[]): import('../../mixins/index.js').SizedElementInterface;
12
8
  prototype: import('../../mixins/index.js').SizedElementInterface;
13
9
  } & import('../../mixins/index.js').SizedElementConstructor;
@@ -19,8 +15,6 @@ declare const BadgeBase_base: typeof SpectrumElement & {
19
15
  *
20
16
  * @slot - Text label of the badge.
21
17
  * @slot icon - Optional icon that appears to the left of the label
22
- *
23
- * @todo review the mixin composition here. We currently have 3 levels of mixins on this class, but the mixin composition guide recommends a maximum of 2.
24
18
  */
25
19
  export declare abstract class BadgeBase extends BadgeBase_base {
26
20
  /**
@@ -87,12 +81,34 @@ export declare abstract class BadgeBase extends BadgeBase_base {
87
81
  * Can only be used with semantic variants.
88
82
  */
89
83
  outline: boolean;
84
+ /**
85
+ * Observes whether an icon is slotted into `[slot="icon"]`.
86
+ *
87
+ * @internal
88
+ */
89
+ protected slotPresence: SlotPresenceController;
90
+ /**
91
+ * Observes whether the default slot has meaningful text content. The default
92
+ * slot must bind `@slotchange=${this.slotText.handleSlotChange}` for changes
93
+ * after the first render to be tracked.
94
+ *
95
+ * @internal
96
+ */
97
+ protected slotText: SlotTextController;
90
98
  /**
91
99
  * @internal
92
100
  *
93
101
  * Used for rendering gap when the badge has an icon.
94
102
  */
95
103
  protected get hasIcon(): boolean;
104
+ /**
105
+ * Whether the default slot has meaningful text content. Consumed by the
106
+ * concrete element's `render()` to toggle icon-only presentation (the
107
+ * `swc-Badge--no-label` class and its icon-only padding tokens).
108
+ *
109
+ * @internal
110
+ */
111
+ protected get slotHasContent(): boolean;
96
112
  protected update(changedProperties: PropertyValues): void;
97
113
  }
98
114
  export {};
@@ -3,42 +3,47 @@ import { BADGE_VALID_SIZES as t, BADGE_VARIANTS_SEMANTIC as n, FIXED_VALUES as r
3
3
  import { property as i } from "lit/decorators.js";
4
4
  import { SpectrumElement as a } from "@adobe/spectrum-wc-core/element/index.js";
5
5
  import { SizedMixin as o } from "@adobe/spectrum-wc-core/mixins/index.js";
6
- import { ObserveSlotPresence as s } from "@adobe/spectrum-wc-core/mixins/observe-slot-presence.js";
7
- import { ObserveSlotText as c } from "@adobe/spectrum-wc-core/mixins/observe-slot-text.js";
6
+ import { validateEnum as s, warnIf as c } from "@adobe/spectrum-wc-core/utils/index.js";
7
+ import { SlotPresenceController as l } from "@adobe/spectrum-wc-core/controllers/slot-presence-controller/index.js";
8
+ import { SlotTextController as u } from "@adobe/spectrum-wc-core/controllers/slot-text-controller/index.js";
8
9
  //#region components/badge/Badge.base.ts
9
- var l, u = class extends o(c(s(a, "[slot=\"icon\"]"), ""), {
10
+ var d, f = class extends o(a, {
10
11
  validSizes: t,
11
12
  defaultSize: "s"
12
13
  }) {
13
14
  constructor(...e) {
14
- super(...e), this.variant = "neutral", this.subtle = !1, this.outline = !1;
15
+ super(...e), this.variant = "neutral", this.subtle = !1, this.outline = !1, this.slotPresence = new l(this, "[slot=\"icon\"]"), this.slotText = new u(this);
15
16
  }
16
17
  get hasIcon() {
17
- return this.slotContentIsPresent;
18
+ return this.slotPresence.isPresent;
19
+ }
20
+ get slotHasContent() {
21
+ return this.slotText.hasContent;
18
22
  }
19
23
  update(e) {
20
- var t;
21
- if ((t = window.__swc) != null && t.DEBUG) {
22
- let e = this.constructor;
23
- e.VARIANTS.includes(this.variant) || window.__swc.warn(this, `<${this.localName}> element expects the "variant" attribute to be one of the following:`, "https://opensource.adobe.com/spectrum-web-components/components/badge/#variants", { issues: [...e.VARIANTS] }), "outline" in this && this.outline === !0 && !e.VARIANTS_SEMANTIC.includes(this.variant) && window.__swc.warn(this, `<${this.localName}> element only supports the outline styling if the variant is a semantic color variant.`, "https://opensource.adobe.com/spectrum-web-components/components/badge/#variants", { issues: [...e.VARIANTS_SEMANTIC] });
24
- }
25
- super.update(e);
24
+ let t = this.constructor;
25
+ s(this, {
26
+ prop: "variant",
27
+ value: this.variant,
28
+ valid: t.VARIANTS,
29
+ url: "https://spectrum-web-components.adobe.com/?path=/docs/components-badge--docs"
30
+ }), c(this, "outline" in this && this.outline === !0 && !t.VARIANTS_SEMANTIC.includes(this.variant), `<${this.localName}> element only supports the outline styling if the variant is a semantic color variant.`, "https://spectrum-web-components.adobe.com/?path=/docs/components-badge--docs", { issues: [...t.VARIANTS_SEMANTIC] }), super.update(e);
26
31
  }
27
32
  };
28
- l = u, l.FIXED_VALUES = r, l.VARIANTS_SEMANTIC = n, e([i({
33
+ d = f, d.FIXED_VALUES = r, d.VARIANTS_SEMANTIC = n, e([i({
29
34
  type: String,
30
35
  reflect: !0
31
- })], u.prototype, "variant", void 0), e([i({
36
+ })], f.prototype, "variant", void 0), e([i({
32
37
  type: String,
33
38
  reflect: !0
34
- })], u.prototype, "fixed", void 0), e([i({
39
+ })], f.prototype, "fixed", void 0), e([i({
35
40
  type: Boolean,
36
41
  reflect: !0
37
- })], u.prototype, "subtle", void 0), e([i({
42
+ })], f.prototype, "subtle", void 0), e([i({
38
43
  type: Boolean,
39
44
  reflect: !0
40
- })], u.prototype, "outline", void 0);
45
+ })], f.prototype, "outline", void 0);
41
46
  //#endregion
42
- export { u as BadgeBase };
47
+ export { f as BadgeBase };
43
48
 
44
49
  //# sourceMappingURL=Badge.base.js.map