@phcdevworks/spectre-components 0.0.1 → 1.1.0

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 (62) hide show
  1. package/README.md +113 -40
  2. package/dist/base-2rD8EmdC.d.cts +32 -0
  3. package/dist/base-2rD8EmdC.d.ts +32 -0
  4. package/dist/button.cjs +295 -170
  5. package/dist/button.cjs.map +1 -1
  6. package/dist/button.d.cts +30 -61
  7. package/dist/button.d.ts +30 -61
  8. package/dist/button.js +296 -171
  9. package/dist/button.js.map +1 -1
  10. package/dist/checkbox.cjs +286 -71
  11. package/dist/checkbox.cjs.map +1 -1
  12. package/dist/checkbox.d.cts +38 -43
  13. package/dist/checkbox.d.ts +38 -43
  14. package/dist/checkbox.js +287 -72
  15. package/dist/checkbox.js.map +1 -1
  16. package/dist/fieldset.cjs +233 -88
  17. package/dist/fieldset.cjs.map +1 -1
  18. package/dist/fieldset.d.cts +23 -40
  19. package/dist/fieldset.d.ts +23 -40
  20. package/dist/fieldset.js +233 -88
  21. package/dist/fieldset.js.map +1 -1
  22. package/dist/form-iI7vV-3W.d.cts +6 -0
  23. package/dist/form-iI7vV-3W.d.ts +6 -0
  24. package/dist/index.cjs +564 -1029
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +5 -2
  27. package/dist/index.d.ts +5 -2
  28. package/dist/index.js +566 -1030
  29. package/dist/index.js.map +1 -1
  30. package/dist/input.cjs +232 -119
  31. package/dist/input.cjs.map +1 -1
  32. package/dist/input.d.cts +52 -68
  33. package/dist/input.d.ts +52 -68
  34. package/dist/input.js +232 -119
  35. package/dist/input.js.map +1 -1
  36. package/dist/label.cjs +232 -73
  37. package/dist/label.cjs.map +1 -1
  38. package/dist/label.d.cts +13 -22
  39. package/dist/label.d.ts +13 -22
  40. package/dist/label.js +232 -73
  41. package/dist/label.js.map +1 -1
  42. package/dist/projectable-BzDQ4xp_.d.cts +17 -0
  43. package/dist/projectable-s3SgvjGX.d.ts +17 -0
  44. package/dist/radio.cjs +286 -71
  45. package/dist/radio.cjs.map +1 -1
  46. package/dist/radio.d.cts +38 -43
  47. package/dist/radio.d.ts +38 -43
  48. package/dist/radio.js +287 -72
  49. package/dist/radio.js.map +1 -1
  50. package/dist/select.cjs +292 -163
  51. package/dist/select.cjs.map +1 -1
  52. package/dist/select.d.cts +35 -58
  53. package/dist/select.d.ts +35 -58
  54. package/dist/select.js +293 -163
  55. package/dist/select.js.map +1 -1
  56. package/dist/textarea.cjs +191 -290
  57. package/dist/textarea.cjs.map +1 -1
  58. package/dist/textarea.d.cts +41 -58
  59. package/dist/textarea.d.ts +41 -58
  60. package/dist/textarea.js +191 -290
  61. package/dist/textarea.js.map +1 -1
  62. package/package.json +13 -12
package/dist/label.js CHANGED
@@ -2,85 +2,251 @@ import { LitElement, nothing, html } from 'lit';
2
2
  import { ifDefined } from 'lit/directives/if-defined.js';
3
3
 
4
4
  // src/components/label/sp-label.ts
