@sondor-technology/sondor-components 1.0.0 → 1.0.1-develop.2

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 (168) hide show
  1. package/README.md +8 -0
  2. package/dist/components/alert/alert.d.ts +13 -0
  3. package/dist/components/alert/alert.d.ts.map +1 -0
  4. package/dist/components/alert/alert.js +105 -0
  5. package/dist/components/badge/badge.d.ts +13 -0
  6. package/dist/components/badge/badge.d.ts.map +1 -0
  7. package/dist/components/badge/badge.js +101 -0
  8. package/dist/components/breadcrumb/breadcrumb.d.ts +19 -0
  9. package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -0
  10. package/dist/components/breadcrumb/breadcrumb.js +99 -0
  11. package/dist/components/button/button.d.ts +23 -0
  12. package/dist/components/button/button.d.ts.map +1 -0
  13. package/dist/components/button/button.js +304 -0
  14. package/dist/components/button-group/button-group.d.ts +6 -0
  15. package/dist/components/button-group/button-group.d.ts.map +1 -0
  16. package/dist/components/button-group/button-group.js +74 -0
  17. package/dist/components/card/card.d.ts +11 -0
  18. package/dist/components/card/card.d.ts.map +1 -0
  19. package/dist/components/card/card.js +54 -0
  20. package/dist/components/checkbox/checkbox.d.ts +28 -0
  21. package/dist/components/checkbox/checkbox.d.ts.map +1 -0
  22. package/dist/components/checkbox/checkbox.js +247 -0
  23. package/dist/components/code-block/code-block.d.ts +20 -0
  24. package/dist/components/code-block/code-block.d.ts.map +1 -0
  25. package/dist/components/code-block/code-block.js +260 -0
  26. package/dist/components/content-card/content-card.d.ts +13 -0
  27. package/dist/components/content-card/content-card.d.ts.map +1 -0
  28. package/dist/components/content-card/content-card.js +140 -0
  29. package/dist/components/divider/divider.d.ts +16 -0
  30. package/dist/components/divider/divider.d.ts.map +1 -0
  31. package/dist/components/divider/divider.js +82 -0
  32. package/dist/components/drawer/drawer.d.ts +22 -0
  33. package/dist/components/drawer/drawer.d.ts.map +1 -0
  34. package/dist/components/drawer/drawer.js +226 -0
  35. package/dist/components/field/field.d.ts +11 -0
  36. package/dist/components/field/field.d.ts.map +1 -0
  37. package/dist/components/field/field.js +32 -0
  38. package/dist/components/footer/footer.d.ts +6 -0
  39. package/dist/components/footer/footer.d.ts.map +1 -0
  40. package/dist/components/footer/footer.js +65 -0
  41. package/dist/components/form/form-step.d.ts +13 -0
  42. package/dist/components/form/form-step.d.ts.map +1 -0
  43. package/dist/components/form/form-step.js +41 -0
  44. package/dist/components/form/form.d.ts +25 -0
  45. package/dist/components/form/form.d.ts.map +1 -0
  46. package/dist/components/form/form.js +358 -0
  47. package/dist/components/grid/grid-row.d.ts +17 -0
  48. package/dist/components/grid/grid-row.d.ts.map +1 -0
  49. package/dist/components/grid/grid-row.js +92 -0
  50. package/dist/components/grid/grid.d.ts +13 -0
  51. package/dist/components/grid/grid.d.ts.map +1 -0
  52. package/dist/components/grid/grid.js +42 -0
  53. package/dist/components/icon/icon-paths.d.ts +116 -0
  54. package/dist/components/icon/icon-paths.d.ts.map +1 -0
  55. package/dist/components/icon/icon-paths.js +121 -0
  56. package/dist/components/icon/icon.d.ts +16 -0
  57. package/dist/components/icon/icon.d.ts.map +1 -0
  58. package/dist/components/icon/icon.js +95 -0
  59. package/dist/components/input/input.d.ts +31 -0
  60. package/dist/components/input/input.d.ts.map +1 -0
  61. package/dist/components/input/input.js +268 -0
  62. package/dist/components/link/link.d.ts +16 -0
  63. package/dist/components/link/link.d.ts.map +1 -0
  64. package/dist/components/link/link.js +116 -0
  65. package/dist/components/metadata/metadata.d.ts +18 -0
  66. package/dist/components/metadata/metadata.d.ts.map +1 -0
  67. package/dist/components/metadata/metadata.js +71 -0
  68. package/dist/components/modal/modal.d.ts +24 -0
  69. package/dist/components/modal/modal.d.ts.map +1 -0
  70. package/dist/components/modal/modal.js +163 -0
  71. package/dist/components/page-layout/page-layout.d.ts +46 -0
  72. package/dist/components/page-layout/page-layout.d.ts.map +1 -0
  73. package/dist/components/page-layout/page-layout.js +697 -0
  74. package/dist/components/radio/radio.d.ts +16 -0
  75. package/dist/components/radio/radio.d.ts.map +1 -0
  76. package/dist/components/radio/radio.js +152 -0
  77. package/dist/components/radio-group/radio-group.d.ts +27 -0
  78. package/dist/components/radio-group/radio-group.d.ts.map +1 -0
  79. package/dist/components/radio-group/radio-group.js +161 -0
  80. package/dist/components/router/router.d.ts +7 -0
  81. package/dist/components/router/router.d.ts.map +1 -0
  82. package/dist/components/router/router.js +37 -0
  83. package/dist/components/select/select.d.ts +16 -0
  84. package/dist/components/select/select.d.ts.map +1 -0
  85. package/dist/components/select/select.js +172 -0
  86. package/dist/components/skeleton/skeleton.d.ts +17 -0
  87. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  88. package/dist/components/skeleton/skeleton.js +78 -0
  89. package/dist/components/switch/switch.d.ts +25 -0
  90. package/dist/components/switch/switch.d.ts.map +1 -0
  91. package/dist/components/switch/switch.js +185 -0
  92. package/dist/components/table/data-table.d.ts +72 -0
  93. package/dist/components/table/data-table.d.ts.map +1 -0
  94. package/dist/components/table/data-table.js +551 -0
  95. package/dist/components/table/table.d.ts +22 -0
  96. package/dist/components/table/table.d.ts.map +1 -0
  97. package/dist/components/table/table.js +167 -0
  98. package/dist/components/tabs/tab-panel.d.ts +8 -0
  99. package/dist/components/tabs/tab-panel.d.ts.map +1 -0
  100. package/dist/components/tabs/tab-panel.js +46 -0
  101. package/dist/components/tabs/tab.d.ts +9 -0
  102. package/dist/components/tabs/tab.d.ts.map +1 -0
  103. package/dist/components/tabs/tab.js +91 -0
  104. package/dist/components/tabs/tabs.d.ts +14 -0
  105. package/dist/components/tabs/tabs.d.ts.map +1 -0
  106. package/dist/components/tabs/tabs.js +85 -0
  107. package/dist/components/textarea/textarea.d.ts +36 -0
  108. package/dist/components/textarea/textarea.d.ts.map +1 -0
  109. package/dist/components/textarea/textarea.js +231 -0
  110. package/dist/components/theme-toggle/theme-toggle.d.ts +15 -0
  111. package/dist/components/theme-toggle/theme-toggle.d.ts.map +1 -0
  112. package/dist/components/theme-toggle/theme-toggle.js +130 -0
  113. package/dist/components/vertical-nav/vertical-nav-group.d.ts +9 -0
  114. package/dist/components/vertical-nav/vertical-nav-group.d.ts.map +1 -0
  115. package/dist/components/vertical-nav/vertical-nav-group.js +111 -0
  116. package/dist/components/vertical-nav/vertical-nav-item.d.ts +8 -0
  117. package/dist/components/vertical-nav/vertical-nav-item.d.ts.map +1 -0
  118. package/dist/components/vertical-nav/vertical-nav-item.js +65 -0
  119. package/dist/styles/index.css +171 -0
  120. package/dist/styles/reset.d.ts +2 -0
  121. package/dist/styles/reset.d.ts.map +1 -0
  122. package/dist/styles/reset.js +50 -0
  123. package/package.json +3 -2
  124. package/src/components/alert/alert.ts +100 -100
  125. package/src/components/badge/badge.ts +96 -96
  126. package/src/components/breadcrumb/breadcrumb.ts +98 -98
  127. package/src/components/button/button.ts +281 -281
  128. package/src/components/button-group/button-group.ts +67 -67
  129. package/src/components/card/card.ts +52 -52
  130. package/src/components/checkbox/checkbox.ts +238 -238
  131. package/src/components/code-block/code-block.ts +256 -256
  132. package/src/components/content-card/content-card.ts +133 -133
  133. package/src/components/divider/divider.ts +68 -68
  134. package/src/components/drawer/drawer.ts +217 -217
  135. package/src/components/field/field.ts +30 -30
  136. package/src/components/footer/footer.ts +58 -58
  137. package/src/components/form/form-step.ts +32 -32
  138. package/src/components/form/form.ts +376 -376
  139. package/src/components/grid/grid-row.ts +75 -75
  140. package/src/components/grid/grid.ts +36 -36
  141. package/src/components/icon/icon-paths.ts +124 -124
  142. package/src/components/icon/icon.ts +82 -82
  143. package/src/components/input/input.ts +248 -248
  144. package/src/components/link/link.ts +97 -97
  145. package/src/components/metadata/metadata.ts +66 -66
  146. package/src/components/modal/modal.ts +158 -158
  147. package/src/components/page-layout/page-layout.ts +704 -704
  148. package/src/components/radio/radio.ts +142 -142
  149. package/src/components/radio-group/radio-group.ts +157 -157
  150. package/src/components/router/router.ts +46 -46
  151. package/src/components/select/select.ts +161 -161
  152. package/src/components/skeleton/skeleton.ts +67 -67
  153. package/src/components/switch/switch.ts +181 -181
  154. package/src/components/table/data-table.ts +556 -556
  155. package/src/components/table/table.ts +153 -153
  156. package/src/components/tabs/tab-panel.ts +30 -30
  157. package/src/components/tabs/tab.ts +76 -76
  158. package/src/components/tabs/tabs.ts +88 -88
  159. package/src/components/textarea/textarea.ts +215 -215
  160. package/src/components/theme-toggle/theme-toggle.ts +131 -131
  161. package/src/components/vertical-nav/vertical-nav-group.ts +96 -96
  162. package/src/components/vertical-nav/vertical-nav-item.ts +49 -49
  163. package/src/styles/globals.css +58 -58
  164. package/src/styles/index.css +80 -80
  165. package/src/styles/reset.ts +50 -50
  166. package/src/styles/theme.css +58 -58
  167. package/src/styles/typography.css +25 -25
  168. package/tsconfig.json +15 -15
