@sondor-technology/sondor-components 1.0.3 → 1.0.5

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 (42) hide show
  1. package/dist/components/button-group/button-group.d.ts +5 -0
  2. package/dist/components/button-group/button-group.d.ts.map +1 -1
  3. package/dist/components/checkbox/checkbox.d.ts +3 -0
  4. package/dist/components/checkbox/checkbox.d.ts.map +1 -1
  5. package/dist/components/checkbox/checkbox.js +38 -20
  6. package/dist/components/code-block/code-block.d.ts +5 -0
  7. package/dist/components/code-block/code-block.d.ts.map +1 -1
  8. package/dist/components/form/form-step.d.ts +1 -0
  9. package/dist/components/form/form-step.d.ts.map +1 -1
  10. package/dist/components/form/form-step.js +3 -0
  11. package/dist/components/form/form.d.ts +7 -2
  12. package/dist/components/form/form.d.ts.map +1 -1
  13. package/dist/components/form/form.js +157 -59
  14. package/dist/components/icon/icon.d.ts +2 -1
  15. package/dist/components/icon/icon.d.ts.map +1 -1
  16. package/dist/components/input/input.d.ts +5 -0
  17. package/dist/components/input/input.d.ts.map +1 -1
  18. package/dist/components/page-layout/page-layout.js +1 -1
  19. package/dist/components/select/select.d.ts +43 -7
  20. package/dist/components/select/select.d.ts.map +1 -1
  21. package/dist/components/select/select.js +458 -150
  22. package/dist/components/tabs/tab-panel.d.ts +5 -0
  23. package/dist/components/tabs/tab-panel.d.ts.map +1 -1
  24. package/dist/components/tabs/tab.d.ts +5 -0
  25. package/dist/components/tabs/tab.d.ts.map +1 -1
  26. package/dist/components/tabs/tabs.d.ts +5 -0
  27. package/dist/components/tabs/tabs.d.ts.map +1 -1
  28. package/dist/styles/index.css +2 -0
  29. package/package.json +1 -1
  30. package/src/components/button-group/button-group.ts +6 -0
  31. package/src/components/checkbox/checkbox.ts +54 -26
  32. package/src/components/code-block/code-block.ts +6 -0
  33. package/src/components/form/form-step.ts +5 -1
  34. package/src/components/form/form.ts +182 -66
  35. package/src/components/icon/icon.ts +3 -1
  36. package/src/components/input/input.ts +6 -0
  37. package/src/components/page-layout/page-layout.ts +1 -1
  38. package/src/components/select/select.ts +502 -130
  39. package/src/components/tabs/tab-panel.ts +5 -0
  40. package/src/components/tabs/tab.ts +6 -0
  41. package/src/components/tabs/tabs.ts +6 -0
  42. package/src/styles/theme.css +2 -0
@@ -3,4 +3,9 @@ export declare class StButtonGroup extends LitElement {
3
3
  static styles: import("lit").CSSResult[];
4
4
  render(): import("lit-html").TemplateResult<1>;
5
5
  }
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "st-button-group": StButtonGroup;
9
+ }
10
+ }
6
11
  //# sourceMappingURL=button-group.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-group.d.ts","sourceRoot":"","sources":["../../../src/components/button-group/button-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAI1C,qBACa,aAAc,SAAQ,UAAU;IAC3C,MAAM,CAAC,MAAM,4BAmDX;IAEF,MAAM,yCAML;CACF"}
