@phcdevworks/spectre-components 0.0.1 → 1.0.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 (61) hide show
  1. package/dist/base-DQtCQ-dP.d.cts +22 -0
  2. package/dist/base-DQtCQ-dP.d.ts +22 -0
  3. package/dist/button.cjs +149 -124
  4. package/dist/button.cjs.map +1 -1
  5. package/dist/button.d.cts +15 -40
  6. package/dist/button.d.ts +15 -40
  7. package/dist/button.js +150 -125
  8. package/dist/button.js.map +1 -1
  9. package/dist/checkbox.cjs +140 -25
  10. package/dist/checkbox.cjs.map +1 -1
  11. package/dist/checkbox.d.cts +32 -32
  12. package/dist/checkbox.d.ts +32 -32
  13. package/dist/checkbox.js +141 -26
  14. package/dist/checkbox.js.map +1 -1
  15. package/dist/fieldset.cjs +96 -50
  16. package/dist/fieldset.cjs.map +1 -1
  17. package/dist/fieldset.d.cts +24 -36
  18. package/dist/fieldset.d.ts +24 -36
  19. package/dist/fieldset.js +96 -50
  20. package/dist/fieldset.js.map +1 -1
  21. package/dist/form-iI7vV-3W.d.cts +6 -0
  22. package/dist/form-iI7vV-3W.d.ts +6 -0
  23. package/dist/index.cjs +298 -826
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +5 -2
  26. package/dist/index.d.ts +5 -2
  27. package/dist/index.js +300 -827
  28. package/dist/index.js.map +1 -1
  29. package/dist/input.cjs +70 -59
  30. package/dist/input.cjs.map +1 -1
  31. package/dist/input.d.cts +25 -36
  32. package/dist/input.d.ts +25 -36
  33. package/dist/input.js +70 -59
  34. package/dist/input.js.map +1 -1
  35. package/dist/label.cjs +101 -38
  36. package/dist/label.cjs.map +1 -1
  37. package/dist/label.d.cts +16 -20
  38. package/dist/label.d.ts +16 -20
  39. package/dist/label.js +101 -38
  40. package/dist/label.js.map +1 -1
  41. package/dist/projectable-DcnBRiko.d.cts +17 -0
  42. package/dist/projectable-SzbPvXfM.d.ts +17 -0
  43. package/dist/radio.cjs +140 -25
  44. package/dist/radio.cjs.map +1 -1
  45. package/dist/radio.d.cts +32 -32
  46. package/dist/radio.d.ts +32 -32
  47. package/dist/radio.js +141 -26
  48. package/dist/radio.js.map +1 -1
  49. package/dist/select.cjs +142 -113
  50. package/dist/select.cjs.map +1 -1
  51. package/dist/select.d.cts +23 -41
  52. package/dist/select.d.ts +23 -41
  53. package/dist/select.js +143 -113
  54. package/dist/select.js.map +1 -1
  55. package/dist/textarea.cjs +24 -223
  56. package/dist/textarea.cjs.map +1 -1
  57. package/dist/textarea.d.cts +20 -32
  58. package/dist/textarea.d.ts +20 -32
  59. package/dist/textarea.js +24 -223
  60. package/dist/textarea.js.map +1 -1
  61. package/package.json +11 -11
package/dist/radio.d.cts CHANGED
@@ -1,31 +1,27 @@
1
1
  import * as lit_html from 'lit-html';
2
- import { LitElement } from 'lit';
2
+ import { S as SpectreProjectableElement } from './projectable-DcnBRiko.cjs';
3
+ import './base-DQtCQ-dP.cjs';
4
+ import 'lit';
3
5
 
4
6
  interface SpectreRadioProps {
7
+ ariaLabel?: string | null;
8
+ ariaLabelledBy?: string | null;
9
+ ariaDescribedBy?: string | null;
5
10
  autofocus?: boolean;
6
11
  checked?: boolean;
7
12
  disabled?: boolean;
13
+ form?: string;
8
14
  invalid?: boolean;
9
- label?: string;
10
- name?: string;
15
+ loading?: boolean;
16
+ label?: string | undefined;
17
+ name?: string | undefined;
11
18
  required?: boolean;
19
+ success?: boolean;
12
20
  title?: string;
13
21
  value?: string;
14
22
  }