@@ -1,238 +1,238 @@
1
- import {LitElement, html, css, PropertyValues} from "lit";
2
- import {customElement, property, query} from "lit/decorators.js";
3
- import {resetStyles} from "../../styles/reset.js";
4
-
5
- @customElement("st-checkbox")
6
- export class StCheckbox extends LitElement {
7
- static formAssociated = true;
8
- private _internals: ElementInternals;
9
-
10
- @query("input") private _inputEl!: HTMLInputElement;
11
-
12
- @property({type: String, reflect: true}) size: "sm" | "md" | "lg" = "md";
13
- @property({type: String, reflect: true}) name = "";
14
- // Checkboxes default to 'on' natively if no value is provided
15
- @property({type: String}) value = "on";
16
-
17
- @property({type: Boolean, reflect: true}) checked = false;
18
- @property({type: Boolean, reflect: true}) indeterminate = false;
19
-
20
- @property({type: Boolean, reflect: true}) disabled = false;
21
- @property({type: Boolean, reflect: true}) invalid = false;
22
- @property({type: Boolean, reflect: true}) required = false;
23
-
24
- @property({attribute: "aria-label"}) ariaLabel = "";
25
-
26
- constructor() {
27
- super();
28
- this._internals = this.attachInternals();
29
-
30
- // 1. Trigger error state if the user clicks away and the field is invalid
31
- this.addEventListener('focusout', () => {
32
- this.invalid = !this._inputEl.validity.valid;
33
- });
34
-
35
- // 2. Trigger error state if the st-form tries to submit and fails
36
- this.addEventListener('invalid', () => {
37
- this.invalid = true;
38
- });
39
- }
40
-
41
- static styles = [
42
- resetStyles,
43
- css`
44
- :host {
45
- display: inline-block;
46
- outline: none;
47
- user-select: none;
48
- --checkbox-size: 1.25rem;
49
- --checkbox-icon-size: 0.875rem;
50
- }
51
-
52
- :host([size="sm"]) {
53
- --checkbox-size: 1rem;
54
- --checkbox-icon-size: 0.75rem;
55
- }
56
- :host([size="lg"]) {
57
- --checkbox-size: 1.5rem;
58
- --checkbox-icon-size: 1rem;
59
- }
60
-
61
- label {
62
- display: inline-flex;
63
- align-items: flex-start;
64
- gap: var(--st-spacing-sm);
65
- cursor: pointer;
66
- color: var(--st-color-text);
67
- font-size: var(--st-font-size-base);
68
- }
69
-
70
- /* Visually hide the native input but keep it in the DOM for focus/screen readers */
71
- input {
72
- position: absolute;
73
- width: var(--checkbox-size);
74
- height: var(--checkbox-size);
75
- padding: 0;
76
- margin: -1px;
77
- overflow: hidden;
78
- clip: rect(0, 0, 0, 0);
79
- white-space: nowrap;
80
- border-width: 0;
81
- }
82
-
83
- /* Custom Checkbox Box */
84
- .control {
85
- display: flex;
86
- align-items: center;
87
- justify-content: center;
88
- width: var(--checkbox-size);
89
- height: var(--checkbox-size);
90
- border: 1px solid var(--st-color-border);
91
- border-radius: 4px;
92
- background-color: var(--st-color-bg);
93
- transition: all 0.2s ease;
94
- flex-shrink: 0;
95
- /* Aligns the box nicely with standard text line-height */
96
- margin-top: 0.125rem;
97
- }
98
-
99
- /* Hover State */
100
- label:hover .control {
101
- border-color: var(--st-color-primary-hover);
102
- }
103
-
104
- /* Focus State */
105
- input:focus-visible + .control {
106
- box-shadow:
107
- 0 0 0 2px var(--st-color-bg),
108
- 0 0 0 4px var(--st-color-primary);
109
- }
110
-
111
- /* Checked & Indeterminate States */
112
- :host([checked]) .control,
113
- :host([indeterminate]) .control {
114
- border-color: var(--st-color-primary);
115
- background-color: var(--st-color-primary);
116
- }
117
-
118
- /* SVG Icons */
119
- svg {
120
- width: var(--checkbox-icon-size);
121
- height: var(--checkbox-icon-size);
122
- stroke: var(--st-white);
123
- stroke-width: 3;
124
- stroke-linecap: round;
125
- stroke-linejoin: round;
126
- fill: none;
127
- opacity: 0;
128
- transform: scale(0.5);
129
- transition:
130
- transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275),
131
- opacity 0.2s ease;
132
- }
133
-
134
- /* Reveal Icons */
135
- :host([checked]) svg.icon-check,
136
- :host([indeterminate]) svg.icon-minus {
137
- opacity: 1;
138
- transform: scale(1);
139
- }
140
-
141
- /* Disabled State */
142
- :host([disabled]) {
143
- pointer-events: none;
144
- }
145
- :host([disabled]) label {
146
- opacity: 0.5;
147
- cursor: not-allowed;
148
- }
149
-
150
- /* Invalid State */
151
- :host([invalid]) .control {
152
- border-color: var(--st-color-error);
153
- }
154
- :host([invalid]) input:focus-visible + .control {
155
- box-shadow:
156
- 0 0 0 2px var(--st-color-bg),
157
- 0 0 0 4px var(--st-color-error);
158
- }
159
- `,
160
- ];
161
-
162
- override updated(changedProperties: PropertyValues<this>) {
163
- super.updated(changedProperties);
164
-
165
- if (changedProperties.has("checked") || changedProperties.has("value")) {
166
- // Form API: If checked, submit the value. If unchecked, submit null to remove it from FormData.
167
- this._internals.setFormValue(this.checked ? this.value : null);
168
- this._syncValidity();
169
- }
170
-
171
- if (changedProperties.has("required")) {
172
- this._syncValidity();
173
- }
174
- }
175
-
176
- private _syncValidity() {
177
- if (!this._inputEl) return;
178
- this._internals.setValidity(
179
- this._inputEl.validity,
180
- this._inputEl.validationMessage,
181
- this._inputEl,
182
- );
183
- }
184
-
185
- formResetCallback() {
186
- this.checked = false;
187
- this.indeterminate = false;
188
- this._internals.setFormValue(null);
189
- this.updateComplete.then(() => this._syncValidity());
190
- }
191
-
192
- private _handleChange(e: Event) {
193
- e.stopPropagation();
194
-
195
- if (this.disabled) return;
196
-
197
- // Standard native behavior: clicking an indeterminate checkbox unsets the indeterminate state
198
- if (this.indeterminate) {
199
- this.indeterminate = false;
200
- }
201
-
202
- this.checked = this._inputEl.checked;
203
- this.dispatchEvent(new Event("change", {bubbles: true, composed: true}));
204
- }
205
-
206
- render() {
207
- return html`
208
- <label>
209
- <input
210
- type="checkbox"
211
- aria-label=${this.ariaLabel || ""}
212
- .name=${this.name}
213
- .value=${this.value}
214
- .checked=${this.checked}
215
- .indeterminate=${this.indeterminate}
216
- ?disabled=${this.disabled}
217
- ?required=${this.required}
218
- @change=${this._handleChange}
219
- />
220
- <div class="control">
221
- <!-- Render both SVGs and use CSS to conditionally reveal them based on host attributes -->
222
- ${this.indeterminate
223
- ? html`<svg class="icon-minus" viewBox="0 0 24 24"><path d="M5 12h14"></path></svg>`
224
- : html`<svg class="icon-check" viewBox="0 0 24 24">
225
- <path d="M20 6L9 17l-5-5"></path>
226
- </svg>`}
227
- </div>
228
- <span class="label"><slot></slot></span>
229
- </label>
230
- `;
231
- }
232
- }
233
-
234
- declare global {
235
- interface HTMLElementTagNameMap {
236
- "st-checkbox": StCheckbox;
237
- }
238
- }
1
+ import {LitElement, html, css, PropertyValues} from "lit";
2
+ import {customElement, property, query} from "lit/decorators.js";
3
+ import {resetStyles} from "../../styles/reset.js";
4
+
5
+ @customElement("st-checkbox")
6
+ export class StCheckbox extends LitElement {
7
+ static formAssociated = true;
8
+ private _internals: ElementInternals;
9
+
10
+ @query("input") private _inputEl!: HTMLInputElement;
11
+
12
+ @property({type: String, reflect: true}) size: "sm" | "md" | "lg" = "md";
13
+ @property({type: String, reflect: true}) name = "";
14
+ // Checkboxes default to 'on' natively if no value is provided
15
+ @property({type: String}) value = "on";
16
+
17
+ @property({type: Boolean, reflect: true}) checked = false;
18
+ @property({type: Boolean, reflect: true}) indeterminate = false;
19
+
20
+ @property({type: Boolean, reflect: true}) disabled = false;
21
+ @property({type: Boolean, reflect: true}) invalid = false;
22
+ @property({type: Boolean, reflect: true}) required = false;
23
+
24
+ @property({attribute: "aria-label"}) ariaLabel = "";
25
+
26
+ constructor() {
27
+ super();
28
+ this._internals = this.attachInternals();
29
+
30
+ // 1. Trigger error state if the user clicks away and the field is invalid
31
+ this.addEventListener('focusout', () => {
32
+ this.invalid = !this._inputEl.validity.valid;
33
+ });
34
+
35
+ // 2. Trigger error state if the st-form tries to submit and fails
36
+ this.addEventListener('invalid', () => {
37
+ this.invalid = true;
38
+ });
39
+ }
40
+
41
+ static styles = [
42
+ resetStyles,
43
+ css`
44
+ :host {
45
+ display: inline-block;
46
+ outline: none;
47
+ user-select: none;
48
+ --checkbox-size: 1.25rem;
49
+ --checkbox-icon-size: 0.875rem;
50
+ }
51
+
52
+ :host([size="sm"]) {
53
+ --checkbox-size: 1rem;
54
+ --checkbox-icon-size: 0.75rem;
55
+ }
56
+ :host([size="lg"]) {
57
+ --checkbox-size: 1.5rem;
58
+ --checkbox-icon-size: 1rem;
59
+ }
60
+
61
+ label {
62
+ display: inline-flex;
63
+ align-items: flex-start;
64
+ gap: var(--st-spacing-sm);
65
+ cursor: pointer;
66
+ color: var(--st-color-text);
67
+ font-size: var(--st-font-size-base);
68
+ }
69
+
70
+ /* Visually hide the native input but keep it in the DOM for focus/screen readers */
71
+ input {
72
+ position: absolute;
73
+ width: var(--checkbox-size);
74
+ height: var(--checkbox-size);
75
+ padding: 0;
76
+ margin: -1px;
77
+ overflow: hidden;
78
+ clip: rect(0, 0, 0, 0);
79
+ white-space: nowrap;
80
+ border-width: 0;
81
+ }
82
+
83
+ /* Custom Checkbox Box */
84
+ .control {
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ width: var(--checkbox-size);
89
+ height: var(--checkbox-size);
90
+ border: 1px solid var(--st-color-border);
91
+ border-radius: 4px;
92
+ background-color: var(--st-color-bg);
93
+ transition: all 0.2s ease;
94
+ flex-shrink: 0;
95
+ /* Aligns the box nicely with standard text line-height */
96
+ margin-top: 0.125rem;
97
+ }
98
+
99
+ /* Hover State */
100
+ label:hover .control {
101
+ border-color: var(--st-color-primary-hover);
102
+ }
103
+
104
+ /* Focus State */
105
+ input:focus-visible + .control {
106
+ box-shadow:
107
+ 0 0 0 2px var(--st-color-bg),
108
+ 0 0 0 4px var(--st-color-primary);
109
+ }
110
+
111
+ /* Checked & Indeterminate States */
112
+ :host([checked]) .control,
113
+ :host([indeterminate]) .control {
114
+ border-color: var(--st-color-primary);
115
+ background-color: var(--st-color-primary);
116
+ }
117
+
118
+ /* SVG Icons */
119
+ svg {
120
+ width: var(--checkbox-icon-size);
121
+ height: var(--checkbox-icon-size);
122
+ stroke: var(--st-white);
123
+ stroke-width: 3;
124
+ stroke-linecap: round;
125
+ stroke-linejoin: round;
126
+ fill: none;
127
+ opacity: 0;
128
+ transform: scale(0.5);
129
+ transition:
130
+ transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275),
131
+ opacity 0.2s ease;
132
+ }
133
+
134
+ /* Reveal Icons */
135
+ :host([checked]) svg.icon-check,
136
+ :host([indeterminate]) svg.icon-minus {
137
+ opacity: 1;
138
+ transform: scale(1);
139
+ }
140
+
141
+ /* Disabled State */
142
+ :host([disabled]) {
143
+ pointer-events: none;
144
+ }
145
+ :host([disabled]) label {
146
+ opacity: 0.5;
147
+ cursor: not-allowed;
148
+ }
149
+
150
+ /* Invalid State */
151
+ :host([invalid]) .control {
152
+ border-color: var(--st-color-error);
153
+ }
154
+ :host([invalid]) input:focus-visible + .control {
155
+ box-shadow:
156
+ 0 0 0 2px var(--st-color-bg),
157
+ 0 0 0 4px var(--st-color-error);
158
+ }
159
+ `,
160
+ ];
161
+
162
+ override updated(changedProperties: PropertyValues<this>) {
163
+ super.updated(changedProperties);
164
+
165
+ if (changedProperties.has("checked") || changedProperties.has("value")) {
166
+ // Form API: If checked, submit the value. If unchecked, submit null to remove it from FormData.
167
+ this._internals.setFormValue(this.checked ? this.value : null);
168
+ this._syncValidity();
169
+ }
170
+
171
+ if (changedProperties.has("required")) {
172
+ this._syncValidity();
173
+ }
174
+ }
175
+
176
+ private _syncValidity() {
177
+ if (!this._inputEl) return;
178
+ this._internals.setValidity(
179
+ this._inputEl.validity,
180
+ this._inputEl.validationMessage,
181
+ this._inputEl,
182
+ );
183
+ }
184
+
185
+ formResetCallback() {
186
+ this.checked = false;
187
+ this.indeterminate = false;
188
+ this._internals.setFormValue(null);
189
+ this.updateComplete.then(() => this._syncValidity());
190
+ }
191
+
192
+ private _handleChange(e: Event) {
193
+ e.stopPropagation();
194
+
195
+ if (this.disabled) return;
196
+
197
+ // Standard native behavior: clicking an indeterminate checkbox unsets the indeterminate state
198
+ if (this.indeterminate) {
199
+ this.indeterminate = false;
200
+ }
201
+
202
+ this.checked = this._inputEl.checked;
203
+ this.dispatchEvent(new Event("change", {bubbles: true, composed: true}));
204
+ }
205
+
206
+ render() {
207
+ return html`
208
+ <label>
209
+ <input
210
+ type="checkbox"
211
+ aria-label=${this.ariaLabel || ""}
212
+ .name=${this.name}
213
+ .value=${this.value}
214
+ .checked=${this.checked}
215
+ .indeterminate=${this.indeterminate}
216
+ ?disabled=${this.disabled}
217
+ ?required=${this.required}
218
+ @change=${this._handleChange}
219
+ />
220
+ <div class="control">
221
+ <!-- Render both SVGs and use CSS to conditionally reveal them based on host attributes -->
222
+ ${this.indeterminate
223
+ ? html`<svg class="icon-minus" viewBox="0 0 24 24"><path d="M5 12h14"></path></svg>`
224
+ : html`<svg class="icon-check" viewBox="0 0 24 24">
225
+ <path d="M20 6L9 17l-5-5"></path>
226
+ </svg>`}
227
+ </div>
228
+ <span class="label"><slot></slot></span>
229
+ </label>
230
+ `;
231
+ }
232
+ }
233
+
234
+ declare global {
235
+ interface HTMLElementTagNameMap {
236
+ "st-checkbox": StCheckbox;
237
+ }
238
+ }