aw-wizard-forms 4.0.0 → 4.3.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.
@@ -762,7 +762,7 @@ function e(e2, r2) {
762
762
  } });
763
763
  };
764
764
  }
765
- i$3`
765
+ const designTokens = i$3`
766
766
  /* Colors */
767
767
  --wf-color-primary: #8040f0;
768
768
  --wf-color-primary-border: #602cbb;
@@ -774,13 +774,20 @@ i$3`
774
774
  --wf-color-text-secondary: #404040;
775
775
  --wf-color-text-muted: #646464;
776
776
  --wf-color-error: #dc3545;
777
+ --wf-color-error-light: rgba(220, 53, 69, 0.1);
777
778
  --wf-color-badge-bg: #fcfcfc;
778
779
  --wf-color-badge-border: #d4d4d4;
779
780
  --wf-color-badge-text: #5f5f5f;
780
781
  --wf-color-progress-active: rgba(0, 0, 0, 0.1);
781
782
  --wf-color-progress-inactive: rgba(0, 0, 0, 0.05);
782
783
 
784
+ /* Focus ring */
785
+ --wf-focus-ring-width: 3px;
786
+ --wf-focus-ring-primary: rgba(128, 64, 240, 0.2);
787
+ --wf-focus-ring-error: rgba(220, 53, 69, 0.2);
788
+
783
789
  /* Spacing scale */
790
+ --wf-spacing-05: 2px;
784
791
  --wf-spacing-1: 4px;
785
792
  --wf-spacing-2: 8px;
786
793
  --wf-spacing-3: 12px;
@@ -803,16 +810,33 @@ i$3`
803
810
  --wf-font-size-xl: 1.5rem;
804
811
  --wf-font-size-2xl: 2rem;
805
812
  --wf-font-size-3xl: 2.5rem;
813
+ --wf-font-family-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
814
+ --wf-font-weight-input: 400;
815
+ --wf-font-weight-label: 500;
816
+ --wf-font-weight-heading: 600;
817
+ --wf-font-weight-button: 400;
806
818
 
807
819
  /* Input dimensions */
808
820
  --wf-input-min-height: 56px;
821
+ --wf-textarea-min-height: 100px;
822
+
823
+ /* Component dimensions */
824
+ --wf-btn-min-height: 48px;
825
+ --wf-badge-size: 24px;
826
+ --wf-spinner-size: 20px;
827
+ --wf-progress-height: 4px;
809
828
 
810
829
  /* Frosted glass effect (iOS-style) */
811
830
  --wf-glass-bg: rgba(255, 255, 255, 0.7);
812
831
  --wf-glass-bg-hover: rgba(255, 255, 255, 0.85);
813
832
  --wf-glass-border: rgba(0, 0, 0, 0.1);
814
833
  --wf-glass-blur: 20px;
815
- --wf-glass-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
834
+ --wf-glass-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
835
+ `;
836
+ const hostTokens = i$3`
837
+ :host {
838
+ ${designTokens}
839
+ }
816
840
  `;
817
841
  i$3`
818
842
  --wf-color-surface: #2d2d2d;
@@ -833,8 +857,8 @@ i$3`
833
857
  --wf-glass-border: rgba(255, 255, 255, 0.1);
834
858
  `;
835
859
  const sharedAnimations = i$3`@keyframes wf-spin{to{transform:rotate(360deg)}}@keyframes wf-blink{0%,to{opacity:1}50%{opacity:.5}}@keyframes wf-stepFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes wf-stepFadeOut{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-10px)}}@keyframes wf-stepSlideInRight{0%{opacity:0;transform:translate(30px)}to{opacity:1;transform:translate(0)}}@keyframes wf-stepSlideInLeft{0%{opacity:0;transform:translate(-30px)}to{opacity:1;transform:translate(0)}}`;