15
- declare class SpectreRadioElement extends LitElement implements SpectreRadioProps {
23
+ declare class SpectreRadioElement extends SpectreProjectableElement implements SpectreRadioProps {
16
24
  static properties: {
17
- ariaLabel: {
18
- attribute: string;
19
- type: StringConstructor;
20
- };
21
- ariaLabelledBy: {
22
- attribute: string;
23
- type: StringConstructor;
24
- };
25
- ariaDescribedBy: {
26
- attribute: string;
27
- type: StringConstructor;
28
- };
29
25
  autofocus: {
30
26
  type: BooleanConstructor;
31
27
  reflect: boolean;
@@ -38,21 +34,33 @@ declare class SpectreRadioElement extends LitElement implements SpectreRadioProp
38
34
  type: BooleanConstructor;
39
35
  reflect: boolean;
40
36
  };
37
+ form: {
38
+ type: StringConstructor;
39
+ };
41
40
  invalid: {
42
41
  type: BooleanConstructor;
43
42
  reflect: boolean;
44
43
  };
44
+ loading: {
45
+ type: BooleanConstructor;
46
+ reflect: boolean;
47
+ };
45
48
  label: {
46
49
  type: StringConstructor;
47
50
  reflect: boolean;
48
51
  };
49
52
  name: {
50
53
  type: StringConstructor;
54
+ reflect: boolean;
51
55
  };
52
56
  required: {
53
57
  type: BooleanConstructor;
54
58
  reflect: boolean;
55
59
  };
60
+ success: {
61
+ type: BooleanConstructor;
62
+ reflect: boolean;
63
+ };
56
64
  title: {
57
65
  type: StringConstructor;
58
66
  reflect: boolean;
@@ -61,32 +69,24 @@ declare class SpectreRadioElement extends LitElement implements SpectreRadioProp
61
69
  type: StringConstructor;
62
70
  };
63
71
  };
64
- ariaLabel: string | null;
65
- ariaLabelledBy: string | null;
66
- ariaDescribedBy: string | null;
67
72
  autofocus: boolean;
68
73
  checked: boolean;
69
74
  disabled: boolean;
75
+ form?: string;
70
76
  invalid: boolean;
71
- label: string;
77
+ loading: boolean;
78
+ label?: string;
72
79
  name?: string;
73
80
  required: boolean;
81
+ success: boolean;
74
82
  title: string;
75
83
  value: string;
76
- private _id?;
77
- get id(): string;
78
- set id(value: string);
79
- createRenderRoot(): this;
80
- connectedCallback(): void;
81
- getAttribute(qualifiedName: string): string | null;
82
- hasAttribute(qualifiedName: string): boolean;
83
- setAttribute(qualifiedName: string, value: string): void;
84
- removeAttribute(qualifiedName: string): void;
84
+ protected getContentContainer(): Element | null;
85
+ protected isInternalNode(node: Node): boolean;
85
86
  protected willUpdate(changedProperties: Map<PropertyKey, unknown>): void;
86
87
  private get nativeInput();
87
- private get forwardedAriaLabel();
88
- private get forwardedAriaLabelledBy();
89
- private get forwardedAriaDescribedBy();
88
+ private get isDisabled();
89
+ private get visibleLabelFallback();
90
90
  private handleInput;
91
91
  private handleChange;
92
92
  focus(options?: FocusOptions): void;
package/dist/radio.d.ts CHANGED
@@ -1,31 +1,27 @@
1
1
  import * as lit_html from 'lit-html';
2
- import { LitElement } from 'lit';
2
+ import { S as SpectreProjectableElement } from './projectable-SzbPvXfM.js';
3
+ import './base-DQtCQ-dP.js';
4
+ import 'lit';
3
5
 
4
6
  interface SpectreRadioProps {
7
+ ariaLabel?: string | null;
8
+ ariaLabelledBy?: string | null;
9
+ ariaDescribedBy?: string | null;
5
10
  autofocus?: boolean;
6
11
  checked?: boolean;
7
12
  disabled?: boolean;
13
+ form?: string;
8
14
  invalid?: boolean;
9
- label?: string;
10
- name?: string;
15
+ loading?: boolean;
16
+ label?: string | undefined;
17
+ name?: string | undefined;
11
18
  required?: boolean;
19
+ success?: boolean;
12
20
  title?: string;
13
21
  value?: string;
14
22
  }
15
- declare class SpectreRadioElement extends LitElement implements SpectreRadioProps {
23
+ declare class SpectreRadioElement extends SpectreProjectableElement implements SpectreRadioProps {
16
24
  static properties: {
17
- ariaLabel: {
18
- attribute: string;
19
- type: StringConstructor;
20
- };
21
- ariaLabelledBy: {
22
- attribute: string;
23
- type: StringConstructor;
24
- };
25
- ariaDescribedBy: {
26
- attribute: string;
27
- type: StringConstructor;
28
- };
29
25
  autofocus: {
30
26
  type: BooleanConstructor;
31
27
  reflect: boolean;
@@ -38,21 +34,33 @@ declare class SpectreRadioElement extends LitElement implements SpectreRadioProp
38
34
  type: BooleanConstructor;
39
35
  reflect: boolean;
40
36
  };
37
+ form: {
38
+ type: StringConstructor;
39
+ };
41
40
  invalid: {
42
41
  type: BooleanConstructor;
43
42
  reflect: boolean;
44
43
  };
44
+ loading: {
45
+ type: BooleanConstructor;
46
+ reflect: boolean;
47
+ };
45
48
  label: {
46
49
  type: StringConstructor;
47
50
  reflect: boolean;
48
51
  };
49
52
  name: {
50
53
  type: StringConstructor;
54
+ reflect: boolean;
51
55
  };
52
56
  required: {
53
57
  type: BooleanConstructor;
54
58
  reflect: boolean;
55
59
  };
60
+ success: {
61
+ type: BooleanConstructor;
62
+ reflect: boolean;
63
+ };
56
64
  title: {
57
65
  type: StringConstructor;
58
66
  reflect: boolean;
@@ -61,32 +69,24 @@ declare class SpectreRadioElement extends LitElement implements SpectreRadioProp
61
69
  type: StringConstructor;
62
70
  };
63
71
  };
64
- ariaLabel: string | null;
65
- ariaLabelledBy: string | null;
66
- ariaDescribedBy: string | null;
67
72
  autofocus: boolean;
68
73
  checked: boolean;
69
74
  disabled: boolean;
75
+ form?: string;
70
76
  invalid: boolean;
71
- label: string;
77
+ loading: boolean;
78
+ label?: string;
72
79
  name?: string;
73
80
  required: boolean;
81
+ success: boolean;
74
82
  title: string;
75
83
  value: string;
76
- private _id?;
77
- get id(): string;
78
- set id(value: string);
79
- createRenderRoot(): this;
80
- connectedCallback(): void;
81
- getAttribute(qualifiedName: string): string | null;
82
- hasAttribute(qualifiedName: string): boolean;
83
- setAttribute(qualifiedName: string, value: string): void;
84
- removeAttribute(qualifiedName: string): void;
84
+ protected getContentContainer(): Element | null;
85
+ protected isInternalNode(node: Node): boolean;
85
86
  protected willUpdate(changedProperties: Map<PropertyKey, unknown>): void;
86
87
  private get nativeInput();
87
- private get forwardedAriaLabel();
88
- private get forwardedAriaLabelledBy();
89
- private get forwardedAriaDescribedBy();
88
+ private get isDisabled();
89
+ private get visibleLabelFallback();
90
90
  private handleInput;
91
91
  private handleChange;
92
92
  focus(options?: FocusOptions): void;
package/dist/radio.js CHANGED
@@ -1,21 +1,14 @@
1
- import { LitElement, html } from 'lit';
1
+ import { LitElement, html, nothing } from 'lit';
2
+ import { live } from 'lit/directives/live.js';
2
3
  import { ifDefined } from 'lit/directives/if-defined.js';
3
4
 
4
5
  // src/components/radio/sp-radio.ts
5
- var SpectreRadioElement = class extends LitElement {
6
+ var SpectreBaseElement = class extends LitElement {
6
7
  constructor() {
7
8
  super(...arguments);
8
9
  this.ariaLabel = null;
9
10
  this.ariaLabelledBy = null;
10
11
  this.ariaDescribedBy = null;
11
- this.autofocus = false;
12
- this.checked = false;
13
- this.disabled = false;
14
- this.invalid = false;
15
- this.label = "";
16
- this.required = false;
17
- this.title = "";
18
- this.value = "on";
19
12
  }
20
13
  get id() {
21
14
  return this._id ?? "";
@@ -31,6 +24,8 @@ var SpectreRadioElement = class extends LitElement {
31
24
  }
32
25
  this.requestUpdate();
33
26
  }
27
+ // Spectre components intentionally render in light DOM so the global
28
+ // `@phcdevworks/spectre-ui` styling contract can apply directly.
34
29
  createRenderRoot() {
35
30
  return this;
36
31
  }
@@ -67,14 +62,6 @@ var SpectreRadioElement = class extends LitElement {
67
62
  }
68
63
  super.removeAttribute(qualifiedName);
69
64
  }
70
- willUpdate(changedProperties) {
71
- if (changedProperties.has("value") && this.value == null) {
72
- this.value = "on";
73
- }
74
- }
75
- get nativeInput() {
76
- return this.querySelector("[data-sp-radio-native]");
77
- }
78
65
  get forwardedAriaLabel() {
79
66
  const value = this.ariaLabel?.trim();
80
67
  return value ? value : void 0;
@@ -87,6 +74,130 @@ var SpectreRadioElement = class extends LitElement {
87
74
  const value = this.ariaDescribedBy?.trim();
88
75
  return value ? value : void 0;
89
76
  }
77
+ };
78
+ SpectreBaseElement.properties = {
79
+ ariaLabel: { attribute: "aria-label", type: String },
80
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
81
+ ariaDescribedBy: { attribute: "aria-describedby", type: String }
82
+ };
83
+
84
+ // src/utils/dom.ts
85
+ function hasMeaningfulContent(nodes) {
86
+ return nodes.some((node) => {
87
+ if (node.nodeType === Node.ELEMENT_NODE) {
88
+ return true;
89
+ }
90
+ if (node.nodeType === Node.TEXT_NODE) {
91
+ return (node.textContent?.trim().length ?? 0) > 0;
92
+ }
93
+ return false;
94
+ });
95
+ }
96
+
97
+ // src/utils/projectable.ts
98
+ var SpectreProjectableElement = class extends SpectreBaseElement {
99
+ constructor() {
100
+ super(...arguments);
101
+ this.projectedContent = [];
102
+ }
103
+ get hasProjectedContent() {
104
+ return hasMeaningfulContent(this.projectedContent);
105
+ }
106
+ connectedCallback() {
107
+ super.connectedCallback();
108
+ this.syncProjectedContent();
109
+ this.startContentObserver();
110
+ }
111
+ disconnectedCallback() {
112
+ this.stopContentObserver();
113
+ super.disconnectedCallback();
114
+ }
115
+ update(changedProperties) {
116
+ this.stopContentObserver();
117
+ super.update(changedProperties);
118
+ this.startContentObserver();
119
+ }
120
+ syncProjectedContent() {
121
+ const nextProjectedContent = [];
122
+ const sourceNodes = [
123
+ ...this.childNodes,
124
+ ...this.getContentContainer()?.childNodes ?? []
125
+ ];
126
+ sourceNodes.forEach((node) => {
127
+ if (!this.isInternalNode(node) && !nextProjectedContent.includes(node)) {
128
+ nextProjectedContent.push(node);
129
+ }
130
+ });
131
+ const hasChanged = nextProjectedContent.length !== this.projectedContent.length || nextProjectedContent.some((node, index) => node !== this.projectedContent[index]);
132
+ if (hasChanged) {
133
+ this.projectedContent = nextProjectedContent;
134
+ }
135
+ return hasChanged;
136
+ }
137
+ startContentObserver() {
138
+ if (this.contentObserver) {
139
+ return;
140
+ }
141
+ this.contentObserver = new MutationObserver((mutations) => {
142
+ const isInternalMovement = mutations.every(
143
+ (mutation) => Array.from(mutation.removedNodes).every(
144
+ (node) => this.isInternalNode(node) || this.contains(node)
145
+ ) && Array.from(mutation.addedNodes).every((node) => this.isInternalNode(node))
146
+ );
147
+ if (isInternalMovement) {
148
+ return;
149
+ }
150
+ if (this.syncProjectedContent()) {
151
+ this.requestUpdate();
152
+ }
153
+ });
154
+ this.contentObserver.observe(this, { childList: true });
155
+ }
156
+ stopContentObserver() {
157
+ this.contentObserver?.disconnect();
158
+ this.contentObserver = void 0;
159
+ }
160
+ };
161
+
162
+ // src/components/radio/sp-radio.ts
163
+ var SpectreRadioElement = class extends SpectreProjectableElement {
164
+ constructor() {
165
+ super(...arguments);
166
+ this.autofocus = false;
167
+ this.checked = false;
168
+ this.disabled = false;
169
+ this.invalid = false;
170
+ this.loading = false;
171
+ this.required = false;
172
+ this.success = false;
173
+ this.title = "";
174
+ this.value = "on";
175
+ }
176
+ getContentContainer() {
177
+ return this.querySelector("[data-sp-radio-label]");
178
+ }
179
+ isInternalNode(node) {
180
+ if (node.nodeType !== Node.ELEMENT_NODE) {
181
+ return false;
182
+ }
183
+ const el = node;
184
+ return el.hasAttribute("data-sp-radio-label") || el.hasAttribute("data-sp-radio-native") || el.hasAttribute("data-sp-radio-label-fallback") || el.hasAttribute("data-sp-radio-indicator");
185
+ }
186
+ willUpdate(changedProperties) {
187
+ if (changedProperties.has("value") && this.value == null) {
188
+ this.value = "on";
189
+ }
190
+ }
191
+ get nativeInput() {
192
+ return this.querySelector("[data-sp-radio-native]");
193
+ }
194
+ get isDisabled() {
195
+ return this.disabled || this.loading;
196
+ }
197
+ get visibleLabelFallback() {
198
+ const trimmedLabel = this.label?.trim();
199
+ return trimmedLabel ? trimmedLabel : void 0;
200
+ }
90
201
  handleInput(event) {
91
202
  const input = event.currentTarget;
92
203
  this.checked = input.checked;
@@ -102,17 +213,20 @@ var SpectreRadioElement = class extends LitElement {
102
213
  this.nativeInput?.blur();
103
214
  }
104
215
  render() {
216
+ const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? html`<span class='sp-label' data-sp-radio-label-fallback>${this.visibleLabelFallback}</span>` : nothing;
105
217
  return html`
106
- <label>
218
+ <label data-sp-radio-label>
107
219
  <input
220
+ aria-busy=${this.loading ? "true" : "false"}
108
221
  aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
109
222
  aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
110
223
  aria-label=${ifDefined(this.forwardedAriaLabel)}
111
224
  aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
112
225
  ?autofocus=${this.autofocus}
113
226
  data-sp-radio-native
114
- ?checked=${this.checked}
115
- ?disabled=${this.disabled}
227
+ .checked=${live(this.checked)}
228
+ ?disabled=${this.isDisabled}
229
+ form=${ifDefined(this.form)}
116
230
  id=${ifDefined(this.id || void 0)}
117
231
  name=${ifDefined(this.name)}
118
232
  ?required=${this.required}
@@ -122,22 +236,23 @@ var SpectreRadioElement = class extends LitElement {
122
236
  @change=${this.handleChange}
123
237
  @input=${this.handleInput}
124
238
  />
125
- <span class='sp-label'>${this.label}</span>
239
+ <span class="sp-radio-indicator" data-sp-radio-indicator></span>
240
+ ${labelContent}
126
241
  </label>
127
242
  `;
128
243
  }
129
244
  };
130
245
  SpectreRadioElement.properties = {
131
- ariaLabel: { attribute: "aria-label", type: String },
132
- ariaLabelledBy: { attribute: "aria-labelledby", type: String },
133
- ariaDescribedBy: { attribute: "aria-describedby", type: String },
134
246
  autofocus: { type: Boolean, reflect: true },
135
247
  checked: { type: Boolean, reflect: true },
136
248
  disabled: { type: Boolean, reflect: true },
249
+ form: { type: String },
137
250
  invalid: { type: Boolean, reflect: true },
251
+ loading: { type: Boolean, reflect: true },
138
252
  label: { type: String, reflect: true },
139
- name: { type: String },
253
+ name: { type: String, reflect: true },
140
254
  required: { type: Boolean, reflect: true },
255
+ success: { type: Boolean, reflect: true },
141
256
  title: { type: String, reflect: true },
142
257
  value: { type: String }
143
258
  };
package/dist/radio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/radio/sp-radio.ts"],"names":[],"mappings":"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","file":"radio.js","sourcesContent":["import { LitElement, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport interface SpectreRadioProps {\n autofocus?: boolean;\n checked?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n label?: string;\n name?: string;\n required?: boolean;\n title?: string;\n value?: string;\n}\n\nexport class SpectreRadioElement extends LitElement implements SpectreRadioProps {\n static properties = {\n ariaLabel: { attribute: 'aria-label', type: String },\n ariaLabelledBy: { attribute: 'aria-labelledby', type: String },\n ariaDescribedBy: { attribute: 'aria-describedby', type: String },\n autofocus: { type: Boolean, reflect: true },\n checked: { type: Boolean, reflect: true },\n disabled: { type: Boolean, reflect: true },\n invalid: { type: Boolean, reflect: true },\n label: { type: String, reflect: true },\n name: { type: String },\n required: { type: Boolean, reflect: true },\n title: { type: String, reflect: true },\n value: { type: String },\n };\n\n ariaLabel: string | null = null;\n ariaLabelledBy: string | null = null;\n ariaDescribedBy: string | null = null;\n autofocus = false;\n checked = false;\n disabled = false;\n invalid = false;\n label = '';\n name?: string;\n required = false;\n override title = '';\n value = 'on';\n private _id?: string;\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\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 willUpdate(changedProperties: Map<PropertyKey, unknown>): void {\n if (changedProperties.has('value') && this.value == null) {\n this.value = 'on';\n }\n }\n\n private get nativeInput(): HTMLInputElement | null {\n return this.querySelector('[data-sp-radio-native]');\n }\n\n private get forwardedAriaLabel(): string | undefined {\n const value = this.ariaLabel?.trim();\n return value ? value : undefined;\n }\n\n private get forwardedAriaLabelledBy(): string | undefined {\n const value = this.ariaLabelledBy?.trim();\n return value ? value : undefined;\n }\n\n private get forwardedAriaDescribedBy(): string | undefined {\n const value = this.ariaDescribedBy?.trim();\n return value ? value : undefined;\n }\n\n private handleInput(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n private handleChange(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeInput?.focus(options);\n }\n\n override blur(): void {\n this.nativeInput?.blur();\n }\n\n override render() {\n return html`\n <label>\n <input\n aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}\n aria-invalid=${ifDefined(this.invalid ? 'true' : undefined)}\n aria-label=${ifDefined(this.forwardedAriaLabel)}\n aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}\n ?autofocus=${this.autofocus}\n data-sp-radio-native\n ?checked=${this.checked}\n ?disabled=${this.disabled}\n id=${ifDefined(this.id || undefined)}\n name=${ifDefined(this.name)}\n ?required=${this.required}\n title=${ifDefined(this.title || undefined)}\n type='radio'\n value=${ifDefined(this.value || undefined)}\n @change=${this.handleChange}\n @input=${this.handleInput}\n />\n <span class='sp-label'>${this.label}</span>\n </label>\n `;\n }\n}\n\nexport function defineSpectreRadio(tagName = 'sp-radio'): typeof SpectreRadioElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreRadioElement;\n }\n\n customElements.define(tagName, SpectreRadioElement);\n return SpectreRadioElement;\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/base.ts","../src/utils/dom.ts","../src/utils/projectable.ts","../src/components/radio/sp-radio.ts"],"names":[],"mappings":"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","file":"radio.js","sourcesContent":["import { LitElement, type PropertyDeclarations } from 'lit';\n\nexport class SpectreBaseElement extends LitElement {\n static properties: PropertyDeclarations = {\n ariaLabel: { attribute: 'aria-label', type: String },\n ariaLabelledBy: { attribute: 'aria-labelledby', type: String },\n ariaDescribedBy: { attribute: 'aria-describedby', type: String },\n };\n\n ariaLabel: string | null = null;\n ariaLabelledBy: string | null = null;\n ariaDescribedBy: string | null = null;\n\n private _id?: string;\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 // 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 hostId = super.getAttribute('id');\n if (hostId !== null) {\n this.id = hostId;\n }\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 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 Array.from(mutation.removedNodes).every(\n (node) => this.isInternalNode(node) || this.contains(node),\n ) &&\n Array.from(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 { live } from 'lit/directives/live.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { SpectreProjectableElement } from '../../utils/projectable';\n\nexport interface SpectreRadioProps {\n ariaLabel?: string | null;\n ariaLabelledBy?: string | null;\n ariaDescribedBy?: string | null;\n autofocus?: boolean;\n checked?: boolean;\n disabled?: boolean;\n form?: string;\n invalid?: boolean;\n loading?: boolean;\n label?: string | undefined;\n name?: string | undefined;\n required?: boolean;\n success?: boolean;\n title?: string;\n value?: string;\n}\n\nexport class SpectreRadioElement extends SpectreProjectableElement implements SpectreRadioProps {\n static properties = {\n autofocus: { type: Boolean, reflect: true },\n checked: { type: Boolean, reflect: true },\n disabled: { type: Boolean, reflect: true },\n form: { type: String },\n invalid: { type: Boolean, reflect: true },\n loading: { type: Boolean, reflect: true },\n label: { type: String, reflect: true },\n name: { type: String, reflect: true },\n required: { type: Boolean, reflect: true },\n success: { type: Boolean, reflect: true },\n title: { type: String, reflect: true },\n value: { type: String },\n };\n\n autofocus = false;\n checked = false;\n disabled = false;\n form?: string;\n invalid = false;\n loading = false;\n label?: string;\n name?: string;\n required = false;\n success = false;\n override title = '';\n value = 'on';\n\n protected override getContentContainer(): Element | null {\n return this.querySelector('[data-sp-radio-label]');\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 (\n el.hasAttribute('data-sp-radio-label') ||\n el.hasAttribute('data-sp-radio-native') ||\n el.hasAttribute('data-sp-radio-label-fallback') ||\n el.hasAttribute('data-sp-radio-indicator')\n );\n }\n\n protected override willUpdate(changedProperties: Map<PropertyKey, unknown>): void {\n if (changedProperties.has('value') && this.value == null) {\n this.value = 'on';\n }\n }\n\n private get nativeInput(): HTMLInputElement | null {\n return this.querySelector('[data-sp-radio-native]');\n }\n\n private get isDisabled(): boolean {\n return this.disabled || this.loading;\n }\n\n private get visibleLabelFallback(): string | undefined {\n const trimmedLabel = this.label?.trim();\n return trimmedLabel ? trimmedLabel : undefined;\n }\n\n private handleInput(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n private handleChange(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeInput?.focus(options);\n }\n\n override blur(): void {\n this.nativeInput?.blur();\n }\n\n override render() {\n const labelContent = this.hasProjectedContent\n ? this.projectedContent\n : this.visibleLabelFallback\n ? html`<span class='sp-label' data-sp-radio-label-fallback>${this.visibleLabelFallback}</span>`\n : nothing;\n\n return html`\n <label data-sp-radio-label>\n <input\n aria-busy=${this.loading ? 'true' : 'false'}\n aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}\n aria-invalid=${ifDefined(this.invalid ? 'true' : undefined)}\n aria-label=${ifDefined(this.forwardedAriaLabel)}\n aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}\n ?autofocus=${this.autofocus}\n data-sp-radio-native\n .checked=${live(this.checked)}\n ?disabled=${this.isDisabled}\n form=${ifDefined(this.form)}\n id=${ifDefined(this.id || undefined)}\n name=${ifDefined(this.name)}\n ?required=${this.required}\n title=${ifDefined(this.title || undefined)}\n type='radio'\n value=${ifDefined(this.value || undefined)}\n @change=${this.handleChange}\n @input=${this.handleInput}\n />\n <span class=\"sp-radio-indicator\" data-sp-radio-indicator></span>\n ${labelContent}\n </label>\n `;\n }\n}\n\nexport function defineSpectreRadio(tagName = 'sp-radio'): typeof SpectreRadioElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreRadioElement;\n }\n\n customElements.define(tagName, SpectreRadioElement);\n return SpectreRadioElement;\n}\n"]}