5
- var SpectreLabelElement = class extends LitElement {
5
+ var SpectreBaseElement = class extends LitElement {
6
6
  constructor() {
7
7
  super(...arguments);
8
- this.projectedContent = [];
8
+ this._ariaLabel = null;
9
+ this._ariaLabelledBy = null;
10
+ this._ariaDescribedBy = null;
11
+ this._title = "";
12
+ this._id = "";
13
+ }
14
+ get ariaLabel() {
15
+ return this._ariaLabel;
16
+ }
17
+ set ariaLabel(value) {
18
+ if (this._ariaLabel === value) {
19
+ return;
20
+ }
21
+ this._ariaLabel = value;
22
+ this._removeHostAttribute("aria-label");
23
+ this.requestUpdate();
24
+ }
25
+ get ariaLabelledBy() {
26
+ return this._ariaLabelledBy;
27
+ }
28
+ set ariaLabelledBy(value) {
29
+ if (this._ariaLabelledBy === value) {
30
+ return;
31
+ }
32
+ this._ariaLabelledBy = value;
33
+ this._removeHostAttribute("aria-labelledby");
34
+ this.requestUpdate();
35
+ }
36
+ get ariaDescribedBy() {
37
+ return this._ariaDescribedBy;
38
+ }
39
+ set ariaDescribedBy(value) {
40
+ if (this._ariaDescribedBy === value) {
41
+ return;
42
+ }
43
+ this._ariaDescribedBy = value;
44
+ this._removeHostAttribute("aria-describedby");
45
+ this.requestUpdate();
46
+ }
47
+ get title() {
48
+ return this._title;
49
+ }
50
+ set title(value) {
51
+ const normalizedValue = value ?? "";
52
+ if (this._title === normalizedValue) {
53
+ return;
54
+ }
55
+ this._title = normalizedValue;
56
+ this._removeHostAttribute("title");
57
+ this.requestUpdate();
9
58
  }
10
59
  get id() {
11
- return this._id ?? "";
60
+ return this._id;
12
61
  }
13
62
  set id(value) {
14
- if ((this._id ?? "") === value) {
63
+ const normalizedValue = value ?? "";
64
+ if (this._id === normalizedValue) {
15
65
  return;
16
66
  }
17
- this._id = value;
18
- const host = this;
19
- if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
20
- HTMLElement.prototype.removeAttribute.call(host, "id");
21
- }
67
+ this._id = normalizedValue;
68
+ this._removeHostAttribute("id");
22
69
  this.requestUpdate();
23
70
  }
71
+ // Spectre components intentionally render in light DOM so the global
72
+ // `@phcdevworks/spectre-ui` styling contract can apply directly.
24
73
  createRenderRoot() {
25
74
  return this;
26
75
  }
27
76
  connectedCallback() {
28
77
  super.connectedCallback();
29
- const hostId = super.getAttribute("id");
30
- if (hostId !== null) {
31
- this.id = hostId;
32
- }
33
- this.syncProjectedContent();
34
- this.startContentObserver();
35
- }
36
- disconnectedCallback() {
37
- this.stopContentObserver();
38
- super.disconnectedCallback();
78
+ const proxiedAttributes = [
79
+ "id",
80
+ "title",
81
+ "aria-label",
82
+ "aria-labelledby",
83
+ "aria-describedby"
84
+ ];
85
+ proxiedAttributes.forEach((attr) => {
86
+ const value = super.getAttribute(attr);
87
+ if (value !== null) {
88
+ this.setAttribute(attr, value);
89
+ }
90
+ });
39
91
  }
40
92
  getAttribute(qualifiedName) {
41
- if (qualifiedName === "id") {
42
- return this.id || null;
93
+ switch (qualifiedName) {
94
+ case "id":
95
+ return this.id || null;
96
+ case "title":
97
+ return this.title || null;
98
+ case "aria-label":
99
+ return this.ariaLabel;
100
+ case "aria-labelledby":
101
+ return this.ariaLabelledBy;
102
+ case "aria-describedby":
103
+ return this.ariaDescribedBy;
104
+ default:
105
+ return super.getAttribute(qualifiedName);
43
106
  }
44
- return super.getAttribute(qualifiedName);
45
107
  }
46
108
  hasAttribute(qualifiedName) {
47
- if (qualifiedName === "id") {
48
- return this.id !== "";
109
+ switch (qualifiedName) {
110
+ case "id":
111
+ return this.id !== "";
112
+ case "title":
113
+ return this.title !== "";
114
+ case "aria-label":
115
+ return this.ariaLabel !== null;
116
+ case "aria-labelledby":
117
+ return this.ariaLabelledBy !== null;
118
+ case "aria-describedby":
119
+ return this.ariaDescribedBy !== null;
120
+ default:
121
+ return super.hasAttribute(qualifiedName);
49
122
  }
50
- return super.hasAttribute(qualifiedName);
51
123
  }
52
124
  setAttribute(qualifiedName, value) {
53
- if (qualifiedName === "id") {
54
- this.id = value;
55
- return;
125
+ switch (qualifiedName) {
126
+ case "id":
127
+ this.id = value;
128
+ break;
129
+ case "title":
130
+ this.title = value;
131
+ break;
132
+ case "aria-label":
133
+ this.ariaLabel = value;
134
+ break;
135
+ case "aria-labelledby":
136
+ this.ariaLabelledBy = value;
137
+ break;
138
+ case "aria-describedby":
139
+ this.ariaDescribedBy = value;
140
+ break;
141
+ default:
142
+ super.setAttribute(qualifiedName, value);
56
143
  }
57
- super.setAttribute(qualifiedName, value);
58
144
  }
59
145
  removeAttribute(qualifiedName) {
60
- if (qualifiedName === "id") {
61
- this.id = "";
62
- return;
146
+ switch (qualifiedName) {
147
+ case "id":
148
+ this.id = "";
149
+ break;
150
+ case "title":
151
+ this.title = "";
152
+ break;
153
+ case "aria-label":
154
+ this.ariaLabel = null;
155
+ break;
156
+ case "aria-labelledby":
157
+ this.ariaLabelledBy = null;
158
+ break;
159
+ case "aria-describedby":
160
+ this.ariaDescribedBy = null;
161
+ break;
162
+ default:
163
+ super.removeAttribute(qualifiedName);
63
164
  }
64
- super.removeAttribute(qualifiedName);
165
+ }
166
+ _removeHostAttribute(name) {
167
+ const host = this;
168
+ if (HTMLElement.prototype.hasAttribute.call(host, name)) {
169
+ HTMLElement.prototype.removeAttribute.call(host, name);
170
+ }
171
+ }
172
+ get forwardedAriaLabel() {
173
+ const value = this.ariaLabel?.trim();
174
+ return value ? value : void 0;
175
+ }
176
+ get forwardedAriaLabelledBy() {
177
+ const value = this.ariaLabelledBy?.trim();
178
+ return value ? value : void 0;
179
+ }
180
+ get forwardedAriaDescribedBy() {
181
+ const value = this.ariaDescribedBy?.trim();
182
+ return value ? value : void 0;
183
+ }
184
+ };
185
+ SpectreBaseElement.properties = {};
186
+
187
+ // src/utils/dom.ts
188
+ function hasMeaningfulContent(nodes) {
189
+ return nodes.some((node) => {
190
+ if (node.nodeType === Node.ELEMENT_NODE) {
191
+ return true;
192
+ }
193
+ if (node.nodeType === Node.TEXT_NODE) {
194
+ return (node.textContent?.trim().length ?? 0) > 0;
195
+ }
196
+ return false;
197
+ });
198
+ }
199
+
200
+ // src/utils/projectable.ts
201
+ var SpectreProjectableElement = class extends SpectreBaseElement {
202
+ constructor() {
203
+ super(...arguments);
204
+ this.projectedContent = [];
205
+ }
206
+ get hasProjectedContent() {
207
+ return hasMeaningfulContent(this.projectedContent);
208
+ }
209
+ connectedCallback() {
210
+ super.connectedCallback();
211
+ this.syncProjectedContent();
212
+ this.startContentObserver();
213
+ }
214
+ disconnectedCallback() {
215
+ this.stopContentObserver();
216
+ super.disconnectedCallback();
65
217
  }
66
218
  update(changedProperties) {
67
219
  this.stopContentObserver();
68
220
  super.update(changedProperties);
69
221
  this.startContentObserver();
70
222
  }
71
- get nativeLabel() {
72
- return this.querySelector("[data-sp-label-native]");
223
+ syncProjectedContent() {
224
+ const nextProjectedContent = [];
225
+ const sourceNodes = [
226
+ ...this.childNodes,
227
+ ...this.getContentContainer()?.childNodes ?? []
228
+ ];
229
+ sourceNodes.forEach((node) => {
230
+ if (!this.isInternalNode(node) && !nextProjectedContent.includes(node)) {
231
+ nextProjectedContent.push(node);
232
+ }
233
+ });
234
+ const hasChanged = nextProjectedContent.length !== this.projectedContent.length || nextProjectedContent.some((node, index) => node !== this.projectedContent[index]);
235
+ if (hasChanged) {
236
+ this.projectedContent = nextProjectedContent;
237
+ }
238
+ return hasChanged;
73
239
  }
74
240
  startContentObserver() {
75
241
  if (this.contentObserver) {
76
242
  return;
77
243
  }
78
244
  this.contentObserver = new MutationObserver((mutations) => {
79
- const isInternalMovement = mutations.every((mutation) => {
80
- return Array.from(mutation.removedNodes).every(
81
- (node) => this.isInternalLabelNode(node) || this.contains(node)
82
- ) && Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node));
83
- });
245
+ const isInternalMovement = mutations.every(
246
+ (mutation) => [...mutation.removedNodes].every(
247
+ (node) => this.isInternalNode(node) || this.contains(node)
248
+ ) && [...mutation.addedNodes].every((node) => this.isInternalNode(node))
249
+ );
84
250
  if (isInternalMovement) {
85
251
  return;
86
252
  }
@@ -94,50 +260,43 @@ var SpectreLabelElement = class extends LitElement {
94
260
  this.contentObserver?.disconnect();
95
261
  this.contentObserver = void 0;
96
262
  }
97
- syncProjectedContent() {
98
- const nextProjectedContent = [];
99
- Array.from(this.childNodes).forEach((node) => {
100
- if (this.isInternalLabelNode(node)) {
101
- this.projectedContent.forEach((projectedNode) => {
102
- if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
103
- nextProjectedContent.push(projectedNode);
104
- }
105
- });
106
- return;
107
- }
108
- nextProjectedContent.push(node);
109
- });
110
- if (nextProjectedContent.length === this.projectedContent.length && nextProjectedContent.every((node, index) => node === this.projectedContent[index])) {
263
+ };
264
+
265
+ // src/components/label/sp-label.ts
266
+ var SpectreLabelElement = class extends SpectreProjectableElement {
267
+ getContentContainer() {
268
+ return this.querySelector("[data-sp-label-native]");
269
+ }
270
+ isInternalNode(node) {
271
+ if (node.nodeType !== Node.ELEMENT_NODE) {
111
272
  return false;
112
273
  }
113
- this.projectedContent = nextProjectedContent;
114
- return true;
115
- }
116
- isInternalLabelNode(node) {
117
- return node === this.nativeLabel;
274
+ const el = node;
275
+ return el.hasAttribute("data-sp-label-native");
118
276
  }
119
277
  focus(options) {
120
- this.nativeLabel?.focus(options);
278
+ this.getContentContainer()?.focus(options);
121
279
  }
122
280
  blur() {
123
- this.nativeLabel?.blur();
281
+ this.getContentContainer()?.blur();
124
282
  }
125
283
  render() {
126
- return html`
127
- <label
128
- class='sp-label'
129
- data-sp-label-native
130
- for=${ifDefined(this.htmlFor)}
131
- id=${ifDefined(this.id || void 0)}
132
- tabindex='-1'
133
- >
134
- ${this.projectedContent.length > 0 ? this.projectedContent : nothing}
135
- </label>
136
- `;
284
+ return html`<label
285
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
286
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
287
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
288
+ class="sp-label"
289
+ data-sp-label-native
290
+ for="${ifDefined(this.htmlFor || void 0)}"
291
+ id="${ifDefined(this.id || void 0)}"
292
+ title="${ifDefined(this.title || void 0)}"
293
+ >
294
+ ${this.hasProjectedContent ? this.projectedContent : nothing}
295
+ </label>`;
137
296
  }
138
297
  };
139
298
  SpectreLabelElement.properties = {
140
- htmlFor: { attribute: "for", type: String }
299
+ htmlFor: { attribute: "for", type: String, reflect: true }
141
300
  };
142
301
  function defineSpectreLabel(tagName = "sp-label") {
143
302
  const existingElement = customElements.get(tagName);
package/dist/label.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/label/sp-label.ts"],"names":[],"mappings":"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","file":"label.js","sourcesContent":["import { LitElement, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport interface SpectreLabelProps {\n htmlFor?: string;\n}\n\nexport class SpectreLabelElement extends LitElement implements SpectreLabelProps {\n static properties = {\n htmlFor: { attribute: 'for', type: String },\n };\n\n htmlFor?: string;\n private _id?: string;\n private projectedContent: Node[] = [];\n private contentObserver?: MutationObserver | undefined;\n\n override get id(): string {\n return this._id ?? '';\n }\n\n override set id(value: string) {\n if ((this._id ?? '') === value) {\n return;\n }\n\n this._id = value;\n\n const host = this as unknown as HTMLElement;\n if (HTMLElement.prototype.hasAttribute.call(host, 'id')) {\n HTMLElement.prototype.removeAttribute.call(host, 'id');\n }\n\n this.requestUpdate();\n }\n\n createRenderRoot(): this {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n const hostId = super.getAttribute('id');\n\n if (hostId !== null) {\n this.id = hostId;\n }\n\n this.syncProjectedContent();\n this.startContentObserver();\n }\n\n override disconnectedCallback(): void {\n this.stopContentObserver();\n super.disconnectedCallback();\n }\n\n override getAttribute(qualifiedName: string): string | null {\n if (qualifiedName === 'id') {\n return this.id || null;\n }\n\n return super.getAttribute(qualifiedName);\n }\n\n override hasAttribute(qualifiedName: string): boolean {\n if (qualifiedName === 'id') {\n return this.id !== '';\n }\n\n return super.hasAttribute(qualifiedName);\n }\n\n override setAttribute(qualifiedName: string, value: string): void {\n if (qualifiedName === 'id') {\n this.id = value;\n return;\n }\n\n super.setAttribute(qualifiedName, value);\n }\n\n override removeAttribute(qualifiedName: string): void {\n if (qualifiedName === 'id') {\n this.id = '';\n return;\n }\n\n super.removeAttribute(qualifiedName);\n }\n\n protected override update(changedProperties: Map<PropertyKey, unknown>): void {\n this.stopContentObserver();\n super.update(changedProperties);\n this.startContentObserver();\n }\n\n private get nativeLabel(): HTMLLabelElement | null {\n return this.querySelector('[data-sp-label-native]');\n }\n\n private startContentObserver(): void {\n if (this.contentObserver) {\n return;\n }\n\n this.contentObserver = new MutationObserver((mutations) => {\n const isInternalMovement = mutations.every((mutation) => {\n return (\n Array.from(mutation.removedNodes).every(\n (node) => this.isInternalLabelNode(node) || this.contains(node),\n ) &&\n Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node))\n );\n });\n\n if (isInternalMovement) {\n return;\n }\n\n if (this.syncProjectedContent()) {\n this.requestUpdate();\n }\n });\n\n this.contentObserver.observe(this, { childList: true });\n }\n\n private stopContentObserver(): void {\n this.contentObserver?.disconnect();\n this.contentObserver = undefined;\n }\n\n private syncProjectedContent(): boolean {\n const nextProjectedContent: Node[] = [];\n\n Array.from(this.childNodes).forEach((node) => {\n if (this.isInternalLabelNode(node)) {\n this.projectedContent.forEach((projectedNode) => {\n if (projectedNode.parentNode !== this && this.contains(projectedNode)) {\n nextProjectedContent.push(projectedNode);\n }\n });\n return;\n }\n\n nextProjectedContent.push(node);\n });\n\n if (\n nextProjectedContent.length === this.projectedContent.length &&\n nextProjectedContent.every((node, index) => node === this.projectedContent[index])\n ) {\n return false;\n }\n\n this.projectedContent = nextProjectedContent;\n return true;\n }\n\n private isInternalLabelNode(node: Node): boolean {\n return node === this.nativeLabel;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeLabel?.focus(options);\n }\n\n override blur(): void {\n this.nativeLabel?.blur();\n }\n\n override render() {\n return html`\n <label\n class='sp-label'\n data-sp-label-native\n for=${ifDefined(this.htmlFor)}\n id=${ifDefined(this.id || undefined)}\n tabindex='-1'\n >\n ${this.projectedContent.length > 0 ? this.projectedContent : nothing}\n </label>\n `;\n }\n}\n\nexport function defineSpectreLabel(tagName = 'sp-label'): typeof SpectreLabelElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreLabelElement;\n }\n\n customElements.define(tagName, SpectreLabelElement);\n return SpectreLabelElement;\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/base.ts","../src/utils/dom.ts","../src/utils/projectable.ts","../src/components/label/sp-label.ts"],"names":[],"mappings":";;;;AAEO,IAAM,kBAAA,GAAN,cAAiC,UAAA,CAAW;AAAA,EAA5C,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAGL,IAAA,IAAA,CAAQ,UAAA,GAA4B,IAAA;AACpC,IAAA,IAAA,CAAQ,eAAA,GAAiC,IAAA;AACzC,IAAA,IAAA,CAAQ,gBAAA,GAAkC,IAAA;AAC1C,IAAA,IAAA,CAAQ,MAAA,GAAS,EAAA;AACjB,IAAA,IAAA,CAAQ,GAAA,GAAM,EAAA;AAAA,EAAA;AAAA,EAEd,IAAI,SAAA,GAA2B;AAC7B,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,IAAI,UAAU,KAAA,EAAsB;AAClC,IAAA,IAAI,IAAA,CAAK,eAAe,KAAA,EAAO;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,IAAA,IAAA,CAAK,qBAAqB,YAAY,CAAA;AACtC,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEA,IAAI,cAAA,GAAgC;AAClC,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA,EAEA,IAAI,eAAe,KAAA,EAAsB;AACvC,IAAA,IAAI,IAAA,CAAK,oBAAoB,KAAA,EAAO;AAClC,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,IAAA,IAAA,CAAK,qBAAqB,iBAAiB,CAAA;AAC3C,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEA,IAAI,eAAA,GAAiC;AACnC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA,EAEA,IAAI,gBAAgB,KAAA,EAAsB;AACxC,IAAA,IAAI,IAAA,CAAK,qBAAqB,KAAA,EAAO;AACnC,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,qBAAqB,kBAAkB,CAAA;AAC5C,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEA,IAAa,KAAA,GAAgB;AAC3B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,IAAa,MAAM,KAAA,EAAkC;AACnD,IAAA,MAAM,kBAAkB,KAAA,IAAS,EAAA;AACjC,IAAA,IAAI,IAAA,CAAK,WAAW,eAAA,EAAiB;AACnC,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,eAAA;AACd,IAAA,IAAA,CAAK,qBAAqB,OAAO,CAAA;AACjC,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEA,IAAa,EAAA,GAAa;AACxB,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA,EAEA,IAAa,GAAG,KAAA,EAAkC;AAChD,IAAA,MAAM,kBAAkB,KAAA,IAAS,EAAA;AACjC,IAAA,IAAI,IAAA,CAAK,QAAQ,eAAA,EAAiB;AAChC,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,GAAA,GAAM,eAAA;AACX,IAAA,IAAA,CAAK,qBAAqB,IAAI,CAAA;AAC9B,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA;AAAA;AAAA,EAIA,gBAAA,GAAyB;AACvB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAES,iBAAA,GAA0B;AACjC,IAAA,KAAA,CAAM,iBAAA,EAAkB;AAExB,IAAA,MAAM,iBAAA,GAAoB;AAAA,MACxB,IAAA;AAAA,MACA,OAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,iBAAA,CAAkB,OAAA,CAAQ,CAAC,IAAA,KAAS;AAClC,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,CAAa,IAAI,CAAA;AACrC,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,IAAA,CAAK,YAAA,CAAa,MAAM,KAAK,CAAA;AAAA,MAC/B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAES,aAAa,aAAA,EAAsC;AAC1D,IAAA,QAAQ,aAAA;AAAe,MACrB,KAAK,IAAA;AACH,QAAA,OAAO,KAAK,EAAA,IAAM,IAAA;AAAA,MACpB,KAAK,OAAA;AACH,QAAA,OAAO,KAAK,KAAA,IAAS,IAAA;AAAA,MACvB,KAAK,YAAA;AACH,QAAA,OAAO,IAAA,CAAK,SAAA;AAAA,MACd,KAAK,iBAAA;AACH,QAAA,OAAO,IAAA,CAAK,cAAA;AAAA,MACd,KAAK,kBAAA;AACH,QAAA,OAAO,IAAA,CAAK,eAAA;AAAA,MACd;AACE,QAAA,OAAO,KAAA,CAAM,aAAa,aAAa,CAAA;AAAA;AAC3C,EACF;AAAA,EAES,aAAa,aAAA,EAAgC;AACpD,IAAA,QAAQ,aAAA;AAAe,MACrB,KAAK,IAAA;AACH,QAAA,OAAO,KAAK,EAAA,KAAO,EAAA;AAAA,MACrB,KAAK,OAAA;AACH,QAAA,OAAO,KAAK,KAAA,KAAU,EAAA;AAAA,MACxB,KAAK,YAAA;AACH,QAAA,OAAO,KAAK,SAAA,KAAc,IAAA;AAAA,MAC5B,KAAK,iBAAA;AACH,QAAA,OAAO,KAAK,cAAA,KAAmB,IAAA;AAAA,MACjC,KAAK,kBAAA;AACH,QAAA,OAAO,KAAK,eAAA,KAAoB,IAAA;AAAA,MAClC;AACE,QAAA,OAAO,KAAA,CAAM,aAAa,aAAa,CAAA;AAAA;AAC3C,EACF;AAAA,EAES,YAAA,CAAa,eAAuB,KAAA,EAAqB;AAChE,IAAA,QAAQ,aAAA;AAAe,MACrB,KAAK,IAAA;AACH,QAAA,IAAA,CAAK,EAAA,GAAK,KAAA;AACV,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,QAAA;AAAA,MACF,KAAK,YAAA;AACH,QAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AACjB,QAAA;AAAA,MACF,KAAK,iBAAA;AACH,QAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,QAAA;AAAA,MACF,KAAK,kBAAA;AACH,QAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,QAAA;AAAA,MACF;AACE,QAAA,KAAA,CAAM,YAAA,CAAa,eAAe,KAAK,CAAA;AAAA;AAC3C,EACF;AAAA,EAES,gBAAgB,aAAA,EAA6B;AACpD,IAAA,QAAQ,aAAA;AAAe,MACrB,KAAK,IAAA;AACH,QAAA,IAAA,CAAK,EAAA,GAAK,EAAA;AACV,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,KAAA,GAAQ,EAAA;AACb,QAAA;AAAA,MACF,KAAK,YAAA;AACH,QAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,QAAA;AAAA,MACF,KAAK,iBAAA;AACH,QAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,QAAA;AAAA,MACF,KAAK,kBAAA;AACH,QAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,QAAA;AAAA,MACF;AACE,QAAA,KAAA,CAAM,gBAAgB,aAAa,CAAA;AAAA;AACvC,EACF;AAAA,EAEQ,qBAAqB,IAAA,EAAoB;AAC/C,IAAA,MAAM,IAAA,GAAO,IAAA;AACb,IAAA,IAAI,YAAY,SAAA,CAAU,YAAA,CAAa,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA,EAAG;AACvD,MAAA,WAAA,CAAY,SAAA,CAAU,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,IAAc,kBAAA,GAAyC;AACrD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,EAAW,IAAA,EAAK;AACnC,IAAA,OAAO,QAAQ,KAAA,GAAQ,MAAA;AAAA,EACzB;AAAA,EAEA,IAAc,uBAAA,GAA8C;AAC1D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,cAAA,EAAgB,IAAA,EAAK;AACxC,IAAA,OAAO,QAAQ,KAAA,GAAQ,MAAA;AAAA,EACzB;AAAA,EAEA,IAAc,wBAAA,GAA+C;AAC3D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,eAAA,EAAiB,IAAA,EAAK;AACzC,IAAA,OAAO,QAAQ,KAAA,GAAQ,MAAA;AAAA,EACzB;AACF,CAAA;AAxMa,kBAAA,CACJ,aAAmC,EAAC;;;ACHtC,SAAS,qBAAqB,KAAA,EAAiC;AACpE,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS;AAC1B,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,YAAA,EAAc;AACvC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,SAAA,EAAW;AACpC,MAAA,OAAA,CAAQ,IAAA,CAAK,WAAA,EAAa,IAAA,EAAK,CAAE,UAAU,CAAA,IAAK,CAAA;AAAA,IAClD;AAEA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;;;ACTO,IAAe,yBAAA,GAAf,cAAiD,kBAAA,CAAmB;AAAA,EAApE,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAA,IAAA,CAAU,mBAA2B,EAAC;AAAA,EAAA;AAAA,EAWtC,IAAc,mBAAA,GAA+B;AAC3C,IAAA,OAAO,oBAAA,CAAqB,KAAK,gBAAgB,CAAA;AAAA,EACnD;AAAA,EAES,iBAAA,GAA0B;AACjC,IAAA,KAAA,CAAM,iBAAA,EAAkB;AACxB,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,EAC5B;AAAA,EAES,oBAAA,GAA6B;AACpC,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,KAAA,CAAM,oBAAA,EAAqB;AAAA,EAC7B;AAAA,EAEmB,OAAO,iBAAA,EAAoD;AAC5E,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,KAAA,CAAM,OAAO,iBAAiB,CAAA;AAC9B,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,EAC5B;AAAA,EAEU,oBAAA,GAAgC;AACxC,IAAA,MAAM,uBAA+B,EAAC;AACtC,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,GAAG,IAAA,CAAK,UAAA;AAAA,MACR,GAAI,IAAA,CAAK,mBAAA,EAAoB,EAAG,cAAc;AAAC,KACjD;AAEA,IAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC5B,MAAA,IAAI,CAAC,KAAK,cAAA,CAAe,IAAI,KAAK,CAAC,oBAAA,CAAqB,QAAA,CAAS,IAAI,CAAA,EAAG;AACtE,QAAA,oBAAA,CAAqB,KAAK,IAAI,CAAA;AAAA,MAChC;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,UAAA,GACJ,oBAAA,CAAqB,MAAA,KAAW,IAAA,CAAK,iBAAiB,MAAA,IACtD,oBAAA,CAAqB,IAAA,CAAK,CAAC,MAAM,KAAA,KAAU,IAAA,KAAS,IAAA,CAAK,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAElF,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,IAAA,CAAK,gBAAA,GAAmB,oBAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAAA,EAEQ,oBAAA,GAA6B;AACnC,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAI,gBAAA,CAAiB,CAAC,SAAA,KAAc;AACzD,MAAA,MAAM,qBAAqB,SAAA,CAAU,KAAA;AAAA,QAAM,CAAC,QAAA,KAC1C,CAAC,GAAG,QAAA,CAAS,YAAY,CAAA,CAAE,KAAA;AAAA,UACzB,CAAC,SAAS,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA,IAAK,IAAA,CAAK,SAAS,IAAI;AAAA,SAC3D,IACA,CAAC,GAAG,QAAA,CAAS,UAAU,CAAA,CAAE,KAAA,CAAM,CAAC,IAAA,KAAS,IAAA,CAAK,cAAA,CAAe,IAAI,CAAC;AAAA,OACpE;AAEA,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,sBAAqB,EAAG;AAC/B,QAAA,IAAA,CAAK,aAAA,EAAc;AAAA,MACrB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,gBAAgB,OAAA,CAAQ,IAAA,EAAM,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,EACxD;AAAA,EAEQ,mBAAA,GAA4B;AAClC,IAAA,IAAA,CAAK,iBAAiB,UAAA,EAAW;AACjC,IAAA,IAAA,CAAK,eAAA,GAAkB,MAAA;AAAA,EACzB;AACF,CAAA;;;AC5EO,IAAM,mBAAA,GAAN,cAAkC,yBAAA,CAAuD;AAAA,EAO3E,mBAAA,GAAsC;AACvD,IAAA,OAAO,IAAA,CAAK,cAAc,wBAAwB,CAAA;AAAA,EACpD;AAAA,EAEmB,eAAe,IAAA,EAAqB;AACrD,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,YAAA,EAAc;AACvC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,EAAA,GAAK,IAAA;AACX,IAAA,OAAO,EAAA,CAAG,aAAa,sBAAsB,CAAA;AAAA,EAC/C;AAAA,EAES,MAAM,OAAA,EAA8B;AAC3C,IAAC,IAAA,CAAK,mBAAA,EAAoB,EAA+B,KAAA,CAAM,OAAO,CAAA;AAAA,EACxE;AAAA,EAES,IAAA,GAAa;AACpB,IAAC,IAAA,CAAK,mBAAA,EAAoB,EAA+B,IAAA,EAAK;AAAA,EAChE;AAAA,EAES,MAAA,GAAS;AAChB,IAAA,OAAO,IAAA,CAAA;AAAA,wBAAA,EACe,SAAA,CAAU,IAAA,CAAK,wBAAwB,CAAC,CAAA;AAAA,kBAAA,EAC9C,SAAA,CAAU,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAAA,uBAAA,EAC7B,SAAA,CAAU,IAAA,CAAK,uBAAuB,CAAC,CAAA;AAAA;AAAA;AAAA,WAAA,EAGnD,SAAA,CAAU,IAAA,CAAK,OAAA,IAAW,MAAS,CAAC,CAAA;AAAA,UAAA,EACrC,SAAA,CAAU,IAAA,CAAK,EAAA,IAAM,MAAS,CAAC,CAAA;AAAA,aAAA,EAC5B,SAAA,CAAU,IAAA,CAAK,KAAA,IAAS,MAAS,CAAC,CAAA;AAAA;AAAA,MAAA,EAEzC,IAAA,CAAK,mBAAA,GAAsB,IAAA,CAAK,gBAAA,GAAmB,OAAO;AAAA,YAAA,CAAA;AAAA,EAEhE;AACF;AA1Ca,mBAAA,CACJ,UAAA,GAAa;AAAA,EAClB,SAAS,EAAE,SAAA,EAAW,OAAO,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA;AACtD,CAAA;AAyCK,SAAS,kBAAA,CAAmB,UAAU,UAAA,EAAwC;AACnF,EAAA,MAAM,eAAA,GAAkB,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA;AAElD,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,OAAO,eAAA;AAAA,EACT;AAEA,EAAA,cAAA,CAAe,MAAA,CAAO,SAAS,mBAAmB,CAAA;AAClD,EAAA,OAAO,mBAAA;AACT","file":"label.js","sourcesContent":["import { LitElement, type PropertyDeclarations } from 'lit';\n\nexport class SpectreBaseElement extends LitElement {\n static properties: PropertyDeclarations = {};\n\n private _ariaLabel: string | null = null;\n private _ariaLabelledBy: string | null = null;\n private _ariaDescribedBy: string | null = null;\n private _title = '';\n private _id = '';\n\n get ariaLabel(): string | null {\n return this._ariaLabel;\n }\n\n set ariaLabel(value: string | null) {\n if (this._ariaLabel === value) {\n return;\n }\n this._ariaLabel = value;\n this._removeHostAttribute('aria-label');\n this.requestUpdate();\n }\n\n get ariaLabelledBy(): string | null {\n return this._ariaLabelledBy;\n }\n\n set ariaLabelledBy(value: string | null) {\n if (this._ariaLabelledBy === value) {\n return;\n }\n this._ariaLabelledBy = value;\n this._removeHostAttribute('aria-labelledby');\n this.requestUpdate();\n }\n\n get ariaDescribedBy(): string | null {\n return this._ariaDescribedBy;\n }\n\n set ariaDescribedBy(value: string | null) {\n if (this._ariaDescribedBy === value) {\n return;\n }\n this._ariaDescribedBy = value;\n this._removeHostAttribute('aria-describedby');\n this.requestUpdate();\n }\n\n override get title(): string {\n return this._title;\n }\n\n override set title(value: string | undefined | null) {\n const normalizedValue = value ?? '';\n if (this._title === normalizedValue) {\n return;\n }\n this._title = normalizedValue;\n this._removeHostAttribute('title');\n this.requestUpdate();\n }\n\n override get id(): string {\n return this._id;\n }\n\n override set id(value: string | undefined | null) {\n const normalizedValue = value ?? '';\n if (this._id === normalizedValue) {\n return;\n }\n this._id = normalizedValue;\n this._removeHostAttribute('id');\n this.requestUpdate();\n }\n\n // Spectre components intentionally render in light DOM so the global\n // `@phcdevworks/spectre-ui` styling contract can apply directly.\n createRenderRoot(): this {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n const proxiedAttributes = [\n 'id',\n 'title',\n 'aria-label',\n 'aria-labelledby',\n 'aria-describedby',\n ];\n\n proxiedAttributes.forEach((attr) => {\n const value = super.getAttribute(attr);\n if (value !== null) {\n this.setAttribute(attr, value);\n }\n });\n }\n\n override getAttribute(qualifiedName: string): string | null {\n switch (qualifiedName) {\n case 'id':\n return this.id || null;\n case 'title':\n return this.title || null;\n case 'aria-label':\n return this.ariaLabel;\n case 'aria-labelledby':\n return this.ariaLabelledBy;\n case 'aria-describedby':\n return this.ariaDescribedBy;\n default:\n return super.getAttribute(qualifiedName);\n }\n }\n\n override hasAttribute(qualifiedName: string): boolean {\n switch (qualifiedName) {\n case 'id':\n return this.id !== '';\n case 'title':\n return this.title !== '';\n case 'aria-label':\n return this.ariaLabel !== null;\n case 'aria-labelledby':\n return this.ariaLabelledBy !== null;\n case 'aria-describedby':\n return this.ariaDescribedBy !== null;\n default:\n return super.hasAttribute(qualifiedName);\n }\n }\n\n override setAttribute(qualifiedName: string, value: string): void {\n switch (qualifiedName) {\n case 'id':\n this.id = value;\n break;\n case 'title':\n this.title = value;\n break;\n case 'aria-label':\n this.ariaLabel = value;\n break;\n case 'aria-labelledby':\n this.ariaLabelledBy = value;\n break;\n case 'aria-describedby':\n this.ariaDescribedBy = value;\n break;\n default:\n super.setAttribute(qualifiedName, value);\n }\n }\n\n override removeAttribute(qualifiedName: string): void {\n switch (qualifiedName) {\n case 'id':\n this.id = '';\n break;\n case 'title':\n this.title = '';\n break;\n case 'aria-label':\n this.ariaLabel = null;\n break;\n case 'aria-labelledby':\n this.ariaLabelledBy = null;\n break;\n case 'aria-describedby':\n this.ariaDescribedBy = null;\n break;\n default:\n super.removeAttribute(qualifiedName);\n }\n }\n\n private _removeHostAttribute(name: string): void {\n const host = this as unknown as HTMLElement;\n if (HTMLElement.prototype.hasAttribute.call(host, name)) {\n HTMLElement.prototype.removeAttribute.call(host, name);\n }\n }\n\n protected get forwardedAriaLabel(): string | undefined {\n const value = this.ariaLabel?.trim();\n return value ? value : undefined;\n }\n\n protected get forwardedAriaLabelledBy(): string | undefined {\n const value = this.ariaLabelledBy?.trim();\n return value ? value : undefined;\n }\n\n protected get forwardedAriaDescribedBy(): string | undefined {\n const value = this.ariaDescribedBy?.trim();\n return value ? value : undefined;\n }\n}\n","export function hasMeaningfulContent(nodes: readonly Node[]): boolean {\n return nodes.some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return true;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent?.trim().length ?? 0) > 0;\n }\n\n return false;\n });\n}\n","import { SpectreBaseElement } from './base';\nimport { hasMeaningfulContent } from './dom';\n\nexport abstract class SpectreProjectableElement extends SpectreBaseElement {\n protected projectedContent: Node[] = [];\n private contentObserver?: MutationObserver | undefined;\n\n // Return the native container whose existing children are also treated as\n // projected content sources (e.g. the rendered <button>, <select>, <label>).\n protected abstract getContentContainer(): Element | null;\n\n // Return true if the node was rendered by this component and should not be\n // treated as external projected content.\n protected abstract isInternalNode(node: Node): boolean;\n\n protected get hasProjectedContent(): boolean {\n return hasMeaningfulContent(this.projectedContent);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.syncProjectedContent();\n this.startContentObserver();\n }\n\n override disconnectedCallback(): void {\n this.stopContentObserver();\n super.disconnectedCallback();\n }\n\n protected override update(changedProperties: Map<PropertyKey, unknown>): void {\n this.stopContentObserver();\n super.update(changedProperties);\n this.startContentObserver();\n }\n\n protected syncProjectedContent(): boolean {\n const nextProjectedContent: Node[] = [];\n const sourceNodes = [\n ...this.childNodes,\n ...(this.getContentContainer()?.childNodes ?? []),\n ];\n\n sourceNodes.forEach((node) => {\n if (!this.isInternalNode(node) && !nextProjectedContent.includes(node)) {\n nextProjectedContent.push(node);\n }\n });\n\n const hasChanged =\n nextProjectedContent.length !== this.projectedContent.length ||\n nextProjectedContent.some((node, index) => node !== this.projectedContent[index]);\n\n if (hasChanged) {\n this.projectedContent = nextProjectedContent;\n }\n\n return hasChanged;\n }\n\n private startContentObserver(): void {\n if (this.contentObserver) {\n return;\n }\n\n this.contentObserver = new MutationObserver((mutations) => {\n const isInternalMovement = mutations.every((mutation) =>\n [...mutation.removedNodes].every(\n (node) => this.isInternalNode(node) || this.contains(node),\n ) &&\n [...mutation.addedNodes].every((node) => this.isInternalNode(node)),\n );\n\n if (isInternalMovement) {\n return;\n }\n\n if (this.syncProjectedContent()) {\n this.requestUpdate();\n }\n });\n\n this.contentObserver.observe(this, { childList: true });\n }\n\n private stopContentObserver(): void {\n this.contentObserver?.disconnect();\n this.contentObserver = undefined;\n }\n}\n","import { html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { SpectreProjectableElement } from '../../utils/projectable';\n\nexport interface SpectreLabelProps {\n ariaLabel: string | null;\n ariaLabelledBy: string | null;\n ariaDescribedBy: string | null;\n htmlFor?: string | undefined;\n title?: string | undefined;\n}\n\nexport class SpectreLabelElement extends SpectreProjectableElement implements SpectreLabelProps {\n static properties = {\n htmlFor: { attribute: 'for', type: String, reflect: true },\n };\n\n htmlFor: string | undefined;\n\n protected override getContentContainer(): Element | null {\n return this.querySelector('[data-sp-label-native]');\n }\n\n protected override isInternalNode(node: Node): boolean {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return false;\n }\n\n const el = node as Element;\n return el.hasAttribute('data-sp-label-native');\n }\n\n override focus(options?: FocusOptions): void {\n (this.getContentContainer() as HTMLLabelElement | null)?.focus(options);\n }\n\n override blur(): void {\n (this.getContentContainer() as HTMLLabelElement | null)?.blur();\n }\n\n override render() {\n return html`<label\n aria-describedby=\"${ifDefined(this.forwardedAriaDescribedBy)}\"\n aria-label=\"${ifDefined(this.forwardedAriaLabel)}\"\n aria-labelledby=\"${ifDefined(this.forwardedAriaLabelledBy)}\"\n class=\"sp-label\"\n data-sp-label-native\n for=\"${ifDefined(this.htmlFor || undefined)}\"\n id=\"${ifDefined(this.id || undefined)}\"\n title=\"${ifDefined(this.title || undefined)}\"\n >\n ${this.hasProjectedContent ? this.projectedContent : nothing}\n </label>`;\n }\n}\n\nexport function defineSpectreLabel(tagName = 'sp-label'): typeof SpectreLabelElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreLabelElement;\n }\n\n customElements.define(tagName, SpectreLabelElement);\n return SpectreLabelElement;\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { S as SpectreBaseElement } from './base-2rD8EmdC.cjs';
2
+
3
+ declare abstract class SpectreProjectableElement extends SpectreBaseElement {
4
+ protected projectedContent: Node[];
5
+ private contentObserver?;
6
+ protected abstract getContentContainer(): Element | null;
7
+ protected abstract isInternalNode(node: Node): boolean;
8
+ protected get hasProjectedContent(): boolean;
9
+ connectedCallback(): void;
10
+ disconnectedCallback(): void;
11
+ protected update(changedProperties: Map<PropertyKey, unknown>): void;
12
+ protected syncProjectedContent(): boolean;
13
+ private startContentObserver;
14
+ private stopContentObserver;
15
+ }
16
+
17
+ export { SpectreProjectableElement as S };
@@ -0,0 +1,17 @@
1
+ import { S as SpectreBaseElement } from './base-2rD8EmdC.js';
2
+
3
+ declare abstract class SpectreProjectableElement extends SpectreBaseElement {
4
+ protected projectedContent: Node[];
5
+ private contentObserver?;
6
+ protected abstract getContentContainer(): Element | null;
7
+ protected abstract isInternalNode(node: Node): boolean;
8
+ protected get hasProjectedContent(): boolean;
9
+ connectedCallback(): void;
10
+ disconnectedCallback(): void;
11
+ protected update(changedProperties: Map<PropertyKey, unknown>): void;
12
+ protected syncProjectedContent(): boolean;
13
+ private startContentObserver;
14
+ private stopContentObserver;
15
+ }
16
+
17
+ export { SpectreProjectableElement as S };