836
- const buttonBaseStyles = i$3`.wf-btn{justify-content:center;align-items:center;gap:var(--wf-spacing-2,8px);padding:var(--wf-spacing-3,12px)var(--wf-spacing-4,16px);min-height:48px;font-size:var(--wf-font-size-base,1rem);border-radius:var(--wf-radius-md,8px);cursor:pointer;box-sizing:border-box;border:1px solid #0000;outline:none;font-family:inherit;font-weight:600;transition:all .15s;display:inline-flex}.wf-btn:focus-visible{box-shadow:0 0 0 3px #8040f04d}.wf-btn:disabled{opacity:.5;cursor:not-allowed}`;
837
- i$3`.wf-glass{background:var(--wf-glass-bg,#ffffffb3);-webkit-backdrop-filter:blur(var(--wf-glass-blur,20px));border:1px solid var(--wf-glass-border,#0000001a);box-shadow:var(--wf-glass-shadow,0 4px 6px #0000000d)}.wf-glass:hover{background:var(--wf-glass-bg-hover,#ffffffd9)}`;
860
+ const buttonBaseStyles = i$3`.wf-btn{justify-content:center;align-items:center;gap:var(--wf-spacing-2);padding:var(--wf-spacing-3)var(--wf-spacing-4);min-height:var(--wf-btn-min-height);font-size:var(--wf-font-size-base);font-weight:var(--wf-font-weight-button);border-radius:var(--wf-radius-md);cursor:pointer;box-sizing:border-box;border:1px solid #0000;outline:none;font-family:inherit;transition:all .15s;display:inline-flex}.wf-btn:focus-visible{box-shadow:0 0 0 var(--wf-focus-ring-width)var(--wf-focus-ring-primary)}.wf-btn:disabled{opacity:.5;cursor:not-allowed}`;
861
+ i$3`.wf-glass{background:var(--wf-glass-bg);-webkit-backdrop-filter:blur(var(--wf-glass-blur));border:1px solid var(--wf-glass-border);box-shadow:var(--wf-glass-shadow)}.wf-glass:hover{background:var(--wf-glass-bg-hover)}`;
838
862
  i$3`
839
863
  ${sharedAnimations}
840
864
 
@@ -862,13 +886,20 @@ const wizardFormStyles = [
862
886
  --wf-color-text-secondary: #404040;
863
887
  --wf-color-text-muted: #646464;
864
888
  --wf-color-error: #dc3545;
889
+ --wf-color-error-light: rgba(220, 53, 69, 0.1);
865
890
  --wf-color-badge-bg: #fcfcfc;
866
891
  --wf-color-badge-border: #d4d4d4;
867
892
  --wf-color-badge-text: #5f5f5f;
868
893
  --wf-color-progress-active: rgba(0, 0, 0, 0.1);
869
894
  --wf-color-progress-inactive: rgba(0, 0, 0, 0.05);
870
895
 
896
+ /* Focus ring */
897
+ --wf-focus-ring-width: 3px;
898
+ --wf-focus-ring-primary: rgba(128, 64, 240, 0.2);
899
+ --wf-focus-ring-error: rgba(220, 53, 69, 0.2);
900
+
871
901
  /* Spacing tokens */
902
+ --wf-spacing-05: 2px;
872
903
  --wf-spacing-1: 4px;
873
904
  --wf-spacing-2: 8px;
874
905
  --wf-spacing-3: 12px;
@@ -891,16 +922,28 @@ const wizardFormStyles = [
891
922
  --wf-font-size-xl: 1.5rem;
892
923
  --wf-font-size-2xl: 2rem;
893
924
  --wf-font-size-3xl: 2.5rem;
925
+ --wf-font-family-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
926
+ --wf-font-weight-input: 400;
927
+ --wf-font-weight-label: 500;
928
+ --wf-font-weight-heading: 600;
929
+ --wf-font-weight-button: 400;
894
930
 
895
931
  /* Input tokens */
896
932
  --wf-input-min-height: 56px;
933
+ --wf-textarea-min-height: 100px;
934
+
935
+ /* Component dimensions */
936
+ --wf-btn-min-height: 48px;
937
+ --wf-badge-size: 24px;
938
+ --wf-spinner-size: 20px;
939
+ --wf-progress-height: 4px;
897
940
 
898
941
  /* Frosted glass effect (iOS-style) */
899
942
  --wf-glass-bg: rgba(255, 255, 255, 0.7);
900
943
  --wf-glass-bg-hover: rgba(255, 255, 255, 0.85);
901
944
  --wf-glass-border: rgba(0, 0, 0, 0.1);
902
945
  --wf-glass-blur: 20px;
903
- --wf-glass-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
946
+ --wf-glass-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
904
947
  }
905
948
 
906
949
  :host([hidden]) {
@@ -961,20 +1004,20 @@ const wizardFormStyles = [
961
1004
  ---------------------------------------- */
962
1005
  .wf-success-screen {
963
1006
  text-align: center;
964
- padding: var(--wf-spacing-6, 24px);
1007
+ padding: var(--wf-spacing-6);
965
1008
  }
966
1009
 
967
1010
  /* ----------------------------------------
968
1011
  Error message
969
1012
  ---------------------------------------- */
970
1013
  .wf-form-error {
971
- padding: var(--wf-spacing-4, 16px);
972
- margin-bottom: var(--wf-spacing-4, 16px);
973
- background-color: rgba(220, 53, 69, 0.1);
974
- border: 1px solid var(--wf-color-error, #dc3545);
975
- border-radius: var(--wf-radius-md, 8px);
976
- color: var(--wf-color-error, #dc3545);
977
- font-size: var(--wf-font-size-base, 1rem);
1014
+ padding: var(--wf-spacing-4);
1015
+ margin-bottom: var(--wf-spacing-4);
1016
+ background-color: var(--wf-color-error-light);
1017
+ border: 1px solid var(--wf-color-error);
1018
+ border-radius: var(--wf-radius-md);
1019
+ color: var(--wf-color-error);
1020
+ font-size: var(--wf-font-size-base);
978
1021
  }
979
1022
 
980
1023
  /* ----------------------------------------
@@ -1360,43 +1403,43 @@ const wfBadgeStyles = i$3`
1360
1403
  align-items: center;
1361
1404
  justify-content: center;
1362
1405
  box-sizing: border-box;
1363
- min-width: 24px;
1364
- height: 24px;
1365
- padding: var(--wf-spacing-1, 4px) var(--wf-spacing-2, 8px);
1366
- font-size: var(--wf-font-size-xs, 0.75rem);
1367
- font-weight: 500;
1368
- font-family: inherit;
1406
+ min-width: var(--wf-badge-size);
1407
+ height: var(--wf-badge-size);
1408
+ padding: var(--wf-spacing-1) var(--wf-spacing-2);
1409
+ font-size: var(--wf-font-size-xs);
1410
+ font-weight: var(--wf-font-weight-label);
1411
+ font-family: var(--wf-font-family-mono);
1369
1412
  text-transform: uppercase;
1370
1413
  flex-shrink: 0;
1371
1414
  line-height: 1;
1372
1415
  }
1373
1416
 