1
+ {"version":3,"file":"button-group.d.ts","sourceRoot":"","sources":["../../../src/components/button-group/button-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAI1C,qBACa,aAAc,SAAQ,UAAU;IAC3C,MAAM,CAAC,MAAM,4BAmDX;IAEF,MAAM,yCAML;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
@@ -11,11 +11,14 @@ export declare class StCheckbox extends LitElement {
11
11
  disabled: boolean;
12
12
  invalid: boolean;
13
13
  required: boolean;
14
+ errorMessage: string;
14
15
  ariaLabel: string;
15
16
  constructor();
16
17
  static styles: import("lit").CSSResult[];
17
18
  updated(changedProperties: PropertyValues<this>): void;
18
19
  private _syncValidity;
20
+ checkValidity(): boolean;
21
+ reportValidity(): boolean;
19
22
  formResetCallback(): void;
20
23
  private _handleChange;
21
24
  render(): import("lit-html").TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAa,cAAc,EAAC,MAAM,KAAK,CAAC;AAI1D,qBACa,UAAW,SAAQ,UAAU;IACxC,MAAM,CAAC,cAAc,UAAQ;IAC7B,OAAO,CAAC,UAAU,CAAmB;IAErB,OAAO,CAAC,QAAQ,CAAoB;IAEX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAChC,IAAI,SAAM;IAEzB,KAAK,SAAQ;IAEG,OAAO,UAAS;IAChB,aAAa,UAAS;IAEtB,QAAQ,UAAS;IACjB,OAAO,UAAS;IAChB,QAAQ,UAAS;IAEtB,SAAS,SAAM;IAEtD,cAaG;IAED,MAAM,CAAC,MAAM,4BAuHX;IAEO,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,QAYvD;IAED,OAAO,CAAC,aAAa;IASrB,iBAAiB,SAKhB;IAED,OAAO,CAAC,aAAa;IAcrB,MAAM,yCAyBL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAa,cAAc,EAAC,MAAM,KAAK,CAAC;AAI1D,qBACa,UAAW,SAAQ,UAAU;IACxC,MAAM,CAAC,cAAc,UAAQ;IAC7B,OAAO,CAAC,UAAU,CAAmB;IAErB,OAAO,CAAC,QAAQ,CAAoB;IAEX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAChC,IAAI,SAAM;IACzB,KAAK,SAAQ;IAEG,OAAO,UAAS;IAChB,aAAa,UAAS;IAEtB,QAAQ,UAAS;IACjB,OAAO,UAAS;IAChB,QAAQ,UAAS;IACjC,YAAY,SAAM;IAEP,SAAS,SAAM;IAEpD,cAWC;IAED,MAAM,CAAC,MAAM,4BA6GX;IAEO,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,QAWvD;IAED,OAAO,CAAC,aAAa;IAmBd,aAAa,IAAI,OAAO,CAkB9B;IAEM,cAAc,IAAI,OAAO,CAK/B;IAED,iBAAiB,SAMhB;IAED,OAAO,CAAC,aAAa;IAkBrB,MAAM,yCAwBL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
@@ -12,28 +12,25 @@ let StCheckbox = class StCheckbox extends LitElement {
12
12
  super();
13
13
  this.size = "md";
14
14
  this.name = "";
15
- // Checkboxes default to 'on' natively if no value is provided
16
15
  this.value = "on";
17
16
  this.checked = false;
18
17
  this.indeterminate = false;
19
18
  this.disabled = false;
20
19
  this.invalid = false;
21
20
  this.required = false;
21
+ this.errorMessage = "";
22
22
  this.ariaLabel = "";
23
23
  this._internals = this.attachInternals();
24
- // 1. Trigger error state if the user clicks away and the field is invalid
25
24
  this.addEventListener('focusout', () => {
26
- this.invalid = !this._inputEl.validity.valid;
25
+ this.invalid = !this.checkValidity();
27
26
  });
28
- // 2. Trigger error state if the st-form tries to submit and fails
29
27
  this.addEventListener('invalid', () => {
30
- this.invalid = true;
28
+ this.invalid = !this.checkValidity();
31
29
  });
32
30
  }
33
31
  updated(changedProperties) {
34
32
  super.updated(changedProperties);
35
- if (changedProperties.has("checked") || changedProperties.has("value")) {
36
- // Form API: If checked, submit the value. If unchecked, submit null to remove it from FormData.
33
+ if (changedProperties.has("checked") || changedProperties.has("value") || changedProperties.has("errorMessage")) {
37
34
  this._internals.setFormValue(this.checked ? this.value : null);
38
35
  this._syncValidity();
39
36
  }
@@ -44,11 +41,38 @@ let StCheckbox = class StCheckbox extends LitElement {
44
41
  _syncValidity() {
45
42
  if (!this._inputEl)
46
43
  return;
47
- this._internals.setValidity(this._inputEl.validity, this._inputEl.validationMessage, this._inputEl);
44
+ if (this.required && !this.checked) {
45
+ const message = this.errorMessage || this._inputEl.validationMessage || "Please check this box if you want to proceed.";
46
+ this._internals.setValidity({ valueMissing: true }, message, this._inputEl);
47
+ }
48
+ else {
49
+ this._internals.setValidity(this._inputEl.validity, this._inputEl.validationMessage, this._inputEl);
50
+ }
51
+ }
52
+ checkValidity() {
53
+ if (!this._inputEl)
54
+ return true;
55
+ if (this.required && !this.checked) {
56
+ const message = this.errorMessage || this._inputEl.validationMessage || "Please check this box if you want to proceed.";
57
+ this._internals.setValidity({ valueMissing: true }, message, this._inputEl);
58
+ this.invalid = true;
59
+ return false;
60
+ }
61
+ const isValid = this._inputEl.checkValidity();
62
+ this._syncValidity();
63
+ this.invalid = !isValid;
64
+ return isValid;
65
+ }
66
+ reportValidity() {
67
+ this._syncValidity();
68
+ const isValid = this._internals.reportValidity();
69
+ this.invalid = !isValid;
70
+ return isValid;
48
71
  }
49
72
  formResetCallback() {
50
73
  this.checked = false;
51
74
  this.indeterminate = false;
75
+ this.invalid = false;
52
76
  this._internals.setFormValue(null);
53
77
  this.updateComplete.then(() => this._syncValidity());
54
78
  }
@@ -56,11 +80,13 @@ let StCheckbox = class StCheckbox extends LitElement {
56
80
  e.stopPropagation();
57
81
  if (this.disabled)
58
82
  return;
59
- // Standard native behavior: clicking an indeterminate checkbox unsets the indeterminate state
60
83
  if (this.indeterminate) {
61
84
  this.indeterminate = false;
62
85
  }
63
86
  this.checked = this._inputEl.checked;
87
+ if (this.checkValidity()) {
88
+ this.invalid = false;
89
+ }
64
90
  this.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
65
91
  }
66
92
  render() {
@@ -78,7 +104,6 @@ let StCheckbox = class StCheckbox extends LitElement {
78
104
  @change=${this._handleChange}
79
105
  />
80
106
  <div class="control">
81
- <!-- Render both SVGs and use CSS to conditionally reveal them based on host attributes -->
82
107
  ${this.indeterminate
83
108
  ? html `<svg class="icon-minus" viewBox="0 0 24 24"><path d="M5 12h14"></path></svg>`
84
109
  : html `<svg class="icon-check" viewBox="0 0 24 24">
@@ -120,7 +145,6 @@ StCheckbox.styles = [
120
145
  font-size: var(--st-font-size-base);
121
146
  }
122
147
 
123
- /* Visually hide the native input but keep it in the DOM for focus/screen readers */
124
148
  input {
125
149
  position: absolute;
126
150
  width: var(--checkbox-size);
@@ -133,7 +157,6 @@ StCheckbox.styles = [
133
157
  border-width: 0;
134
158
  }
135
159
 
136
- /* Custom Checkbox Box */
137
160
  .control {
138
161
  display: flex;
139
162
  align-items: center;
@@ -145,30 +168,25 @@ StCheckbox.styles = [
145
168
  background-color: var(--st-color-bg);
146
169
  transition: all 0.2s ease;
147
170
  flex-shrink: 0;
148
- /* Aligns the box nicely with standard text line-height */
149
171
  margin-top: 0.125rem;
150
172
  }
151
173
 
152
- /* Hover State */
153
174
  label:hover .control {
154
175
  border-color: var(--st-color-primary-hover);
155
176
  }
156
177
 
157
- /* Focus State */
158
178
  input:focus-visible + .control {
159
179
  box-shadow:
160
180
  0 0 0 2px var(--st-color-bg),
161
181
  0 0 0 4px var(--st-color-primary);
162
182
  }
163
183
 
164
- /* Checked & Indeterminate States */
165
184
  :host([checked]) .control,
166
185
  :host([indeterminate]) .control {
167
186
  border-color: var(--st-color-primary);
168
187
  background-color: var(--st-color-primary);
169
188
  }
170
189
 
171
- /* SVG Icons */
172
190
  svg {
173
191
  width: var(--checkbox-icon-size);
174
192
  height: var(--checkbox-icon-size);
@@ -184,14 +202,12 @@ StCheckbox.styles = [
184
202
  opacity 0.2s ease;
185
203
  }
186
204
 
187
- /* Reveal Icons */
188
205
  :host([checked]) svg.icon-check,
189
206
  :host([indeterminate]) svg.icon-minus {
190
207
  opacity: 1;
191
208
  transform: scale(1);
192
209
  }
193
210
 
194
- /* Disabled State */
195
211
  :host([disabled]) {
196
212
  pointer-events: none;
197
213
  }
@@ -200,7 +216,6 @@ StCheckbox.styles = [
200
216
  cursor: not-allowed;
201
217
  }
202
218
 
203
- /* Invalid State */
204
219
  :host([invalid]) .control {
205
220
  border-color: var(--st-color-error);
206
221
  }
@@ -238,6 +253,9 @@ __decorate([
238
253
  __decorate([
239
254
  property({ type: Boolean, reflect: true })
240
255
  ], StCheckbox.prototype, "required", void 0);
256
+ __decorate([
257
+ property({ type: String })
258
+ ], StCheckbox.prototype, "errorMessage", void 0);
241
259
  __decorate([
242
260
  property({ attribute: "aria-label" })
243
261
  ], StCheckbox.prototype, "ariaLabel", void 0);
@@ -17,4 +17,9 @@ export declare class StCodeBlock extends LitElement {
17
17
  private _copyToClipboard;
18
18
  render(): import("lit-html").TemplateResult<1>;
19
19
  }
20
+ declare global {
21
+ interface HTMLElementTagNameMap {
22
+ "st-code-block": StCodeBlock;
23
+ }
24
+ }
20
25
  //# sourceMappingURL=code-block.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../../src/components/code-block/code-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAM5C,OAAO,wCAAwC,CAAC;AAChD,OAAO,wCAAwC,CAAC;AAChD,OAAO,iCAAiC,CAAC;AACzC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAS5C,qBACa,WAAY,SAAQ,UAAU;IAEb,QAAQ,SAAgB;IAE3C,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAAS;IAEN,OAAO,CAAC,KAAK,CAAmB;IAE3D,MAAM,CAAC,MAAM,4BAyHX;IAEF,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,OAAO;YAaD,gBAAgB;IAc9B,MAAM,yCAwCL;CACF"}
1
+ {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../../src/components/code-block/code-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAM5C,OAAO,wCAAwC,CAAC;AAChD,OAAO,wCAAwC,CAAC;AAChD,OAAO,iCAAiC,CAAC;AACzC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAS5C,qBACa,WAAY,SAAQ,UAAU;IAEb,QAAQ,SAAgB;IAE3C,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAAS;IAEN,OAAO,CAAC,KAAK,CAAmB;IAE3D,MAAM,CAAC,MAAM,4BAyHX;IAEF,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,OAAO;YAaD,gBAAgB;IAc9B,MAAM,yCAwCL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,WAAW,CAAC;KAC9B;CACF"}
@@ -2,6 +2,7 @@ import { LitElement } from "lit";
2
2
  export declare class StFormStep extends LitElement {
3
3
  title: string;
4
4
  active: boolean;
5
+ validate?: () => Promise<boolean> | boolean;
5
6
  static styles: import("lit").CSSResult[];
6
7
  render(): import("lit-html").TemplateResult<1>;
7
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"form-step.d.ts","sourceRoot":"","sources":["../../../src/components/form/form-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAI1C,qBACa,UAAW,SAAQ,UAAU;IACd,KAAK,SAAM;IACK,MAAM,UAAS;IAEzD,MAAM,CAAC,MAAM,4BAWX;IAEF,MAAM,yCAEL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
1
+ {"version":3,"file":"form-step.d.ts","sourceRoot":"","sources":["../../../src/components/form/form-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAI1C,qBACa,UAAW,SAAQ,UAAU;IACd,KAAK,SAAM;IACK,MAAM,UAAS;IAIzD,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAE5C,MAAM,CAAC,MAAM,4BAWX;IAEF,MAAM,yCAEL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
@@ -35,6 +35,9 @@ __decorate([
35
35
  __decorate([
36
36
  property({ type: Boolean, reflect: true })
37
37
  ], StFormStep.prototype, "active", void 0);
38
+ __decorate([
39
+ property({ attribute: false })
40
+ ], StFormStep.prototype, "validate", void 0);
38
41
  StFormStep = __decorate([
39
42
  customElement("st-form-step")
40
43
  ], StFormStep);
@@ -1,13 +1,18 @@
1
- import { LitElement } from "lit";
1
+ import { LitElement, PropertyValues } from "lit";
2
2
  export type FormLayout = "vertical" | "horizontal" | "inline";
3
3
  export declare class StForm extends LitElement {
4
4
  layout: FormLayout;
5
5
  loading: boolean;
6
6
  error: string;
7
7
  private _currentStepIndex;
8
- private _stepElements;
9
8
  private _formEl;
9
+ private _modalFooterEl;
10
+ private get _steps();
10
11
  static styles: import("lit").CSSResult[];
12
+ connectedCallback(): void;
13
+ disconnectedCallback(): void;
14
+ updated(changedProperties: PropertyValues<this>): void;
15
+ private _updateModalFooter;
11
16
  private _handleSlotChange;
12
17
  private _updateStepVisibility;
13
18
  private _validateCurrentContext;
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/components/form/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAK1C,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE9D,qBACa,MAAO,SAAQ,UAAU;IACK,MAAM,EAAE,UAAU,CAAc;IAC/B,OAAO,UAAS;IAChC,KAAK,SAAM;IAE5B,OAAO,CAAC,iBAAiB,CAAK;IAGvC,OAAO,CAAC,aAAa,CAAgB;IAEtB,OAAO,CAAC,OAAO,CAAmB;IAEjD,MAAM,CAAC,MAAM,4BA8IX;IAEF,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,uBAAuB;IA8B/B,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,aAAa;IA4BrB,MAAM,yCAkFL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/components/form/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAa,cAAc,EAAC,MAAM,KAAK,CAAC;AAK1D,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE9D,qBACa,MAAO,SAAQ,UAAU;IACK,MAAM,EAAE,UAAU,CAAc;IAC/B,OAAO,UAAS;IAChC,KAAK,SAAM;IAE5B,OAAO,CAAC,iBAAiB,CAAK;IAExB,OAAO,CAAC,OAAO,CAAmB;IAEjD,OAAO,CAAC,cAAc,CAA4B;IAElD,OAAO,KAAK,MAAM,GAEjB;IAED,MAAM,CAAC,MAAM,4BAqIX;IAEO,iBAAiB,SAMzB;IAEQ,oBAAoB,SAM5B;IAEQ,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,QAGvD;IAED,OAAO,CAAC,kBAAkB;IAmD1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,qBAAqB;YAQf,uBAAuB;IAiFrC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,gBAAgB;YAkCV,aAAa;IA6B3B,MAAM,yCAsFL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { LitElement, html, css } from "lit";
8
- import { customElement, property, state, queryAssignedElements, query } from "lit/decorators.js";
8
+ import { customElement, property, state, query } from "lit/decorators.js";
9
9
  import { resetStyles } from "../../styles/reset.js";
10
10
  let StForm = class StForm extends LitElement {
11
11
  constructor() {
@@ -14,41 +14,151 @@ let StForm = class StForm extends LitElement {
14
14
  this.loading = false;
15
15
  this.error = "";
16
16
  this._currentStepIndex = 0;
17
+ this._modalFooterEl = null;
17
18
  }
18
- _handleSlotChange() {
19
- if (this._stepElements.length > 0) {
19
+ get _steps() {
20
+ return Array.from(this.querySelectorAll("st-form-step"));
21
+ }
22
+ connectedCallback() {
23
+ super.connectedCallback();
24
+ this.updateComplete.then(() => {
20
25
  this._updateStepVisibility();
26
+ this._updateModalFooter();
27
+ });
28
+ }
29
+ disconnectedCallback() {
30
+ super.disconnectedCallback();
31
+ if (this._modalFooterEl) {
32
+ this._modalFooterEl.remove();
33
+ this._modalFooterEl = null;
21
34
  }
22
35
  }
36
+ updated(changedProperties) {
37
+ super.updated(changedProperties);
38
+ this._updateModalFooter();
39
+ }
40
+ _updateModalFooter() {
41
+ const modal = this.closest("st-modal");
42
+ if (modal) {
43
+ if (!this._modalFooterEl) {
44
+ this._modalFooterEl = document.createElement("div");
45
+ this._modalFooterEl.setAttribute("slot", "footer");
46
+ this._modalFooterEl.style.display = "flex";
47
+ this._modalFooterEl.style.gap = "var(--st-spacing-md)";
48
+ this._modalFooterEl.style.width = "100%";
49
+ this._modalFooterEl.style.justifyContent = "flex-end";
50
+ this._modalFooterEl.style.alignItems = "center";
51
+ modal.appendChild(this._modalFooterEl);
52
+ }
53
+ const steps = this._steps;
54
+ const hasSteps = steps.length > 0;
55
+ const isLastStep = hasSteps ? this._currentStepIndex === steps.length - 1 : true;
56
+ // Imperative DOM management prevents event listener loss and re-rendering conflicts
57
+ this._modalFooterEl.innerHTML = "";
58
+ if (hasSteps && this._currentStepIndex > 0) {
59
+ const backBtn = document.createElement("st-button");
60
+ backBtn.setAttribute("variant", "secondary");
61
+ backBtn.setAttribute("type", "button");
62
+ if (this.loading)
63
+ backBtn.setAttribute("disabled", "");
64
+ backBtn.textContent = "Back";
65
+ backBtn.addEventListener("click", (e) => {
66
+ e.preventDefault();
67
+ this._prevStep();
68
+ });
69
+ this._modalFooterEl.appendChild(backBtn);
70
+ }
71
+ const submitBtn = document.createElement("st-button");
72
+ submitBtn.setAttribute("color", "primary");
73
+ submitBtn.setAttribute("type", "button");
74
+ if (this.loading)
75
+ submitBtn.setAttribute("disabled", "");
76
+ submitBtn.textContent = this.loading ? "Submitting..." : (isLastStep ? "Submit" : "Continue");
77
+ submitBtn.addEventListener("click", (e) => {
78
+ e.preventDefault();
79
+ this._triggerSubmission();
80
+ });
81
+ this._modalFooterEl.appendChild(submitBtn);
82
+ }
83
+ else if (this._modalFooterEl) {
84
+ this._modalFooterEl.remove();
85
+ this._modalFooterEl = null;
86
+ }
87
+ }
88
+ _handleSlotChange() {
89
+ this._updateStepVisibility();
90
+ this._updateModalFooter();
91
+ }
23
92
  _updateStepVisibility() {
24
- this._stepElements.forEach((step, index) => {
93
+ const steps = this._steps;
94
+ steps.forEach((step, index) => {
25
95
  step.active = index === this._currentStepIndex;
26
96
  });
27
97
  this.requestUpdate();
28
98
  }
29
- _validateCurrentContext() {
30
- if (this._stepElements.length === 0) {
31
- return this._formEl.checkValidity();
32
- }
33
- const currentStep = this._stepElements[this._currentStepIndex];
99
+ async _validateCurrentContext() {
100
+ const steps = this._steps;
101
+ const scope = steps.length > 0
102
+ ? steps[this._currentStepIndex]
103
+ : this;
34
104
  let isValid = true;
35
- // Find all custom and native form inputs assigned to the current step
36
- const inputs = Array.from(currentStep.querySelectorAll("*"));
105
+ const inputs = Array.from(scope.querySelectorAll("st-input, st-select, st-textarea, st-checkbox, st-radio, input, select, textarea"));
37
106
  for (const input of inputs) {
107
+ if (input.hasAttribute("disabled") || input.disabled)
108
+ continue;
109
+ let fieldValid = true;
38
110
  if (typeof input.checkValidity === "function") {
39
- if (!input.checkValidity()) {
40
- // Focus and report on the first invalid element encountered
41
- if (isValid && typeof input.reportValidity === "function") {
42
- input.reportValidity();
111
+ fieldValid = input.checkValidity();
112
+ }
113
+ else {
114
+ const isRequired = input.hasAttribute("required") || input.required;
115
+ if (isRequired) {
116
+ const isToggle = input.tagName === "ST-CHECKBOX" || input.tagName === "ST-RADIO";
117
+ const val = isToggle ? input.checked : input.value;
118
+ if (val === undefined || val === null || val === "" || val === false) {
119
+ fieldValid = false;
43
120
  }
121
+ }
122
+ }
123
+ if (!fieldValid) {
124
+ if (typeof input.reportValidity === "function") {
125
+ input.reportValidity();
126
+ }
127
+ else if ("invalid" in input) {
128
+ input.invalid = true;
129
+ }
130
+ if (isValid && typeof input.focus === "function") {
131
+ input.focus();
132
+ }
133
+ isValid = false;
134
+ }
135
+ }
136
+ if (steps.length === 0 && this._formEl) {
137
+ if (!this._formEl.checkValidity()) {
138
+ isValid = false;
139
+ }
140
+ }
141
+ if (isValid && steps.length > 0) {
142
+ const currentStep = steps[this._currentStepIndex];
143
+ if (typeof currentStep.validate === "function") {
144
+ try {
145
+ this.loading = true;
146
+ const stepPassed = await currentStep.validate();
147
+ if (!stepPassed) {
148
+ isValid = false;
149
+ }
150
+ }
151
+ catch {
44
152
  isValid = false;
45
153
  }
154
+ finally {
155
+ this.loading = false;
156
+ }
46
157
  }
47
158
  }
48
159
  return isValid;
49
160
  }
50
161
  _triggerSubmission() {
51
- // HTML5 method that triggers form validation and fires the native submit event
52
162
  this._formEl.requestSubmit();
53
163
  }
54
164
  _prevStep() {
@@ -59,10 +169,8 @@ let StForm = class StForm extends LitElement {
59
169
  }
60
170
  _extractFormData() {
61
171
  const formData = new FormData();
62
- // Query all light-DOM children that have a 'name' attribute
63
172
  const fields = this.querySelectorAll("[name]");
64
173
  fields.forEach((field) => {
65
- // Standard HTML form behavior: ignore disabled fields
66
174
  if (field.hasAttribute("disabled"))
67
175
  return;
68
176
  const isToggle = field.tagName === "ST-RADIO" ||
@@ -70,7 +178,6 @@ let StForm = class StForm extends LitElement {
70
178
  field.getAttribute("type") === "radio" ||
71
179
  field.getAttribute("type") === "checkbox";
72
180
  if (isToggle) {
73
- // Only append radios/checkboxes if they are actively checked
74
181
  if (field.checked) {
75
182
  formData.append(field.name, field.value || "on");
76
183
  }
@@ -78,29 +185,28 @@ let StForm = class StForm extends LitElement {
78
185
  else if (field.tagName === "INPUT" &&
79
186
  field.getAttribute("type") === "file" &&
80
187
  field.files) {
81
- // Handle native file uploads
82
188
  Array.from(field.files).forEach((file) => formData.append(field.name, file));
83
189
  }
84
190
  else if (field.value !== undefined) {
85
- // Handle st-input, st-select, st-textarea, and standard inputs
86
191
  formData.append(field.name, field.value);
87
192
  }
88
193
  });
89
194
  return formData;
90
195
  }
91
- _handleSubmit(e) {
196
+ async _handleSubmit(e) {
92
197
  e.preventDefault();
93
198
  e.stopPropagation();
94
- if (!this._validateCurrentContext())
199
+ const isValid = await this._validateCurrentContext();
200
+ if (!isValid)
95
201
  return;
96
- const hasSteps = this._stepElements.length > 0;
97
- const isLastStep = hasSteps ? this._currentStepIndex === this._stepElements.length - 1 : true;
202
+ const steps = this._steps;
203
+ const hasSteps = steps.length > 0;
204
+ const isLastStep = hasSteps ? this._currentStepIndex === steps.length - 1 : true;
98
205
  if (hasSteps && !isLastStep) {
99
206
  this._currentStepIndex++;
100
207
  this._updateStepVisibility();
101
208
  return;
102
209
  }
103
- // Use our custom extractor to pierce the Shadow DOM boundary
104
210
  const formData = this._extractFormData();
105
211
  this.dispatchEvent(new CustomEvent("submit", {
106
212
  bubbles: true,
@@ -110,8 +216,9 @@ let StForm = class StForm extends LitElement {
110
216
  }));
111
217
  }
112
218
  render() {
113
- const hasSteps = this._stepElements?.length > 0;
114
- const isLastStep = hasSteps ? this._currentStepIndex === this._stepElements.length - 1 : true;
219
+ const steps = this._steps;
220
+ const hasSteps = steps.length > 0;
221
+ const isInModal = !!this.closest("st-modal");
115
222
  return html `
116
223
  <div class="${hasSteps ? "has-steps" : ""}" aria-busy=${this.loading}>
117
224
  ${this.loading
@@ -124,7 +231,7 @@ let StForm = class StForm extends LitElement {
124
231
  ${hasSteps
125
232
  ? html `
126
233
  <div class="progress-nav" role="tablist">
127
- ${this._stepElements.map((step, index) => {
234
+ ${steps.map((step, index) => {
128
235
  const isActive = index === this._currentStepIndex;
129
236
  const isCompleted = index < this._currentStepIndex;
130
237
  return html `
@@ -142,7 +249,7 @@ let StForm = class StForm extends LitElement {
142
249
  </div>
143
250
  <span>${step.title || `Step ${index + 1}`}</span>
144
251
  </div>
145
- ${index < this._stepElements.length - 1
252
+ ${index < steps.length - 1
146
253
  ? html ` <div class="step-connector ${isCompleted ? "completed" : ""}"></div> `
147
254
  : ""}
148
255
  `;
@@ -162,30 +269,33 @@ let StForm = class StForm extends LitElement {
162
269
  <form @submit=${this._handleSubmit}>
163
270
  <slot @slotchange=${this._handleSlotChange}></slot>
164
271
 
165
- <div class="form-actions">
166
- ${hasSteps && this._currentStepIndex > 0
272
+ ${!isInModal
167
273
  ? html `
274
+ <div class="form-actions">
275
+ ${hasSteps && this._currentStepIndex > 0
276
+ ? html `
277
+ <st-button
278
+ variant="secondary"
279
+ type="button"
280
+ @click=${this._prevStep}
281
+ ?disabled=${this.loading}
282
+ >
283
+ Back
284
+ </st-button>
285
+ `
286
+ : ""}
287
+
168
288
  <st-button
169
- variant="secondary"
289
+ color="primary"
170
290
  type="button"
171
- @click=${this._prevStep}
291
+ @click=${this._triggerSubmission}
172
292
  ?disabled=${this.loading}
173
293
  >
174
- Back
294
+ ${this.loading ? "Submitting..." : hasSteps && this._currentStepIndex === steps.length - 1 ? "Submit" : hasSteps ? "Continue" : "Submit"}
175
295
  </st-button>
176
- `
296
+ </div>
297
+ `
177
298
  : ""}
178
-
179
- <!-- Type is "button", but click triggers requestSubmit() on the internal form -->
180
- <st-button
181
- color="primary"
182
- type="button"
183
- @click=${this._triggerSubmission}
184
- ?disabled=${this.loading}
185
- >
186
- ${this.loading ? "Submitting..." : isLastStep ? "Submit" : "Continue"}
187
- </st-button>
188
- </div>
189
299
  </form>
190
300
  </div>
191
301
  `;
@@ -204,9 +314,6 @@ StForm.styles = [
204
314
  gap: var(--st-spacing-md);
205
315
  }
206
316
 
207
- /* ==========================================================
208
- Layouts
209
- ========================================================== */
210
317
  :host([layout="vertical"]) form {
211
318
  flex-direction: column;
212
319
  }
@@ -228,9 +335,6 @@ StForm.styles = [
228
335
  flex-direction: column;
229
336
  }
230
337
 
231
- /* ==========================================================
232
- Progress Navigation
233
- ========================================================== */
234
338
  .progress-nav {
235
339
  display: flex;
236
340
  align-items: center;
@@ -294,9 +398,6 @@ StForm.styles = [
294
398
  background-color: var(--st-color-success);
295
399
  }
296
400
 
297
- /* ==========================================================
298
- Actions & States
299
- ========================================================== */
300
401
  .form-actions {
301
402
  display: flex;
302
403
  gap: var(--st-spacing-md);
@@ -346,9 +447,6 @@ __decorate([
346
447
  __decorate([
347
448
  state()
348
449
  ], StForm.prototype, "_currentStepIndex", void 0);
349
- __decorate([
350
- queryAssignedElements({ selector: "st-form-step" })
351
- ], StForm.prototype, "_stepElements", void 0);
352
450
  __decorate([
353
451
  query("form")
354
452
  ], StForm.prototype, "_formEl", void 0);
@@ -1,8 +1,9 @@
1
1
  import { LitElement } from 'lit';
2
2
  import { IconName } from './icon-paths.js';
3
+ export type IconVariant = 'outline' | 'solid';
3
4
  export declare class StIcon extends LitElement {
4
5
  name: IconName | string;
5
- variant: 'outline' | 'solid';
6
+ variant: IconVariant;
6
7
  color: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
7
8
  size: 'sm' | 'md' | 'lg' | 'xl';
8
9
  static styles: import("lit").CSSResult[];
@@ -1 +1 @@
1
- {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAa,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,qBACa,MAAO,SAAQ,UAAU;IACR,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAM;IAC7B,OAAO,EAAE,SAAS,GAAG,OAAO,CAAa;IAG1B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAa;IAGlG,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAElF,MAAM,CAAC,MAAM,4BAsCX;IAEF,MAAM,yCAmBL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
1
+ {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAa,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAE9C,qBACa,MAAO,SAAQ,UAAU;IACR,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAM;IAC7B,OAAO,EAAE,WAAW,CAAa;IAGlB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAa;IAGlG,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAElF,MAAM,CAAC,MAAM,4BAsCX;IAEF,MAAM,yCAmBL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
@@ -28,4 +28,9 @@ export declare class StInput extends LitElement {
28
28
  private _handleChange;
29
29
  render(): import("lit-html").TemplateResult<1>;
30
30
  }
31
+ declare global {
32
+ interface HTMLElementTagNameMap {
33
+ "st-input": StInput;
34
+ }
35
+ }
31
36
  //# sourceMappingURL=input.d.ts.map