aw-wizard-forms 3.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -177,7 +177,7 @@ function createRevenueHeroAdapter(config) {
177
177
  * Copyright 2019 Google LLC
178
178
  * SPDX-License-Identifier: BSD-3-Clause
179
179
  */
180
- const t$2 = globalThis, e$2 = t$2.ShadowRoot && (void 0 === t$2.ShadyCSS || t$2.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, s$2 = Symbol(), o$4 = /* @__PURE__ */ new WeakMap();
180
+ const t$2 = globalThis, e$4 = t$2.ShadowRoot && (void 0 === t$2.ShadyCSS || t$2.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, s$2 = Symbol(), o$4 = /* @__PURE__ */ new WeakMap();
181
181
  let n$3 = class n {
182
182
  constructor(t2, e2, o2) {
183
183
  if (this._$cssResult$ = true, o2 !== s$2) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
@@ -186,7 +186,7 @@ let n$3 = class n {
186
186
  get styleSheet() {
187
187
  let t2 = this.o;
188
188
  const s2 = this.t;
189
- if (e$2 && void 0 === t2) {
189
+ if (e$4 && void 0 === t2) {
190
190
  const e2 = void 0 !== s2 && 1 === s2.length;
191
191
  e2 && (t2 = o$4.get(s2)), void 0 === t2 && ((this.o = t2 = new CSSStyleSheet()).replaceSync(this.cssText), e2 && o$4.set(s2, t2));
192
192
  }
@@ -196,13 +196,20 @@ let n$3 = class n {
196
196
  return this.cssText;
197
197
  }
198
198
  };
199
- const r$4 = (t2) => new n$3("string" == typeof t2 ? t2 : t2 + "", void 0, s$2), S$1 = (s2, o2) => {
200
- if (e$2) s2.adoptedStyleSheets = o2.map((t2) => t2 instanceof CSSStyleSheet ? t2 : t2.styleSheet);
199
+ const r$4 = (t2) => new n$3("string" == typeof t2 ? t2 : t2 + "", void 0, s$2), i$3 = (t2, ...e2) => {
200
+ const o2 = 1 === t2.length ? t2[0] : e2.reduce((e3, s2, o3) => e3 + ((t3) => {
201
+ if (true === t3._$cssResult$) return t3.cssText;
202
+ if ("number" == typeof t3) return t3;
203
+ throw Error("Value passed to 'css' function must be a 'css' function result: " + t3 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.");
204
+ })(s2) + t2[o3 + 1], t2[0]);
205
+ return new n$3(o2, t2, s$2);
206
+ }, S$1 = (s2, o2) => {
207
+ if (e$4) s2.adoptedStyleSheets = o2.map((t2) => t2 instanceof CSSStyleSheet ? t2 : t2.styleSheet);
201
208
  else for (const e2 of o2) {
202
209
  const o3 = document.createElement("style"), n3 = t$2.litNonce;
203
210
  void 0 !== n3 && o3.setAttribute("nonce", n3), o3.textContent = e2.cssText, s2.appendChild(o3);
204
211
  }
205
- }, c$2 = e$2 ? (t2) => t2 : (t2) => t2 instanceof CSSStyleSheet ? ((t3) => {
212
+ }, c$2 = e$4 ? (t2) => t2 : (t2) => t2 instanceof CSSStyleSheet ? ((t3) => {
206
213
  let e2 = "";
207
214
  for (const s2 of t3.cssRules) e2 += s2.cssText;
208
215
  return r$4(e2);
@@ -212,7 +219,7 @@ const r$4 = (t2) => new n$3("string" == typeof t2 ? t2 : t2 + "", void 0, s$2),
212
219
  * Copyright 2017 Google LLC
213
220
  * SPDX-License-Identifier: BSD-3-Clause
214
221
  */
215
- const { is: i$2, defineProperty: e$1, getOwnPropertyDescriptor: h$1, getOwnPropertyNames: r$3, getOwnPropertySymbols: o$3, getPrototypeOf: n$2 } = Object, a$1 = globalThis, c$1 = a$1.trustedTypes, l$1 = c$1 ? c$1.emptyScript : "", p$1 = a$1.reactiveElementPolyfillSupport, d$1 = (t2, s2) => t2, u$1 = { toAttribute(t2, s2) {
222
+ const { is: i$2, defineProperty: e$3, getOwnPropertyDescriptor: h$1, getOwnPropertyNames: r$3, getOwnPropertySymbols: o$3, getPrototypeOf: n$2 } = Object, a$1 = globalThis, c$1 = a$1.trustedTypes, l$1 = c$1 ? c$1.emptyScript : "", p$1 = a$1.reactiveElementPolyfillSupport, d$1 = (t2, s2) => t2, u$1 = { toAttribute(t2, s2) {
216
223
  switch (s2) {
217
224
  case Boolean:
218
225
  t2 = t2 ? l$1 : null;
@@ -252,7 +259,7 @@ let y$1 = class y extends HTMLElement {
252
259
  static createProperty(t2, s2 = b$1) {
253
260
  if (s2.state && (s2.attribute = false), this._$Ei(), this.prototype.hasOwnProperty(t2) && ((s2 = Object.create(s2)).wrapped = true), this.elementProperties.set(t2, s2), !s2.noAccessor) {
254
261
  const i2 = Symbol(), h2 = this.getPropertyDescriptor(t2, i2, s2);
255
- void 0 !== h2 && e$1(this.prototype, t2, h2);
262
+ void 0 !== h2 && e$3(this.prototype, t2, h2);
256
263
  }
257
264
  }
258
265
  static getPropertyDescriptor(t2, s2, i2) {
@@ -429,11 +436,11 @@ y$1.elementStyles = [], y$1.shadowRootOptions = { mode: "open" }, y$1[d$1("eleme
429
436
  * Copyright 2017 Google LLC
430
437
  * SPDX-License-Identifier: BSD-3-Clause
431
438
  */
432
- const t$1 = globalThis, i$1 = (t2) => t2, s$1 = t$1.trustedTypes, e = s$1 ? s$1.createPolicy("lit-html", { createHTML: (t2) => t2 }) : void 0, h = "$lit$", o$2 = `lit$${Math.random().toFixed(9).slice(2)}$`, n$1 = "?" + o$2, r$2 = `<${n$1}>`, l = document, c = () => l.createComment(""), a = (t2) => null === t2 || "object" != typeof t2 && "function" != typeof t2, u = Array.isArray, d = (t2) => u(t2) || "function" == typeof t2?.[Symbol.iterator], f = "[ \n\f\r]", v = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, _ = /-->/g, m = />/g, p = RegExp(`>|${f}(?:([^\\s"'>=/]+)(${f}*=${f}*(?:[^
439
+ const t$1 = globalThis, i$1 = (t2) => t2, s$1 = t$1.trustedTypes, e$2 = s$1 ? s$1.createPolicy("lit-html", { createHTML: (t2) => t2 }) : void 0, h = "$lit$", o$2 = `lit$${Math.random().toFixed(9).slice(2)}$`, n$1 = "?" + o$2, r$2 = `<${n$1}>`, l = document, c = () => l.createComment(""), a = (t2) => null === t2 || "object" != typeof t2 && "function" != typeof t2, u = Array.isArray, d = (t2) => u(t2) || "function" == typeof t2?.[Symbol.iterator], f = "[ \n\f\r]", v = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, _ = /-->/g, m = />/g, p = RegExp(`>|${f}(?:([^\\s"'>=/]+)(${f}*=${f}*(?:[^
433
440
  \f\r"'\`<>=]|("|')|))|$)`, "g"), g = /'/g, $ = /"/g, y2 = /^(?:script|style|textarea|title)$/i, x = (t2) => (i2, ...s2) => ({ _$litType$: t2, strings: i2, values: s2 }), b = x(1), E = Symbol.for("lit-noChange"), A = Symbol.for("lit-nothing"), C = /* @__PURE__ */ new WeakMap(), P = l.createTreeWalker(l, 129);
434
441
  function V(t2, i2) {
435
442
  if (!u(t2) || !t2.hasOwnProperty("raw")) throw Error("invalid template strings array");
436
- return void 0 !== e ? e.createHTML(i2) : i2;
443
+ return void 0 !== e$2 ? e$2.createHTML(i2) : i2;
437
444
  }
438
445
  const N = (t2, i2) => {
439
446
  const s2 = t2.length - 1, e2 = [];
@@ -736,6 +743,280 @@ function n2(t2) {
736
743
  function r(r2) {
737
744
  return n2({ ...r2, state: true, attribute: false });
738
745
  }
746
+ /**
747
+ * @license
748
+ * Copyright 2017 Google LLC
749
+ * SPDX-License-Identifier: BSD-3-Clause
750
+ */
751
+ const e$1 = (e2, t2, c2) => (c2.configurable = true, c2.enumerable = true, Reflect.decorate && "object" != typeof t2 && Object.defineProperty(e2, t2, c2), c2);
752
+ /**
753
+ * @license
754
+ * Copyright 2017 Google LLC
755
+ * SPDX-License-Identifier: BSD-3-Clause
756
+ */
757
+ function e(e2, r2) {
758
+ return (n3, s2, i2) => {
759
+ const o2 = (t2) => t2.renderRoot?.querySelector(e2) ?? null;
760
+ return e$1(n3, s2, { get() {
761
+ return o2(this);
762
+ } });
763
+ };
764
+ }
765
+ i$3`
766
+ /* Colors */
767
+ --wf-color-primary: #8040f0;
768
+ --wf-color-primary-border: #602cbb;
769
+ --wf-color-primary-light: rgba(128, 64, 240, 0.08);
770
+ --wf-color-surface: #f3f3f5;
771
+ --wf-color-surface-hover: #e9e9eb;
772
+ --wf-color-border: #d4d4d4;
773
+ --wf-color-text: #0a0a0a;
774
+ --wf-color-text-secondary: #404040;
775
+ --wf-color-text-muted: #646464;
776
+ --wf-color-error: #dc3545;
777
+ --wf-color-badge-bg: #fcfcfc;
778
+ --wf-color-badge-border: #d4d4d4;
779
+ --wf-color-badge-text: #5f5f5f;
780
+ --wf-color-progress-active: rgba(0, 0, 0, 0.1);
781
+ --wf-color-progress-inactive: rgba(0, 0, 0, 0.05);
782
+
783
+ /* Spacing scale */
784
+ --wf-spacing-1: 4px;
785
+ --wf-spacing-2: 8px;
786
+ --wf-spacing-3: 12px;
787
+ --wf-spacing-4: 16px;
788
+ --wf-spacing-5: 20px;
789
+ --wf-spacing-6: 24px;
790
+ --wf-spacing-8: 32px;
791
+
792
+ /* Border radius */
793
+ --wf-radius-sm: 4px;
794
+ --wf-radius-md: 8px;
795
+ --wf-radius-lg: 8px;
796
+ --wf-radius-full: 99px;
797
+
798
+ /* Typography */
799
+ --wf-font-size-xs: 0.75rem;
800
+ --wf-font-size-sm: 0.875rem;
801
+ --wf-font-size-base: 1rem;
802
+ --wf-font-size-lg: 1.25rem;
803
+ --wf-font-size-xl: 1.5rem;
804
+ --wf-font-size-2xl: 2rem;
805
+ --wf-font-size-3xl: 2.5rem;
806
+
807
+ /* Input dimensions */
808
+ --wf-input-min-height: 56px;
809
+
810
+ /* Frosted glass effect (iOS-style) */
811
+ --wf-glass-bg: rgba(255, 255, 255, 0.7);
812
+ --wf-glass-bg-hover: rgba(255, 255, 255, 0.85);
813
+ --wf-glass-border: rgba(0, 0, 0, 0.1);
814
+ --wf-glass-blur: 20px;
815
+ --wf-glass-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
816
+ `;
817
+ i$3`
818
+ --wf-color-surface: #2d2d2d;
819
+ --wf-color-surface-hover: #3d3d3d;
820
+ --wf-color-border: #4d4d4d;
821
+ --wf-color-text: #f8f9fa;
822
+ --wf-color-text-secondary: #d0d0d0;
823
+ --wf-color-text-muted: #adb5bd;
824
+ --wf-color-badge-bg: #3d3d3d;
825
+ --wf-color-badge-border: #4d4d4d;
826
+ --wf-color-badge-text: #adb5bd;
827
+ --wf-color-progress-active: rgba(200, 200, 200, 0.6);
828
+ --wf-color-progress-inactive: rgba(100, 100, 100, 0.6);
829
+
830
+ /* Dark theme frosted glass */
831
+ --wf-glass-bg: rgba(45, 45, 45, 0.7);
832
+ --wf-glass-bg-hover: rgba(60, 60, 60, 0.8);
833
+ --wf-glass-border: rgba(255, 255, 255, 0.1);
834
+ `;
835
+ 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)}`;
838
+ i$3`
839
+ ${sharedAnimations}
840
+
841
+ * {
842
+ box-sizing: border-box;
843
+ }
844
+ `;
845
+ const wizardFormStyles = [
846
+ sharedAnimations,
847
+ i$3`
848
+ /* ----------------------------------------
849
+ :host - Design tokens & base styles
850
+ ---------------------------------------- */
851
+ :host {
852
+ display: block;
853
+
854
+ /* Color tokens */
855
+ --wf-color-primary: #8040f0;
856
+ --wf-color-primary-border: #602cbb;
857
+ --wf-color-primary-light: rgba(128, 64, 240, 0.08);
858
+ --wf-color-surface: #f3f3f5;
859
+ --wf-color-surface-hover: #e9e9eb;
860
+ --wf-color-border: #d4d4d4;
861
+ --wf-color-text: #0a0a0a;
862
+ --wf-color-text-secondary: #404040;
863
+ --wf-color-text-muted: #646464;
864
+ --wf-color-error: #dc3545;
865
+ --wf-color-badge-bg: #fcfcfc;
866
+ --wf-color-badge-border: #d4d4d4;
867
+ --wf-color-badge-text: #5f5f5f;
868
+ --wf-color-progress-active: rgba(0, 0, 0, 0.1);
869
+ --wf-color-progress-inactive: rgba(0, 0, 0, 0.05);
870
+
871
+ /* Spacing tokens */
872
+ --wf-spacing-1: 4px;
873
+ --wf-spacing-2: 8px;
874
+ --wf-spacing-3: 12px;
875
+ --wf-spacing-4: 16px;
876
+ --wf-spacing-5: 20px;
877
+ --wf-spacing-6: 24px;
878
+ --wf-spacing-8: 32px;
879
+
880
+ /* Border radius tokens */
881
+ --wf-radius-sm: 4px;
882
+ --wf-radius-md: 8px;
883
+ --wf-radius-lg: 8px;
884
+ --wf-radius-full: 99px;
885
+
886
+ /* Typography tokens */
887
+ --wf-font-size-xs: 0.75rem;
888
+ --wf-font-size-sm: 0.875rem;
889
+ --wf-font-size-base: 1rem;
890
+ --wf-font-size-lg: 1.25rem;
891
+ --wf-font-size-xl: 1.5rem;
892
+ --wf-font-size-2xl: 2rem;
893
+ --wf-font-size-3xl: 2.5rem;
894
+
895
+ /* Input tokens */
896
+ --wf-input-min-height: 56px;
897
+
898
+ /* Frosted glass effect (iOS-style) */
899
+ --wf-glass-bg: rgba(255, 255, 255, 0.7);
900
+ --wf-glass-bg-hover: rgba(255, 255, 255, 0.85);
901
+ --wf-glass-border: rgba(0, 0, 0, 0.1);
902
+ --wf-glass-blur: 20px;
903
+ --wf-glass-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
904
+ }
905
+
906
+ :host([hidden]) {
907
+ display: none;
908
+ }
909
+
910
+ /* Dark theme */
911
+ :host([theme='dark']) {
912
+ --wf-color-surface: #2d2d2d;
913
+ --wf-color-surface-hover: #3d3d3d;
914
+ --wf-color-border: #4d4d4d;
915
+ --wf-color-text: #f8f9fa;
916
+ --wf-color-text-secondary: #d0d0d0;
917
+ --wf-color-text-muted: #adb5bd;
918
+ --wf-color-badge-bg: #3d3d3d;
919
+ --wf-color-badge-border: #4d4d4d;
920
+ --wf-color-badge-text: #adb5bd;
921
+ --wf-color-progress-active: rgba(200, 200, 200, 0.6);
922
+ --wf-color-progress-inactive: rgba(100, 100, 100, 0.6);
923
+
924
+ /* Dark theme frosted glass */
925
+ --wf-glass-bg: rgba(45, 45, 45, 0.7);
926
+ --wf-glass-bg-hover: rgba(60, 60, 60, 0.8);
927
+ --wf-glass-border: rgba(255, 255, 255, 0.1);
928
+ }
929
+
930
+ /* Auto theme (respects system preference) */
931
+ @media (prefers-color-scheme: dark) {
932
+ :host([theme='auto']) {
933
+ --wf-color-surface: #2d2d2d;
934
+ --wf-color-surface-hover: #3d3d3d;
935
+ --wf-color-border: #4d4d4d;
936
+ --wf-color-text: #f8f9fa;
937
+ --wf-color-text-secondary: #d0d0d0;
938
+ --wf-color-text-muted: #adb5bd;
939
+ --wf-color-badge-bg: #3d3d3d;
940
+ --wf-color-badge-border: #4d4d4d;
941
+ --wf-color-badge-text: #adb5bd;
942
+ --wf-color-progress-active: rgba(200, 200, 200, 0.6);
943
+ --wf-color-progress-inactive: rgba(100, 100, 100, 0.6);
944
+
945
+ /* Dark theme frosted glass */
946
+ --wf-glass-bg: rgba(45, 45, 45, 0.7);
947
+ --wf-glass-bg-hover: rgba(60, 60, 60, 0.8);
948
+ --wf-glass-border: rgba(255, 255, 255, 0.1);
949
+ }
950
+ }
951
+
952
+ /* ----------------------------------------
953
+ Container
954
+ ---------------------------------------- */
955
+ .wf-container {
956
+ margin: 0 auto;
957
+ }
958
+
959
+ /* ----------------------------------------
960
+ Success screen
961
+ ---------------------------------------- */
962
+ .wf-success-screen {
963
+ text-align: center;
964
+ padding: var(--wf-spacing-6, 24px);
965
+ }
966
+
967
+ /* ----------------------------------------
968
+ Error message
969
+ ---------------------------------------- */
970
+ .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);
978
+ }
979
+
980
+ /* ----------------------------------------
981
+ Slot styles
982
+ ---------------------------------------- */
983
+ ::slotted(wf-step) {
984
+ display: none;
985
+ width: 100%;
986
+ }
987
+
988
+ ::slotted(wf-step[active]) {
989
+ display: block;
990
+ animation: wf-stepFadeIn 0.3s ease forwards;
991
+ }
992
+
993
+ ::slotted(wf-step[direction='forward'][active]) {
994
+ animation: wf-stepSlideInRight 0.3s ease forwards;
995
+ }
996
+
997
+ ::slotted(wf-step[direction='backward'][active]) {
998
+ animation: wf-stepSlideInLeft 0.3s ease forwards;
999
+ }
1000
+
1001
+ ::slotted(wf-step[leaving]) {
1002
+ display: block;
1003
+ animation: wf-stepFadeOut 0.2s ease forwards;
1004
+ }
1005
+
1006
+ /* Success slot hidden by default, shown when submitted */
1007
+ ::slotted([slot='success']) {
1008
+ display: none;
1009
+ }
1010
+
1011
+ :host([submitted]) ::slotted([slot='success']) {
1012
+ display: block;
1013
+ }
1014
+
1015
+ :host([submitted]) ::slotted(wf-step) {
1016
+ display: none !important;
1017
+ }
1018
+ `
1019
+ ];
739
1020
  class FormStateController {
740
1021
  constructor(host) {
741
1022
  this._formData = {};
@@ -1065,14 +1346,67 @@ class KeyboardController {
1065
1346
  return this._enabled;
1066
1347
  }
1067
1348
  }
1068
- var __defProp$d = Object.defineProperty;
1069
- var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
1070
- var __decorateClass$d = (decorators, target, key, kind) => {
1071
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
1349
+ const wfBadgeStyles = i$3`
1350
+ :host {
1351
+ display: inline-flex;
1352
+ }
1353
+
1354
+ :host([hidden]) {
1355
+ display: none;
1356
+ }
1357
+
1358
+ .wf-badge {
1359
+ display: inline-flex;
1360
+ align-items: center;
1361
+ justify-content: center;
1362
+ 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;
1369
+ text-transform: uppercase;
1370
+ flex-shrink: 0;
1371
+ line-height: 1;
1372
+ }
1373
+
1374
+ .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);
1379
+ }
1380
+
1381
+ .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);
1385
+ color: white;
1386
+ }
1387
+
1388
+ .wf-badge--button {
1389
+ background-color: transparent;
1390
+ border: none;
1391
+ border-radius: var(--wf-radius-sm, 4px);
1392
+ color: rgba(255, 255, 255, 0.65);
1393
+ }
1394
+
1395
+ .wf-badge--button-secondary {
1396
+ background-color: transparent;
1397
+ border: none;
1398
+ border-radius: var(--wf-radius-sm, 4px);
1399
+ color: var(--wf-color-text-muted, #5f5f5f);
1400
+ }
1401
+ `;
1402
+ var __defProp$f = Object.defineProperty;
1403
+ var __getOwnPropDesc$d = Object.getOwnPropertyDescriptor;
1404
+ var __decorateClass$f = (decorators, target, key, kind) => {
1405
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$d(target, key) : target;
1072
1406
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1073
1407
  if (decorator = decorators[i2])
1074
1408
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1075
- if (kind && result) __defProp$d(target, key, result);
1409
+ if (kind && result) __defProp$f(target, key, result);
1076
1410
  return result;
1077
1411
  };
1078
1412
  let WfBadge = class extends i {
@@ -1081,40 +1415,36 @@ let WfBadge = class extends i {
1081
1415
  this.shortcut = "";
1082
1416
  this.variant = "default";
1083
1417
  }
1084
- /**
1085
- * Disable Shadow DOM - render to Light DOM for external styling
1086
- */
1087
- createRenderRoot() {
1088
- return this;
1089
- }
1090
1418
  render() {
1091
1419
  return b`
1092
1420
  <span
1093
1421
  class="wf-badge wf-badge--${this.variant}"
1094
1422
  aria-hidden="true"
1423
+ data-testid="wf-badge"
1095
1424
  >
1096
1425
  ${this.shortcut}
1097
1426
  </span>
1098
1427
  `;
1099
1428
  }
1100
1429
  };
1101
- __decorateClass$d([
1430
+ WfBadge.styles = wfBadgeStyles;
1431
+ __decorateClass$f([
1102
1432
  n2({ type: String })
1103
1433
  ], WfBadge.prototype, "shortcut", 2);
1104
- __decorateClass$d([
1434
+ __decorateClass$f([
1105
1435
  n2({ type: String })
1106
1436
  ], WfBadge.prototype, "variant", 2);
1107
- WfBadge = __decorateClass$d([
1437
+ WfBadge = __decorateClass$f([
1108
1438
  t("wf-badge")
1109
1439
  ], WfBadge);
1110
- var __defProp$c = Object.defineProperty;
1111
- var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
1112
- var __decorateClass$c = (decorators, target, key, kind) => {
1113
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
1440
+ var __defProp$e = Object.defineProperty;
1441
+ var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
1442
+ var __decorateClass$e = (decorators, target, key, kind) => {
1443
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
1114
1444
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1115
1445
  if (decorator = decorators[i2])
1116
1446
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1117
- if (kind && result) __defProp$c(target, key, result);
1447
+ if (kind && result) __defProp$e(target, key, result);
1118
1448
  return result;
1119
1449
  };
1120
1450
  let WizardForm = class extends i {
@@ -1133,9 +1463,9 @@ let WizardForm = class extends i {
1133
1463
  this._totalSteps = 0;
1134
1464
  this._formData = {};
1135
1465
  this._submitting = false;
1136
- this._submitted = false;
1466
+ this.submitted = false;
1137
1467
  this._error = "";
1138
- this._cachedSuccessContent = null;
1468
+ this._otherInputActive = false;
1139
1469
  this._stateController = new FormStateController(this);
1140
1470
  this._handleFieldChange = (e2) => {
1141
1471
  const { name, value, extraFields } = e2.detail;
@@ -1146,6 +1476,10 @@ let WizardForm = class extends i {
1146
1476
  this._formData[fieldName] = fieldValue;
1147
1477
  this._stateController.setValue(fieldName, fieldValue);
1148
1478
  });
1479
+ const hasOtherText = Object.values(extraFields).some((v2) => v2 && String(v2).trim());
1480
+ this._otherInputActive = hasOtherText;
1481
+ } else {
1482
+ this._otherInputActive = false;
1149
1483
  }
1150
1484
  this._error = "";
1151
1485
  this.dispatchEvent(
@@ -1161,6 +1495,9 @@ let WizardForm = class extends i {
1161
1495
  );
1162
1496
  };
1163
1497
  this._handleOptionSelect = (e2) => {
1498
+ if (this._stepHasComposableNav()) {
1499
+ return;
1500
+ }
1164
1501
  if (this.autoAdvance) {
1165
1502
  const target = e2.target;
1166
1503
  const optionsParent = target.closest("wf-options");
@@ -1171,17 +1508,22 @@ let WizardForm = class extends i {
1171
1508
  }
1172
1509
  }
1173
1510
  };
1511
+ this._handleNavNext = async (e2) => {
1512
+ e2.stopPropagation();
1513
+ await this._goNext();
1514
+ };
1515
+ this._handleNavBack = (e2) => {
1516
+ e2.stopPropagation();
1517
+ this._goBack();
1518
+ };
1519
+ this._handleNavStateRequest = () => {
1520
+ this._broadcastNavState();
1521
+ };
1174
1522
  new KeyboardController(this, {
1175
1523
  onEnter: () => this._handleEnter(),
1176
1524
  onEscape: () => this._handleEscape()
1177
1525
  });
1178
1526
  }
1179
- /**
1180
- * Disable Shadow DOM - render to Light DOM for external styling
1181
- */
1182
- createRenderRoot() {
1183
- return this;
1184
- }
1185
1527
  // ============================================
1186
1528
  // Lifecycle
1187
1529
  // ============================================
@@ -1189,56 +1531,56 @@ let WizardForm = class extends i {
1189
1531
  super.connectedCallback();
1190
1532
  this.addEventListener("wf-change", this._handleFieldChange);
1191
1533
  this.addEventListener("wf-option-select", this._handleOptionSelect);
1534
+ this.addEventListener("wf:nav-next", this._handleNavNext);
1535
+ this.addEventListener("wf:nav-back", this._handleNavBack);
1536
+ this.addEventListener("wf:nav-state-request", this._handleNavStateRequest);
1192
1537
  }
1193
1538
  disconnectedCallback() {
1194
1539
  super.disconnectedCallback();
1195
1540
  this.removeEventListener("wf-change", this._handleFieldChange);
1196
1541
  this.removeEventListener("wf-option-select", this._handleOptionSelect);
1542
+ this.removeEventListener("wf:nav-next", this._handleNavNext);
1543
+ this.removeEventListener("wf:nav-back", this._handleNavBack);
1544
+ this.removeEventListener("wf:nav-state-request", this._handleNavStateRequest);
1197
1545
  }
1198
1546
  firstUpdated() {
1199
- this._cachedSuccessContent = this.querySelector('[slot="success"]');
1200
1547
  this._discoverSteps();
1201
1548
  this._showCurrentStep();
1549
+ this._broadcastNavState();
1202
1550
  }
1203
1551
  // ============================================
1204
1552
  // Rendering
1205
1553
  // ============================================
1206
1554
  render() {
1207
- if (this._submitted) {
1555
+ if (this.submitted) {
1208
1556
  this._steps.forEach((step) => {
1209
1557
  step.active = false;
1210
- step.style.display = "none";
1211
1558
  });
1212
- if (this._cachedSuccessContent) {
1213
- this._cachedSuccessContent.style.display = "";
1214
- return b`
1215
- <div class="wf-container wf-submitted">
1559
+ return b`
1560
+ <div class="wf-container" data-testid="wf-container">
1561
+ <slot name="success">
1216
1562
  <div class="wf-success-screen">
1217
- ${this._cachedSuccessContent}
1563
+ <h2>Thank you!</h2>
1564
+ <p>Your submission has been received.</p>
1218
1565
  </div>
1219
- </div>
1220
- `;
1221
- }
1222
- return b`
1223
- <div class="wf-container wf-submitted">
1224
- <div class="wf-success-screen">
1225
- <h2>Thank you!</h2>
1226
- <p>Your submission has been received.</p>
1227
- </div>
1566
+ </slot>
1228
1567
  </div>
1229
1568
  `;
1230
1569
  }
1231
- if (this._cachedSuccessContent) {
1232
- this._cachedSuccessContent.style.display = "none";
1233
- }
1234
1570
  return b`
1235
- <div class="wf-container">
1236
- ${this._error ? b`<div class="wf-form-error" role="alert">${this._error}</div>` : A}
1571
+ <div class="wf-container" data-testid="wf-container">
1572
+ ${this._error ? b`<div class="wf-form-error" role="alert" data-testid="wf-form-error">${this._error}</div>` : A}
1237
1573
 
1238
- ${this._renderNavigation()}
1574
+ <slot @slotchange="${this._handleSlotChange}"></slot>
1239
1575
  </div>
1240
1576
  `;
1241
1577
  }
1578
+ /**
1579
+ * Handle slot changes to re-discover steps when DOM changes
1580
+ */
1581
+ _handleSlotChange() {
1582
+ this._discoverSteps();
1583
+ }
1242
1584
  _renderProgress() {
1243
1585
  const segments = [];
1244
1586
  for (let i2 = 1; i2 <= this._totalSteps; i2++) {
@@ -1252,41 +1594,27 @@ let WizardForm = class extends i {
1252
1594
  }
1253
1595
  return b`<div class="wf-progress">${segments}</div>`;
1254
1596
  }
1597
+ /**
1598
+ * Centralized navigation is no longer rendered.
1599
+ * All navigation is now fully composable via <wf-next-btn> and <wf-back-btn>.
1600
+ * Keyboard shortcuts (Enter/Esc) still work regardless of button presence.
1601
+ */
1255
1602
  _renderNavigation() {
1256
- const isFirst = this._currentStep === 1;
1257
- const isLast = this._currentStep === this._totalSteps;
1258
- const showBack = !this.hideBack && !isFirst;
1259
- return b`
1260
- <div class="wf-navigation">
1261
- ${showBack ? b`
1262
- <button
1263
- class="wf-btn wf-btn-back"
1264
- @click="${this._goBack}"
1265
- ?disabled="${this._submitting}"
1266
- data-testid="wf-back-btn"
1267
- >
1268
- <span class="wf-btn-shortcut"><wf-badge shortcut="Esc" variant="button-secondary"></wf-badge></span>
1269
- Back
1270
- </button>
1271
- ` : A}
1272
-
1273
- <button
1274
- class="wf-btn wf-btn-next"
1275
- @click="${this._goNext}"
1276
- ?disabled="${this._submitting}"
1277
- data-testid="wf-next-btn"
1278
- >
1279
- ${this._submitting ? b`<span class="wf-loading"></span>` : isLast ? "Submit" : "Continue"}
1280
- <span class="wf-btn-shortcut"><wf-badge shortcut="Enter ↵" variant="button"></wf-badge></span>
1281
- </button>
1282
- </div>
1283
- `;
1603
+ return A;
1284
1604
  }
1285
1605
  // ============================================
1286
1606
  // Step Discovery
1287
1607
  // ============================================
1288
1608
  _discoverSteps() {
1289
- this._steps = Array.from(this.querySelectorAll(":scope > wf-step"));
1609
+ const slot = this.shadowRoot?.querySelector("slot:not([name])");
1610
+ if (slot) {
1611
+ const assignedElements = slot.assignedElements({ flatten: true });
1612
+ this._steps = assignedElements.filter(
1613
+ (el) => el.tagName.toLowerCase() === "wf-step"
1614
+ );
1615
+ } else {
1616
+ this._steps = Array.from(this.querySelectorAll(":scope > wf-step"));
1617
+ }
1290
1618
  this._steps.forEach((step, index) => {
1291
1619
  step.step = index + 1;
1292
1620
  });
@@ -1323,6 +1651,71 @@ let WizardForm = class extends i {
1323
1651
  // ============================================
1324
1652
  // Navigation
1325
1653
  // ============================================
1654
+ /**
1655
+ * Check if the current step requires manual navigation (Continue button).
1656
+ * Returns true if step contains typing inputs or multi-select options.
1657
+ * Returns false if step only has single-select options (auto-advance handles it).
1658
+ */
1659
+ _stepRequiresManualNav() {
1660
+ if (!this.autoAdvance) {
1661
+ return true;
1662
+ }
1663
+ const currentStep = this._getStepByNumber(this._currentStep);
1664
+ if (!currentStep) {
1665
+ return true;
1666
+ }
1667
+ const typingControls = ["wf-input", "wf-email", "wf-textarea", "wf-number"];
1668
+ for (const selector of typingControls) {
1669
+ if (currentStep.querySelector(selector)) {
1670
+ return true;
1671
+ }
1672
+ }
1673
+ const multiSelectOptions = currentStep.querySelector("wf-options[multi]");
1674
+ if (multiSelectOptions) {
1675
+ return true;
1676
+ }
1677
+ const allowOtherOptions = currentStep.querySelector("wf-options[allow-other]");
1678
+ if (allowOtherOptions && this._otherInputActive) {
1679
+ return true;
1680
+ }
1681
+ return false;
1682
+ }
1683
+ /**
1684
+ * Check if the current step has composable navigation buttons at the step level.
1685
+ * Excludes buttons inside wf-other (those are for inline "Others" input only).
1686
+ * When present, auto-advance is disabled for the step.
1687
+ */
1688
+ _stepHasComposableNav() {
1689
+ const currentStep = this._getStepByNumber(this._currentStep);
1690
+ if (!currentStep) {
1691
+ return false;
1692
+ }
1693
+ const navButtons = currentStep.querySelectorAll("wf-next-btn, wf-back-btn");
1694
+ for (const btn of navButtons) {
1695
+ if (!btn.closest("wf-other")) {
1696
+ return true;
1697
+ }
1698
+ }
1699
+ return false;
1700
+ }
1701
+ /**
1702
+ * Broadcast navigation state to composable buttons.
1703
+ * Called on step changes and submit state changes.
1704
+ */
1705
+ _broadcastNavState() {
1706
+ this.dispatchEvent(
1707
+ new CustomEvent("wf:nav-state", {
1708
+ detail: {
1709
+ currentStep: this._currentStep,
1710
+ totalSteps: this._totalSteps,
1711
+ isFirstStep: this._currentStep === 1,
1712
+ isLastStep: this._currentStep === this._totalSteps,
1713
+ isSubmitting: this._submitting
1714
+ },
1715
+ bubbles: false
1716
+ })
1717
+ );
1718
+ }
1326
1719
  async _goNext() {
1327
1720
  if (this._submitting) {
1328
1721
  return;
@@ -1393,6 +1786,8 @@ let WizardForm = class extends i {
1393
1786
  }
1394
1787
  this._currentStep = targetStep;
1395
1788
  this._stateController.goToStep(targetStep);
1789
+ this._otherInputActive = false;
1790
+ this._broadcastNavState();
1396
1791
  targetStepEl.show(direction);
1397
1792
  this.dispatchEvent(
1398
1793
  new CustomEvent("wf:step-change", {
@@ -1434,6 +1829,7 @@ let WizardForm = class extends i {
1434
1829
  }
1435
1830
  this._submitting = true;
1436
1831
  this._error = "";
1832
+ this._broadcastNavState();
1437
1833
  let submitData = rawData;
1438
1834
  if (this.serialize) {
1439
1835
  submitData = this.serialize(rawData);
@@ -1449,7 +1845,7 @@ let WizardForm = class extends i {
1449
1845
  console.warn("[WizardForm] No submission target configured. Use hubspot-portal/hubspot-form or mock.");
1450
1846
  response = { success: true };
1451
1847
  }
1452
- this._submitted = true;
1848
+ this.submitted = true;
1453
1849
  this.dispatchEvent(
1454
1850
  new CustomEvent("wf:success", {
1455
1851
  detail: {
@@ -1475,6 +1871,7 @@ let WizardForm = class extends i {
1475
1871
  );
1476
1872
  } finally {
1477
1873
  this._submitting = false;
1874
+ this._broadcastNavState();
1478
1875
  }
1479
1876
  }
1480
1877
  async _submitToHubSpot(formData) {
@@ -1566,7 +1963,7 @@ let WizardForm = class extends i {
1566
1963
  * Check if form was submitted
1567
1964
  */
1568
1965
  get isSubmitted() {
1569
- return this._submitted;
1966
+ return this.submitted;
1570
1967
  }
1571
1968
  /**
1572
1969
  * Go to a specific step
@@ -1600,7 +1997,7 @@ let WizardForm = class extends i {
1600
1997
  this._formData = {};
1601
1998
  this._currentStep = 1;
1602
1999
  this._submitting = false;
1603
- this._submitted = false;
2000
+ this.submitted = false;
1604
2001
  this._error = "";
1605
2002
  this._stateController.reset();
1606
2003
  this._showCurrentStep();
@@ -1623,79 +2020,142 @@ let WizardForm = class extends i {
1623
2020
  });
1624
2021
  }
1625
2022
  };
1626
- __decorateClass$c([
2023
+ WizardForm.styles = wizardFormStyles;
2024
+ __decorateClass$e([
1627
2025
  n2({ type: String, attribute: "hubspot-portal" })
1628
2026
  ], WizardForm.prototype, "hubspotPortal", 2);
1629
- __decorateClass$c([
2027
+ __decorateClass$e([
1630
2028
  n2({ type: String, attribute: "hubspot-form" })
1631
2029
  ], WizardForm.prototype, "hubspotForm", 2);
1632
- __decorateClass$c([
2030
+ __decorateClass$e([
1633
2031
  n2({ type: String, reflect: true })
1634
2032
  ], WizardForm.prototype, "theme", 2);
1635
- __decorateClass$c([
2033
+ __decorateClass$e([
1636
2034
  n2({ type: Boolean })
1637
2035
  ], WizardForm.prototype, "mock", 2);
1638
- __decorateClass$c([
2036
+ __decorateClass$e([
1639
2037
  n2({ type: Boolean, attribute: "show-progress" })
1640
2038
  ], WizardForm.prototype, "showProgress", 2);
1641
- __decorateClass$c([
2039
+ __decorateClass$e([
1642
2040
  n2({ type: Boolean, attribute: "auto-advance" })
1643
2041
  ], WizardForm.prototype, "autoAdvance", 2);
1644
- __decorateClass$c([
2042
+ __decorateClass$e([
1645
2043
  n2({ type: Boolean, attribute: "hide-back" })
1646
2044
  ], WizardForm.prototype, "hideBack", 2);
1647
- __decorateClass$c([
2045
+ __decorateClass$e([
1648
2046
  n2({ attribute: false })
1649
2047
  ], WizardForm.prototype, "serialize", 2);
1650
- __decorateClass$c([
2048
+ __decorateClass$e([
1651
2049
  n2({ type: Boolean, attribute: "submit-on-step" })
1652
2050
  ], WizardForm.prototype, "submitOnStep", 2);
1653
- __decorateClass$c([
2051
+ __decorateClass$e([
1654
2052
  r()
1655
2053
  ], WizardForm.prototype, "_steps", 2);
1656
- __decorateClass$c([
2054
+ __decorateClass$e([
1657
2055
  r()
1658
2056
  ], WizardForm.prototype, "_currentStep", 2);
1659
- __decorateClass$c([
2057
+ __decorateClass$e([
1660
2058
  r()
1661
2059
  ], WizardForm.prototype, "_totalSteps", 2);
1662
- __decorateClass$c([
2060
+ __decorateClass$e([
1663
2061
  r()
1664
2062
  ], WizardForm.prototype, "_formData", 2);
1665
- __decorateClass$c([
2063
+ __decorateClass$e([
1666
2064
  r()
1667
2065
  ], WizardForm.prototype, "_submitting", 2);
1668
- __decorateClass$c([
1669
- r()
1670
- ], WizardForm.prototype, "_submitted", 2);
1671
- __decorateClass$c([
2066
+ __decorateClass$e([
2067
+ n2({ type: Boolean, reflect: true })
2068
+ ], WizardForm.prototype, "submitted", 2);
2069
+ __decorateClass$e([
1672
2070
  r()
1673
2071
  ], WizardForm.prototype, "_error", 2);
1674
- WizardForm = __decorateClass$c([
2072
+ __decorateClass$e([
2073
+ r()
2074
+ ], WizardForm.prototype, "_otherInputActive", 2);
2075
+ WizardForm = __decorateClass$e([
1675
2076
  t("wizard-form")
1676
2077
  ], WizardForm);
1677
2078
  let WfSuccess = class extends i {
1678
- /**
1679
- * Disable Shadow DOM - render to Light DOM for external styling
1680
- */
1681
- createRenderRoot() {
1682
- return this;
1683
- }
1684
2079
  render() {
1685
- return b``;
2080
+ return b`<slot></slot>`;
1686
2081
  }
1687
2082
  };
1688
- WfSuccess = __decorateClass$c([
2083
+ WfSuccess.styles = i$3`
2084
+ :host {
2085
+ display: block;
2086
+ }
2087
+
2088
+ :host([hidden]) {
2089
+ display: none;
2090
+ }
2091
+ `;
2092
+ WfSuccess = __decorateClass$e([
1689
2093
  t("wf-success")
1690
2094
  ], WfSuccess);
1691
- var __defProp$b = Object.defineProperty;
1692
- var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
1693
- var __decorateClass$b = (decorators, target, key, kind) => {
1694
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
2095
+ const wfStepStyles = [
2096
+ sharedAnimations,
2097
+ i$3`
2098
+ :host {
2099
+ display: none;
2100
+ width: 100%;
2101
+ }
2102
+
2103
+ :host([hidden]) {
2104
+ display: none !important;
2105
+ }
2106
+
2107
+ :host([active]) {
2108
+ display: block;
2109
+ animation: wf-stepFadeIn 0.3s ease forwards;
2110
+ }
2111
+
2112
+ :host([direction='forward'][active]) {
2113
+ animation: wf-stepSlideInRight 0.3s ease forwards;
2114
+ }
2115
+
2116
+ :host([direction='backward'][active]) {
2117
+ animation: wf-stepSlideInLeft 0.3s ease forwards;
2118
+ }
2119
+
2120
+ :host([leaving]) {
2121
+ display: block;
2122
+ animation: wf-stepFadeOut 0.2s ease forwards;
2123
+ }
2124
+
2125
+ .wf-step-content {
2126
+ display: flex;
2127
+ flex-direction: column;
2128
+ gap: var(--wf-spacing-4, 16px);
2129
+ }
2130
+
2131
+ /* Slotted heading styles */
2132
+ ::slotted(h1),
2133
+ ::slotted(h2),
2134
+ ::slotted(h3) {
2135
+ margin: 0;
2136
+ font-weight: 600;
2137
+ color: var(--wf-color-text, #212529);
2138
+ }
2139
+
2140
+ ::slotted(h2) {
2141
+ font-size: var(--wf-font-size-3xl, 2rem);
2142
+ }
2143
+
2144
+ ::slotted(p) {
2145
+ margin: 0;
2146
+ color: var(--wf-color-text-muted, #6c757d);
2147
+ font-size: var(--wf-font-size-xl, 1.375rem);
2148
+ }
2149
+ `
2150
+ ];
2151
+ var __defProp$d = Object.defineProperty;
2152
+ var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
2153
+ var __decorateClass$d = (decorators, target, key, kind) => {
2154
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
1695
2155
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1696
2156
  if (decorator = decorators[i2])
1697
2157
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1698
- if (kind && result) __defProp$b(target, key, result);
2158
+ if (kind && result) __defProp$d(target, key, result);
1699
2159
  return result;
1700
2160
  };
1701
2161
  let WfStep = class extends i {
@@ -1708,15 +2168,11 @@ let WfStep = class extends i {
1708
2168
  this.skipIf = "";
1709
2169
  this._fields = [];
1710
2170
  }
1711
- /**
1712
- * Disable Shadow DOM - render to Light DOM for external styling
1713
- */
1714
- createRenderRoot() {
1715
- return this;
1716
- }
1717
2171
  render() {
1718
2172
  return b`
1719
- <div class="wf-step-content"></div>
2173
+ <div class="wf-step-content" data-testid="wf-step-content">
2174
+ <slot></slot>
2175
+ </div>
1720
2176
  `;
1721
2177
  }
1722
2178
  firstUpdated() {
@@ -1884,35 +2340,59 @@ let WfStep = class extends i {
1884
2340
  return allValid;
1885
2341
  }
1886
2342
  };
1887
- __decorateClass$b([
2343
+ WfStep.styles = wfStepStyles;
2344
+ __decorateClass$d([
1888
2345
  n2({ type: Number, attribute: "data-step" })
1889
2346
  ], WfStep.prototype, "step", 2);
1890
- __decorateClass$b([
2347
+ __decorateClass$d([
1891
2348
  n2({ type: Boolean, reflect: true })
1892
2349
  ], WfStep.prototype, "active", 2);
1893
- __decorateClass$b([
2350
+ __decorateClass$d([
1894
2351
  n2({ type: String, reflect: true })
1895
2352
  ], WfStep.prototype, "direction", 2);
1896
- __decorateClass$b([
2353
+ __decorateClass$d([
1897
2354
  n2({ type: Boolean, reflect: true })
1898
2355
  ], WfStep.prototype, "leaving", 2);
1899
- __decorateClass$b([
2356
+ __decorateClass$d([
1900
2357
  n2({ type: String, attribute: "data-skip-if" })
1901
2358
  ], WfStep.prototype, "skipIf", 2);
1902
- __decorateClass$b([
2359
+ __decorateClass$d([
1903
2360
  r()
1904
2361
  ], WfStep.prototype, "_fields", 2);
1905
- WfStep = __decorateClass$b([
2362
+ WfStep = __decorateClass$d([
1906
2363
  t("wf-step")
1907
2364
  ], WfStep);
1908
- var __defProp$a = Object.defineProperty;
1909
- var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
1910
- var __decorateClass$a = (decorators, target, key, kind) => {
1911
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
2365
+ const wfLayoutStyles = i$3`
2366
+ :host {
2367
+ display: block;
2368
+ box-sizing: border-box;
2369
+ }
2370
+
2371
+ :host([hidden]) {
2372
+ display: none;
2373
+ }
2374
+
2375
+ /* Width classes */
2376
+ :host(.wf-layout--width-full) {
2377
+ width: 100%;
2378
+ }
2379
+
2380
+ :host(.wf-layout--width-auto) {
2381
+ width: auto;
2382
+ }
2383
+
2384
+ :host(.wf-layout--width-fit) {
2385
+ width: fit-content;
2386
+ }
2387
+ `;
2388
+ var __defProp$c = Object.defineProperty;
2389
+ var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
2390
+ var __decorateClass$c = (decorators, target, key, kind) => {
2391
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
1912
2392
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1913
2393
  if (decorator = decorators[i2])
1914
2394
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1915
- if (kind && result) __defProp$a(target, key, result);
2395
+ if (kind && result) __defProp$c(target, key, result);
1916
2396
  return result;
1917
2397
  };
1918
2398
  const SPACING_SCALE = {
@@ -1941,12 +2421,6 @@ let WfLayout = class extends i {
1941
2421
  this.columns = "auto";
1942
2422
  this.minItemWidth = "200px";
1943
2423
  }
1944
- /**
1945
- * Disable Shadow DOM - render to Light DOM for external styling
1946
- */
1947
- createRenderRoot() {
1948
- return this;
1949
- }
1950
2424
  /**
1951
2425
  * Convert spacing value to pixels
1952
2426
  */
@@ -2031,99 +2505,429 @@ let WfLayout = class extends i {
2031
2505
  return styles.join("; ");
2032
2506
  }
2033
2507
  /**
2034
- * Apply styles to host element when properties change
2508
+ * Apply data-* attributes from children as inline styles
2509
+ * Supports: data-span, data-row-span, data-grow, data-shrink, data-align, data-order
2035
2510
  */
2036
- updated(changedProperties) {
2037
- super.updated(changedProperties);
2038
- this.style.cssText = this._buildStyles();
2039
- this.classList.remove("wf-layout--width-full", "wf-layout--width-auto", "wf-layout--width-fit");
2040
- this.classList.add(`wf-layout--width-${this.width}`);
2041
- }
2042
- render() {
2043
- return b``;
2044
- }
2511
+ _applyChildStyles() {
2512
+ if (!this._slot) {
2513
+ return;
2514
+ }
2515
+ const children = this._slot.assignedElements({ flatten: true });
2516
+ for (const child of children) {
2517
+ const el = child;
2518
+ const styles = [];
2519
+ const span = el.getAttribute("data-span");
2520
+ if (span) {
2521
+ styles.push(`grid-column: span ${span}`);
2522
+ }
2523
+ const rowSpan = el.getAttribute("data-row-span");
2524
+ if (rowSpan) {
2525
+ styles.push(`grid-row: span ${rowSpan}`);
2526
+ }
2527
+ if (el.hasAttribute("data-grow")) {
2528
+ styles.push("flex-grow: 1");
2529
+ }
2530
+ if (el.hasAttribute("data-shrink")) {
2531
+ styles.push("flex-shrink: 0");
2532
+ }
2533
+ const align = el.getAttribute("data-align");
2534
+ if (align) {
2535
+ styles.push(`align-self: ${align}`);
2536
+ }
2537
+ const order = el.getAttribute("data-order");
2538
+ if (order) {
2539
+ styles.push(`order: ${order}`);
2540
+ }
2541
+ if (styles.length > 0) {
2542
+ const existingStyles = el.style.cssText;
2543
+ const newStyles = styles.join("; ");
2544
+ el.style.cssText = existingStyles ? `${existingStyles}; ${newStyles}` : newStyles;
2545
+ }
2546
+ }
2547
+ }
2548
+ /**
2549
+ * Handle slot changes to apply child styles
2550
+ */
2551
+ _handleLayoutSlotChange() {
2552
+ this._applyChildStyles();
2553
+ }
2554
+ /**
2555
+ * Apply styles to host element when properties change
2556
+ */
2557
+ updated(changedProperties) {
2558
+ super.updated(changedProperties);
2559
+ this.style.cssText = this._buildStyles();
2560
+ this.classList.remove("wf-layout--width-full", "wf-layout--width-auto", "wf-layout--width-fit");
2561
+ this.classList.add(`wf-layout--width-${this.width}`);
2562
+ this._applyChildStyles();
2563
+ }
2564
+ render() {
2565
+ return b`<slot @slotchange="${this._handleLayoutSlotChange}"></slot>`;
2566
+ }
2045
2567
  };
2046
- __decorateClass$a([
2568
+ WfLayout.styles = wfLayoutStyles;
2569
+ __decorateClass$c([
2047
2570
  n2({ type: String })
2048
2571
  ], WfLayout.prototype, "mode", 2);
2049
- __decorateClass$a([
2572
+ __decorateClass$c([
2050
2573
  n2({ type: String })
2051
2574
  ], WfLayout.prototype, "direction", 2);
2052
- __decorateClass$a([
2575
+ __decorateClass$c([
2053
2576
  n2({ type: String })
2054
2577
  ], WfLayout.prototype, "gap", 2);
2055
- __decorateClass$a([
2578
+ __decorateClass$c([
2056
2579
  n2({ type: String, attribute: "gap-x" })
2057
2580
  ], WfLayout.prototype, "gapX", 2);
2058
- __decorateClass$a([
2581
+ __decorateClass$c([
2059
2582
  n2({ type: String, attribute: "gap-y" })
2060
2583
  ], WfLayout.prototype, "gapY", 2);
2061
- __decorateClass$a([
2584
+ __decorateClass$c([
2062
2585
  n2({ type: String })
2063
2586
  ], WfLayout.prototype, "align", 2);
2064
- __decorateClass$a([
2587
+ __decorateClass$c([
2065
2588
  n2({ type: String })
2066
2589
  ], WfLayout.prototype, "justify", 2);
2067
- __decorateClass$a([
2590
+ __decorateClass$c([
2068
2591
  n2({ type: String })
2069
2592
  ], WfLayout.prototype, "padding", 2);
2070
- __decorateClass$a([
2593
+ __decorateClass$c([
2071
2594
  n2({ type: String, attribute: "padding-x" })
2072
2595
  ], WfLayout.prototype, "paddingX", 2);
2073
- __decorateClass$a([
2596
+ __decorateClass$c([
2074
2597
  n2({ type: String, attribute: "padding-y" })
2075
2598
  ], WfLayout.prototype, "paddingY", 2);
2076
- __decorateClass$a([
2599
+ __decorateClass$c([
2077
2600
  n2({ type: Boolean })
2078
2601
  ], WfLayout.prototype, "wrap", 2);
2079
- __decorateClass$a([
2602
+ __decorateClass$c([
2080
2603
  n2({ type: String })
2081
2604
  ], WfLayout.prototype, "width", 2);
2082
- __decorateClass$a([
2605
+ __decorateClass$c([
2083
2606
  n2({ type: String })
2084
2607
  ], WfLayout.prototype, "columns", 2);
2085
- __decorateClass$a([
2608
+ __decorateClass$c([
2086
2609
  n2({ type: String, attribute: "min-item-width" })
2087
2610
  ], WfLayout.prototype, "minItemWidth", 2);
2088
- WfLayout = __decorateClass$a([
2611
+ __decorateClass$c([
2612
+ e("slot")
2613
+ ], WfLayout.prototype, "_slot", 2);
2614
+ WfLayout = __decorateClass$c([
2089
2615
  t("wf-layout")
2090
2616
  ], WfLayout);
2091
- var __defProp$9 = Object.defineProperty;
2617
+ const wfOptionsStyles = i$3`
2618
+ :host {
2619
+ display: grid;
2620
+ box-sizing: border-box;
2621
+ }
2622
+
2623
+ :host([hidden]) {
2624
+ display: none;
2625
+ }
2626
+
2627
+ /* Width classes inherited from WfLayout */
2628
+ :host(.wf-layout--width-full) {
2629
+ width: 100%;
2630
+ }
2631
+
2632
+ :host(.wf-layout--width-auto) {
2633
+ width: auto;
2634
+ }
2635
+
2636
+ :host(.wf-layout--width-fit) {
2637
+ width: fit-content;
2638
+ }
2639
+
2640
+ /* Error wrapper for animated expand/collapse */
2641
+ .wf-error-wrapper {
2642
+ grid-column: 1 / -1;
2643
+ order: 1000;
2644
+ display: grid;
2645
+ grid-template-rows: 0fr;
2646
+ transition: grid-template-rows 200ms ease-out;
2647
+ }
2648
+
2649
+ .wf-error-wrapper.wf-has-error {
2650
+ grid-template-rows: 1fr;
2651
+ }
2652
+
2653
+ .wf-error-message {
2654
+ overflow: hidden;
2655
+ min-height: 0;
2656
+ font-size: var(--wf-font-size-sm, 0.875rem);
2657
+ color: var(--wf-color-error, #dc3545);
2658
+ opacity: 0;
2659
+ transform: translateY(-4px);
2660
+ transition: opacity 200ms ease-out, transform 200ms ease-out;
2661
+ }
2662
+
2663
+ .wf-has-error .wf-error-message {
2664
+ margin-top: var(--wf-spacing-2, 8px);
2665
+ opacity: 1;
2666
+ transform: translateY(0);
2667
+ }
2668
+
2669
+ /* Slotted wf-other spans full width and appears after options */
2670
+ ::slotted(wf-other) {
2671
+ grid-column: 1 / -1;
2672
+ order: 999;
2673
+ }
2674
+ `;
2675
+ const wfOtherStyles = i$3`
2676
+ :host {
2677
+ display: block;
2678
+ }
2679
+
2680
+ :host([hidden]) {
2681
+ display: none;
2682
+ }
2683
+
2684
+ .wf-other-container {
2685
+ margin-top: var(--wf-spacing-4, 16px);
2686
+ }
2687
+
2688
+ .wf-other-label {
2689
+ 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);
2694
+ }
2695
+
2696
+ .wf-other-label span {
2697
+ font-weight: 400;
2698
+ color: var(--wf-color-text-muted, #646464);
2699
+ }
2700
+
2701
+ .wf-other-input-wrapper {
2702
+ display: flex;
2703
+ 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);
2713
+ transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
2714
+ }
2715
+
2716
+ .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);
2719
+ }
2720
+
2721
+ .wf-other-input {
2722
+ flex: 1;
2723
+ min-height: calc(var(--wf-input-min-height, 56px) - 2px);
2724
+ padding: var(--wf-spacing-3, 12px);
2725
+ padding-left: 0;
2726
+ font-size: var(--wf-font-size-base, 1rem);
2727
+ font-weight: 500;
2728
+ color: var(--wf-color-text, #0a0a0a);
2729
+ background: transparent;
2730
+ border: none;
2731
+ outline: none;
2732
+ box-sizing: border-box;
2733
+ }
2734
+
2735
+ .wf-other-input::placeholder {
2736
+ color: var(--wf-color-text-muted, #646464);
2737
+ font-weight: 500;
2738
+ }
2739
+
2740
+ .wf-other-actions {
2741
+ display: flex;
2742
+ align-items: center;
2743
+ justify-content: stretch;
2744
+ }
2745
+
2746
+ /* Ensure slotted button fills the action column */
2747
+ .wf-other-actions ::slotted(*) {
2748
+ width: 100%;
2749
+ }
2750
+ `;
2751
+ var __defProp$b = Object.defineProperty;
2752
+ var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
2753
+ var __decorateClass$b = (decorators, target, key, kind) => {
2754
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
2755
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2756
+ if (decorator = decorators[i2])
2757
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2758
+ if (kind && result) __defProp$b(target, key, result);
2759
+ return result;
2760
+ };
2761
+ let WfOther = class extends i {
2762
+ constructor() {
2763
+ super(...arguments);
2764
+ this.label = "Others, please specify:";
2765
+ this.placeholder = "";
2766
+ this.required = false;
2767
+ this.disabled = false;
2768
+ this.shortcut = "";
2769
+ this._value = "";
2770
+ this._handleInput = (e2) => {
2771
+ const input = e2.target;
2772
+ this._value = input.value;
2773
+ this._notifyChange();
2774
+ };
2775
+ }
2776
+ // ============================================
2777
+ // Public API
2778
+ // ============================================
2779
+ /**
2780
+ * Get current value
2781
+ */
2782
+ get value() {
2783
+ return this._value;
2784
+ }
2785
+ /**
2786
+ * Set value
2787
+ */
2788
+ set value(val) {
2789
+ this._value = val;
2790
+ }
2791
+ /**
2792
+ * Clear the input value
2793
+ */
2794
+ clear() {
2795
+ this._value = "";
2796
+ this._notifyChange();
2797
+ }
2798
+ /**
2799
+ * Focus the input
2800
+ */
2801
+ focusInput() {
2802
+ const input = this.shadowRoot?.querySelector(".wf-other-input");
2803
+ input?.focus();
2804
+ }
2805
+ _notifyChange() {
2806
+ this.dispatchEvent(
2807
+ new CustomEvent("wf-other-change", {
2808
+ detail: {
2809
+ value: this._value,
2810
+ name: this.name
2811
+ },
2812
+ bubbles: true,
2813
+ composed: true
2814
+ })
2815
+ );
2816
+ }
2817
+ // ============================================
2818
+ // Render
2819
+ // ============================================
2820
+ render() {
2821
+ return b`
2822
+ <div class="wf-other-container" data-testid="wf-other">
2823
+ <label class="wf-other-label">
2824
+ ${this.label}
2825
+ ${this.labelHint ? b`<span>${this.labelHint}</span>` : A}
2826
+ </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) -->
2842
+ <div class="wf-other-actions">
2843
+ <slot></slot>
2844
+ </div>
2845
+ </wf-layout>
2846
+ </div>
2847
+ `;
2848
+ }
2849
+ };
2850
+ WfOther.styles = wfOtherStyles;
2851
+ __decorateClass$b([
2852
+ n2({ type: String })
2853
+ ], WfOther.prototype, "label", 2);
2854
+ __decorateClass$b([
2855
+ n2({ type: String, attribute: "label-hint" })
2856
+ ], WfOther.prototype, "labelHint", 2);
2857
+ __decorateClass$b([
2858
+ n2({ type: String })
2859
+ ], WfOther.prototype, "placeholder", 2);
2860
+ __decorateClass$b([
2861
+ n2({ type: String })
2862
+ ], WfOther.prototype, "name", 2);
2863
+ __decorateClass$b([
2864
+ n2({ type: Boolean })
2865
+ ], WfOther.prototype, "required", 2);
2866
+ __decorateClass$b([
2867
+ n2({ type: Boolean })
2868
+ ], WfOther.prototype, "disabled", 2);
2869
+ __decorateClass$b([
2870
+ n2({ type: String })
2871
+ ], WfOther.prototype, "shortcut", 2);
2872
+ __decorateClass$b([
2873
+ r()
2874
+ ], WfOther.prototype, "_value", 2);
2875
+ WfOther = __decorateClass$b([
2876
+ t("wf-other")
2877
+ ], WfOther);
2878
+ var __defProp$a = Object.defineProperty;
2092
2879
  var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
2093
- var __decorateClass$9 = (decorators, target, key, kind) => {
2880
+ var __decorateClass$a = (decorators, target, key, kind) => {
2094
2881
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
2095
2882
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2096
2883
  if (decorator = decorators[i2])
2097
2884
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2098
- if (kind && result) __defProp$9(target, key, result);
2885
+ if (kind && result) __defProp$a(target, key, result);
2099
2886
  return result;
2100
2887
  };
2101
- let WfOptions = class extends i {
2888
+ let WfOptions = class extends WfLayout {
2102
2889
  constructor() {
2103
2890
  super(...arguments);
2891
+ this.mode = "grid";
2892
+ this.gap = "md";
2104
2893
  this.name = "";
2105
2894
  this.multi = false;
2106
2895
  this.required = false;
2107
2896
  this.min = 0;
2108
2897
  this.max = 0;
2109
- this.columns = 2;
2110
- this.allowOther = false;
2111
- this.otherLabel = "Other, please specify:";
2112
- this.otherPlaceholder = "Enter your answer";
2113
- this.otherRequired = false;
2114
- this.otherName = "";
2115
- this.otherFieldValue = "Others";
2898
+ this.columns = "2";
2116
2899
  this._selected = /* @__PURE__ */ new Set();
2117
2900
  this._otherValue = "";
2118
2901
  this._errorMessage = "";
2119
2902
  this._validationActivated = false;
2120
2903
  this._options = [];
2121
2904
  this._shortcutMap = /* @__PURE__ */ new Map();
2122
- this._otherShortcut = "";
2905
+ this._composableOther = null;
2906
+ this._handleComposableOtherChange = (e2) => {
2907
+ e2.stopPropagation();
2908
+ this._otherValue = e2.detail.value;
2909
+ if (this._otherValue.trim() && this._selected.size > 0) {
2910
+ this._selected.clear();
2911
+ this._updateOptionStates();
2912
+ }
2913
+ this._dispatchChange();
2914
+ };
2123
2915
  this._handleOptionSelect = (e2) => {
2916
+ if (e2.detail.forwarded) {
2917
+ return;
2918
+ }
2124
2919
  e2.stopPropagation();
2125
2920
  const { value } = e2.detail;
2126
2921
  this._selectValue(value);
2922
+ if (!this.multi) {
2923
+ this.dispatchEvent(
2924
+ new CustomEvent("wf-option-select", {
2925
+ detail: { ...e2.detail, forwarded: true },
2926
+ bubbles: true,
2927
+ composed: true
2928
+ })
2929
+ );
2930
+ }
2127
2931
  };
2128
2932
  this._handleKeydown = (e2) => {
2129
2933
  const parentStep = this.closest("wf-step");
@@ -2135,18 +2939,11 @@ let WfOptions = class extends i {
2135
2939
  if (actualTarget?.tagName === "INPUT" || actualTarget?.tagName === "TEXTAREA") {
2136
2940
  return;
2137
2941
  }
2138
- const otherInput = this.querySelector(".wf-other-input");
2139
- if (otherInput && document.activeElement === otherInput) {
2140
- return;
2141
- }
2142
2942
  const key = e2.key.toUpperCase();
2143
2943
  if (key.length === 1 && key >= "A" && key <= "Z") {
2144
- if (this.allowOther && key === this._otherShortcut) {
2944
+ if (this._composableOther && key === this._composableOther.shortcut) {
2145
2945
  e2.preventDefault();
2146
- const otherInput2 = this.querySelector(".wf-other-input");
2147
- if (otherInput2) {
2148
- otherInput2.focus();
2149
- }
2946
+ this._composableOther.focusInput();
2150
2947
  return;
2151
2948
  }
2152
2949
  const option = this._shortcutMap.get(key);
@@ -2157,88 +2954,72 @@ let WfOptions = class extends i {
2157
2954
  }
2158
2955
  };
2159
2956
  }
2160
- /**
2161
- * Disable Shadow DOM - render to Light DOM for external styling
2162
- */
2163
- createRenderRoot() {
2164
- return this;
2165
- }
2166
2957
  connectedCallback() {
2167
2958
  super.connectedCallback();
2168
2959
  this._errorMessage = "";
2169
2960
  this._validationActivated = false;
2170
2961
  this.addEventListener("wf-option-select", this._handleOptionSelect);
2962
+ this.addEventListener("wf-other-change", this._handleComposableOtherChange);
2171
2963
  document.addEventListener("keydown", this._handleKeydown);
2172
2964
  }
2173
2965
  disconnectedCallback() {
2174
2966
  super.disconnectedCallback();
2175
2967
  this.removeEventListener("wf-option-select", this._handleOptionSelect);
2968
+ this.removeEventListener("wf-other-change", this._handleComposableOtherChange);
2176
2969
  document.removeEventListener("keydown", this._handleKeydown);
2177
2970
  }
2178
- firstUpdated() {
2179
- const layout = this.querySelector("wf-layout");
2180
- const options = Array.from(this.querySelectorAll(":scope > wf-option"));
2181
- options.forEach((option) => layout?.appendChild(option));
2971
+ firstUpdated(changedProperties) {
2972
+ super.firstUpdated(changedProperties);
2973
+ const slottedElements = this._defaultSlot?.assignedElements({ flatten: true }) || [];
2974
+ const foundOther = slottedElements.find(
2975
+ (el) => el.tagName.toLowerCase() === "wf-other"
2976
+ );
2977
+ this._composableOther = foundOther ? foundOther : null;
2182
2978
  this._discoverOptions();
2183
2979
  this.requestUpdate();
2184
2980
  }
2981
+ /**
2982
+ * Check if this component has a composable wf-other child
2983
+ */
2984
+ _hasComposableOther() {
2985
+ return this._composableOther !== null;
2986
+ }
2185
2987
  updated(changedProperties) {
2988
+ super.updated(changedProperties);
2186
2989
  if (changedProperties.has("multi") || changedProperties.has("max")) {
2187
2990
  this._updateOptionStates();
2188
2991
  }
2189
2992
  }
2190
2993
  render() {
2994
+ super.updated(/* @__PURE__ */ new Map());
2191
2995
  this.setAttribute("role", "listbox");
2192
2996
  this.setAttribute("aria-multiselectable", String(this.multi));
2193
2997
  this.setAttribute("aria-required", String(this.required));
2194
2998
  return b`
2195
- <wf-layout mode="grid" columns="${this.columns}" gap="md">
2196
- <!-- wf-option children will be moved here in firstUpdated -->
2197
- </wf-layout>
2198
- ${this.allowOther ? b`
2199
- <div class="wf-other-container">
2200
- <label class="wf-other-label">${this.otherLabel}</label>
2201
- <div class="wf-other-input-wrapper">
2202
- ${this._otherShortcut ? b`<wf-badge shortcut="${this._otherShortcut}"></wf-badge>` : ""}
2203
- <input
2204
- type="text"
2205
- class="wf-other-input"
2206
- .value="${this._otherValue}"
2207
- placeholder="${this.otherPlaceholder}"
2208
- data-testid="wf-other-input"
2209
- @input="${this._handleOtherInput}"
2210
- @keydown="${this._handleOtherKeydown}"
2211
- @focus="${this._handleOtherFocus}"
2212
- />
2213
- </div>
2214
- </div>
2215
- ` : ""}
2216
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
2217
- ${this._errorMessage}
2218
- </span>
2999
+ <slot @slotchange="${this._handleSlotChange}"></slot>
3000
+ <div class="wf-error-wrapper ${this._errorMessage ? "wf-has-error" : ""}">
3001
+ <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3002
+ ${this._errorMessage || ""}
3003
+ </span>
3004
+ </div>
2219
3005
  `;
2220
3006
  }
2221
- _handleOtherInput(e2) {
2222
- const input = e2.target;
2223
- this._otherValue = input.value;
2224
- if (this._otherValue.trim() && this._selected.size > 0) {
2225
- this._selected.clear();
2226
- this._updateOptionStates();
2227
- }
2228
- this._dispatchChange();
2229
- }
2230
- _handleOtherFocus() {
2231
- }
2232
- _handleOtherKeydown(e2) {
2233
- if (e2.key === "Escape") {
2234
- e2.stopPropagation();
2235
- const input = e2.target;
2236
- input.blur();
2237
- }
3007
+ /**
3008
+ * Handle slot content changes to rediscover options
3009
+ */
3010
+ _handleSlotChange() {
3011
+ const slottedElements = this._defaultSlot?.assignedElements({ flatten: true }) || [];
3012
+ const foundOther = slottedElements.find(
3013
+ (el) => el.tagName.toLowerCase() === "wf-other"
3014
+ );
3015
+ this._composableOther = foundOther ? foundOther : null;
3016
+ this._discoverOptions();
2238
3017
  }
2239
3018
  _discoverOptions() {
2240
- const layout = this.querySelector("wf-layout");
2241
- this._options = layout ? Array.from(layout.querySelectorAll(":scope > wf-option")) : [];
3019
+ const slottedElements = this._defaultSlot?.assignedElements({ flatten: true }) || [];
3020
+ this._options = slottedElements.filter(
3021
+ (el) => el.tagName.toLowerCase() === "wf-option"
3022
+ );
2242
3023
  this._shortcutMap.clear();
2243
3024
  this._options.forEach((option, index) => {
2244
3025
  if (index < 26) {
@@ -2248,8 +3029,9 @@ let WfOptions = class extends i {
2248
3029
  }
2249
3030
  option.setSelected(this._selected.has(option.value));
2250
3031
  });
2251
- if (this.allowOther && this._options.length < 26) {
2252
- this._otherShortcut = String.fromCharCode(65 + this._options.length);
3032
+ if (this._composableOther && this._options.length < 26) {
3033
+ const otherShortcut = String.fromCharCode(65 + this._options.length);
3034
+ this._composableOther.shortcut = otherShortcut;
2253
3035
  }
2254
3036
  }
2255
3037
  _selectValue(value) {
@@ -2258,8 +3040,11 @@ let WfOptions = class extends i {
2258
3040
  } else {
2259
3041
  this._handleSingleSelect(value);
2260
3042
  }
2261
- if (this.allowOther && this._otherValue) {
3043
+ if (this._otherValue) {
2262
3044
  this._otherValue = "";
3045
+ if (this._composableOther) {
3046
+ this._composableOther.clear();
3047
+ }
2263
3048
  }
2264
3049
  this._updateOptionStates();
2265
3050
  this._validateSelection();
@@ -2288,7 +3073,7 @@ let WfOptions = class extends i {
2288
3073
  * Silent validation check (no side effects)
2289
3074
  */
2290
3075
  _checkValidation() {
2291
- const hasOtherValue = this.allowOther && this._otherValue.trim();
3076
+ const hasOtherValue = this._hasComposableOther() && this._otherValue.trim();
2292
3077
  const hasSelection = this._selected.size > 0 || hasOtherValue;
2293
3078
  if (this.required && !hasSelection) {
2294
3079
  return false;
@@ -2312,10 +3097,10 @@ let WfOptions = class extends i {
2312
3097
  return this._checkValidation();
2313
3098
  }
2314
3099
  this._errorMessage = "";
2315
- const hasOtherValue = this.allowOther && this._otherValue.trim();
3100
+ const hasOtherValue = this._hasComposableOther() && this._otherValue.trim();
2316
3101
  const hasSelection = this._selected.size > 0 || hasOtherValue;
2317
3102
  if (this.required && !hasSelection) {
2318
- this._errorMessage = this.allowOther ? "Please select an option or specify in the text field" : "Please select an option";
3103
+ this._errorMessage = this._hasComposableOther() ? "Please select an option or specify in the text field" : "Please select an option";
2319
3104
  return false;
2320
3105
  }
2321
3106
  if (this.multi) {
@@ -2332,23 +3117,11 @@ let WfOptions = class extends i {
2332
3117
  }
2333
3118
  _dispatchChange() {
2334
3119
  const selectedArray = Array.from(this._selected);
2335
- const hasOtherText = this.allowOther && this._otherValue.trim() && this._selected.size === 0;
2336
- let currentValue;
2337
- if (this.otherName && hasOtherText) {
2338
- currentValue = this.multi ? [this.otherFieldValue] : this.otherFieldValue;
2339
- } else {
2340
- currentValue = this.value;
2341
- }
2342
3120
  const detail = {
2343
3121
  name: this.name,
2344
- value: currentValue,
3122
+ value: this.value,
2345
3123
  selected: selectedArray
2346
3124
  };
2347
- if (this.otherName) {
2348
- detail.extraFields = {
2349
- [this.otherName]: hasOtherText ? this._otherValue.trim() : ""
2350
- };
2351
- }
2352
3125
  this.dispatchEvent(
2353
3126
  new CustomEvent("wf-change", {
2354
3127
  detail,
@@ -2362,10 +3135,10 @@ let WfOptions = class extends i {
2362
3135
  // ============================================
2363
3136
  /**
2364
3137
  * Get current value (string for single, array for multi)
2365
- * If allowOther is enabled and "Others" text is filled, returns the custom text
3138
+ * If wf-other child is present and has text, returns the custom text
2366
3139
  */
2367
3140
  get value() {
2368
- if (this.allowOther && this._otherValue.trim() && this._selected.size === 0) {
3141
+ if (this._hasComposableOther() && this._otherValue.trim() && this._selected.size === 0) {
2369
3142
  return this.multi ? [this._otherValue] : this._otherValue;
2370
3143
  }
2371
3144
  const selectedArray = Array.from(this._selected);
@@ -2464,6 +3237,9 @@ let WfOptions = class extends i {
2464
3237
  this._otherValue = "";
2465
3238
  this._errorMessage = "";
2466
3239
  this._validationActivated = false;
3240
+ if (this._composableOther) {
3241
+ this._composableOther.clear();
3242
+ }
2467
3243
  this._options.forEach((option) => {
2468
3244
  if (option.hasAttribute("selected")) {
2469
3245
  this._selected.add(option.value);
@@ -2473,65 +3249,146 @@ let WfOptions = class extends i {
2473
3249
  this._dispatchChange();
2474
3250
  }
2475
3251
  };
2476
- __decorateClass$9([
3252
+ WfOptions.styles = [WfLayout.styles, wfOptionsStyles];
3253
+ __decorateClass$a([
3254
+ e("slot:not([name])")
3255
+ ], WfOptions.prototype, "_defaultSlot", 2);
3256
+ __decorateClass$a([
3257
+ n2({ type: String })
3258
+ ], WfOptions.prototype, "mode", 2);
3259
+ __decorateClass$a([
3260
+ n2({ type: String })
3261
+ ], WfOptions.prototype, "gap", 2);
3262
+ __decorateClass$a([
2477
3263
  n2({ type: String })
2478
3264
  ], WfOptions.prototype, "name", 2);
2479
- __decorateClass$9([
3265
+ __decorateClass$a([
2480
3266
  n2({ type: Boolean })
2481
3267
  ], WfOptions.prototype, "multi", 2);
2482
- __decorateClass$9([
3268
+ __decorateClass$a([
2483
3269
  n2({ type: Boolean })
2484
3270
  ], WfOptions.prototype, "required", 2);
2485
- __decorateClass$9([
3271
+ __decorateClass$a([
2486
3272
  n2({ type: Number })
2487
3273
  ], WfOptions.prototype, "min", 2);
2488
- __decorateClass$9([
3274
+ __decorateClass$a([
2489
3275
  n2({ type: Number })
2490
3276
  ], WfOptions.prototype, "max", 2);
2491
- __decorateClass$9([
2492
- n2({ type: Number, reflect: true })
3277
+ __decorateClass$a([
3278
+ n2({ type: String, reflect: true })
2493
3279
  ], WfOptions.prototype, "columns", 2);
2494
- __decorateClass$9([
2495
- n2({ type: Boolean, attribute: "allow-other" })
2496
- ], WfOptions.prototype, "allowOther", 2);
2497
- __decorateClass$9([
2498
- n2({ type: String, attribute: "other-label" })
2499
- ], WfOptions.prototype, "otherLabel", 2);
2500
- __decorateClass$9([
2501
- n2({ type: String, attribute: "other-placeholder" })
2502
- ], WfOptions.prototype, "otherPlaceholder", 2);
2503
- __decorateClass$9([
2504
- n2({ type: Boolean, attribute: "other-required" })
2505
- ], WfOptions.prototype, "otherRequired", 2);
2506
- __decorateClass$9([
2507
- n2({ type: String, attribute: "other-name" })
2508
- ], WfOptions.prototype, "otherName", 2);
2509
- __decorateClass$9([
2510
- n2({ type: String, attribute: "other-value" })
2511
- ], WfOptions.prototype, "otherFieldValue", 2);
2512
- __decorateClass$9([
3280
+ __decorateClass$a([
2513
3281
  r()
2514
3282
  ], WfOptions.prototype, "_selected", 2);
2515
- __decorateClass$9([
3283
+ __decorateClass$a([
2516
3284
  r()
2517
3285
  ], WfOptions.prototype, "_otherValue", 2);
2518
- __decorateClass$9([
3286
+ __decorateClass$a([
2519
3287
  r()
2520
3288
  ], WfOptions.prototype, "_errorMessage", 2);
2521
- __decorateClass$9([
2522
- r()
2523
- ], WfOptions.prototype, "_otherShortcut", 2);
2524
- WfOptions = __decorateClass$9([
3289
+ WfOptions = __decorateClass$a([
2525
3290
  t("wf-options")
2526
3291
  ], WfOptions);
2527
- var __defProp$8 = Object.defineProperty;
3292
+ const wfOptionStyles = i$3`
3293
+ :host {
3294
+ display: block;
3295
+ }
3296
+
3297
+ :host([hidden]) {
3298
+ display: none;
3299
+ }
3300
+
3301
+ .wf-option-card {
3302
+ display: flex;
3303
+ align-items: center;
3304
+ gap: var(--wf-spacing-3, 12px);
3305
+ 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));
3314
+ cursor: pointer;
3315
+ text-align: left;
3316
+ font-family: inherit;
3317
+ font-size: var(--wf-font-size-base, 1rem);
3318
+ font-weight: 500;
3319
+ color: var(--wf-color-text, #0a0a0a);
3320
+ transition: border-color 150ms ease, background 150ms ease, transform 100ms ease;
3321
+ outline: none;
3322
+ box-sizing: border-box;
3323
+ }
3324
+
3325
+ .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));
3328
+ }
3329
+
3330
+ .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);
3333
+ }
3334
+
3335
+ .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));
3338
+ }
3339
+
3340
+ .wf-option-card:disabled {
3341
+ opacity: 0.5;
3342
+ cursor: not-allowed;
3343
+ }
3344
+
3345
+ .wf-option-card:active:not(:disabled) {
3346
+ transform: scale(0.98);
3347
+ }
3348
+
3349
+ .wf-option-card.selecting {
3350
+ animation: wf-blink 0.3s ease;
3351
+ }
3352
+
3353
+ @keyframes wf-blink {
3354
+ 0%, 100% {
3355
+ opacity: 1;
3356
+ }
3357
+ 50% {
3358
+ opacity: 0.5;
3359
+ }
3360
+ }
3361
+
3362
+ .wf-option-content {
3363
+ flex: 1;
3364
+ min-width: 0;
3365
+ }
3366
+
3367
+ /* Slotted content styling */
3368
+ ::slotted(strong),
3369
+ ::slotted(h3),
3370
+ ::slotted(h4) {
3371
+ display: block;
3372
+ font-weight: 600;
3373
+ margin: 0;
3374
+ }
3375
+
3376
+ ::slotted(span),
3377
+ ::slotted(p) {
3378
+ 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;
3382
+ }
3383
+ `;
3384
+ var __defProp$9 = Object.defineProperty;
2528
3385
  var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
2529
- var __decorateClass$8 = (decorators, target, key, kind) => {
3386
+ var __decorateClass$9 = (decorators, target, key, kind) => {
2530
3387
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
2531
3388
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2532
3389
  if (decorator = decorators[i2])
2533
3390
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2534
- if (kind && result) __defProp$8(target, key, result);
3391
+ if (kind && result) __defProp$9(target, key, result);
2535
3392
  return result;
2536
3393
  };
2537
3394
  let WfOption = class extends i {
@@ -2542,20 +3399,6 @@ let WfOption = class extends i {
2542
3399
  this.disabled = false;
2543
3400
  this.shortcut = "";
2544
3401
  this._selecting = false;
2545
- this._cachedContent = [];
2546
- }
2547
- /**
2548
- * Disable Shadow DOM - render to Light DOM for external styling
2549
- */
2550
- createRenderRoot() {
2551
- return this;
2552
- }
2553
- connectedCallback() {
2554
- if (this._cachedContent.length === 0) {
2555
- this._cachedContent = Array.from(this.childNodes).map((node) => node.cloneNode(true));
2556
- this.textContent = "";
2557
- }
2558
- super.connectedCallback();
2559
3402
  }
2560
3403
  render() {
2561
3404
  return b`
@@ -2572,7 +3415,7 @@ let WfOption = class extends i {
2572
3415
  variant="${this.selected ? "selected" : "default"}"
2573
3416
  ></wf-badge>` : A}
2574
3417
  <div class="wf-option-content">
2575
- ${this._cachedContent}
3418
+ <slot></slot>
2576
3419
  </div>
2577
3420
  </button>
2578
3421
  `;
@@ -2614,7 +3457,7 @@ let WfOption = class extends i {
2614
3457
  * Focus the option button
2615
3458
  */
2616
3459
  focus() {
2617
- const button = this.querySelector("button");
3460
+ const button = this.shadowRoot?.querySelector("button");
2618
3461
  button?.focus();
2619
3462
  }
2620
3463
  /**
@@ -2624,35 +3467,205 @@ let WfOption = class extends i {
2624
3467
  this.selected = selected;
2625
3468
  }
2626
3469
  };
2627
- __decorateClass$8([
3470
+ WfOption.styles = wfOptionStyles;
3471
+ __decorateClass$9([
2628
3472
  n2({ type: String })
2629
3473
  ], WfOption.prototype, "value", 2);
2630
- __decorateClass$8([
3474
+ __decorateClass$9([
2631
3475
  n2({ type: Boolean, reflect: true })
2632
3476
  ], WfOption.prototype, "selected", 2);
2633
- __decorateClass$8([
3477
+ __decorateClass$9([
2634
3478
  n2({ type: Boolean, reflect: true })
2635
3479
  ], WfOption.prototype, "disabled", 2);
2636
- __decorateClass$8([
3480
+ __decorateClass$9([
2637
3481
  n2({ type: String })
2638
3482
  ], WfOption.prototype, "shortcut", 2);
2639
- __decorateClass$8([
3483
+ __decorateClass$9([
2640
3484
  r()
2641
3485
  ], WfOption.prototype, "_selecting", 2);
2642
- WfOption = __decorateClass$8([
3486
+ WfOption = __decorateClass$9([
2643
3487
  t("wf-option")
2644
3488
  ], WfOption);
2645
- var __defProp$7 = Object.defineProperty;
2646
- var __decorateClass$7 = (decorators, target, key, kind) => {
3489
+ const formInputBaseStyles = i$3`
3490
+ :host {
3491
+ display: block;
3492
+ }
3493
+
3494
+ :host([hidden]) {
3495
+ display: none;
3496
+ }
3497
+
3498
+ .wf-field-container {
3499
+ display: flex;
3500
+ flex-direction: column;
3501
+ }
3502
+
3503
+ .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);
3508
+ }
3509
+
3510
+ .wf-label-required::after {
3511
+ content: ' *';
3512
+ color: var(--wf-color-error, #dc3545);
3513
+ }
3514
+
3515
+ /* Error wrapper for animated expand/collapse */
3516
+ .wf-error-wrapper {
3517
+ display: grid;
3518
+ grid-template-rows: 0fr;
3519
+ transition: grid-template-rows 200ms ease-out;
3520
+ }
3521
+
3522
+ .wf-error-wrapper.wf-has-error {
3523
+ grid-template-rows: 1fr;
3524
+ }
3525
+
3526
+ .wf-error-message {
3527
+ overflow: hidden;
3528
+ min-height: 0;
3529
+ font-size: var(--wf-font-size-sm, 0.875rem);
3530
+ color: var(--wf-color-error, #dc3545);
3531
+ opacity: 0;
3532
+ transform: translateY(-4px);
3533
+ transition: opacity 200ms ease-out, transform 200ms ease-out;
3534
+ }
3535
+
3536
+ .wf-has-error .wf-error-message {
3537
+ margin-top: var(--wf-spacing-2, 8px);
3538
+ opacity: 1;
3539
+ transform: translateY(0);
3540
+ }
3541
+
3542
+ .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);
3546
+ }
3547
+
3548
+ .wf-input {
3549
+ 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;
3554
+ 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);
3562
+ transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
3563
+ outline: none;
3564
+ box-sizing: border-box;
3565
+ }
3566
+
3567
+ .wf-input::placeholder {
3568
+ color: var(--wf-color-text-muted, #646464);
3569
+ font-weight: 500;
3570
+ }
3571
+
3572
+ .wf-input:focus {
3573
+ border-color: var(--wf-color-primary, #8040f0);
3574
+ box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
3575
+ }
3576
+
3577
+ .wf-input:disabled {
3578
+ opacity: 0.5;
3579
+ cursor: not-allowed;
3580
+ }
3581
+
3582
+ .wf-input.wf-input-error {
3583
+ border-color: var(--wf-color-error, #dc3545);
3584
+ }
3585
+
3586
+ .wf-input.wf-input-error:focus {
3587
+ box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
3588
+ }
3589
+
3590
+ /* Textarea-specific styles */
3591
+ .wf-textarea {
3592
+ width: 100%;
3593
+ padding: var(--wf-spacing-4, 16px);
3594
+ font-size: var(--wf-font-size-base, 1rem);
3595
+ 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);
3603
+ transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
3604
+ outline: none;
3605
+ box-sizing: border-box;
3606
+ resize: vertical;
3607
+ min-height: 100px;
3608
+ }
3609
+
3610
+ .wf-textarea::placeholder {
3611
+ color: var(--wf-color-text-muted, #6c757d);
3612
+ }
3613
+
3614
+ .wf-textarea:focus {
3615
+ border-color: var(--wf-color-primary, #8b5cf6);
3616
+ box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
3617
+ }
3618
+
3619
+ .wf-textarea:disabled {
3620
+ opacity: 0.5;
3621
+ cursor: not-allowed;
3622
+ }
3623
+
3624
+ .wf-textarea.wf-textarea-error {
3625
+ border-color: var(--wf-color-error, #dc3545);
3626
+ }
3627
+
3628
+ .wf-textarea.wf-textarea-error:focus {
3629
+ box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
3630
+ }
3631
+
3632
+ .wf-char-count {
3633
+ font-size: var(--wf-font-size-sm, 0.875rem);
3634
+ color: var(--wf-color-text-muted, #6c757d);
3635
+ text-align: right;
3636
+ }
3637
+
3638
+ .wf-char-count.wf-char-limit {
3639
+ color: var(--wf-color-error, #dc3545);
3640
+ }
3641
+
3642
+ /* wf-field slotted input styles */
3643
+ .wf-input-wrapper {
3644
+ position: relative;
3645
+ }
3646
+
3647
+ /* Number input - hide spinners */
3648
+ .wf-input::-webkit-outer-spin-button,
3649
+ .wf-input::-webkit-inner-spin-button {
3650
+ -webkit-appearance: none;
3651
+ margin: 0;
3652
+ }
3653
+
3654
+ .wf-input[type='number'] {
3655
+ -moz-appearance: textfield;
3656
+ }
3657
+ `;
3658
+ var __defProp$8 = Object.defineProperty;
3659
+ var __decorateClass$8 = (decorators, target, key, kind) => {
2647
3660
  var result = void 0;
2648
3661
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2649
3662
  if (decorator = decorators[i2])
2650
3663
  result = decorator(target, key, result) || result;
2651
- if (result) __defProp$7(target, key, result);
3664
+ if (result) __defProp$8(target, key, result);
2652
3665
  return result;
2653
3666
  };
2654
3667
  const DEFAULT_DEBOUNCE_MS = 600;
2655
- class FormInputBase extends i {
3668
+ const _FormInputBase = class _FormInputBase extends i {
2656
3669
  constructor() {
2657
3670
  super(...arguments);
2658
3671
  this.name = "";
@@ -2705,12 +3718,6 @@ class FormInputBase extends i {
2705
3718
  );
2706
3719
  };
2707
3720
  }
2708
- /**
2709
- * Disable Shadow DOM - render to Light DOM for external styling
2710
- */
2711
- createRenderRoot() {
2712
- return this;
2713
- }
2714
3721
  // ============================================
2715
3722
  // Lifecycle Methods
2716
3723
  // ============================================
@@ -2743,6 +3750,41 @@ class FormInputBase extends i {
2743
3750
  return "input";
2744
3751
  }
2745
3752
  // ============================================
3753
+ // Shared Render Helpers
3754
+ // ============================================
3755
+ /**
3756
+ * Render the label element
3757
+ */
3758
+ _renderLabel() {
3759
+ if (!this.label) {
3760
+ return A;
3761
+ }
3762
+ return b`<label
3763
+ class="wf-label ${this.required ? "wf-label-required" : ""}"
3764
+ for="${this.name}"
3765
+ data-testid="wf-label"
3766
+ >${this.label}</label>`;
3767
+ }
3768
+ /**
3769
+ * Render the hint text (only shown when no error)
3770
+ */
3771
+ _renderHint() {
3772
+ if (!this.hint || this._errorMessage) {
3773
+ return A;
3774
+ }
3775
+ return b`<span class="wf-hint">${this.hint}</span>`;
3776
+ }
3777
+ /**
3778
+ * Render the error message container with animation support
3779
+ */
3780
+ _renderError() {
3781
+ return b`<div class="wf-error-wrapper ${this._errorMessage ? "wf-has-error" : ""}">
3782
+ <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3783
+ ${this._errorMessage || ""}
3784
+ </span>
3785
+ </div>`;
3786
+ }
3787
+ // ============================================
2746
3788
  // Public API
2747
3789
  // ============================================
2748
3790
  /**
@@ -2819,7 +3861,7 @@ class FormInputBase extends i {
2819
3861
  * Focus the input element
2820
3862
  */
2821
3863
  focus() {
2822
- const element = this.querySelector(this._getFocusableSelector());
3864
+ const element = this.shadowRoot?.querySelector(this._getFocusableSelector());
2823
3865
  element?.focus();
2824
3866
  }
2825
3867
  /**
@@ -2834,23 +3876,25 @@ class FormInputBase extends i {
2834
3876
  this._debounceTimer = null;
2835
3877
  }
2836
3878
  }
2837
- }
2838
- __decorateClass$7([
3879
+ };
3880
+ _FormInputBase.styles = formInputBaseStyles;
3881
+ let FormInputBase = _FormInputBase;
3882
+ __decorateClass$8([
2839
3883
  n2({ type: String })
2840
3884
  ], FormInputBase.prototype, "name");
2841
- __decorateClass$7([
3885
+ __decorateClass$8([
2842
3886
  n2({ type: String })
2843
3887
  ], FormInputBase.prototype, "label");
2844
- __decorateClass$7([
3888
+ __decorateClass$8([
2845
3889
  n2({ type: Boolean })
2846
3890
  ], FormInputBase.prototype, "required");
2847
- __decorateClass$7([
3891
+ __decorateClass$8([
2848
3892
  n2({ type: String })
2849
3893
  ], FormInputBase.prototype, "hint");
2850
- __decorateClass$7([
3894
+ __decorateClass$8([
2851
3895
  r()
2852
3896
  ], FormInputBase.prototype, "_errorMessage");
2853
- __decorateClass$7([
3897
+ __decorateClass$8([
2854
3898
  r()
2855
3899
  ], FormInputBase.prototype, "_value");
2856
3900
  const DEFAULT_BLOCKED_DOMAINS = [
@@ -3088,182 +4132,14 @@ class ValidationController {
3088
4132
  };
3089
4133
  }
3090
4134
  }
3091
- var __defProp$6 = Object.defineProperty;
4135
+ var __defProp$7 = Object.defineProperty;
3092
4136
  var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
3093
- var __decorateClass$6 = (decorators, target, key, kind) => {
4137
+ var __decorateClass$7 = (decorators, target, key, kind) => {
3094
4138
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
3095
4139
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3096
4140
  if (decorator = decorators[i2])
3097
4141
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3098
- if (kind && result) __defProp$6(target, key, result);
3099
- return result;
3100
- };
3101
- let WfField = class extends FormInputBase {
3102
- constructor() {
3103
- super(...arguments);
3104
- this._inputElement = null;
3105
- }
3106
- // ============================================
3107
- // Lifecycle Overrides
3108
- // ============================================
3109
- connectedCallback() {
3110
- super.connectedCallback();
3111
- this.addEventListener("input", this._handleInput);
3112
- this.addEventListener("blur", this._handleBlur, true);
3113
- this.addEventListener("focus", this._handleFocus, true);
3114
- }
3115
- disconnectedCallback() {
3116
- super.disconnectedCallback();
3117
- this.removeEventListener("input", this._handleInput);
3118
- this.removeEventListener("blur", this._handleBlur, true);
3119
- this.removeEventListener("focus", this._handleFocus, true);
3120
- }
3121
- firstUpdated() {
3122
- this._discoverInput();
3123
- this._setupValidators();
3124
- }
3125
- // ============================================
3126
- // Abstract Method Implementations
3127
- // ============================================
3128
- _getValidationTriggerProperties() {
3129
- return ["required"];
3130
- }
3131
- /**
3132
- * Field uses faster debounce (300ms) for responsive validation
3133
- */
3134
- _getDebounceMs() {
3135
- return 300;
3136
- }
3137
- _setupValidators() {
3138
- if (!this._inputElement) {
3139
- return;
3140
- }
3141
- this._validators = [];
3142
- if (this.required || this._inputElement.hasAttribute("required")) {
3143
- this._validators.push(ValidationController.required());
3144
- }
3145
- if (this._inputElement.getAttribute("type") === "email") {
3146
- this._validators.push(ValidationController.email());
3147
- }
3148
- if (this._inputElement.hasAttribute("data-work-email")) {
3149
- const blockedDomainsAttr = this._inputElement.getAttribute("data-blocked-domains");
3150
- const blockedDomains = blockedDomainsAttr ? blockedDomainsAttr.split(",").map((d2) => d2.trim()) : void 0;
3151
- this._validators.push(ValidationController.workEmail(blockedDomains));
3152
- }
3153
- const pattern = this._inputElement.getAttribute("pattern");
3154
- if (pattern) {
3155
- const message = this._inputElement.getAttribute("data-pattern-message") || "Invalid format";
3156
- this._validators.push(ValidationController.pattern(new RegExp(pattern), message));
3157
- }
3158
- const minLength = this._inputElement.getAttribute("minlength");
3159
- if (minLength) {
3160
- this._validators.push(ValidationController.minLength(parseInt(minLength, 10)));
3161
- }
3162
- const maxLength = this._inputElement.getAttribute("maxlength");
3163
- if (maxLength) {
3164
- this._validators.push(ValidationController.maxLength(parseInt(maxLength, 10)));
3165
- }
3166
- }
3167
- // ============================================
3168
- // Slot Handling
3169
- // ============================================
3170
- _handleSlotChange() {
3171
- this._discoverInput();
3172
- this._setupValidators();
3173
- }
3174
- _discoverInput() {
3175
- const slot = this.shadowRoot?.querySelector("slot");
3176
- if (!slot) {
3177
- return;
3178
- }
3179
- const elements = slot.assignedElements({ flatten: true });
3180
- for (const el of elements) {
3181
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
3182
- this._inputElement = el;
3183
- if (!el.id) {
3184
- el.id = this.name;
3185
- }
3186
- if (!el.name) {
3187
- el.name = this.name;
3188
- }
3189
- this._value = el.value;
3190
- break;
3191
- }
3192
- }
3193
- }
3194
- // ============================================
3195
- // Value Override (for slotted elements)
3196
- // ============================================
3197
- /**
3198
- * Get current value from slotted element or internal state
3199
- */
3200
- get value() {
3201
- return this._inputElement?.value ?? this._value;
3202
- }
3203
- /**
3204
- * Set value on both internal state and slotted element
3205
- */
3206
- set value(val) {
3207
- this._value = val;
3208
- if (this._inputElement) {
3209
- this._inputElement.value = String(val ?? "");
3210
- }
3211
- }
3212
- // ============================================
3213
- // Focus and Reset Overrides
3214
- // ============================================
3215
- /**
3216
- * Focus the slotted input element
3217
- */
3218
- focus() {
3219
- this._inputElement?.focus();
3220
- }
3221
- /**
3222
- * Reset field to initial state including slotted element
3223
- */
3224
- reset() {
3225
- super.reset();
3226
- if (this._inputElement) {
3227
- this._inputElement.value = "";
3228
- }
3229
- }
3230
- // ============================================
3231
- // Render
3232
- // ============================================
3233
- render() {
3234
- return b`
3235
- <div class="wf-field-container">
3236
- ${this.label ? b`<label
3237
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3238
- for="${this.name}"
3239
- >
3240
- ${this.label}
3241
- </label>` : ""}
3242
- <div class="wf-input-wrapper">
3243
- <slot @slotchange="${this._handleSlotChange}"></slot>
3244
- </div>
3245
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3246
- <span class="wf-error-message" role="alert" aria-live="polite">
3247
- ${this._errorMessage}
3248
- </span>
3249
- </div>
3250
- `;
3251
- }
3252
- };
3253
- __decorateClass$6([
3254
- r()
3255
- ], WfField.prototype, "_inputElement", 2);
3256
- WfField = __decorateClass$6([
3257
- t("wf-field")
3258
- ], WfField);
3259
- var __defProp$5 = Object.defineProperty;
3260
- var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
3261
- var __decorateClass$5 = (decorators, target, key, kind) => {
3262
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
3263
- for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3264
- if (decorator = decorators[i2])
3265
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3266
- if (kind && result) __defProp$5(target, key, result);
4142
+ if (kind && result) __defProp$7(target, key, result);
3267
4143
  return result;
3268
4144
  };
3269
4145
  let WfEmail = class extends FormInputBase {
@@ -3309,13 +4185,7 @@ let WfEmail = class extends FormInputBase {
3309
4185
  render() {
3310
4186
  return b`
3311
4187
  <div class="wf-field-container">
3312
- ${this.label ? b`<label
3313
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3314
- for="${this.name}"
3315
- data-testid="wf-label"
3316
- >
3317
- ${this.label}
3318
- </label>` : ""}
4188
+ ${this._renderLabel()}
3319
4189
  <input
3320
4190
  type="email"
3321
4191
  class="wf-input ${this._errorMessage ? "wf-input-error" : ""}"
@@ -3330,40 +4200,38 @@ let WfEmail = class extends FormInputBase {
3330
4200
  @blur="${this._handleBlur}"
3331
4201
  @focus="${this._handleFocus}"
3332
4202
  />
3333
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3334
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3335
- ${this._errorMessage}
3336
- </span>
4203
+ ${this._renderHint()}
4204
+ ${this._renderError()}
3337
4205
  </div>
3338
4206
  `;
3339
4207
  }
3340
4208
  };
3341
- __decorateClass$5([
4209
+ __decorateClass$7([
3342
4210
  n2({ type: String })
3343
4211
  ], WfEmail.prototype, "placeholder", 2);
3344
- __decorateClass$5([
4212
+ __decorateClass$7([
3345
4213
  n2({ type: Boolean, attribute: "work-email" })
3346
4214
  ], WfEmail.prototype, "workEmail", 2);
3347
- __decorateClass$5([
4215
+ __decorateClass$7([
3348
4216
  n2({ type: String, attribute: "blocked-domains" })
3349
4217
  ], WfEmail.prototype, "blockedDomains", 2);
3350
- __decorateClass$5([
4218
+ __decorateClass$7([
3351
4219
  n2({ type: String, attribute: "work-email-message" })
3352
4220
  ], WfEmail.prototype, "workEmailMessage", 2);
3353
- __decorateClass$5([
4221
+ __decorateClass$7([
3354
4222
  n2({ type: Boolean })
3355
4223
  ], WfEmail.prototype, "disabled", 2);
3356
- WfEmail = __decorateClass$5([
4224
+ WfEmail = __decorateClass$7([
3357
4225
  t("wf-email")
3358
4226
  ], WfEmail);
3359
- var __defProp$4 = Object.defineProperty;
3360
- var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
3361
- var __decorateClass$4 = (decorators, target, key, kind) => {
3362
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
4227
+ var __defProp$6 = Object.defineProperty;
4228
+ var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
4229
+ var __decorateClass$6 = (decorators, target, key, kind) => {
4230
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
3363
4231
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3364
4232
  if (decorator = decorators[i2])
3365
4233
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3366
- if (kind && result) __defProp$4(target, key, result);
4234
+ if (kind && result) __defProp$6(target, key, result);
3367
4235
  return result;
3368
4236
  };
3369
4237
  let WfInput = class extends FormInputBase {
@@ -3404,13 +4272,7 @@ let WfInput = class extends FormInputBase {
3404
4272
  render() {
3405
4273
  return b`
3406
4274
  <div class="wf-field-container">
3407
- ${this.label ? b`<label
3408
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3409
- for="${this.name}"
3410
- data-testid="wf-label"
3411
- >
3412
- ${this.label}
3413
- </label>` : ""}
4275
+ ${this._renderLabel()}
3414
4276
  <input
3415
4277
  type="${this.type}"
3416
4278
  class="wf-input ${this._errorMessage ? "wf-input-error" : ""}"
@@ -3426,49 +4288,47 @@ let WfInput = class extends FormInputBase {
3426
4288
  @blur="${this._handleBlur}"
3427
4289
  @focus="${this._handleFocus}"
3428
4290
  />
3429
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3430
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3431
- ${this._errorMessage}
3432
- </span>
4291
+ ${this._renderHint()}
4292
+ ${this._renderError()}
3433
4293
  </div>
3434
4294
  `;
3435
4295
  }
3436
4296
  };
3437
- __decorateClass$4([
4297
+ __decorateClass$6([
3438
4298
  n2({ type: String })
3439
4299
  ], WfInput.prototype, "placeholder", 2);
3440
- __decorateClass$4([
4300
+ __decorateClass$6([
3441
4301
  n2({ type: String })
3442
4302
  ], WfInput.prototype, "type", 2);
3443
- __decorateClass$4([
4303
+ __decorateClass$6([
3444
4304
  n2({ type: Number })
3445
4305
  ], WfInput.prototype, "minlength", 2);
3446
- __decorateClass$4([
4306
+ __decorateClass$6([
3447
4307
  n2({ type: Number })
3448
4308
  ], WfInput.prototype, "maxlength", 2);
3449
- __decorateClass$4([
4309
+ __decorateClass$6([
3450
4310
  n2({ type: String })
3451
4311
  ], WfInput.prototype, "pattern", 2);
3452
- __decorateClass$4([
4312
+ __decorateClass$6([
3453
4313
  n2({ type: String, attribute: "pattern-message" })
3454
4314
  ], WfInput.prototype, "patternMessage", 2);
3455
- __decorateClass$4([
4315
+ __decorateClass$6([
3456
4316
  n2({ type: Boolean })
3457
4317
  ], WfInput.prototype, "disabled", 2);
3458
- __decorateClass$4([
4318
+ __decorateClass$6([
3459
4319
  n2({ type: String })
3460
4320
  ], WfInput.prototype, "autocomplete", 2);
3461
- WfInput = __decorateClass$4([
4321
+ WfInput = __decorateClass$6([
3462
4322
  t("wf-input")
3463
4323
  ], WfInput);
3464
- var __defProp$3 = Object.defineProperty;
3465
- var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
3466
- var __decorateClass$3 = (decorators, target, key, kind) => {
3467
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
4324
+ var __defProp$5 = Object.defineProperty;
4325
+ var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
4326
+ var __decorateClass$5 = (decorators, target, key, kind) => {
4327
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
3468
4328
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3469
4329
  if (decorator = decorators[i2])
3470
4330
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3471
- if (kind && result) __defProp$3(target, key, result);
4331
+ if (kind && result) __defProp$5(target, key, result);
3472
4332
  return result;
3473
4333
  };
3474
4334
  let WfNumber = class extends WfInput {
@@ -3509,13 +4369,7 @@ let WfNumber = class extends WfInput {
3509
4369
  render() {
3510
4370
  return b`
3511
4371
  <div class="wf-field-container">
3512
- ${this.label ? b`<label
3513
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3514
- for="${this.name}"
3515
- data-testid="wf-label"
3516
- >
3517
- ${this.label}
3518
- </label>` : ""}
4372
+ ${this._renderLabel()}
3519
4373
  <input
3520
4374
  type="number"
3521
4375
  class="wf-input ${this._errorMessage ? "wf-input-error" : ""}"
@@ -3534,10 +4388,8 @@ let WfNumber = class extends WfInput {
3534
4388
  @blur="${this._handleBlur}"
3535
4389
  @focus="${this._handleFocus}"
3536
4390
  />
3537
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3538
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3539
- ${this._errorMessage}
3540
- </span>
4391
+ ${this._renderHint()}
4392
+ ${this._renderError()}
3541
4393
  </div>
3542
4394
  `;
3543
4395
  }
@@ -3554,26 +4406,26 @@ let WfNumber = class extends WfInput {
3554
4406
  this._value = String(val);
3555
4407
  }
3556
4408
  };
3557
- __decorateClass$3([
4409
+ __decorateClass$5([
3558
4410
  n2({ type: Number })
3559
4411
  ], WfNumber.prototype, "min", 2);
3560
- __decorateClass$3([
4412
+ __decorateClass$5([
3561
4413
  n2({ type: Number })
3562
4414
  ], WfNumber.prototype, "max", 2);
3563
- __decorateClass$3([
4415
+ __decorateClass$5([
3564
4416
  n2({ type: Number })
3565
4417
  ], WfNumber.prototype, "step", 2);
3566
- WfNumber = __decorateClass$3([
4418
+ WfNumber = __decorateClass$5([
3567
4419
  t("wf-number")
3568
4420
  ], WfNumber);
3569
- var __defProp$2 = Object.defineProperty;
3570
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
3571
- var __decorateClass$2 = (decorators, target, key, kind) => {
3572
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
4421
+ var __defProp$4 = Object.defineProperty;
4422
+ var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
4423
+ var __decorateClass$4 = (decorators, target, key, kind) => {
4424
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
3573
4425
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3574
4426
  if (decorator = decorators[i2])
3575
4427
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3576
- if (kind && result) __defProp$2(target, key, result);
4428
+ if (kind && result) __defProp$4(target, key, result);
3577
4429
  return result;
3578
4430
  };
3579
4431
  let WfTextarea = class extends FormInputBase {
@@ -3618,13 +4470,7 @@ let WfTextarea = class extends FormInputBase {
3618
4470
  const isAtLimit = this.maxlength !== void 0 && charCount >= this.maxlength;
3619
4471
  return b`
3620
4472
  <div class="wf-field-container">
3621
- ${this.label ? b`<label
3622
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3623
- for="${this.name}"
3624
- data-testid="wf-label"
3625
- >
3626
- ${this.label}
3627
- </label>` : ""}
4473
+ ${this._renderLabel()}
3628
4474
  <textarea
3629
4475
  class="wf-textarea ${this._errorMessage ? "wf-textarea-error" : ""}"
3630
4476
  id="${this.name}"
@@ -3644,33 +4490,31 @@ let WfTextarea = class extends FormInputBase {
3644
4490
  ${this.showCount && this.maxlength ? b`<span class="wf-char-count ${isAtLimit ? "wf-char-limit" : ""}" data-testid="wf-counter">
3645
4491
  ${charCount}/${this.maxlength}
3646
4492
  </span>` : ""}
3647
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3648
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3649
- ${this._errorMessage}
3650
- </span>
4493
+ ${this._renderHint()}
4494
+ ${this._renderError()}
3651
4495
  </div>
3652
4496
  `;
3653
4497
  }
3654
4498
  };
3655
- __decorateClass$2([
4499
+ __decorateClass$4([
3656
4500
  n2({ type: String })
3657
4501
  ], WfTextarea.prototype, "placeholder", 2);
3658
- __decorateClass$2([
4502
+ __decorateClass$4([
3659
4503
  n2({ type: Number })
3660
4504
  ], WfTextarea.prototype, "rows", 2);
3661
- __decorateClass$2([
4505
+ __decorateClass$4([
3662
4506
  n2({ type: Number })
3663
4507
  ], WfTextarea.prototype, "minlength", 2);
3664
- __decorateClass$2([
4508
+ __decorateClass$4([
3665
4509
  n2({ type: Number })
3666
4510
  ], WfTextarea.prototype, "maxlength", 2);
3667
- __decorateClass$2([
4511
+ __decorateClass$4([
3668
4512
  n2({ type: Boolean })
3669
4513
  ], WfTextarea.prototype, "disabled", 2);
3670
- __decorateClass$2([
4514
+ __decorateClass$4([
3671
4515
  n2({ type: Boolean, attribute: "show-count" })
3672
4516
  ], WfTextarea.prototype, "showCount", 2);
3673
- WfTextarea = __decorateClass$2([
4517
+ WfTextarea = __decorateClass$4([
3674
4518
  t("wf-textarea")
3675
4519
  ], WfTextarea);
3676
4520
  function init(config) {
@@ -3875,14 +4719,41 @@ function init(config) {
3875
4719
  return instance;
3876
4720
  }
3877
4721
  const init_default = { init };
3878
- var __defProp$1 = Object.defineProperty;
3879
- var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
3880
- var __decorateClass$1 = (decorators, target, key, kind) => {
3881
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
4722
+ const wfProgressStyles = i$3`
4723
+ :host {
4724
+ display: block;
4725
+ }
4726
+
4727
+ :host([hidden]) {
4728
+ display: none;
4729
+ }
4730
+
4731
+ .wf-progress {
4732
+ display: flex;
4733
+ gap: var(--wf-spacing-4, 16px);
4734
+ }
4735
+
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
+ }
4743
+
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
+ `;
4749
+ var __defProp$3 = Object.defineProperty;
4750
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
4751
+ var __decorateClass$3 = (decorators, target, key, kind) => {
4752
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
3882
4753
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3883
4754
  if (decorator = decorators[i2])
3884
4755
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3885
- if (kind && result) __defProp$1(target, key, result);
4756
+ if (kind && result) __defProp$3(target, key, result);
3886
4757
  return result;
3887
4758
  };
3888
4759
  let WfProgress = class extends i {
@@ -3897,12 +4768,6 @@ let WfProgress = class extends i {
3897
4768
  this._boundHandleSuccess = this._handleSuccess.bind(this);
3898
4769
  this._boundHandleStepsDiscovered = this._handleStepsDiscovered.bind(this);
3899
4770
  }
3900
- /**
3901
- * Disable Shadow DOM - render to Light DOM for external styling
3902
- */
3903
- createRenderRoot() {
3904
- return this;
3905
- }
3906
4771
  connectedCallback() {
3907
4772
  super.connectedCallback();
3908
4773
  document.addEventListener("wf:steps-discovered", this._boundHandleStepsDiscovered);
@@ -3976,6 +4841,10 @@ let WfProgress = class extends i {
3976
4841
  segments.push(b`
3977
4842
  <div
3978
4843
  class="wf-progress-segment ${completed ? "completed" : ""} ${active ? "active" : ""}"
4844
+ data-testid="wf-progress-segment"
4845
+ data-step="${i2}"
4846
+ data-completed="${completed}"
4847
+ data-active="${active}"
3979
4848
  role="progressbar"
3980
4849
  aria-valuenow="${this._currentStep}"
3981
4850
  aria-valuemin="1"
@@ -3983,24 +4852,273 @@ let WfProgress = class extends i {
3983
4852
  ></div>
3984
4853
  `);
3985
4854
  }
3986
- return b`<div class="wf-progress" role="group" aria-label="Form progress">${segments}</div>`;
4855
+ return b`<div class="wf-progress" data-testid="wf-progress-bar" role="group" aria-label="Form progress">${segments}</div>`;
3987
4856
  }
3988
4857
  };
3989
- __decorateClass$1([
4858
+ WfProgress.styles = wfProgressStyles;
4859
+ __decorateClass$3([
3990
4860
  n2({ type: String })
3991
4861
  ], WfProgress.prototype, "for", 2);
3992
- __decorateClass$1([
4862
+ __decorateClass$3([
3993
4863
  r()
3994
4864
  ], WfProgress.prototype, "_currentStep", 2);
3995
- __decorateClass$1([
4865
+ __decorateClass$3([
3996
4866
  r()
3997
4867
  ], WfProgress.prototype, "_totalSteps", 2);
3998
- __decorateClass$1([
4868
+ __decorateClass$3([
3999
4869
  r()
4000
4870
  ], WfProgress.prototype, "_isComplete", 2);
4001
- WfProgress = __decorateClass$1([
4871
+ WfProgress = __decorateClass$3([
4002
4872
  t("wf-progress")
4003
4873
  ], WfProgress);
4874
+ var __defProp$2 = Object.defineProperty;
4875
+ var __decorateClass$2 = (decorators, target, key, kind) => {
4876
+ var result = void 0;
4877
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
4878
+ if (decorator = decorators[i2])
4879
+ result = decorator(target, key, result) || result;
4880
+ if (result) __defProp$2(target, key, result);
4881
+ return result;
4882
+ };
4883
+ class NavigationButtonBase extends i {
4884
+ constructor() {
4885
+ super(...arguments);
4886
+ this._isFirstStep = true;
4887
+ this._isLastStep = false;
4888
+ this._isSubmitting = false;
4889
+ this._handleNavState = (e2) => {
4890
+ this._isFirstStep = e2.detail.isFirstStep;
4891
+ this._isLastStep = e2.detail.isLastStep;
4892
+ this._isSubmitting = e2.detail.isSubmitting;
4893
+ };
4894
+ }
4895
+ // ============================================
4896
+ // Lifecycle
4897
+ // ============================================
4898
+ connectedCallback() {
4899
+ super.connectedCallback();
4900
+ this._findWizardForm()?.addEventListener("wf:nav-state", this._handleNavState);
4901
+ this._requestNavState();
4902
+ }
4903
+ disconnectedCallback() {
4904
+ super.disconnectedCallback();
4905
+ this._findWizardForm()?.removeEventListener("wf:nav-state", this._handleNavState);
4906
+ }
4907
+ // ============================================
4908
+ // Helpers
4909
+ // ============================================
4910
+ _findWizardForm() {
4911
+ return this.closest("wizard-form");
4912
+ }
4913
+ _requestNavState() {
4914
+ this.dispatchEvent(
4915
+ new CustomEvent("wf:nav-state-request", {
4916
+ bubbles: true,
4917
+ composed: true
4918
+ })
4919
+ );
4920
+ }
4921
+ /**
4922
+ * Dispatch the navigation event
4923
+ */
4924
+ _dispatchNavEvent() {
4925
+ this.dispatchEvent(
4926
+ new CustomEvent(this._getEventName(), {
4927
+ bubbles: true,
4928
+ composed: true
4929
+ })
4930
+ );
4931
+ }
4932
+ }
4933
+ __decorateClass$2([
4934
+ r()
4935
+ ], NavigationButtonBase.prototype, "_isFirstStep");
4936
+ __decorateClass$2([
4937
+ r()
4938
+ ], NavigationButtonBase.prototype, "_isLastStep");
4939
+ __decorateClass$2([
4940
+ r()
4941
+ ], NavigationButtonBase.prototype, "_isSubmitting");
4942
+ const wfNextBtnStyles = [
4943
+ sharedAnimations,
4944
+ buttonBaseStyles,
4945
+ i$3`
4946
+ :host {
4947
+ display: block;
4948
+ width: 100%;
4949
+ }
4950
+
4951
+ :host([hidden]) {
4952
+ display: none;
4953
+ }
4954
+
4955
+ .wf-btn-next {
4956
+ width: 100%;
4957
+ flex: 1;
4958
+ background-color: var(--wf-color-primary, #8040f0);
4959
+ border: 1px solid var(--wf-color-primary-border, #602cbb);
4960
+ color: white;
4961
+ position: relative;
4962
+ }
4963
+
4964
+ .wf-btn-next:hover:not(:disabled) {
4965
+ filter: brightness(1.1);
4966
+ }
4967
+
4968
+ .wf-btn-shortcut {
4969
+ position: absolute;
4970
+ right: var(--wf-spacing-4, 16px);
4971
+ display: inline-flex;
4972
+ align-items: center;
4973
+ gap: 2px;
4974
+ }
4975
+
4976
+ .wf-loading {
4977
+ display: inline-block;
4978
+ width: 20px;
4979
+ height: 20px;
4980
+ border: 2px solid rgba(0, 0, 0, 0.1);
4981
+ border-radius: 50%;
4982
+ border-top-color: white;
4983
+ animation: wf-spin 0.8s linear infinite;
4984
+ }
4985
+
4986
+ /* Inline button styles (for use inside wf-other) */
4987
+ :host([inline]) {
4988
+ display: inline-block;
4989
+ width: auto;
4990
+ }
4991
+
4992
+ :host([inline]) .wf-btn {
4993
+ min-height: var(--wf-input-min-height, 56px);
4994
+ 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);
5001
+ }
5002
+ `
5003
+ ];
5004
+ var __defProp$1 = Object.defineProperty;
5005
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
5006
+ var __decorateClass$1 = (decorators, target, key, kind) => {
5007
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
5008
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
5009
+ if (decorator = decorators[i2])
5010
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
5011
+ if (kind && result) __defProp$1(target, key, result);
5012
+ return result;
5013
+ };
5014
+ let WfNextBtn = class extends NavigationButtonBase {
5015
+ constructor() {
5016
+ super(...arguments);
5017
+ this.showShortcut = true;
5018
+ this.inline = false;
5019
+ this.disabled = false;
5020
+ this._handleClick = () => {
5021
+ if (this.disabled || this._isSubmitting) {
5022
+ return;
5023
+ }
5024
+ this._dispatchNavEvent();
5025
+ };
5026
+ }
5027
+ // ============================================
5028
+ // Abstract Implementation
5029
+ // ============================================
5030
+ _getEventName() {
5031
+ return "wf:nav-next";
5032
+ }
5033
+ // ============================================
5034
+ // Helpers
5035
+ // ============================================
5036
+ _getButtonLabel() {
5037
+ if (this.label) {
5038
+ return this.label;
5039
+ }
5040
+ const isSubmit = !this.inline && (this.action === "submit" || this.action !== "next" && this._isLastStep);
5041
+ return isSubmit ? "Submit" : "Continue";
5042
+ }
5043
+ _isSubmitAction() {
5044
+ return !this.inline && (this.action === "submit" || this.action !== "next" && this._isLastStep);
5045
+ }
5046
+ // ============================================
5047
+ // Render
5048
+ // ============================================
5049
+ render() {
5050
+ const buttonLabel = this._getButtonLabel();
5051
+ const isDisabled = this.disabled || this._isSubmitting;
5052
+ return b`
5053
+ <button
5054
+ type="button"
5055
+ class="wf-btn wf-btn-next"
5056
+ ?disabled="${isDisabled}"
5057
+ @click="${this._handleClick}"
5058
+ data-testid="wf-next-btn"
5059
+ >
5060
+ ${this._isSubmitting ? b`<span class="wf-loading"></span>` : b`
5061
+ ${buttonLabel}
5062
+ ${this.showShortcut ? b`
5063
+ <span class="wf-btn-shortcut ${this.inline ? "wf-btn-shortcut-inline" : ""}">
5064
+ <wf-badge variant="button" shortcut="↵"></wf-badge>
5065
+ </span>
5066
+ ` : A}
5067
+ `}
5068
+ </button>
5069
+ `;
5070
+ }
5071
+ };
5072
+ WfNextBtn.styles = wfNextBtnStyles;
5073
+ __decorateClass$1([
5074
+ n2({ type: String })
5075
+ ], WfNextBtn.prototype, "label", 2);
5076
+ __decorateClass$1([
5077
+ n2({ type: String })
5078
+ ], WfNextBtn.prototype, "action", 2);
5079
+ __decorateClass$1([
5080
+ n2({ type: Boolean, attribute: "show-shortcut" })
5081
+ ], WfNextBtn.prototype, "showShortcut", 2);
5082
+ __decorateClass$1([
5083
+ n2({ type: Boolean })
5084
+ ], WfNextBtn.prototype, "inline", 2);
5085
+ __decorateClass$1([
5086
+ n2({ type: Boolean })
5087
+ ], WfNextBtn.prototype, "disabled", 2);
5088
+ WfNextBtn = __decorateClass$1([
5089
+ t("wf-next-btn")
5090
+ ], WfNextBtn);
5091
+ const wfBackBtnStyles = [
5092
+ buttonBaseStyles,
5093
+ i$3`
5094
+ :host {
5095
+ display: inline-block;
5096
+ }
5097
+
5098
+ :host([hidden]) {
5099
+ display: none;
5100
+ }
5101
+
5102
+ .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);
5109
+ }
5110
+
5111
+ .wf-btn-back:hover:not(:disabled) {
5112
+ background: var(--wf-glass-bg-hover, rgba(255, 255, 255, 0.85));
5113
+ }
5114
+
5115
+ .wf-btn-shortcut {
5116
+ display: inline-flex;
5117
+ align-items: center;
5118
+ gap: 2px;
5119
+ }
5120
+ `
5121
+ ];
4004
5122
  var __defProp = Object.defineProperty;
4005
5123
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4006
5124
  var __decorateClass = (decorators, target, key, kind) => {
@@ -4011,92 +5129,86 @@ var __decorateClass = (decorators, target, key, kind) => {
4011
5129
  if (kind && result) __defProp(target, key, result);
4012
5130
  return result;
4013
5131
  };
4014
- let WfThankYou = class extends i {
5132
+ let WfBackBtn = class extends NavigationButtonBase {
4015
5133
  constructor() {
4016
5134
  super(...arguments);
4017
- this.title = "Thank you!";
4018
- this.subtitle = "We've received your request.";
4019
- this.hideIcon = false;
5135
+ this.label = "Back";
5136
+ this.showShortcut = true;
5137
+ this.disabled = false;
5138
+ this.hideOnFirst = true;
5139
+ this._handleClick = () => {
5140
+ if (this.disabled) {
5141
+ return;
5142
+ }
5143
+ this._dispatchNavEvent();
5144
+ };
4020
5145
  }
4021
- /**
4022
- * Disable Shadow DOM - render to Light DOM for external styling
4023
- */
4024
- createRenderRoot() {
4025
- return this;
5146
+ // ============================================
5147
+ // Abstract Implementation
5148
+ // ============================================
5149
+ _getEventName() {
5150
+ return "wf:nav-back";
4026
5151
  }
5152
+ // ============================================
5153
+ // Render
5154
+ // ============================================
4027
5155
  render() {
5156
+ if (this.hideOnFirst && this._isFirstStep) {
5157
+ return A;
5158
+ }
4028
5159
  return b`
4029
- ${!this.hideIcon ? b`
4030
- <div class="wf-thank-you-icon">
4031
- <slot name="icon">
4032
- <svg
4033
- xmlns="http://www.w3.org/2000/svg"
4034
- fill="none"
4035
- viewBox="0 0 24 24"
4036
- stroke="currentColor"
4037
- >
4038
- <path
4039
- stroke-linecap="round"
4040
- stroke-linejoin="round"
4041
- stroke-width="2"
4042
- d="M5 13l4 4L19 7"
4043
- />
4044
- </svg>
4045
- </slot>
4046
- </div>
4047
- ` : ""}
4048
- <h2 class="wf-thank-you-title">${this.title}</h2>
4049
- <p class="wf-thank-you-subtitle">${this.subtitle}</p>
4050
- <slot></slot>
4051
- <slot name="footer"></slot>
5160
+ <button
5161
+ type="button"
5162
+ class="wf-btn wf-btn-back"
5163
+ ?disabled="${this.disabled}"
5164
+ @click="${this._handleClick}"
5165
+ data-testid="wf-back-btn"
5166
+ >
5167
+ ${this.showShortcut ? b`
5168
+ <span class="wf-btn-shortcut">
5169
+ <wf-badge variant="button-secondary">Esc</wf-badge>
5170
+ </span>
5171
+ ` : A}
5172
+ ${this.label}
5173
+ </button>
4052
5174
  `;
4053
5175
  }
4054
5176
  };
5177
+ WfBackBtn.styles = wfBackBtnStyles;
4055
5178
  __decorateClass([
4056
5179
  n2({ type: String })
4057
- ], WfThankYou.prototype, "title", 2);
5180
+ ], WfBackBtn.prototype, "label", 2);
4058
5181
  __decorateClass([
4059
- n2({ type: String })
4060
- ], WfThankYou.prototype, "subtitle", 2);
5182
+ n2({ type: Boolean, attribute: "show-shortcut" })
5183
+ ], WfBackBtn.prototype, "showShortcut", 2);
4061
5184
  __decorateClass([
4062
- n2({ type: Boolean, attribute: "hide-icon" })
4063
- ], WfThankYou.prototype, "hideIcon", 2);
4064
- WfThankYou = __decorateClass([
4065
- t("wf-thank-you")
4066
- ], WfThankYou);
4067
- const GLOBAL_STYLES = `wizard-form{--wf-color-primary:#8040f0;--wf-color-primary-border:#602cbb;--wf-color-primary-light:#8040f014;--wf-color-surface:#f3f3f5;--wf-color-surface-hover:#e9e9eb;--wf-color-border:#d4d4d4;--wf-color-text:#0a0a0a;--wf-color-text-secondary:#404040;--wf-color-text-muted:#646464;--wf-color-error:#dc3545;--wf-color-badge-bg:#fcfcfc;--wf-color-badge-border:#d4d4d4;--wf-color-badge-text:#5f5f5f;--wf-color-progress-active:#8b8b8b99;--wf-color-progress-inactive:#d9d9d999;--wf-spacing-1:4px;--wf-spacing-2:8px;--wf-spacing-3:12px;--wf-spacing-4:16px;--wf-spacing-5:20px;--wf-spacing-6:24px;--wf-spacing-8:32px;--wf-radius-sm:4px;--wf-radius-md:8px;--wf-radius-lg:8px;--wf-radius-full:99px;--wf-font-size-xs:.75rem;--wf-font-size-sm:.875rem;--wf-font-size-base:1rem;--wf-font-size-lg:1.25rem;--wf-font-size-xl:1.5rem;--wf-font-size-2xl:2rem;--wf-font-size-3xl:2.5rem;--wf-input-min-height:56px;--wf-glass-bg:#ffffffb3;--wf-glass-bg-hover:#ffffffd9;--wf-glass-border:#0000001a;--wf-glass-blur:20px;--wf-glass-shadow:0 4px 6px #0000000d;display:block}wizard-form[theme=dark]{--wf-color-surface:#2d2d2d;--wf-color-surface-hover:#3d3d3d;--wf-color-border:#4d4d4d;--wf-color-text:#f8f9fa;--wf-color-text-secondary:#d0d0d0;--wf-color-text-muted:#adb5bd;--wf-color-badge-bg:#3d3d3d;--wf-color-badge-border:#4d4d4d;--wf-color-badge-text:#adb5bd;--wf-color-progress-active:#c8c8c899;--wf-color-progress-inactive:#64646499;--wf-glass-bg:#2d2d2db3;--wf-glass-bg-hover:#3c3c3ccc;--wf-glass-border:#ffffff1a}@media (prefers-color-scheme:dark){wizard-form[theme=auto]{--wf-color-surface:#2d2d2d;--wf-color-surface-hover:#3d3d3d;--wf-color-border:#4d4d4d;--wf-color-text:#f8f9fa;--wf-color-text-secondary:#d0d0d0;--wf-color-text-muted:#adb5bd;--wf-color-badge-bg:#3d3d3d;--wf-color-badge-border:#4d4d4d;--wf-color-badge-text:#adb5bd;--wf-color-progress-active:#c8c8c899;--wf-color-progress-inactive:#64646499;--wf-glass-bg:#2d2d2db3;--wf-glass-bg-hover:#3c3c3ccc;--wf-glass-border:#ffffff1a}}wizard-form .wf-container{margin:0 auto}wizard-form .wf-progress{gap:var(--wf-spacing-4,16px);margin-top:var(--wf-spacing-6,24px);display:flex}wizard-form .wf-progress-segment{background-color:var(--wf-color-progress-inactive,#0000001a);border-radius:var(--wf-radius-full,99px);width:32px;height:8px;transition:background-color .3s}wizard-form .wf-progress-segment.completed,wizard-form .wf-progress-segment.active{background-color:var(--wf-color-progress-active,#0000004d)}wizard-form .wf-steps-container{min-height:200px}wizard-form .wf-navigation{justify-content:space-between;gap:var(--wf-spacing-4,16px);margin-top:var(--wf-spacing-6,24px);display:flex}wizard-form .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;border:1px solid #0000;outline:none;font-family:inherit;font-weight:600;transition:all .15s;display:inline-flex}wizard-form .wf-btn:focus-visible{box-shadow:0 0 0 3px #8040f04d}wizard-form .wf-btn-back{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);color:var(--wf-color-text,#0a0a0a)}wizard-form .wf-btn-back:hover:not(:disabled){background:var(--wf-glass-bg-hover,#ffffffd9)}wizard-form .wf-btn-next{background-color:var(--wf-color-primary,#8040f0);border:1px solid var(--wf-color-primary-border,#602cbb);color:#fff;flex:1;margin-left:auto;position:relative}wizard-form .wf-btn-next:hover:not(:disabled){filter:brightness(1.1)}wizard-form .wf-btn:disabled{opacity:.5;cursor:not-allowed}wizard-form .wf-btn-shortcut{right:var(--wf-spacing-4,16px);align-items:center;gap:2px;display:inline-flex;position:absolute}wizard-form .wf-btn-back .wf-btn-shortcut{position:static}wizard-form .wf-success-screen{text-align:center;padding:var(--wf-spacing-6,24px)}wizard-form .wf-loading{border:2px solid #0000001a;border-top-color:#fff;border-radius:50%;width:20px;height:20px;animation:.8s linear infinite wf-spin;display:inline-block}@keyframes wf-spin{to{transform:rotate(360deg)}}wizard-form .wf-form-error{padding:var(--wf-spacing-4,16px);margin-bottom:var(--wf-spacing-4,16px);border:1px solid var(--wf-color-error,#dc3545);border-radius:var(--wf-radius-md,8px);color:var(--wf-color-error,#dc3545);font-size:var(--wf-font-size-base,1rem);background-color:#dc35451a}wf-success{display:block}wf-success h1,wf-success h2,wf-success h3{margin:0 0 var(--wf-spacing-4,16px)0;color:var(--wf-color-text,#212529);font-weight:600}wf-success p{color:var(--wf-color-text-muted,#6c757d);margin:0}wf-step{width:100%;display:none}wf-step[active]{animation:.3s forwards wf-stepFadeIn;display:block}wf-step[direction=forward][active]{animation:.3s forwards wf-stepSlideInRight}wf-step[direction=backward][active]{animation:.3s forwards wf-stepSlideInLeft}wf-step[leaving]{animation:.2s forwards wf-stepFadeOut;display:block}@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)}}wf-step .wf-step-content{gap:var(--wf-spacing-4,16px);flex-direction:column;display:flex}wf-step h1,wf-step h2,wf-step h3{color:var(--wf-color-text,#212529);margin:0;font-weight:600}wf-step h2{font-size:var(--wf-font-size-3xl,2rem)}wf-step p{color:var(--wf-color-text-muted,#6c757d);font-size:var(--wf-font-size-xl,1.375rem);margin:0}wf-options{display:block}wf-options[hidden]{display:none}wf-options .wf-options-container{gap:var(--wf-spacing-4,16px);grid-template-columns:repeat(2,1fr);display:grid}wf-options[columns="1"] .wf-options-container{grid-template-columns:1fr}@media (width<=600px){wf-options .wf-options-container{grid-template-columns:1fr}}wf-options .wf-error-message{margin-top:var(--wf-spacing-2,8px);font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-error,#dc3545);min-height:20px;display:block}wf-options .wf-other-container{margin-top:var(--wf-spacing-4,16px)}wf-options .wf-other-label{margin-bottom:var(--wf-spacing-2,8px);font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-text,#0a0a0a);font-weight:500;display:block}wf-options .wf-other-label span{color:var(--wf-color-text-muted,#646464);font-weight:400}wf-options .wf-other-input-wrapper{align-items:center;gap:var(--wf-spacing-3,12px);min-height:var(--wf-input-min-height,56px);background:var(--wf-glass-bg,#ffffffb3);-webkit-backdrop-filter:blur(var(--wf-glass-blur,20px));border:1px solid var(--wf-glass-border,#0000001a);border-radius:var(--wf-radius-md,8px);box-shadow:var(--wf-glass-shadow,0 4px 6px #0000000d);padding-left:var(--wf-spacing-4,16px);transition:border-color .15s,box-shadow .15s,background .15s;display:flex}wf-options .wf-other-input-wrapper:focus-within{border-color:var(--wf-color-primary,#8040f0);box-shadow:0 0 0 3px #8040f01a}wf-options .wf-other-input{min-height:calc(var(--wf-input-min-height,56px) - 2px);padding:var(--wf-spacing-4,16px);font-size:var(--wf-font-size-base,1rem);color:var(--wf-color-text,#0a0a0a);box-sizing:border-box;background:0 0;border:none;outline:none;flex:1;padding-left:0;font-weight:500}wf-options .wf-other-input::placeholder{color:var(--wf-color-text-muted,#646464);font-weight:500}wf-option{display:block}wf-option[hidden]{display:none}wf-option .wf-option-card{align-items:center;gap:var(--wf-spacing-3,12px);width:100%;min-height:var(--wf-input-min-height,56px);padding:var(--wf-spacing-3,12px);background:var(--wf-glass-bg,#ffffffb3);-webkit-backdrop-filter:blur(var(--wf-glass-blur,20px));border:1px solid var(--wf-glass-border,#0000001a);border-radius:var(--wf-radius-md,8px);box-shadow:var(--wf-glass-shadow,0 4px 6px #0000000d);cursor:pointer;text-align:left;font-family:inherit;font-size:var(--wf-font-size-base,1rem);color:var(--wf-color-text,#0a0a0a);box-sizing:border-box;outline:none;font-weight:500;transition:border-color .15s,background .15s,transform .1s;display:flex}wf-option .wf-option-card:hover:not(:disabled){border-color:var(--wf-color-primary,#8040f0);background:var(--wf-glass-bg-hover,#ffffffd9)}wf-option .wf-option-card:focus-visible{border-color:var(--wf-color-primary,#8040f0);box-shadow:0 0 0 3px #8040f033}wf-option .wf-option-card[aria-selected=true]{border-color:var(--wf-color-primary,#8040f0);background-color:var(--wf-color-primary-light,#8040f01a)}wf-option .wf-option-card:disabled{opacity:.5;cursor:not-allowed}wf-option .wf-option-card:active:not(:disabled){transform:scale(.98)}wf-option .wf-option-card.selecting{animation:.3s wf-blink}@keyframes wf-blink{0%,to{opacity:1}50%{opacity:.5}}wf-option .wf-option-content{flex:1;min-width:0}wf-option .wf-option-content strong,wf-option .wf-option-content h3,wf-option .wf-option-content h4{margin:0;font-weight:600;display:block}wf-option .wf-option-content span,wf-option .wf-option-content p{font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-text-muted,#646464);margin:4px 0 0;display:block}wf-progress{display:block}wf-progress[hidden]{display:none}wf-progress .wf-progress{gap:var(--wf-spacing-4,16px);display:flex}wf-progress .wf-progress-segment{background-color:var(--wf-color-progress-inactive,#0000001a);border-radius:var(--wf-radius-full,99px);width:32px;height:8px;transition:background-color .3s}wf-progress .wf-progress-segment.completed,wf-progress .wf-progress-segment.active{background-color:var(--wf-color-progress-active,#0000004d)}wf-badge{display:inline-flex}wf-badge[hidden]{display:none}wf-badge .wf-badge{box-sizing:border-box;min-width:24px;height:24px;padding:var(--wf-spacing-1,4px)var(--wf-spacing-2,8px);font-size:var(--wf-font-size-xs,.75rem);text-transform:uppercase;flex-shrink:0;justify-content:center;align-items:center;font-family:inherit;font-weight:500;line-height:1;display:inline-flex}wf-badge .wf-badge--default{background-color:var(--wf-color-badge-bg,#fcfcfc);border:1px solid var(--wf-color-badge-border,#d4d4d4);border-radius:var(--wf-radius-sm,4px);color:var(--wf-color-badge-text,#5f5f5f)}wf-badge .wf-badge--selected{background-color:var(--wf-color-primary,#8040f0);border:1px solid var(--wf-color-primary,#8040f0);border-radius:var(--wf-radius-sm,4px);color:#fff}wf-badge .wf-badge--button{border-radius:var(--wf-radius-sm,4px);color:#ffffffa6;background-color:#0000;border:none}wf-badge .wf-badge--button-secondary{border-radius:var(--wf-radius-sm,4px);color:var(--wf-color-text-muted,#5f5f5f);background-color:#0000;border:none}wf-layout{box-sizing:border-box;display:block}wf-layout[hidden]{display:none}wf-layout.wf-layout--width-full{width:100%}wf-layout.wf-layout--width-auto{width:auto}wf-layout.wf-layout--width-fit{width:fit-content}wf-thank-you{text-align:center;padding:var(--wf-spacing-8,48px)var(--wf-spacing-4,24px);display:block}wf-thank-you[hidden]{display:none}wf-thank-you .wf-thank-you-icon{width:72px;height:72px;margin:0 auto var(--wf-spacing-4,24px);background:linear-gradient(135deg,#10b981 0%,#059669 100%);border-radius:50%;justify-content:center;align-items:center;display:flex;box-shadow:0 10px 25px -5px #10b98166}wf-thank-you .wf-thank-you-icon svg{color:#fff;width:36px;height:36px}wf-thank-you .wf-thank-you-title{color:var(--wf-color-text,#1e293b);margin:0 0 12px;font-size:28px;font-weight:700}wf-thank-you .wf-thank-you-subtitle{color:var(--wf-color-text-muted,#64748b);margin:0 0 24px;font-size:16px;line-height:1.6}wf-thank-you [slot=footer]{margin-top:var(--wf-spacing-4,24px)}wf-input,wf-email,wf-textarea,wf-field,wf-number{display:block}wf-input[hidden],wf-email[hidden],wf-textarea[hidden],wf-field[hidden],wf-number[hidden]{display:none}.wf-field-container{gap:var(--wf-spacing-2,8px);flex-direction:column;display:flex}.wf-label{font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-text,#0a0a0a);font-weight:500}.wf-label-required:after{content:" *";color:var(--wf-color-error,#dc3545)}.wf-error-message{font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-error,#dc3545)}.wf-hint{font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-text-muted,#646464)}.wf-input{width:100%;min-height:var(--wf-input-min-height,56px);padding:var(--wf-spacing-4,16px);font-size:var(--wf-font-size-base,1rem);background:var(--wf-glass-bg,#ffffffb3);-webkit-backdrop-filter:blur(var(--wf-glass-blur,20px));border:1px solid var(--wf-glass-border,#0000001a);border-radius:var(--wf-radius-md,8px);box-shadow:var(--wf-glass-shadow,0 4px 6px #0000000d);color:var(--wf-color-text,#0a0a0a);box-sizing:border-box;outline:none;font-family:inherit;font-weight:400;transition:border-color .15s,box-shadow .15s,background .15s}.wf-input::placeholder{color:var(--wf-color-text-muted,#646464);font-weight:500}.wf-input:focus{border-color:var(--wf-color-primary,#8040f0);box-shadow:0 0 0 3px #8040f033}.wf-input:disabled{opacity:.5;cursor:not-allowed}.wf-input.wf-input-error{border-color:var(--wf-color-error,#dc3545)}.wf-input.wf-input-error:focus{box-shadow:0 0 0 3px #dc354533}.wf-textarea{width:100%;padding:var(--wf-spacing-4,16px);font-size:var(--wf-font-size-base,1rem);background:var(--wf-glass-bg,#ffffffb3);-webkit-backdrop-filter:blur(var(--wf-glass-blur,20px));border:1px solid var(--wf-glass-border,#0000001a);border-radius:var(--wf-radius-lg,12px);box-shadow:var(--wf-glass-shadow,0 4px 6px #0000000d);color:var(--wf-color-text,#212529);box-sizing:border-box;resize:vertical;outline:none;min-height:100px;font-family:inherit;transition:border-color .15s,box-shadow .15s,background .15s}.wf-textarea::placeholder{color:var(--wf-color-text-muted,#6c757d)}.wf-textarea:focus{border-color:var(--wf-color-primary,#8b5cf6);box-shadow:0 0 0 3px #8b5cf633}.wf-textarea:disabled{opacity:.5;cursor:not-allowed}.wf-textarea.wf-textarea-error{border-color:var(--wf-color-error,#dc3545)}.wf-textarea.wf-textarea-error:focus{box-shadow:0 0 0 3px #dc354533}.wf-char-count{font-size:var(--wf-font-size-sm,.875rem);color:var(--wf-color-text-muted,#6c757d);text-align:right}.wf-char-count.wf-char-limit{color:var(--wf-color-error,#dc3545)}wf-field .wf-input-wrapper{position:relative}wf-field .wf-input-wrapper input,wf-field .wf-input-wrapper textarea,wf-field .wf-input-wrapper select{width:100%;padding:var(--wf-spacing-4,16px);font-size:var(--wf-font-size-base,1rem);background-color:var(--wf-color-surface,#f8f9fa);border:2px solid var(--wf-color-border,#dee2e6);border-radius:var(--wf-radius-lg,12px);color:var(--wf-color-text,#212529);box-sizing:border-box;outline:none;font-family:inherit;transition:border-color .15s,box-shadow .15s}wf-field .wf-input-wrapper input::placeholder,wf-field .wf-input-wrapper textarea::placeholder{color:var(--wf-color-text-muted,#6c757d)}wf-field .wf-input-wrapper input:focus,wf-field .wf-input-wrapper textarea:focus,wf-field .wf-input-wrapper select:focus{border-color:var(--wf-color-primary,#8b5cf6);box-shadow:0 0 0 3px #8b5cf633}wf-field .wf-input-wrapper input:disabled,wf-field .wf-input-wrapper textarea:disabled,wf-field .wf-input-wrapper select:disabled{opacity:.5;cursor:not-allowed}wf-number .wf-input::-webkit-outer-spin-button,wf-number .wf-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}wf-number .wf-input[type=number]{-moz-appearance:textfield}`;
4068
- function injectGlobalStyles() {
4069
- if (typeof document === "undefined") {
4070
- return;
4071
- }
4072
- const STYLE_ID = "wf-global-styles";
4073
- if (document.getElementById(STYLE_ID)) {
4074
- return;
4075
- }
4076
- const style = document.createElement("style");
4077
- style.id = STYLE_ID;
4078
- style.textContent = GLOBAL_STYLES;
4079
- document.head.appendChild(style);
4080
- }
4081
- injectGlobalStyles();
5185
+ n2({ type: Boolean })
5186
+ ], WfBackBtn.prototype, "disabled", 2);
5187
+ __decorateClass([
5188
+ n2({ type: Boolean, attribute: "hide-on-first" })
5189
+ ], WfBackBtn.prototype, "hideOnFirst", 2);
5190
+ WfBackBtn = __decorateClass([
5191
+ t("wf-back-btn")
5192
+ ], WfBackBtn);
4082
5193
  export {
4083
5194
  DEFAULT_BLOCKED_DOMAINS,
4084
5195
  FormStateController,
4085
5196
  KeyboardController,
4086
5197
  ValidationController,
5198
+ WfBackBtn,
4087
5199
  WfBadge,
4088
5200
  WfEmail,
4089
- WfField,
4090
5201
  WfInput,
4091
5202
  WfLayout,
5203
+ WfNextBtn,
4092
5204
  WfNumber,
4093
5205
  WfOption,
4094
5206
  WfOptions,
5207
+ WfOther,
4095
5208
  WfProgress,
4096
5209
  WfStep,
4097
5210
  WfSuccess,
4098
5211
  WfTextarea,
4099
- WfThankYou,
4100
5212
  WizardForm,
4101
5213
  createHubSpotAdapter,
4102
5214
  createRevenueHeroAdapter,