1374
1417
  .wf-badge--default {
1375
- background-color: var(--wf-color-badge-bg, #fcfcfc);
1376
- border: 1px solid var(--wf-color-badge-border, #d4d4d4);
1377
- border-radius: var(--wf-radius-sm, 4px);
1378
- color: var(--wf-color-badge-text, #5f5f5f);
1418
+ background-color: var(--wf-color-badge-bg);
1419
+ border: 1px solid var(--wf-color-badge-border);
1420
+ border-radius: var(--wf-radius-sm);
1421
+ color: var(--wf-color-badge-text);
1379
1422
  }
1380
1423
 
1381
1424
  .wf-badge--selected {
1382
- background-color: var(--wf-color-primary, #8040f0);
1383
- border: 1px solid var(--wf-color-primary, #8040f0);
1384
- border-radius: var(--wf-radius-sm, 4px);
1425
+ background-color: var(--wf-color-primary);
1426
+ border: 1px solid var(--wf-color-primary);
1427
+ border-radius: var(--wf-radius-sm);
1385
1428
  color: white;
1386
1429
  }
1387
1430
 
1388
1431
  .wf-badge--button {
1389
1432
  background-color: transparent;
1390
1433
  border: none;
1391
- border-radius: var(--wf-radius-sm, 4px);
1434
+ border-radius: var(--wf-radius-sm);
1392
1435
  color: rgba(255, 255, 255, 0.65);
1393
1436
  }
1394
1437
 
1395
1438
  .wf-badge--button-secondary {
1396
1439
  background-color: transparent;
1397
1440
  border: none;
1398
- border-radius: var(--wf-radius-sm, 4px);
1399
- color: var(--wf-color-text-muted, #5f5f5f);
1441
+ border-radius: var(--wf-radius-sm);
1442
+ color: var(--wf-color-text-muted);
1400
1443
  }
1401
1444
  `;
1402
1445
  var __defProp$f = Object.defineProperty;
@@ -1466,6 +1509,7 @@ let WizardForm = class extends i {
1466
1509
  this.submitted = false;
1467
1510
  this._error = "";
1468
1511
  this._otherInputActive = false;
1512
+ this._partialSubmitting = false;
1469
1513
  this._stateController = new FormStateController(this);
1470
1514
  this._handleFieldChange = (e2) => {
1471
1515
  const { name, value, extraFields } = e2.detail;
@@ -1760,8 +1804,9 @@ let WizardForm = class extends i {
1760
1804
  const previousStep = this._currentStep;
1761
1805
  let submitted = false;
1762
1806
  let adapter;
1763
- if (this.submitOnStep && this.hubspotPortal && this.hubspotForm) {
1807
+ if (this.submitOnStep && this.hubspotPortal && this.hubspotForm && direction === "forward" && !this._partialSubmitting) {
1764
1808
  try {
1809
+ this._partialSubmitting = true;
1765
1810
  await this._submitPartialToHubSpot();
1766
1811
  submitted = true;
1767
1812
  adapter = "hubspot";
@@ -1778,6 +1823,8 @@ let WizardForm = class extends i {
1778
1823
  })
1779
1824
  );
1780
1825
  return;
1826
+ } finally {
1827
+ this._partialSubmitting = false;
1781
1828
  }
1782
1829
  }
1783
1830
  const currentStepEl = this._getStepByNumber(this._currentStep);
@@ -1923,6 +1970,7 @@ let WizardForm = class extends i {
1923
1970
  /**
1924
1971
  * Submit partial form data to HubSpot.
1925
1972
  * Only includes fields from steps up to and including the current step.
1973
+ * Filters out empty/blank values to avoid submitting unfilled fields.
1926
1974
  */
1927
1975
  async _submitPartialToHubSpot() {
1928
1976
  const partialData = this._getFieldsUpToStep(this._currentStep);
@@ -1930,7 +1978,18 @@ let WizardForm = class extends i {
1930
1978
  if (this.serialize) {
1931
1979
  submitData = this.serialize(submitData);
1932
1980
  }
1933
- await this._submitToHubSpot(submitData);
1981
+ const filteredData = Object.fromEntries(
1982
+ Object.entries(submitData).filter(([, value]) => {
1983
+ if (value === null || value === void 0 || value === "") {
1984
+ return false;
1985
+ }
1986
+ if (Array.isArray(value) && value.length === 0) {
1987
+ return false;
1988
+ }
1989
+ return true;
1990
+ })
1991
+ );
1992
+ await this._submitToHubSpot(filteredData);
1934
1993
  }
1935
1994
  // ============================================
1936
1995
  // Public API
@@ -2125,7 +2184,7 @@ const wfStepStyles = [
2125
2184
  .wf-step-content {
2126
2185
  display: flex;
2127
2186
  flex-direction: column;
2128
- gap: var(--wf-spacing-4, 16px);
2187
+ gap: var(--wf-spacing-4);
2129
2188
  }
2130
2189
 
2131
2190
  /* Slotted heading styles */
@@ -2133,18 +2192,18 @@ const wfStepStyles = [
2133
2192
  ::slotted(h2),
2134
2193
  ::slotted(h3) {
2135
2194
  margin: 0;
2136
- font-weight: 600;
2137
- color: var(--wf-color-text, #212529);
2195
+ font-weight: var(--wf-font-weight-heading);
2196
+ color: var(--wf-color-text);
2138
2197
  }
2139
2198
 
2140
2199
  ::slotted(h2) {
2141
- font-size: var(--wf-font-size-3xl, 2rem);
2200
+ font-size: var(--wf-font-size-3xl);
2142
2201
  }
2143
2202
 
2144
2203
  ::slotted(p) {
2145
2204
  margin: 0;
2146
- color: var(--wf-color-text-muted, #6c757d);
2147
- font-size: var(--wf-font-size-xl, 1.375rem);
2205
+ color: var(--wf-color-text-muted);
2206
+ font-size: var(--wf-font-size-xl);
2148
2207
  }
2149
2208
  `
2150
2209
  ];
@@ -2653,15 +2712,15 @@ const wfOptionsStyles = i$3`
2653
2712
  .wf-error-message {
2654
2713
  overflow: hidden;
2655
2714
  min-height: 0;
2656
- font-size: var(--wf-font-size-sm, 0.875rem);
2657
- color: var(--wf-color-error, #dc3545);
2715
+ font-size: var(--wf-font-size-sm);
2716
+ color: var(--wf-color-error);
2658
2717
  opacity: 0;
2659
2718
  transform: translateY(-4px);
2660
2719
  transition: opacity 200ms ease-out, transform 200ms ease-out;
2661
2720
  }
2662
2721
 
2663
2722
  .wf-has-error .wf-error-message {
2664
- margin-top: var(--wf-spacing-2, 8px);
2723
+ margin-top: var(--wf-spacing-2);
2665
2724
  opacity: 1;
2666
2725
  transform: translateY(0);
2667
2726
  }
@@ -2682,50 +2741,51 @@ const wfOtherStyles = i$3`
2682
2741
  }
2683
2742
 
2684
2743
  .wf-other-container {
2685
- margin-top: var(--wf-spacing-4, 16px);
2744
+ margin-top: var(--wf-spacing-4);
2686
2745
  }
2687
2746
 
2688
2747
  .wf-other-label {
2689
2748
  display: block;
2690
- margin-bottom: var(--wf-spacing-2, 8px);
2691
- font-size: var(--wf-font-size-sm, 0.875rem);
2692
- font-weight: 500;
2693
- color: var(--wf-color-text, #0a0a0a);
2749
+ margin-bottom: var(--wf-spacing-2);
2750
+ font-size: var(--wf-font-size-sm);
2751
+ font-weight: var(--wf-font-weight-label);
2752
+ color: var(--wf-color-text);
2694
2753
  }
2695
2754
 
2696
2755
  .wf-other-label span {
2697
- font-weight: 400;
2698
- color: var(--wf-color-text-muted, #646464);
2756
+ font-weight: var(--wf-font-weight-input);
2757
+ color: var(--wf-color-text-muted);
2699
2758
  }
2700
2759
 
2701
2760
  .wf-other-input-wrapper {
2702
2761
  display: flex;
2703
2762
  align-items: center;
2704
- gap: var(--wf-spacing-3, 12px);
2705
- min-height: var(--wf-input-min-height, 56px);
2706
- background: var(--wf-glass-bg, rgba(255, 255, 255, 0.7));
2707
- backdrop-filter: blur(var(--wf-glass-blur, 20px));
2708
- -webkit-backdrop-filter: blur(var(--wf-glass-blur, 20px));
2709
- border: 1px solid var(--wf-glass-border, rgba(0, 0, 0, 0.1));
2710
- border-radius: var(--wf-radius-md, 8px);
2711
- box-shadow: var(--wf-glass-shadow, 0 4px 6px rgba(0, 0, 0, 0.05));
2712
- padding-left: var(--wf-spacing-3, 12px);
2763
+ gap: var(--wf-spacing-3);
2764
+ height: var(--wf-input-min-height);
2765
+ background: var(--wf-glass-bg);
2766
+ backdrop-filter: blur(var(--wf-glass-blur));
2767
+ -webkit-backdrop-filter: blur(var(--wf-glass-blur));
2768
+ border: 1px solid var(--wf-glass-border);
2769
+ border-radius: var(--wf-radius-md);
2770
+ box-shadow: var(--wf-glass-shadow);
2771
+ padding-left: var(--wf-spacing-3);
2772
+ padding-right: var(--wf-spacing-2);
2713
2773
  transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
2714
2774
  }
2715
2775
 
2716
2776
  .wf-other-input-wrapper:focus-within {
2717
- border-color: var(--wf-color-primary, #8040f0);
2718
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.1);
2777
+ border-color: var(--wf-color-primary);
2778
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-primary);
2719
2779
  }
2720
2780
 
2721
2781
  .wf-other-input {
2722
2782
  flex: 1;
2723
- min-height: calc(var(--wf-input-min-height, 56px) - 2px);
2724
- padding: var(--wf-spacing-3, 12px);
2783
+ min-height: calc(var(--wf-input-min-height) - 2px);
2784
+ padding: var(--wf-spacing-3);
2725
2785
  padding-left: 0;
2726
- font-size: var(--wf-font-size-base, 1rem);
2727
- font-weight: 500;
2728
- color: var(--wf-color-text, #0a0a0a);
2786
+ font-size: var(--wf-font-size-base);
2787
+ font-weight: var(--wf-font-weight-input);
2788
+ color: var(--wf-color-text);
2729
2789
  background: transparent;
2730
2790
  border: none;
2731
2791
  outline: none;
@@ -2733,19 +2793,29 @@ const wfOtherStyles = i$3`
2733
2793
  }
2734
2794
 
2735
2795
  .wf-other-input::placeholder {
2736
- color: var(--wf-color-text-muted, #646464);
2737
- font-weight: 500;
2796
+ color: var(--wf-color-text-muted);
2797
+ font-weight: var(--wf-font-weight-input);
2738
2798
  }
2739
2799
 
2740
2800
  .wf-other-actions {
2741
2801
  display: flex;
2742
2802
  align-items: center;
2743
- justify-content: stretch;
2803
+ justify-content: flex-end;
2804
+ flex-shrink: 0;
2805
+ opacity: 0;
2806
+ visibility: hidden;
2807
+ transition: opacity 200ms ease, visibility 200ms ease;
2808
+ }
2809
+
2810
+ /* Show button when input has value */
2811
+ .wf-other-input-wrapper.has-value .wf-other-actions {
2812
+ opacity: 1;
2813
+ visibility: visible;
2744
2814
  }
2745
2815
 
2746
- /* Ensure slotted button fills the action column */
2816
+ /* Button inside input box should not stretch */
2747
2817
  .wf-other-actions ::slotted(*) {
2748
- width: 100%;
2818
+ width: auto;
2749
2819
  }
2750
2820
  `;
2751
2821
  var __defProp$b = Object.defineProperty;
@@ -2763,6 +2833,7 @@ let WfOther = class extends i {
2763
2833
  super(...arguments);
2764
2834
  this.label = "Others, please specify:";
2765
2835
  this.placeholder = "";
2836
+ this.parentValue = "Others";
2766
2837
  this.required = false;
2767
2838
  this.disabled = false;
2768
2839
  this.shortcut = "";
@@ -2818,31 +2889,30 @@ let WfOther = class extends i {
2818
2889
  // Render
2819
2890
  // ============================================
2820
2891
  render() {
2892
+ const hasValue = this._value.trim().length > 0;
2821
2893
  return b`
2822
2894
  <div class="wf-other-container" data-testid="wf-other">
2823
2895
  <label class="wf-other-label">
2824
2896
  ${this.label}
2825
2897
  ${this.labelHint ? b`<span>${this.labelHint}</span>` : A}
2826
2898
  </label>
2827
- <wf-layout mode="grid" columns="4" gap="md">
2828
- <div class="wf-other-input-wrapper" data-span="3">
2829
- ${this.shortcut ? b`<wf-badge shortcut="${this.shortcut}"></wf-badge>` : A}
2830
- <input
2831
- type="text"
2832
- class="wf-other-input"
2833
- placeholder="${this.placeholder}"
2834
- .value="${this._value}"
2835
- ?disabled="${this.disabled}"
2836
- ?required="${this.required}"
2837
- @input="${this._handleInput}"
2838
- data-testid="wf-other-input"
2839
- />
2840
- </div>
2841
- <!-- Slot for action buttons (like wf-next-btn) -->
2899
+ <div class="wf-other-input-wrapper ${hasValue ? "has-value" : ""}">
2900
+ ${this.shortcut ? b`<wf-badge shortcut="${this.shortcut}"></wf-badge>` : A}
2901
+ <input
2902
+ type="text"
2903
+ class="wf-other-input"
2904
+ placeholder="${this.placeholder}"
2905
+ .value="${this._value}"
2906
+ ?disabled="${this.disabled}"
2907
+ ?required="${this.required}"
2908
+ @input="${this._handleInput}"
2909
+ data-testid="wf-other-input"
2910
+ />
2911
+ <!-- Slot for action buttons (like wf-next-btn) inside input -->
2842
2912
  <div class="wf-other-actions">
2843
2913
  <slot></slot>
2844
2914
  </div>
2845
- </wf-layout>
2915
+ </div>
2846
2916
  </div>
2847
2917
  `;
2848
2918
  }
@@ -2860,6 +2930,9 @@ __decorateClass$b([
2860
2930
  __decorateClass$b([
2861
2931
  n2({ type: String })
2862
2932
  ], WfOther.prototype, "name", 2);
2933
+ __decorateClass$b([
2934
+ n2({ type: String, attribute: "parent-value" })
2935
+ ], WfOther.prototype, "parentValue", 2);
2863
2936
  __decorateClass$b([
2864
2937
  n2({ type: Boolean })
2865
2938
  ], WfOther.prototype, "required", 2);
@@ -3122,6 +3195,13 @@ let WfOptions = class extends WfLayout {
3122
3195
  value: this.value,
3123
3196
  selected: selectedArray
3124
3197
  };
3198
+ if (this._hasComposableOther() && this._otherValue.trim() && this._selected.size === 0) {
3199
+ const otherName = this._composableOther?.name || `${this.name}_other`;
3200
+ detail.extraFields = {
3201
+ [otherName]: this._otherValue
3202
+ };
3203
+ detail.value = this._composableOther?.parentValue || "Others";
3204
+ }
3125
3205
  this.dispatchEvent(
3126
3206
  new CustomEvent("wf-change", {
3127
3207
  detail,
@@ -3301,40 +3381,40 @@ const wfOptionStyles = i$3`
3301
3381
  .wf-option-card {
3302
3382
  display: flex;
3303
3383
  align-items: center;
3304
- gap: var(--wf-spacing-3, 12px);
3384
+ gap: var(--wf-spacing-3);
3305
3385
  width: 100%;
3306
- min-height: var(--wf-input-min-height, 56px);
3307
- padding: var(--wf-spacing-3, 12px);
3308
- background: var(--wf-glass-bg, rgba(255, 255, 255, 0.7));
3309
- backdrop-filter: blur(var(--wf-glass-blur, 20px));
3310
- -webkit-backdrop-filter: blur(var(--wf-glass-blur, 20px));
3311
- border: 1px solid var(--wf-glass-border, rgba(0, 0, 0, 0.1));
3312
- border-radius: var(--wf-radius-md, 8px);
3313
- box-shadow: var(--wf-glass-shadow, 0 4px 6px rgba(0, 0, 0, 0.05));
3386
+ min-height: var(--wf-input-min-height);
3387
+ padding: var(--wf-spacing-3);
3388
+ background: var(--wf-glass-bg);
3389
+ backdrop-filter: blur(var(--wf-glass-blur));
3390
+ -webkit-backdrop-filter: blur(var(--wf-glass-blur));
3391
+ border: 1px solid var(--wf-glass-border);
3392
+ border-radius: var(--wf-radius-md);
3393
+ box-shadow: var(--wf-glass-shadow);
3314
3394
  cursor: pointer;
3315
3395
  text-align: left;
3316
3396
  font-family: inherit;
3317
- font-size: var(--wf-font-size-base, 1rem);
3318
- font-weight: 500;
3319
- color: var(--wf-color-text, #0a0a0a);
3397
+ font-size: var(--wf-font-size-base);
3398
+ font-weight: var(--wf-font-weight-input);
3399
+ color: var(--wf-color-text);
3320
3400
  transition: border-color 150ms ease, background 150ms ease, transform 100ms ease;
3321
3401
  outline: none;
3322
3402
  box-sizing: border-box;
3323
3403
  }
3324
3404
 
3325
3405
  .wf-option-card:hover:not(:disabled) {
3326
- border-color: var(--wf-color-primary, #8040f0);
3327
- background: var(--wf-glass-bg-hover, rgba(255, 255, 255, 0.85));
3406
+ border-color: var(--wf-color-primary);
3407
+ background: var(--wf-glass-bg-hover);
3328
3408
  }
3329
3409
 
3330
3410
  .wf-option-card:focus-visible {
3331
- border-color: var(--wf-color-primary, #8040f0);
3332
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
3411
+ border-color: var(--wf-color-primary);
3412
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-primary);
3333
3413
  }
3334
3414
 
3335
3415
  .wf-option-card[aria-selected='true'] {
3336
- border-color: var(--wf-color-primary, #8040f0);
3337
- background-color: var(--wf-color-primary-light, rgba(128, 64, 240, 0.1));
3416
+ border-color: var(--wf-color-primary);
3417
+ background-color: var(--wf-color-primary-light);
3338
3418
  }
3339
3419
 
3340
3420
  .wf-option-card:disabled {
@@ -3369,16 +3449,16 @@ const wfOptionStyles = i$3`
3369
3449
  ::slotted(h3),
3370
3450
  ::slotted(h4) {
3371
3451
  display: block;
3372
- font-weight: 600;
3452
+ font-weight: var(--wf-font-weight-heading);
3373
3453
  margin: 0;
3374
3454
  }
3375
3455
 
3376
3456
  ::slotted(span),
3377
3457
  ::slotted(p) {
3378
3458
  display: block;
3379
- font-size: var(--wf-font-size-sm, 0.875rem);
3380
- color: var(--wf-color-text-muted, #646464);
3381
- margin: 4px 0 0 0;
3459
+ font-size: var(--wf-font-size-sm);
3460
+ color: var(--wf-color-text-muted);
3461
+ margin: var(--wf-spacing-1) 0 0 0;
3382
3462
  }
3383
3463
  `;
3384
3464
  var __defProp$9 = Object.defineProperty;
@@ -3501,15 +3581,15 @@ const formInputBaseStyles = i$3`
3501
3581
  }
3502
3582
 
3503
3583
  .wf-label {
3504
- font-size: var(--wf-font-size-sm, 0.875rem);
3505
- font-weight: 500;
3506
- color: var(--wf-color-text, #0a0a0a);
3507
- margin-bottom: var(--wf-spacing-2, 8px);
3584
+ font-size: var(--wf-font-size-sm);
3585
+ font-weight: var(--wf-font-weight-label);
3586
+ color: var(--wf-color-text);
3587
+ margin-bottom: var(--wf-spacing-2);
3508
3588
  }
3509
3589
 
3510
3590
  .wf-label-required::after {
3511
3591
  content: ' *';
3512
- color: var(--wf-color-error, #dc3545);
3592
+ color: var(--wf-color-error);
3513
3593
  }
3514
3594
 
3515
3595
  /* Error wrapper for animated expand/collapse */
@@ -3526,52 +3606,52 @@ const formInputBaseStyles = i$3`
3526
3606
  .wf-error-message {
3527
3607
  overflow: hidden;
3528
3608
  min-height: 0;
3529
- font-size: var(--wf-font-size-sm, 0.875rem);
3530
- color: var(--wf-color-error, #dc3545);
3609
+ font-size: var(--wf-font-size-sm);
3610
+ color: var(--wf-color-error);
3531
3611
  opacity: 0;
3532
3612
  transform: translateY(-4px);
3533
3613
  transition: opacity 200ms ease-out, transform 200ms ease-out;
3534
3614
  }
3535
3615
 
3536
3616
  .wf-has-error .wf-error-message {
3537
- margin-top: var(--wf-spacing-2, 8px);
3617
+ margin-top: var(--wf-spacing-2);
3538
3618
  opacity: 1;
3539
3619
  transform: translateY(0);
3540
3620
  }
3541
3621
 
3542
3622
  .wf-hint {
3543
- font-size: var(--wf-font-size-sm, 0.875rem);
3544
- color: var(--wf-color-text-muted, #646464);
3545
- margin-top: var(--wf-spacing-2, 8px);
3623
+ font-size: var(--wf-font-size-sm);
3624
+ color: var(--wf-color-text-muted);
3625
+ margin-top: var(--wf-spacing-2);
3546
3626
  }
3547
3627
 
3548
3628
  .wf-input {
3549
3629
  width: 100%;
3550
- min-height: var(--wf-input-min-height, 56px);
3551
- padding: var(--wf-spacing-4, 16px);
3552
- font-size: var(--wf-font-size-base, 1rem);
3553
- font-weight: 400;
3630
+ min-height: var(--wf-input-min-height);
3631
+ padding: var(--wf-spacing-4);
3632
+ font-size: var(--wf-font-size-base);
3633
+ font-weight: var(--wf-font-weight-input);
3554
3634
  font-family: inherit;
3555
- background: var(--wf-glass-bg, rgba(255, 255, 255, 0.7));
3556
- backdrop-filter: blur(var(--wf-glass-blur, 20px));
3557
- -webkit-backdrop-filter: blur(var(--wf-glass-blur, 20px));
3558
- border: 1px solid var(--wf-glass-border, rgba(0, 0, 0, 0.1));
3559
- border-radius: var(--wf-radius-md, 8px);
3560
- box-shadow: var(--wf-glass-shadow, 0 4px 6px rgba(0, 0, 0, 0.05));
3561
- color: var(--wf-color-text, #0a0a0a);
3635
+ background: var(--wf-glass-bg);
3636
+ backdrop-filter: blur(var(--wf-glass-blur));
3637
+ -webkit-backdrop-filter: blur(var(--wf-glass-blur));
3638
+ border: 1px solid var(--wf-glass-border);
3639
+ border-radius: var(--wf-radius-md);
3640
+ box-shadow: var(--wf-glass-shadow);
3641
+ color: var(--wf-color-text);
3562
3642
  transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
3563
3643
  outline: none;
3564
3644
  box-sizing: border-box;
3565
3645
  }
3566
3646
 
3567
3647
  .wf-input::placeholder {
3568
- color: var(--wf-color-text-muted, #646464);
3569
- font-weight: 500;
3648
+ color: var(--wf-color-text-muted);
3649
+ font-weight: var(--wf-font-weight-input);
3570
3650
  }
3571
3651
 
3572
3652
  .wf-input:focus {
3573
- border-color: var(--wf-color-primary, #8040f0);
3574
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
3653
+ border-color: var(--wf-color-primary);
3654
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-primary);
3575
3655
  }
3576
3656
 
3577
3657
  .wf-input:disabled {
@@ -3580,40 +3660,40 @@ const formInputBaseStyles = i$3`
3580
3660
  }
3581
3661
 
3582
3662
  .wf-input.wf-input-error {
3583
- border-color: var(--wf-color-error, #dc3545);
3663
+ border-color: var(--wf-color-error);
3584
3664
  }
3585
3665
 
3586
3666
  .wf-input.wf-input-error:focus {
3587
- box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
3667
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-error);
3588
3668
  }
3589
3669
 
3590
3670
  /* Textarea-specific styles */
3591
3671
  .wf-textarea {
3592
3672
  width: 100%;
3593
- padding: var(--wf-spacing-4, 16px);
3594
- font-size: var(--wf-font-size-base, 1rem);
3673
+ padding: var(--wf-spacing-4);
3674
+ font-size: var(--wf-font-size-base);
3595
3675
  font-family: inherit;
3596
- background: var(--wf-glass-bg, rgba(255, 255, 255, 0.7));
3597
- backdrop-filter: blur(var(--wf-glass-blur, 20px));
3598
- -webkit-backdrop-filter: blur(var(--wf-glass-blur, 20px));
3599
- border: 1px solid var(--wf-glass-border, rgba(0, 0, 0, 0.1));
3600
- border-radius: var(--wf-radius-lg, 12px);
3601
- box-shadow: var(--wf-glass-shadow, 0 4px 6px rgba(0, 0, 0, 0.05));
3602
- color: var(--wf-color-text, #212529);
3676
+ background: var(--wf-glass-bg);
3677
+ backdrop-filter: blur(var(--wf-glass-blur));
3678
+ -webkit-backdrop-filter: blur(var(--wf-glass-blur));
3679
+ border: 1px solid var(--wf-glass-border);
3680
+ border-radius: var(--wf-radius-lg);
3681
+ box-shadow: var(--wf-glass-shadow);
3682
+ color: var(--wf-color-text);
3603
3683
  transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
3604
3684
  outline: none;
3605
3685
  box-sizing: border-box;
3606
3686
  resize: vertical;
3607
- min-height: 100px;
3687
+ min-height: var(--wf-textarea-min-height);
3608
3688
  }
3609
3689
 
3610
3690
  .wf-textarea::placeholder {
3611
- color: var(--wf-color-text-muted, #6c757d);
3691
+ color: var(--wf-color-text-muted);
3612
3692
  }
3613
3693
 
3614
3694
  .wf-textarea:focus {
3615
- border-color: var(--wf-color-primary, #8b5cf6);
3616
- box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
3695
+ border-color: var(--wf-color-primary);
3696
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-primary);
3617
3697
  }
3618
3698
 
3619
3699
  .wf-textarea:disabled {
@@ -3622,21 +3702,21 @@ const formInputBaseStyles = i$3`
3622
3702
  }
3623
3703
 
3624
3704
  .wf-textarea.wf-textarea-error {
3625
- border-color: var(--wf-color-error, #dc3545);
3705
+ border-color: var(--wf-color-error);
3626
3706
  }
3627
3707
 
3628
3708
  .wf-textarea.wf-textarea-error:focus {
3629
- box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
3709
+ box-shadow: 0 0 0 var(--wf-focus-ring-width) var(--wf-focus-ring-error);
3630
3710
  }
3631
3711
 
3632
3712
  .wf-char-count {
3633
- font-size: var(--wf-font-size-sm, 0.875rem);
3634
- color: var(--wf-color-text-muted, #6c757d);
3713
+ font-size: var(--wf-font-size-sm);
3714
+ color: var(--wf-color-text-muted);
3635
3715
  text-align: right;
3636
3716
  }
3637
3717
 
3638
3718
  .wf-char-count.wf-char-limit {
3639
- color: var(--wf-color-error, #dc3545);
3719
+ color: var(--wf-color-error);
3640
3720
  }
3641
3721
 
3642
3722
  /* wf-field slotted input styles */
@@ -4719,33 +4799,38 @@ function init(config) {
4719
4799
  return instance;
4720
4800
  }
4721
4801
  const init_default = { init };
4722
- const wfProgressStyles = i$3`
4723
- :host {
4724
- display: block;
4725
- }
4802
+ const wfProgressStyles = [
4803
+ hostTokens,
4804
+ i$3`
4805
+ :host {
4806
+ display: block;
4807
+ }
4726
4808
 
4727
- :host([hidden]) {
4728
- display: none;
4729
- }
4809
+ :host([hidden]) {
4810
+ display: none;
4811
+ }
4730
4812
 
4731
- .wf-progress {
4732
- display: flex;
4733
- gap: var(--wf-spacing-4, 16px);
4734
- }
4813
+ .wf-progress {
4814
+ display: flex;
4815
+ gap: 16px;
4816
+ align-items: center;
4817
+ justify-content: center;
4818
+ }
4735
4819
 
4736
- .wf-progress-segment {
4737
- width: 32px;
4738
- height: 8px;
4739
- background-color: var(--wf-color-progress-inactive, rgba(0, 0, 0, 0.05));
4740
- border-radius: var(--wf-radius-full, 99px);
4741
- transition: background-color 300ms ease;
4742
- }
4820
+ .wf-progress-segment {
4821
+ width: 32px;
4822
+ height: 8px;
4823
+ background-color: white;
4824
+ border-radius: 100vw;
4825
+ transition: background-color 300ms ease;
4826
+ }
4743
4827
 
4744
- .wf-progress-segment.completed,
4745
- .wf-progress-segment.active {
4746
- background-color: var(--wf-color-progress-active, rgba(0, 0, 0, 0.1));
4747
- }
4748
- `;
4828
+ .wf-progress-segment.completed,
4829
+ .wf-progress-segment.active {
4830
+ background-color: rgb(136 66 240);
4831
+ }
4832
+ `
4833
+ ];
4749
4834
  var __defProp$3 = Object.defineProperty;
4750
4835
  var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
4751
4836
  var __decorateClass$3 = (decorators, target, key, kind) => {
@@ -4955,8 +5040,8 @@ const wfNextBtnStyles = [
4955
5040
  .wf-btn-next {
4956
5041
  width: 100%;
4957
5042
  flex: 1;
4958
- background-color: var(--wf-color-primary, #8040f0);
4959
- border: 1px solid var(--wf-color-primary-border, #602cbb);
5043
+ background-color: var(--wf-color-primary);
5044
+ border: 1px solid var(--wf-color-primary-border);
4960
5045
  color: white;
4961
5046
  position: relative;
4962
5047
  }
@@ -4966,17 +5051,15 @@ const wfNextBtnStyles = [
4966
5051
  }
4967
5052
 
4968
5053
  .wf-btn-shortcut {
4969
- position: absolute;
4970
- right: var(--wf-spacing-4, 16px);
4971
5054
  display: inline-flex;
4972
5055
  align-items: center;
4973
- gap: 2px;
5056
+ gap: var(--wf-spacing-05);
4974
5057
  }
4975
5058
 
4976
5059
  .wf-loading {
4977
5060
  display: inline-block;
4978
- width: 20px;
4979
- height: 20px;
5061
+ width: var(--wf-spinner-size);
5062
+ height: var(--wf-spinner-size);
4980
5063
  border: 2px solid rgba(0, 0, 0, 0.1);
4981
5064
  border-radius: 50%;
4982
5065
  border-top-color: white;
@@ -4990,14 +5073,12 @@ const wfNextBtnStyles = [
4990
5073
  }
4991
5074
 
4992
5075
  :host([inline]) .wf-btn {
4993
- min-height: var(--wf-input-min-height, 56px);
5076
+ min-height: 16px;
4994
5077
  width: auto;
4995
- padding: var(--wf-spacing-3, 12px) var(--wf-spacing-5, 20px);
4996
- }
4997
-
4998
- :host([inline]) .wf-btn-shortcut {
4999
- position: static;
5000
- margin-left: var(--wf-spacing-2, 8px);
5078
+ padding-top: 8px;
5079
+ padding-bottom: 8px;
5080
+ padding-left: 12px;
5081
+ padding-right: 8px;
5001
5082
  }
5002
5083
  `
5003
5084
  ];
@@ -5061,7 +5142,7 @@ let WfNextBtn = class extends NavigationButtonBase {
5061
5142
  ${buttonLabel}
5062
5143
  ${this.showShortcut ? b`
5063
5144
  <span class="wf-btn-shortcut ${this.inline ? "wf-btn-shortcut-inline" : ""}">
5064
- <wf-badge variant="button" shortcut="↵"></wf-badge>
5145
+ <wf-badge variant="button" shortcut="Enter ↵"></wf-badge>
5065
5146
  </span>
5066
5147
  ` : A}
5067
5148
  `}
@@ -5100,22 +5181,22 @@ const wfBackBtnStyles = [
5100
5181
  }
5101
5182
 
5102
5183
  .wf-btn-back {
5103
- background: var(--wf-glass-bg, rgba(255, 255, 255, 0.7));
5104
- backdrop-filter: blur(var(--wf-glass-blur, 20px));
5105
- -webkit-backdrop-filter: blur(var(--wf-glass-blur, 20px));
5106
- border: 1px solid var(--wf-glass-border, rgba(0, 0, 0, 0.1));
5107
- box-shadow: var(--wf-glass-shadow, 0 4px 6px rgba(0, 0, 0, 0.05));
5108
- color: var(--wf-color-text, #0a0a0a);
5184
+ background: var(--wf-glass-bg);
5185
+ backdrop-filter: blur(var(--wf-glass-blur));
5186
+ -webkit-backdrop-filter: blur(var(--wf-glass-blur));
5187
+ border: 1px solid var(--wf-glass-border);
5188
+ box-shadow: var(--wf-glass-shadow);
5189
+ color: var(--wf-color-text);
5109
5190
  }
5110
5191
 
5111
5192
  .wf-btn-back:hover:not(:disabled) {
5112
- background: var(--wf-glass-bg-hover, rgba(255, 255, 255, 0.85));
5193
+ background: var(--wf-glass-bg-hover);
5113
5194
  }
5114
5195
 
5115
5196
  .wf-btn-shortcut {
5116
5197
  display: inline-flex;
5117
5198
  align-items: center;
5118
- gap: 2px;
5199
+ gap: var(--wf-spacing-05);
5119
5200
  }
5120
5201
  `
5121
5202
  ];