aw-wizard-forms 3.0.7 → 3.1.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.
@@ -196,14 +196,7 @@ 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), 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) => {
199
+ const r$4 = (t2) => new n$3("string" == typeof t2 ? t2 : t2 + "", void 0, s$2), S$1 = (s2, o2) => {
207
200
  if (e$2) s2.adoptedStyleSheets = o2.map((t2) => t2 instanceof CSSStyleSheet ? t2 : t2.styleSheet);
208
201
  else for (const e2 of o2) {
209
202
  const o3 = document.createElement("style"), n3 = t$2.litNonce;
@@ -1072,14 +1065,14 @@ class KeyboardController {
1072
1065
  return this._enabled;
1073
1066
  }
1074
1067
  }
1075
- var __defProp$c = Object.defineProperty;
1068
+ var __defProp$d = Object.defineProperty;
1076
1069
  var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
1077
- var __decorateClass$c = (decorators, target, key, kind) => {
1070
+ var __decorateClass$d = (decorators, target, key, kind) => {
1078
1071
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
1079
1072
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1080
1073
  if (decorator = decorators[i2])
1081
1074
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1082
- if (kind && result) __defProp$c(target, key, result);
1075
+ if (kind && result) __defProp$d(target, key, result);
1083
1076
  return result;
1084
1077
  };
1085
1078
  let WfBadge = class extends i {
@@ -1088,6 +1081,12 @@ let WfBadge = class extends i {
1088
1081
  this.shortcut = "";
1089
1082
  this.variant = "default";
1090
1083
  }
1084
+ /**
1085
+ * Disable Shadow DOM - render to Light DOM for external styling
1086
+ */
1087
+ createRenderRoot() {
1088
+ return this;
1089
+ }
1091
1090
  render() {
1092
1091
  return b`
1093
1092
  <span
@@ -1099,80 +1098,23 @@ let WfBadge = class extends i {
1099
1098
  `;
1100
1099
  }
1101
1100
  };
1102
- WfBadge.styles = i$3`
1103
- :host {
1104
- display: inline-flex;
1105
- }
1106
-
1107
- :host([hidden]) {
1108
- display: none;
1109
- }
1110
-
1111
- .wf-badge {
1112
- display: inline-flex;
1113
- align-items: center;
1114
- justify-content: center;
1115
- box-sizing: border-box;
1116
- min-width: 24px;
1117
- height: 24px;
1118
- padding: var(--wf-spacing-1, 4px) var(--wf-spacing-2, 8px);
1119
- font-size: var(--wf-font-size-xs, 0.75rem);
1120
- font-weight: 500;
1121
- font-family: inherit;
1122
- text-transform: uppercase;
1123
- flex-shrink: 0;
1124
- line-height: 1;
1125
- }
1126
-
1127
- /* Default variant - unselected options */
1128
- .wf-badge--default {
1129
- background-color: var(--wf-color-badge-bg, #fcfcfc);
1130
- border: 1px solid var(--wf-color-badge-border, #d4d4d4);
1131
- border-radius: var(--wf-radius-sm, 4px);
1132
- color: var(--wf-color-badge-text, #5f5f5f);
1133
- }
1134
-
1135
- /* Selected variant - selected options */
1136
- .wf-badge--selected {
1137
- background-color: var(--wf-color-primary, #8040f0);
1138
- border: 1px solid var(--wf-color-primary, #8040f0);
1139
- border-radius: var(--wf-radius-sm, 4px);
1140
- color: white;
1141
- }
1142
-
1143
- /* Button variant - primary buttons (transparent) */
1144
- .wf-badge--button {
1145
- background-color: transparent;
1146
- border: none;
1147
- border-radius: var(--wf-radius-sm, 4px);
1148
- color: rgba(255, 255, 255, 0.65);
1149
- }
1150
-
1151
- /* Button-secondary variant - back button (transparent like primary) */
1152
- .wf-badge--button-secondary {
1153
- background-color: transparent;
1154
- border: none;
1155
- border-radius: var(--wf-radius-sm, 4px);
1156
- color: var(--wf-color-text-muted, #5f5f5f);
1157
- }
1158
- `;
1159
- __decorateClass$c([
1101
+ __decorateClass$d([
1160
1102
  n2({ type: String })
1161
1103
  ], WfBadge.prototype, "shortcut", 2);
1162
- __decorateClass$c([
1104
+ __decorateClass$d([
1163
1105
  n2({ type: String })
1164
1106
  ], WfBadge.prototype, "variant", 2);
1165
- WfBadge = __decorateClass$c([
1107
+ WfBadge = __decorateClass$d([
1166
1108
  t("wf-badge")
1167
1109
  ], WfBadge);
1168
- var __defProp$b = Object.defineProperty;
1110
+ var __defProp$c = Object.defineProperty;
1169
1111
  var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
1170
- var __decorateClass$b = (decorators, target, key, kind) => {
1112
+ var __decorateClass$c = (decorators, target, key, kind) => {
1171
1113
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
1172
1114
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1173
1115
  if (decorator = decorators[i2])
1174
1116
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1175
- if (kind && result) __defProp$b(target, key, result);
1117
+ if (kind && result) __defProp$c(target, key, result);
1176
1118
  return result;
1177
1119
  };
1178
1120
  let WizardForm = class extends i {
@@ -1185,6 +1127,7 @@ let WizardForm = class extends i {
1185
1127
  this.showProgress = false;
1186
1128
  this.autoAdvance = true;
1187
1129
  this.hideBack = true;
1130
+ this.submitOnStep = false;
1188
1131
  this._steps = [];
1189
1132
  this._currentStep = 1;
1190
1133
  this._totalSteps = 0;
@@ -1192,6 +1135,7 @@ let WizardForm = class extends i {
1192
1135
  this._submitting = false;
1193
1136
  this._submitted = false;
1194
1137
  this._error = "";
1138
+ this._cachedSuccessContent = null;
1195
1139
  this._stateController = new FormStateController(this);
1196
1140
  this._handleFieldChange = (e2) => {
1197
1141
  const { name, value, extraFields } = e2.detail;
@@ -1232,6 +1176,12 @@ let WizardForm = class extends i {
1232
1176
  onEscape: () => this._handleEscape()
1233
1177
  });
1234
1178
  }
1179
+ /**
1180
+ * Disable Shadow DOM - render to Light DOM for external styling
1181
+ */
1182
+ createRenderRoot() {
1183
+ return this;
1184
+ }
1235
1185
  // ============================================
1236
1186
  // Lifecycle
1237
1187
  // ============================================
@@ -1246,6 +1196,7 @@ let WizardForm = class extends i {
1246
1196
  this.removeEventListener("wf-option-select", this._handleOptionSelect);
1247
1197
  }
1248
1198
  firstUpdated() {
1199
+ this._cachedSuccessContent = this.querySelector('[slot="success"]');
1249
1200
  this._discoverSteps();
1250
1201
  this._showCurrentStep();
1251
1202
  }
@@ -1254,25 +1205,36 @@ let WizardForm = class extends i {
1254
1205
  // ============================================
1255
1206
  render() {
1256
1207
  if (this._submitted) {
1208
+ this._steps.forEach((step) => {
1209
+ step.active = false;
1210
+ step.style.display = "none";
1211
+ });
1212
+ if (this._cachedSuccessContent) {
1213
+ this._cachedSuccessContent.style.display = "";
1214
+ return b`
1215
+ <div class="wf-container wf-submitted">
1216
+ <div class="wf-success-screen">
1217
+ ${this._cachedSuccessContent}
1218
+ </div>
1219
+ </div>
1220
+ `;
1221
+ }
1257
1222
  return b`
1258
- <div class="wf-container">
1223
+ <div class="wf-container wf-submitted">
1259
1224
  <div class="wf-success-screen">
1260
- <slot name="success">
1261
- <h2>Thank you!</h2>
1262
- <p>Your submission has been received.</p>
1263
- </slot>
1225
+ <h2>Thank you!</h2>
1226
+ <p>Your submission has been received.</p>
1264
1227
  </div>
1265
1228
  </div>
1266
1229
  `;
1267
1230
  }
1231
+ if (this._cachedSuccessContent) {
1232
+ this._cachedSuccessContent.style.display = "none";
1233
+ }
1268
1234
  return b`
1269
1235
  <div class="wf-container">
1270
1236
  ${this._error ? b`<div class="wf-form-error" role="alert">${this._error}</div>` : A}
1271
1237
 
1272
- <div class="wf-steps-container">
1273
- <slot @slotchange="${this._handleSlotChange}"></slot>
1274
- </div>
1275
-
1276
1238
  ${this._renderNavigation()}
1277
1239
  </div>
1278
1240
  `;
@@ -1323,19 +1285,8 @@ let WizardForm = class extends i {
1323
1285
  // ============================================
1324
1286
  // Step Discovery
1325
1287
  // ============================================
1326
- _handleSlotChange() {
1327
- this._discoverSteps();
1328
- this._showCurrentStep();
1329
- }
1330
1288
  _discoverSteps() {
1331
- const slot = this.shadowRoot?.querySelector("slot:not([name])");
1332
- if (!slot) {
1333
- return;
1334
- }
1335
- const elements = slot.assignedElements({ flatten: true });
1336
- this._steps = elements.filter(
1337
- (el) => el.tagName.toLowerCase() === "wf-step"
1338
- );
1289
+ this._steps = Array.from(this.querySelectorAll(":scope > wf-step"));
1339
1290
  this._steps.forEach((step, index) => {
1340
1291
  step.step = index + 1;
1341
1292
  });
@@ -1414,6 +1365,28 @@ let WizardForm = class extends i {
1414
1365
  return;
1415
1366
  }
1416
1367
  const previousStep = this._currentStep;
1368
+ let submitted = false;
1369
+ let adapter;
1370
+ if (this.submitOnStep && this.hubspotPortal && this.hubspotForm) {
1371
+ try {
1372
+ await this._submitPartialToHubSpot();
1373
+ submitted = true;
1374
+ adapter = "hubspot";
1375
+ } catch (error) {
1376
+ console.error("[wizard-form] Partial submission failed:", error);
1377
+ this.dispatchEvent(
1378
+ new CustomEvent("wf:error", {
1379
+ detail: {
1380
+ error: error instanceof Error ? error.message : "Partial submission failed",
1381
+ formData: this._getFieldsUpToStep(this._currentStep)
1382
+ },
1383
+ bubbles: true,
1384
+ composed: true
1385
+ })
1386
+ );
1387
+ return;
1388
+ }
1389
+ }
1417
1390
  const currentStepEl = this._getStepByNumber(this._currentStep);
1418
1391
  if (currentStepEl) {
1419
1392
  await currentStepEl.hide();
@@ -1426,7 +1399,9 @@ let WizardForm = class extends i {
1426
1399
  detail: {
1427
1400
  from: previousStep,
1428
1401
  to: targetStep,
1429
- direction
1402
+ direction,
1403
+ submitted,
1404
+ adapter
1430
1405
  },
1431
1406
  bubbles: true,
1432
1407
  composed: true
@@ -1446,8 +1421,9 @@ let WizardForm = class extends i {
1446
1421
  if (this._submitting) {
1447
1422
  return;
1448
1423
  }
1424
+ const rawData = { ...this._formData };
1449
1425
  const submitEvent = new CustomEvent("wf:submit", {
1450
- detail: { formData: { ...this._formData } },
1426
+ detail: { formData: rawData },
1451
1427
  bubbles: true,
1452
1428
  composed: true,
1453
1429
  cancelable: true
@@ -1458,13 +1434,17 @@ let WizardForm = class extends i {
1458
1434
  }
1459
1435
  this._submitting = true;
1460
1436
  this._error = "";
1437
+ let submitData = rawData;
1438
+ if (this.serialize) {
1439
+ submitData = this.serialize(rawData);
1440
+ }
1461
1441
  try {
1462
1442
  let response;
1463
1443
  if (this.mock) {
1464
1444
  await new Promise((resolve) => setTimeout(resolve, 1e3));
1465
1445
  response = { success: true };
1466
1446
  } else if (this.hubspotPortal && this.hubspotForm) {
1467
- response = await this._submitToHubSpot();
1447
+ response = await this._submitToHubSpot(submitData);
1468
1448
  } else {
1469
1449
  console.warn("[WizardForm] No submission target configured. Use hubspot-portal/hubspot-form or mock.");
1470
1450
  response = { success: true };
@@ -1473,7 +1453,7 @@ let WizardForm = class extends i {
1473
1453
  this.dispatchEvent(
1474
1454
  new CustomEvent("wf:success", {
1475
1455
  detail: {
1476
- formData: { ...this._formData },
1456
+ formData: submitData,
1477
1457
  response
1478
1458
  },
1479
1459
  bubbles: true,
@@ -1487,7 +1467,7 @@ let WizardForm = class extends i {
1487
1467
  new CustomEvent("wf:error", {
1488
1468
  detail: {
1489
1469
  error: errorMessage,
1490
- formData: { ...this._formData }
1470
+ formData: submitData
1491
1471
  },
1492
1472
  bubbles: true,
1493
1473
  composed: true
@@ -1497,9 +1477,9 @@ let WizardForm = class extends i {
1497
1477
  this._submitting = false;
1498
1478
  }
1499
1479
  }
1500
- async _submitToHubSpot() {
1480
+ async _submitToHubSpot(formData) {
1501
1481
  const endpoint = `https://api.hsforms.com/submissions/v3/integration/submit/${this.hubspotPortal}/${this.hubspotForm}`;
1502
- const fields = Object.entries(this._formData).map(([name, value]) => ({
1482
+ const fields = Object.entries(formData).map(([name, value]) => ({
1503
1483
  name,
1504
1484
  value: Array.isArray(value) ? value.join(";") : String(value ?? "")
1505
1485
  }));
@@ -1524,6 +1504,38 @@ let WizardForm = class extends i {
1524
1504
  return response.json();
1525
1505
  }
1526
1506
  // ============================================
1507
+ // Partial Submission
1508
+ // ============================================
1509
+ /**
1510
+ * Get form fields from steps up to and including the specified step number.
1511
+ * Used for partial submission to only include completed step data.
1512
+ */
1513
+ _getFieldsUpToStep(stepNumber) {
1514
+ const result = {};
1515
+ for (let i2 = 0; i2 < stepNumber && i2 < this._steps.length; i2++) {
1516
+ const step = this._steps[i2];
1517
+ const fields = step.querySelectorAll("[name]");
1518
+ fields.forEach((field) => {
1519
+ if (field.name && this._formData[field.name] !== void 0) {
1520
+ result[field.name] = this._formData[field.name];
1521
+ }
1522
+ });
1523
+ }
1524
+ return result;
1525
+ }
1526
+ /**
1527
+ * Submit partial form data to HubSpot.
1528
+ * Only includes fields from steps up to and including the current step.
1529
+ */
1530
+ async _submitPartialToHubSpot() {
1531
+ const partialData = this._getFieldsUpToStep(this._currentStep);
1532
+ let submitData = { ...partialData };
1533
+ if (this.serialize) {
1534
+ submitData = this.serialize(submitData);
1535
+ }
1536
+ await this._submitToHubSpot(submitData);
1537
+ }
1538
+ // ============================================
1527
1539
  // Public API
1528
1540
  // ============================================
1529
1541
  /**
@@ -1611,289 +1623,79 @@ let WizardForm = class extends i {
1611
1623
  });
1612
1624
  }
1613
1625
  };
1614
- WizardForm.styles = i$3`
1615
- :host {
1616
- display: block;
1617
- --wf-color-primary: #8040f0;
1618
- --wf-color-primary-border: #602cbb;
1619
- --wf-color-primary-light: rgba(128, 64, 240, 0.08);
1620
- --wf-color-surface: #f3f3f5;
1621
- --wf-color-surface-hover: #e9e9eb;
1622
- --wf-color-border: #d4d4d4;
1623
- --wf-color-text: #0a0a0a;
1624
- --wf-color-text-secondary: #404040;
1625
- --wf-color-text-muted: #646464;
1626
- --wf-color-error: #dc3545;
1627
- --wf-color-badge-bg: #fcfcfc;
1628
- --wf-color-badge-border: #d4d4d4;
1629
- --wf-color-badge-text: #5f5f5f;
1630
- --wf-color-progress-active: rgba(139, 139, 139, 0.6);
1631
- --wf-color-progress-inactive: rgba(217, 217, 217, 0.6);
1632
- --wf-spacing-1: 4px;
1633
- --wf-spacing-2: 8px;
1634
- --wf-spacing-3: 12px;
1635
- --wf-spacing-4: 16px;
1636
- --wf-spacing-5: 20px;
1637
- --wf-spacing-6: 24px;
1638
- --wf-spacing-8: 32px;
1639
- --wf-radius-sm: 4px;
1640
- --wf-radius-md: 8px;
1641
- --wf-radius-lg: 8px;
1642
- --wf-radius-full: 99px;
1643
- /* Typography Scale (Major Third based, 16px = 1rem) */
1644
- --wf-font-size-xs: 0.75rem; /* 12px - badges, captions */
1645
- --wf-font-size-sm: 0.875rem; /* 14px - labels, hints */
1646
- --wf-font-size-base: 1rem; /* 16px - body, inputs */
1647
- --wf-font-size-lg: 1.25rem; /* 20px - buttons */
1648
- --wf-font-size-xl: 1.5rem; /* 24px - subtitles */
1649
- --wf-font-size-2xl: 2rem; /* 32px - small headings */
1650
- --wf-font-size-3xl: 2.5rem; /* 40px - main headings */
1651
- --wf-input-min-height: 56px;
1652
- }
1653
-
1654
- /* Dark theme */
1655
- :host([theme='dark']) {
1656
- --wf-color-surface: #2d2d2d;
1657
- --wf-color-surface-hover: #3d3d3d;
1658
- --wf-color-border: #4d4d4d;
1659
- --wf-color-text: #f8f9fa;
1660
- --wf-color-text-secondary: #d0d0d0;
1661
- --wf-color-text-muted: #adb5bd;
1662
- --wf-color-badge-bg: #3d3d3d;
1663
- --wf-color-badge-border: #4d4d4d;
1664
- --wf-color-badge-text: #adb5bd;
1665
- --wf-color-progress-active: rgba(200, 200, 200, 0.6);
1666
- --wf-color-progress-inactive: rgba(100, 100, 100, 0.6);
1667
- }
1668
-
1669
- /* Auto theme (respects system preference) */
1670
- @media (prefers-color-scheme: dark) {
1671
- :host([theme='auto']) {
1672
- --wf-color-surface: #2d2d2d;
1673
- --wf-color-surface-hover: #3d3d3d;
1674
- --wf-color-border: #4d4d4d;
1675
- --wf-color-text: #f8f9fa;
1676
- --wf-color-text-secondary: #d0d0d0;
1677
- --wf-color-text-muted: #adb5bd;
1678
- --wf-color-badge-bg: #3d3d3d;
1679
- --wf-color-badge-border: #4d4d4d;
1680
- --wf-color-badge-text: #adb5bd;
1681
- --wf-color-progress-active: rgba(200, 200, 200, 0.6);
1682
- --wf-color-progress-inactive: rgba(100, 100, 100, 0.6);
1683
- }
1684
- }
1685
-
1686
- .wf-container {
1687
- margin: 0 auto;
1688
- }
1689
-
1690
- .wf-progress {
1691
- display: flex;
1692
- gap: var(--wf-spacing-4, 16px);
1693
- margin-top: var(--wf-spacing-6, 24px);
1694
- }
1695
-
1696
- .wf-progress-segment {
1697
- width: 32px;
1698
- height: 8px;
1699
- background-color: var(--wf-color-progress-inactive, rgba(217, 217, 217, 0.6));
1700
- border-radius: var(--wf-radius-full, 99px);
1701
- transition: background-color 300ms ease;
1702
- }
1703
-
1704
- .wf-progress-segment.completed {
1705
- background-color: var(--wf-color-progress-active, rgba(139, 139, 139, 0.6));
1706
- }
1707
-
1708
- .wf-progress-segment.active {
1709
- background-color: var(--wf-color-progress-active, rgba(139, 139, 139, 0.6));
1710
- }
1711
-
1712
- .wf-steps-container {
1713
- min-height: 200px;
1714
- }
1715
-
1716
- .wf-navigation {
1717
- display: flex;
1718
- justify-content: space-between;
1719
- gap: var(--wf-spacing-4, 16px);
1720
- margin-top: var(--wf-spacing-6, 24px);
1721
- }
1722
-
1723
- .wf-btn {
1724
- display: inline-flex;
1725
- align-items: center;
1726
- justify-content: center;
1727
- gap: var(--wf-spacing-2, 8px);
1728
- padding: var(--wf-spacing-3, 12px) var(--wf-spacing-4, 16px);
1729
- min-height: 48px;
1730
- font-size: var(--wf-font-size-base, 1rem);
1731
- font-weight: 600;
1732
- font-family: inherit;
1733
- border-radius: var(--wf-radius-md, 8px);
1734
- cursor: pointer;
1735
- transition: all 150ms ease;
1736
- border: 1px solid transparent;
1737
- outline: none;
1738
- }
1739
-
1740
- .wf-btn:focus-visible {
1741
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.3);
1742
- }
1743
-
1744
- .wf-btn-back {
1745
- background-color: var(--wf-color-surface, #f3f3f5);
1746
- border: 1px solid var(--wf-color-border, #d4d4d4);
1747
- color: var(--wf-color-text, #0a0a0a);
1748
- }
1749
-
1750
- .wf-btn-back:hover:not(:disabled) {
1751
- background-color: var(--wf-color-surface-hover, #e9e9eb);
1752
- }
1753
-
1754
- .wf-btn-next {
1755
- flex: 1;
1756
- background-color: var(--wf-color-primary, #8040f0);
1757
- border: 1px solid var(--wf-color-primary-border, #602cbb);
1758
- color: white;
1759
- margin-left: auto;
1760
- position: relative;
1761
- }
1762
-
1763
- .wf-btn-next:hover:not(:disabled) {
1764
- filter: brightness(1.1);
1765
- }
1766
-
1767
- .wf-btn:disabled {
1768
- opacity: 0.5;
1769
- cursor: not-allowed;
1770
- }
1771
-
1772
- .wf-btn-shortcut {
1773
- position: absolute;
1774
- right: var(--wf-spacing-4, 16px);
1775
- display: inline-flex;
1776
- align-items: center;
1777
- gap: 2px;
1778
- }
1779
-
1780
- .wf-btn-back .wf-btn-shortcut {
1781
- position: static;
1782
- }
1783
-
1784
- /* Success screen styles */
1785
- .wf-success-screen {
1786
- text-align: center;
1787
- padding: var(--wf-spacing-6, 24px);
1788
- }
1789
-
1790
- /* Loading spinner */
1791
- .wf-loading {
1792
- display: inline-block;
1793
- width: 20px;
1794
- height: 20px;
1795
- border: 2px solid rgba(255, 255, 255, 0.3);
1796
- border-radius: 50%;
1797
- border-top-color: white;
1798
- animation: spin 0.8s linear infinite;
1799
- }
1800
-
1801
- @keyframes spin {
1802
- to {
1803
- transform: rotate(360deg);
1804
- }
1805
- }
1806
-
1807
- /* Error message */
1808
- .wf-form-error {
1809
- padding: var(--wf-spacing-4, 16px);
1810
- margin-bottom: var(--wf-spacing-4, 16px);
1811
- background-color: rgba(220, 53, 69, 0.1);
1812
- border: 1px solid var(--wf-color-error, #dc3545);
1813
- border-radius: var(--wf-radius-md, 8px);
1814
- color: var(--wf-color-error, #dc3545);
1815
- font-size: var(--wf-font-size-base, 1rem);
1816
- }
1817
- `;
1818
- __decorateClass$b([
1626
+ __decorateClass$c([
1819
1627
  n2({ type: String, attribute: "hubspot-portal" })
1820
1628
  ], WizardForm.prototype, "hubspotPortal", 2);
1821
- __decorateClass$b([
1629
+ __decorateClass$c([
1822
1630
  n2({ type: String, attribute: "hubspot-form" })
1823
1631
  ], WizardForm.prototype, "hubspotForm", 2);
1824
- __decorateClass$b([
1632
+ __decorateClass$c([
1825
1633
  n2({ type: String, reflect: true })
1826
1634
  ], WizardForm.prototype, "theme", 2);
1827
- __decorateClass$b([
1635
+ __decorateClass$c([
1828
1636
  n2({ type: Boolean })
1829
1637
  ], WizardForm.prototype, "mock", 2);
1830
- __decorateClass$b([
1638
+ __decorateClass$c([
1831
1639
  n2({ type: Boolean, attribute: "show-progress" })
1832
1640
  ], WizardForm.prototype, "showProgress", 2);
1833
- __decorateClass$b([
1641
+ __decorateClass$c([
1834
1642
  n2({ type: Boolean, attribute: "auto-advance" })
1835
1643
  ], WizardForm.prototype, "autoAdvance", 2);
1836
- __decorateClass$b([
1644
+ __decorateClass$c([
1837
1645
  n2({ type: Boolean, attribute: "hide-back" })
1838
1646
  ], WizardForm.prototype, "hideBack", 2);
1839
- __decorateClass$b([
1647
+ __decorateClass$c([
1648
+ n2({ attribute: false })
1649
+ ], WizardForm.prototype, "serialize", 2);
1650
+ __decorateClass$c([
1651
+ n2({ type: Boolean, attribute: "submit-on-step" })
1652
+ ], WizardForm.prototype, "submitOnStep", 2);
1653
+ __decorateClass$c([
1840
1654
  r()
1841
1655
  ], WizardForm.prototype, "_steps", 2);
1842
- __decorateClass$b([
1656
+ __decorateClass$c([
1843
1657
  r()
1844
1658
  ], WizardForm.prototype, "_currentStep", 2);
1845
- __decorateClass$b([
1659
+ __decorateClass$c([
1846
1660
  r()
1847
1661
  ], WizardForm.prototype, "_totalSteps", 2);
1848
- __decorateClass$b([
1662
+ __decorateClass$c([
1849
1663
  r()
1850
1664
  ], WizardForm.prototype, "_formData", 2);
1851
- __decorateClass$b([
1665
+ __decorateClass$c([
1852
1666
  r()
1853
1667
  ], WizardForm.prototype, "_submitting", 2);
1854
- __decorateClass$b([
1668
+ __decorateClass$c([
1855
1669
  r()
1856
1670
  ], WizardForm.prototype, "_submitted", 2);
1857
- __decorateClass$b([
1671
+ __decorateClass$c([
1858
1672
  r()
1859
1673
  ], WizardForm.prototype, "_error", 2);
1860
- WizardForm = __decorateClass$b([
1674
+ WizardForm = __decorateClass$c([
1861
1675
  t("wizard-form")
1862
1676
  ], WizardForm);
1863
1677
  let WfSuccess = class extends i {
1678
+ /**
1679
+ * Disable Shadow DOM - render to Light DOM for external styling
1680
+ */
1681
+ createRenderRoot() {
1682
+ return this;
1683
+ }
1864
1684
  render() {
1865
- return b`<slot></slot>`;
1685
+ return b``;
1866
1686
  }
1867
1687
  };
1868
- WfSuccess.styles = i$3`
1869
- :host {
1870
- display: block;
1871
- }
1872
-
1873
- ::slotted(h1),
1874
- ::slotted(h2),
1875
- ::slotted(h3) {
1876
- margin: 0 0 var(--wf-spacing-4, 16px) 0;
1877
- font-weight: 600;
1878
- color: var(--wf-color-text, #212529);
1879
- }
1880
-
1881
- ::slotted(p) {
1882
- margin: 0;
1883
- color: var(--wf-color-text-muted, #6c757d);
1884
- }
1885
- `;
1886
- WfSuccess = __decorateClass$b([
1688
+ WfSuccess = __decorateClass$c([
1887
1689
  t("wf-success")
1888
1690
  ], WfSuccess);
1889
- var __defProp$a = Object.defineProperty;
1691
+ var __defProp$b = Object.defineProperty;
1890
1692
  var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
1891
- var __decorateClass$a = (decorators, target, key, kind) => {
1693
+ var __decorateClass$b = (decorators, target, key, kind) => {
1892
1694
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
1893
1695
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
1894
1696
  if (decorator = decorators[i2])
1895
1697
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1896
- if (kind && result) __defProp$a(target, key, result);
1698
+ if (kind && result) __defProp$b(target, key, result);
1897
1699
  return result;
1898
1700
  };
1899
1701
  let WfStep = class extends i {
@@ -1906,16 +1708,17 @@ let WfStep = class extends i {
1906
1708
  this.skipIf = "";
1907
1709
  this._fields = [];
1908
1710
  }
1711
+ /**
1712
+ * Disable Shadow DOM - render to Light DOM for external styling
1713
+ */
1714
+ createRenderRoot() {
1715
+ return this;
1716
+ }
1909
1717
  render() {
1910
1718
  return b`
1911
- <div class="wf-step-content">
1912
- <slot @slotchange="${this._handleSlotChange}"></slot>
1913
- </div>
1719
+ <div class="wf-step-content"></div>
1914
1720
  `;
1915
1721
  }
1916
- _handleSlotChange() {
1917
- this._discoverFields();
1918
- }
1919
1722
  firstUpdated() {
1920
1723
  this._discoverFields();
1921
1724
  }
@@ -1931,14 +1734,9 @@ let WfStep = class extends i {
1931
1734
  * Discover field elements within this step
1932
1735
  */
1933
1736
  _discoverFields() {
1934
- const slot = this.shadowRoot?.querySelector("slot");
1935
- if (!slot) {
1936
- return;
1937
- }
1938
- const elements = slot.assignedElements({ flatten: true });
1737
+ const fieldElements = ["wf-options", "wf-field", "wf-email", "wf-input", "wf-textarea", "wf-number"];
1939
1738
  const fields = [];
1940
1739
  const findFields = (el) => {
1941
- const fieldElements = ["wf-options", "wf-field", "wf-email", "wf-input", "wf-textarea"];
1942
1740
  if (fieldElements.includes(el.tagName.toLowerCase())) {
1943
1741
  const name = el.getAttribute("name");
1944
1742
  if (name) {
@@ -1947,7 +1745,7 @@ let WfStep = class extends i {
1947
1745
  }
1948
1746
  Array.from(el.children).forEach(findFields);
1949
1747
  };
1950
- elements.forEach(findFields);
1748
+ Array.from(this.children).forEach(findFields);
1951
1749
  this._fields = fields;
1952
1750
  }
1953
1751
  /**
@@ -1955,12 +1753,7 @@ let WfStep = class extends i {
1955
1753
  */
1956
1754
  _focusFirstField() {
1957
1755
  requestAnimationFrame(() => {
1958
- const slot = this.shadowRoot?.querySelector("slot");
1959
- if (!slot) {
1960
- return;
1961
- }
1962
- const elements = slot.assignedElements({ flatten: true });
1963
- for (const el of elements) {
1756
+ for (const el of this.children) {
1964
1757
  const focusable = this._findFocusable(el);
1965
1758
  if (focusable) {
1966
1759
  focusable.focus();
@@ -2059,11 +1852,6 @@ let WfStep = class extends i {
2059
1852
  * Scrolls to and focuses the first invalid field if validation fails
2060
1853
  */
2061
1854
  async validate() {
2062
- const slot = this.shadowRoot?.querySelector("slot");
2063
- if (!slot) {
2064
- return true;
2065
- }
2066
- const elements = slot.assignedElements({ flatten: true });
2067
1855
  const invalidElements = [];
2068
1856
  let allValid = true;
2069
1857
  const validateElement = async (el) => {
@@ -2078,7 +1866,7 @@ let WfStep = class extends i {
2078
1866
  await validateElement(child);
2079
1867
  }
2080
1868
  };
2081
- for (const el of elements) {
1869
+ for (const el of this.children) {
2082
1870
  await validateElement(el);
2083
1871
  }
2084
1872
  if (invalidElements.length > 0) {
@@ -2096,147 +1884,237 @@ let WfStep = class extends i {
2096
1884
  return allValid;
2097
1885
  }
2098
1886
  };
2099
- WfStep.styles = i$3`
2100
- :host {
2101
- display: none;
2102
- width: 100%;
2103
- }
2104
-
2105
- :host([active]) {
2106
- display: block;
2107
- animation: stepFadeIn 0.3s ease forwards;
2108
- }
2109
-
2110
- :host([direction='forward'][active]) {
2111
- animation: stepSlideInRight 0.3s ease forwards;
2112
- }
2113
-
2114
- :host([direction='backward'][active]) {
2115
- animation: stepSlideInLeft 0.3s ease forwards;
2116
- }
2117
-
2118
- :host([leaving]) {
2119
- display: block;
2120
- animation: stepFadeOut 0.2s ease forwards;
2121
- }
2122
-
2123
- @keyframes stepFadeIn {
2124
- from {
2125
- opacity: 0;
2126
- transform: translateY(10px);
2127
- }
2128
- to {
2129
- opacity: 1;
2130
- transform: translateY(0);
2131
- }
2132
- }
2133
-
2134
- @keyframes stepFadeOut {
2135
- from {
2136
- opacity: 1;
2137
- transform: translateY(0);
2138
- }
2139
- to {
2140
- opacity: 0;
2141
- transform: translateY(-10px);
2142
- }
2143
- }
2144
-
2145
- @keyframes stepSlideInRight {
2146
- from {
2147
- opacity: 0;
2148
- transform: translateX(30px);
2149
- }
2150
- to {
2151
- opacity: 1;
2152
- transform: translateX(0);
2153
- }
2154
- }
2155
-
2156
- @keyframes stepSlideInLeft {
2157
- from {
2158
- opacity: 0;
2159
- transform: translateX(-30px);
2160
- }
2161
- to {
2162
- opacity: 1;
2163
- transform: translateX(0);
2164
- }
2165
- }
2166
-
2167
- .wf-step-content {
2168
- display: flex;
2169
- flex-direction: column;
2170
- gap: var(--wf-spacing-4, 16px);
2171
- }
2172
-
2173
- /* Slotted heading styles */
2174
- ::slotted(h1),
2175
- ::slotted(h2),
2176
- ::slotted(h3) {
2177
- margin: 0;
2178
- font-weight: 600;
2179
- color: var(--wf-color-text, #212529);
2180
- }
2181
-
2182
- ::slotted(h2) {
2183
- font-size: var(--wf-font-size-3xl, 2rem);
2184
- }
2185
-
2186
- ::slotted(p) {
2187
- margin: 0;
2188
- color: var(--wf-color-text-muted, #6c757d);
2189
- font-size: var(--wf-font-size-xl, 1.375rem);
2190
- }
2191
- `;
2192
- __decorateClass$a([
1887
+ __decorateClass$b([
2193
1888
  n2({ type: Number, attribute: "data-step" })
2194
1889
  ], WfStep.prototype, "step", 2);
2195
- __decorateClass$a([
1890
+ __decorateClass$b([
2196
1891
  n2({ type: Boolean, reflect: true })
2197
1892
  ], WfStep.prototype, "active", 2);
2198
- __decorateClass$a([
1893
+ __decorateClass$b([
2199
1894
  n2({ type: String, reflect: true })
2200
1895
  ], WfStep.prototype, "direction", 2);
2201
- __decorateClass$a([
1896
+ __decorateClass$b([
2202
1897
  n2({ type: Boolean, reflect: true })
2203
1898
  ], WfStep.prototype, "leaving", 2);
2204
- __decorateClass$a([
1899
+ __decorateClass$b([
2205
1900
  n2({ type: String, attribute: "data-skip-if" })
2206
1901
  ], WfStep.prototype, "skipIf", 2);
2207
- __decorateClass$a([
1902
+ __decorateClass$b([
2208
1903
  r()
2209
1904
  ], WfStep.prototype, "_fields", 2);
2210
- WfStep = __decorateClass$a([
1905
+ WfStep = __decorateClass$b([
2211
1906
  t("wf-step")
2212
1907
  ], WfStep);
2213
- var __defProp$9 = Object.defineProperty;
1908
+ var __defProp$a = Object.defineProperty;
2214
1909
  var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
2215
- var __decorateClass$9 = (decorators, target, key, kind) => {
1910
+ var __decorateClass$a = (decorators, target, key, kind) => {
2216
1911
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
2217
1912
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2218
1913
  if (decorator = decorators[i2])
2219
1914
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2220
- if (kind && result) __defProp$9(target, key, result);
1915
+ if (kind && result) __defProp$a(target, key, result);
2221
1916
  return result;
2222
1917
  };
2223
- let WfOptions = class extends i {
1918
+ const SPACING_SCALE = {
1919
+ none: 0,
1920
+ xs: 4,
1921
+ sm: 8,
1922
+ md: 16,
1923
+ lg: 24,
1924
+ xl: 32
1925
+ };
1926
+ let WfLayout = class extends i {
2224
1927
  constructor() {
2225
1928
  super(...arguments);
2226
- this.name = "";
2227
- this.multi = false;
2228
- this.required = false;
2229
- this.min = 0;
2230
- this.max = 0;
2231
- this.columns = 2;
2232
- this.allowOther = false;
2233
- this.otherLabel = "Other, please specify:";
2234
- this.otherPlaceholder = "Enter your answer";
2235
- this.otherRequired = false;
2236
- this.otherName = "";
2237
- this.otherFieldValue = "Others";
2238
- this._selected = /* @__PURE__ */ new Set();
2239
- this._otherValue = "";
1929
+ this.mode = "flex";
1930
+ this.direction = "column";
1931
+ this.gap = "none";
1932
+ this.gapX = "";
1933
+ this.gapY = "";
1934
+ this.align = "stretch";
1935
+ this.justify = "start";
1936
+ this.padding = "none";
1937
+ this.paddingX = "";
1938
+ this.paddingY = "";
1939
+ this.wrap = false;
1940
+ this.width = "full";
1941
+ this.columns = "auto";
1942
+ this.minItemWidth = "200px";
1943
+ }
1944
+ /**
1945
+ * Disable Shadow DOM - render to Light DOM for external styling
1946
+ */
1947
+ createRenderRoot() {
1948
+ return this;
1949
+ }
1950
+ /**
1951
+ * Convert spacing value to pixels
1952
+ */
1953
+ _resolveSpacing(value) {
1954
+ if (!value || value === "none") {
1955
+ return "0";
1956
+ }
1957
+ if (value in SPACING_SCALE) {
1958
+ return `${SPACING_SCALE[value]}px`;
1959
+ }
1960
+ const num = parseFloat(value);
1961
+ if (!isNaN(num)) {
1962
+ return `${num}px`;
1963
+ }
1964
+ return value;
1965
+ }
1966
+ /**
1967
+ * Get computed gap-x value
1968
+ */
1969
+ _getGapX() {
1970
+ return this._resolveSpacing(this.gapX || this.gap);
1971
+ }
1972
+ /**
1973
+ * Get computed gap-y value
1974
+ */
1975
+ _getGapY() {
1976
+ return this._resolveSpacing(this.gapY || this.gap);
1977
+ }
1978
+ /**
1979
+ * Get computed padding values
1980
+ */
1981
+ _getPadding() {
1982
+ const uniformPadding = this._resolveSpacing(this.padding);
1983
+ const px = this.paddingX ? this._resolveSpacing(this.paddingX) : uniformPadding;
1984
+ const py = this.paddingY ? this._resolveSpacing(this.paddingY) : uniformPadding;
1985
+ return `${py} ${px}`;
1986
+ }
1987
+ /**
1988
+ * Build inline styles based on properties
1989
+ */
1990
+ _buildStyles() {
1991
+ const styles = [];
1992
+ if (this.mode === "grid") {
1993
+ styles.push("display: grid");
1994
+ const cols = parseInt(this.columns, 10);
1995
+ if (!isNaN(cols) && cols > 0) {
1996
+ styles.push(`grid-template-columns: repeat(${cols}, 1fr)`);
1997
+ } else {
1998
+ styles.push(
1999
+ `grid-template-columns: repeat(auto-fit, minmax(${this.minItemWidth}, 1fr))`
2000
+ );
2001
+ }
2002
+ if (this.align !== "stretch") {
2003
+ styles.push(`align-items: ${this.align}`);
2004
+ }
2005
+ if (this.justify !== "start") {
2006
+ styles.push(`justify-content: ${this.justify}`);
2007
+ }
2008
+ } else {
2009
+ styles.push("display: flex");
2010
+ styles.push(`flex-direction: ${this.direction}`);
2011
+ if (this.wrap) {
2012
+ styles.push("flex-wrap: wrap");
2013
+ }
2014
+ if (this.align !== "stretch") {
2015
+ styles.push(`align-items: ${this.align}`);
2016
+ }
2017
+ if (this.justify !== "start") {
2018
+ styles.push(`justify-content: ${this.justify}`);
2019
+ }
2020
+ }
2021
+ const gapX = this._getGapX();
2022
+ const gapY = this._getGapY();
2023
+ if (gapX !== "0" || gapY !== "0") {
2024
+ styles.push(`column-gap: ${gapX}`);
2025
+ styles.push(`row-gap: ${gapY}`);
2026
+ }
2027
+ const padding = this._getPadding();
2028
+ if (padding !== "0 0") {
2029
+ styles.push(`padding: ${padding}`);
2030
+ }
2031
+ return styles.join("; ");
2032
+ }
2033
+ /**
2034
+ * Apply styles to host element when properties change
2035
+ */
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
+ }
2045
+ };
2046
+ __decorateClass$a([
2047
+ n2({ type: String })
2048
+ ], WfLayout.prototype, "mode", 2);
2049
+ __decorateClass$a([
2050
+ n2({ type: String })
2051
+ ], WfLayout.prototype, "direction", 2);
2052
+ __decorateClass$a([
2053
+ n2({ type: String })
2054
+ ], WfLayout.prototype, "gap", 2);
2055
+ __decorateClass$a([
2056
+ n2({ type: String, attribute: "gap-x" })
2057
+ ], WfLayout.prototype, "gapX", 2);
2058
+ __decorateClass$a([
2059
+ n2({ type: String, attribute: "gap-y" })
2060
+ ], WfLayout.prototype, "gapY", 2);
2061
+ __decorateClass$a([
2062
+ n2({ type: String })
2063
+ ], WfLayout.prototype, "align", 2);
2064
+ __decorateClass$a([
2065
+ n2({ type: String })
2066
+ ], WfLayout.prototype, "justify", 2);
2067
+ __decorateClass$a([
2068
+ n2({ type: String })
2069
+ ], WfLayout.prototype, "padding", 2);
2070
+ __decorateClass$a([
2071
+ n2({ type: String, attribute: "padding-x" })
2072
+ ], WfLayout.prototype, "paddingX", 2);
2073
+ __decorateClass$a([
2074
+ n2({ type: String, attribute: "padding-y" })
2075
+ ], WfLayout.prototype, "paddingY", 2);
2076
+ __decorateClass$a([
2077
+ n2({ type: Boolean })
2078
+ ], WfLayout.prototype, "wrap", 2);
2079
+ __decorateClass$a([
2080
+ n2({ type: String })
2081
+ ], WfLayout.prototype, "width", 2);
2082
+ __decorateClass$a([
2083
+ n2({ type: String })
2084
+ ], WfLayout.prototype, "columns", 2);
2085
+ __decorateClass$a([
2086
+ n2({ type: String, attribute: "min-item-width" })
2087
+ ], WfLayout.prototype, "minItemWidth", 2);
2088
+ WfLayout = __decorateClass$a([
2089
+ t("wf-layout")
2090
+ ], WfLayout);
2091
+ var __defProp$9 = Object.defineProperty;
2092
+ var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
2093
+ var __decorateClass$9 = (decorators, target, key, kind) => {
2094
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
2095
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2096
+ if (decorator = decorators[i2])
2097
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
2098
+ if (kind && result) __defProp$9(target, key, result);
2099
+ return result;
2100
+ };
2101
+ let WfOptions = class extends i {
2102
+ constructor() {
2103
+ super(...arguments);
2104
+ this.name = "";
2105
+ this.multi = false;
2106
+ this.required = false;
2107
+ this.min = 0;
2108
+ 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";
2116
+ this._selected = /* @__PURE__ */ new Set();
2117
+ this._otherValue = "";
2240
2118
  this._errorMessage = "";
2241
2119
  this._validationActivated = false;
2242
2120
  this._options = [];
@@ -2257,15 +2135,15 @@ let WfOptions = class extends i {
2257
2135
  if (actualTarget?.tagName === "INPUT" || actualTarget?.tagName === "TEXTAREA") {
2258
2136
  return;
2259
2137
  }
2260
- const otherInput = this.shadowRoot?.querySelector("#wf-other-input");
2261
- if (otherInput && otherInput === this.shadowRoot?.activeElement) {
2138
+ const otherInput = this.querySelector(".wf-other-input");
2139
+ if (otherInput && document.activeElement === otherInput) {
2262
2140
  return;
2263
2141
  }
2264
2142
  const key = e2.key.toUpperCase();
2265
2143
  if (key.length === 1 && key >= "A" && key <= "Z") {
2266
2144
  if (this.allowOther && key === this._otherShortcut) {
2267
2145
  e2.preventDefault();
2268
- const otherInput2 = this.shadowRoot?.querySelector("#wf-other-input");
2146
+ const otherInput2 = this.querySelector(".wf-other-input");
2269
2147
  if (otherInput2) {
2270
2148
  otherInput2.focus();
2271
2149
  }
@@ -2279,6 +2157,12 @@ let WfOptions = class extends i {
2279
2157
  }
2280
2158
  };
2281
2159
  }
2160
+ /**
2161
+ * Disable Shadow DOM - render to Light DOM for external styling
2162
+ */
2163
+ createRenderRoot() {
2164
+ return this;
2165
+ }
2282
2166
  connectedCallback() {
2283
2167
  super.connectedCallback();
2284
2168
  this._errorMessage = "";
@@ -2292,7 +2176,11 @@ let WfOptions = class extends i {
2292
2176
  document.removeEventListener("keydown", this._handleKeydown);
2293
2177
  }
2294
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));
2295
2182
  this._discoverOptions();
2183
+ this.requestUpdate();
2296
2184
  }
2297
2185
  updated(changedProperties) {
2298
2186
  if (changedProperties.has("multi") || changedProperties.has("max")) {
@@ -2300,15 +2188,13 @@ let WfOptions = class extends i {
2300
2188
  }
2301
2189
  }
2302
2190
  render() {
2191
+ this.setAttribute("role", "listbox");
2192
+ this.setAttribute("aria-multiselectable", String(this.multi));
2193
+ this.setAttribute("aria-required", String(this.required));
2303
2194
  return b`
2304
- <div
2305
- class="wf-options-container"
2306
- role="listbox"
2307
- aria-multiselectable="${this.multi}"
2308
- aria-required="${this.required}"
2309
- >
2310
- <slot @slotchange="${this._handleSlotChange}"></slot>
2311
- </div>
2195
+ <wf-layout mode="grid" columns="${this.columns}" gap="md">
2196
+ <!-- wf-option children will be moved here in firstUpdated -->
2197
+ </wf-layout>
2312
2198
  ${this.allowOther ? b`
2313
2199
  <div class="wf-other-container">
2314
2200
  <label class="wf-other-label">${this.otherLabel}</label>
@@ -2316,7 +2202,6 @@ let WfOptions = class extends i {
2316
2202
  ${this._otherShortcut ? b`<wf-badge shortcut="${this._otherShortcut}"></wf-badge>` : ""}
2317
2203
  <input
2318
2204
  type="text"
2319
- id="wf-other-input"
2320
2205
  class="wf-other-input"
2321
2206
  .value="${this._otherValue}"
2322
2207
  placeholder="${this.otherPlaceholder}"
@@ -2351,18 +2236,9 @@ let WfOptions = class extends i {
2351
2236
  input.blur();
2352
2237
  }
2353
2238
  }
2354
- _handleSlotChange() {
2355
- this._discoverOptions();
2356
- }
2357
2239
  _discoverOptions() {
2358
- const slot = this.shadowRoot?.querySelector("slot");
2359
- if (!slot) {
2360
- return;
2361
- }
2362
- const elements = slot.assignedElements({ flatten: true });
2363
- this._options = elements.filter(
2364
- (el) => el.tagName.toLowerCase() === "wf-option"
2365
- );
2240
+ const layout = this.querySelector("wf-layout");
2241
+ this._options = layout ? Array.from(layout.querySelectorAll(":scope > wf-option")) : [];
2366
2242
  this._shortcutMap.clear();
2367
2243
  this._options.forEach((option, index) => {
2368
2244
  if (index < 26) {
@@ -2597,97 +2473,6 @@ let WfOptions = class extends i {
2597
2473
  this._dispatchChange();
2598
2474
  }
2599
2475
  };
2600
- WfOptions.styles = i$3`
2601
- :host {
2602
- display: block;
2603
- }
2604
-
2605
- :host([hidden]) {
2606
- display: none;
2607
- }
2608
-
2609
- /* Two columns (default) */
2610
- .wf-options-container {
2611
- display: grid;
2612
- grid-template-columns: repeat(2, 1fr);
2613
- gap: var(--wf-spacing-4, 16px);
2614
- }
2615
-
2616
- /* Single column via attribute */
2617
- :host([columns='1']) .wf-options-container {
2618
- grid-template-columns: 1fr;
2619
- }
2620
-
2621
- /* Single column on mobile */
2622
- @media (max-width: 600px) {
2623
- .wf-options-container {
2624
- grid-template-columns: 1fr;
2625
- }
2626
- }
2627
-
2628
- .wf-error-message {
2629
- display: block;
2630
- margin-top: var(--wf-spacing-2, 8px);
2631
- font-size: var(--wf-font-size-sm, 0.875rem);
2632
- color: var(--wf-color-error, #dc3545);
2633
- min-height: 20px;
2634
- }
2635
-
2636
- /* Other input styles */
2637
- .wf-other-container {
2638
- margin-top: var(--wf-spacing-4, 16px);
2639
- }
2640
-
2641
- .wf-other-label {
2642
- display: block;
2643
- margin-bottom: var(--wf-spacing-2, 8px);
2644
- font-size: var(--wf-font-size-sm, 0.875rem);
2645
- font-weight: 500;
2646
- color: var(--wf-color-text, #0a0a0a);
2647
- }
2648
-
2649
- .wf-other-label span {
2650
- font-weight: 400;
2651
- color: var(--wf-color-text-muted, #646464);
2652
- }
2653
-
2654
- /* Wrapper puts badge inside the input */
2655
- .wf-other-input-wrapper {
2656
- display: flex;
2657
- align-items: center;
2658
- gap: var(--wf-spacing-3, 12px);
2659
- min-height: var(--wf-input-min-height, 56px);
2660
- background: var(--wf-color-surface, #f3f3f5);
2661
- border: 1px solid var(--wf-color-border, #d4d4d4);
2662
- border-radius: var(--wf-radius-md, 8px);
2663
- padding-left: var(--wf-spacing-4, 16px);
2664
- transition: border-color 150ms ease, box-shadow 150ms ease;
2665
- }
2666
-
2667
- .wf-other-input-wrapper:focus-within {
2668
- border-color: var(--wf-color-primary, #8040f0);
2669
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.1);
2670
- }
2671
-
2672
- .wf-other-input {
2673
- flex: 1;
2674
- min-height: calc(var(--wf-input-min-height, 56px) - 2px);
2675
- padding: var(--wf-spacing-4, 16px);
2676
- padding-left: 0;
2677
- font-size: var(--wf-font-size-base, 1rem);
2678
- font-weight: 500;
2679
- color: var(--wf-color-text, #0a0a0a);
2680
- background: transparent;
2681
- border: none;
2682
- outline: none;
2683
- box-sizing: border-box;
2684
- }
2685
-
2686
- .wf-other-input::placeholder {
2687
- color: var(--wf-color-text-muted, #646464);
2688
- font-weight: 500;
2689
- }
2690
- `;
2691
2476
  __decorateClass$9([
2692
2477
  n2({ type: String })
2693
2478
  ], WfOptions.prototype, "name", 2);
@@ -2740,9 +2525,9 @@ WfOptions = __decorateClass$9([
2740
2525
  t("wf-options")
2741
2526
  ], WfOptions);
2742
2527
  var __defProp$8 = Object.defineProperty;
2743
- var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
2528
+ var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
2744
2529
  var __decorateClass$8 = (decorators, target, key, kind) => {
2745
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
2530
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
2746
2531
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2747
2532
  if (decorator = decorators[i2])
2748
2533
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
@@ -2757,6 +2542,20 @@ let WfOption = class extends i {
2757
2542
  this.disabled = false;
2758
2543
  this.shortcut = "";
2759
2544
  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();
2760
2559
  }
2761
2560
  render() {
2762
2561
  return b`
@@ -2773,7 +2572,7 @@ let WfOption = class extends i {
2773
2572
  variant="${this.selected ? "selected" : "default"}"
2774
2573
  ></wf-badge>` : A}
2775
2574
  <div class="wf-option-content">
2776
- <slot></slot>
2575
+ ${this._cachedContent}
2777
2576
  </div>
2778
2577
  </button>
2779
2578
  `;
@@ -2815,7 +2614,7 @@ let WfOption = class extends i {
2815
2614
  * Focus the option button
2816
2615
  */
2817
2616
  focus() {
2818
- const button = this.shadowRoot?.querySelector("button");
2617
+ const button = this.querySelector("button");
2819
2618
  button?.focus();
2820
2619
  }
2821
2620
  /**
@@ -2825,98 +2624,6 @@ let WfOption = class extends i {
2825
2624
  this.selected = selected;
2826
2625
  }
2827
2626
  };
2828
- WfOption.styles = i$3`
2829
- :host {
2830
- display: block;
2831
- }
2832
-
2833
- :host([hidden]) {
2834
- display: none;
2835
- }
2836
-
2837
- .wf-option-card {
2838
- display: flex;
2839
- align-items: center;
2840
- gap: var(--wf-spacing-3, 12px);
2841
- width: 100%;
2842
- min-height: var(--wf-input-min-height, 56px);
2843
- padding: var(--wf-spacing-3, 12px);
2844
- background-color: var(--wf-color-surface, #f3f3f5);
2845
- border: 1px solid var(--wf-color-border, #d4d4d4);
2846
- border-radius: var(--wf-radius-md, 8px);
2847
- cursor: pointer;
2848
- text-align: left;
2849
- font-family: inherit;
2850
- font-size: var(--wf-font-size-base, 1rem);
2851
- font-weight: 500;
2852
- color: var(--wf-color-text, #0a0a0a);
2853
- transition: border-color 150ms ease, background-color 150ms ease,
2854
- transform 100ms ease;
2855
- outline: none;
2856
- box-sizing: border-box;
2857
- }
2858
-
2859
- .wf-option-card:hover:not(:disabled) {
2860
- border-color: var(--wf-color-primary, #8040f0);
2861
- background-color: var(--wf-color-primary-light, rgba(128, 64, 240, 0.08));
2862
- }
2863
-
2864
- .wf-option-card:focus-visible {
2865
- border-color: var(--wf-color-primary, #8040f0);
2866
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
2867
- }
2868
-
2869
- .wf-option-card[aria-selected='true'] {
2870
- border-color: var(--wf-color-primary, #8040f0);
2871
- background-color: var(--wf-color-primary-light, rgba(128, 64, 240, 0.1));
2872
- }
2873
-
2874
- .wf-option-card:disabled {
2875
- opacity: 0.5;
2876
- cursor: not-allowed;
2877
- }
2878
-
2879
- .wf-option-card:active:not(:disabled) {
2880
- transform: scale(0.98);
2881
- }
2882
-
2883
- /* Blink animation on selection */
2884
- .wf-option-card.selecting {
2885
- animation: blink 0.3s ease;
2886
- }
2887
-
2888
- @keyframes blink {
2889
- 0%,
2890
- 100% {
2891
- opacity: 1;
2892
- }
2893
- 50% {
2894
- opacity: 0.5;
2895
- }
2896
- }
2897
-
2898
- .wf-option-content {
2899
- flex: 1;
2900
- min-width: 0;
2901
- }
2902
-
2903
- /* Slotted content styling */
2904
- ::slotted(strong),
2905
- ::slotted(h3),
2906
- ::slotted(h4) {
2907
- display: block;
2908
- font-weight: 600;
2909
- margin: 0;
2910
- }
2911
-
2912
- ::slotted(span),
2913
- ::slotted(p) {
2914
- display: block;
2915
- font-size: var(--wf-font-size-sm, 0.875rem);
2916
- color: var(--wf-color-text-muted, #646464);
2917
- margin: 4px 0 0 0;
2918
- }
2919
- `;
2920
2627
  __decorateClass$8([
2921
2628
  n2({ type: String })
2922
2629
  ], WfOption.prototype, "value", 2);
@@ -2935,6 +2642,217 @@ __decorateClass$8([
2935
2642
  WfOption = __decorateClass$8([
2936
2643
  t("wf-option")
2937
2644
  ], WfOption);
2645
+ var __defProp$7 = Object.defineProperty;
2646
+ var __decorateClass$7 = (decorators, target, key, kind) => {
2647
+ var result = void 0;
2648
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
2649
+ if (decorator = decorators[i2])
2650
+ result = decorator(target, key, result) || result;
2651
+ if (result) __defProp$7(target, key, result);
2652
+ return result;
2653
+ };
2654
+ const DEFAULT_DEBOUNCE_MS = 600;
2655
+ class FormInputBase extends i {
2656
+ constructor() {
2657
+ super(...arguments);
2658
+ this.name = "";
2659
+ this.label = "";
2660
+ this.required = false;
2661
+ this.hint = "";
2662
+ this._errorMessage = "";
2663
+ this._value = "";
2664
+ this._validationActivated = false;
2665
+ this._debounceTimer = null;
2666
+ this._validators = [];
2667
+ this._handleInput = (e2) => {
2668
+ const target = e2.target;
2669
+ this._value = target.value;
2670
+ if (this._validationActivated) {
2671
+ if (this._debounceTimer) {
2672
+ clearTimeout(this._debounceTimer);
2673
+ }
2674
+ this._debounceTimer = setTimeout(() => {
2675
+ this.validate();
2676
+ }, this._getDebounceMs());
2677
+ }
2678
+ this.dispatchEvent(
2679
+ new CustomEvent("wf-change", {
2680
+ detail: {
2681
+ name: this.name,
2682
+ value: this._value
2683
+ },
2684
+ bubbles: true,
2685
+ composed: true
2686
+ })
2687
+ );
2688
+ };
2689
+ this._handleBlur = () => {
2690
+ this.dispatchEvent(
2691
+ new CustomEvent("wf-blur", {
2692
+ detail: { name: this.name, value: this._value },
2693
+ bubbles: true,
2694
+ composed: true
2695
+ })
2696
+ );
2697
+ };
2698
+ this._handleFocus = () => {
2699
+ this.dispatchEvent(
2700
+ new CustomEvent("wf-focus", {
2701
+ detail: { name: this.name },
2702
+ bubbles: true,
2703
+ composed: true
2704
+ })
2705
+ );
2706
+ };
2707
+ }
2708
+ /**
2709
+ * Disable Shadow DOM - render to Light DOM for external styling
2710
+ */
2711
+ createRenderRoot() {
2712
+ return this;
2713
+ }
2714
+ // ============================================
2715
+ // Lifecycle Methods
2716
+ // ============================================
2717
+ connectedCallback() {
2718
+ super.connectedCallback();
2719
+ this._setupValidators();
2720
+ }
2721
+ updated(changedProperties) {
2722
+ const triggerProps = this._getValidationTriggerProperties();
2723
+ const shouldRebuild = triggerProps.some((prop) => changedProperties.has(prop));
2724
+ if (shouldRebuild) {
2725
+ this._setupValidators();
2726
+ }
2727
+ }
2728
+ // ============================================
2729
+ // Overridable Methods
2730
+ // ============================================
2731
+ /**
2732
+ * Return the debounce delay for input validation (in milliseconds).
2733
+ * Override in subclasses that need different debounce timing.
2734
+ */
2735
+ _getDebounceMs() {
2736
+ return DEFAULT_DEBOUNCE_MS;
2737
+ }
2738
+ /**
2739
+ * Return the CSS selector for the focusable element.
2740
+ * Override in subclasses with different focusable elements (e.g., 'textarea').
2741
+ */
2742
+ _getFocusableSelector() {
2743
+ return "input";
2744
+ }
2745
+ // ============================================
2746
+ // Public API
2747
+ // ============================================
2748
+ /**
2749
+ * Get current value
2750
+ */
2751
+ get value() {
2752
+ return this._value;
2753
+ }
2754
+ /**
2755
+ * Set value programmatically
2756
+ */
2757
+ set value(val) {
2758
+ this._value = val;
2759
+ }
2760
+ /**
2761
+ * Add a custom validator
2762
+ */
2763
+ addValidator(validator) {
2764
+ this._validators.push(validator);
2765
+ }
2766
+ /**
2767
+ * Validate the field asynchronously
2768
+ * @returns Promise resolving to true if valid, false otherwise
2769
+ */
2770
+ async validate() {
2771
+ this._validationActivated = true;
2772
+ const currentValue = this.value;
2773
+ for (const validator of this._validators) {
2774
+ try {
2775
+ const result = await validator.validate(currentValue);
2776
+ if (!result.valid) {
2777
+ this._errorMessage = result.error ?? validator.message ?? "Validation failed";
2778
+ return false;
2779
+ }
2780
+ } catch (error) {
2781
+ console.error(`[${this.tagName}] Validator error:`, error);
2782
+ this._errorMessage = "Validation error occurred";
2783
+ return false;
2784
+ }
2785
+ }
2786
+ this._errorMessage = "";
2787
+ return true;
2788
+ }
2789
+ /**
2790
+ * Check if field is valid synchronously (doesn't update UI)
2791
+ */
2792
+ get isValid() {
2793
+ const currentValue = this.value;
2794
+ for (const validator of this._validators) {
2795
+ const result = validator.validate(currentValue);
2796
+ if (result instanceof Promise) {
2797
+ console.warn(`[${this.tagName}] Async validator called synchronously`);
2798
+ continue;
2799
+ }
2800
+ if (!result.valid) {
2801
+ return false;
2802
+ }
2803
+ }
2804
+ return true;
2805
+ }
2806
+ /**
2807
+ * Show an error message manually
2808
+ */
2809
+ showError(message) {
2810
+ this._errorMessage = message;
2811
+ }
2812
+ /**
2813
+ * Clear the error message
2814
+ */
2815
+ clearError() {
2816
+ this._errorMessage = "";
2817
+ }
2818
+ /**
2819
+ * Focus the input element
2820
+ */
2821
+ focus() {
2822
+ const element = this.querySelector(this._getFocusableSelector());
2823
+ element?.focus();
2824
+ }
2825
+ /**
2826
+ * Reset field to initial state
2827
+ */
2828
+ reset() {
2829
+ this._value = "";
2830
+ this._errorMessage = "";
2831
+ this._validationActivated = false;
2832
+ if (this._debounceTimer) {
2833
+ clearTimeout(this._debounceTimer);
2834
+ this._debounceTimer = null;
2835
+ }
2836
+ }
2837
+ }
2838
+ __decorateClass$7([
2839
+ n2({ type: String })
2840
+ ], FormInputBase.prototype, "name");
2841
+ __decorateClass$7([
2842
+ n2({ type: String })
2843
+ ], FormInputBase.prototype, "label");
2844
+ __decorateClass$7([
2845
+ n2({ type: Boolean })
2846
+ ], FormInputBase.prototype, "required");
2847
+ __decorateClass$7([
2848
+ n2({ type: String })
2849
+ ], FormInputBase.prototype, "hint");
2850
+ __decorateClass$7([
2851
+ r()
2852
+ ], FormInputBase.prototype, "_errorMessage");
2853
+ __decorateClass$7([
2854
+ r()
2855
+ ], FormInputBase.prototype, "_value");
2938
2856
  const DEFAULT_BLOCKED_DOMAINS = [
2939
2857
  "gmail.com",
2940
2858
  "yahoo.com",
@@ -3170,70 +3088,24 @@ class ValidationController {
3170
3088
  };
3171
3089
  }
3172
3090
  }
3173
- var __defProp$7 = Object.defineProperty;
3174
- var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
3175
- var __decorateClass$7 = (decorators, target, key, kind) => {
3176
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
3091
+ var __defProp$6 = Object.defineProperty;
3092
+ var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
3093
+ var __decorateClass$6 = (decorators, target, key, kind) => {
3094
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
3177
3095
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3178
3096
  if (decorator = decorators[i2])
3179
3097
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3180
- if (kind && result) __defProp$7(target, key, result);
3098
+ if (kind && result) __defProp$6(target, key, result);
3181
3099
  return result;
3182
3100
  };
3183
- let WfField = class extends i {
3101
+ let WfField = class extends FormInputBase {
3184
3102
  constructor() {
3185
3103
  super(...arguments);
3186
- this.name = "";
3187
- this.label = "";
3188
- this.required = false;
3189
- this.hint = "";
3190
- this._errorMessage = "";
3191
- this._value = "";
3192
- this._validationActivated = false;
3193
- this._debounceTimer = null;
3194
- this._validators = [];
3195
3104
  this._inputElement = null;
3196
- this._handleInput = (e2) => {
3197
- const target = e2.target;
3198
- this._value = target.value;
3199
- if (this._validationActivated) {
3200
- if (this._debounceTimer) {
3201
- clearTimeout(this._debounceTimer);
3202
- }
3203
- this._debounceTimer = setTimeout(() => {
3204
- this.validate();
3205
- }, 300);
3206
- }
3207
- this.dispatchEvent(
3208
- new CustomEvent("wf-change", {
3209
- detail: {
3210
- name: this.name,
3211
- value: this._value
3212
- },
3213
- bubbles: true,
3214
- composed: true
3215
- })
3216
- );
3217
- };
3218
- this._handleBlur = () => {
3219
- this.dispatchEvent(
3220
- new CustomEvent("wf-blur", {
3221
- detail: { name: this.name, value: this._value },
3222
- bubbles: true,
3223
- composed: true
3224
- })
3225
- );
3226
- };
3227
- this._handleFocus = () => {
3228
- this.dispatchEvent(
3229
- new CustomEvent("wf-focus", {
3230
- detail: { name: this.name },
3231
- bubbles: true,
3232
- composed: true
3233
- })
3234
- );
3235
- };
3236
3105
  }
3106
+ // ============================================
3107
+ // Lifecycle Overrides
3108
+ // ============================================
3237
3109
  connectedCallback() {
3238
3110
  super.connectedCallback();
3239
3111
  this.addEventListener("input", this._handleInput);
@@ -3248,52 +3120,21 @@ let WfField = class extends i {
3248
3120
  }
3249
3121
  firstUpdated() {
3250
3122
  this._discoverInput();
3251
- this._setupValidatorsFromAttributes();
3123
+ this._setupValidators();
3252
3124
  }
3253
- render() {
3254
- return b`
3255
- <div class="wf-field-container">
3256
- ${this.label ? b`<label
3257
- class="wf-label ${this.required ? "wf-label-required" : ""}"
3258
- for="${this.name}"
3259
- >
3260
- ${this.label}
3261
- </label>` : ""}
3262
- <div class="wf-input-wrapper">
3263
- <slot @slotchange="${this._handleSlotChange}"></slot>
3264
- </div>
3265
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3266
- <span class="wf-error-message" role="alert" aria-live="polite">
3267
- ${this._errorMessage}
3268
- </span>
3269
- </div>
3270
- `;
3125
+ // ============================================
3126
+ // Abstract Method Implementations
3127
+ // ============================================
3128
+ _getValidationTriggerProperties() {
3129
+ return ["required"];
3271
3130
  }
3272
- _handleSlotChange() {
3273
- this._discoverInput();
3274
- this._setupValidatorsFromAttributes();
3275
- }
3276
- _discoverInput() {
3277
- const slot = this.shadowRoot?.querySelector("slot");
3278
- if (!slot) {
3279
- return;
3280
- }
3281
- const elements = slot.assignedElements({ flatten: true });
3282
- for (const el of elements) {
3283
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
3284
- this._inputElement = el;
3285
- if (!el.id) {
3286
- el.id = this.name;
3287
- }
3288
- if (!el.name) {
3289
- el.name = this.name;
3290
- }
3291
- this._value = el.value;
3292
- break;
3293
- }
3294
- }
3131
+ /**
3132
+ * Field uses faster debounce (300ms) for responsive validation
3133
+ */
3134
+ _getDebounceMs() {
3135
+ return 300;
3295
3136
  }
3296
- _setupValidatorsFromAttributes() {
3137
+ _setupValidators() {
3297
3138
  if (!this._inputElement) {
3298
3139
  return;
3299
3140
  }
@@ -3324,16 +3165,43 @@ let WfField = class extends i {
3324
3165
  }
3325
3166
  }
3326
3167
  // ============================================
3327
- // Public API
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)
3328
3196
  // ============================================
3329
3197
  /**
3330
- * Get current value
3198
+ * Get current value from slotted element or internal state
3331
3199
  */
3332
3200
  get value() {
3333
3201
  return this._inputElement?.value ?? this._value;
3334
3202
  }
3335
3203
  /**
3336
- * Set value
3204
+ * Set value on both internal state and slotted element
3337
3205
  */
3338
3206
  set value(val) {
3339
3207
  this._value = val;
@@ -3341,259 +3209,83 @@ let WfField = class extends i {
3341
3209
  this._inputElement.value = String(val ?? "");
3342
3210
  }
3343
3211
  }
3212
+ // ============================================
3213
+ // Focus and Reset Overrides
3214
+ // ============================================
3344
3215
  /**
3345
- * Add a custom validator
3346
- */
3347
- addValidator(validator) {
3348
- this._validators.push(validator);
3349
- }
3350
- /**
3351
- * Validate the field
3352
- */
3353
- async validate() {
3354
- this._validationActivated = true;
3355
- const value = this.value;
3356
- for (const validator of this._validators) {
3357
- try {
3358
- const result = await validator.validate(value);
3359
- if (!result.valid) {
3360
- this._errorMessage = result.error ?? validator.message ?? "Validation failed";
3361
- return false;
3362
- }
3363
- } catch (error) {
3364
- console.error("[WfField] Validator error:", error);
3365
- this._errorMessage = "Validation error occurred";
3366
- return false;
3367
- }
3368
- }
3369
- this._errorMessage = "";
3370
- return true;
3371
- }
3372
- /**
3373
- * Check if field is valid (sync check, doesn't update UI)
3374
- */
3375
- get isValid() {
3376
- const value = this.value;
3377
- for (const validator of this._validators) {
3378
- const result = validator.validate(value);
3379
- if (result instanceof Promise) {
3380
- console.warn("[WfField] Async validator called synchronously");
3381
- continue;
3382
- }
3383
- if (!result.valid) {
3384
- return false;
3385
- }
3386
- }
3387
- return true;
3388
- }
3389
- /**
3390
- * Show error message
3391
- */
3392
- showError(message) {
3393
- this._errorMessage = message;
3394
- }
3395
- /**
3396
- * Clear error message
3397
- */
3398
- clearError() {
3399
- this._errorMessage = "";
3400
- }
3401
- /**
3402
- * Focus the input element
3216
+ * Focus the slotted input element
3403
3217
  */
3404
3218
  focus() {
3405
3219
  this._inputElement?.focus();
3406
3220
  }
3407
3221
  /**
3408
- * Reset field to initial state
3222
+ * Reset field to initial state including slotted element
3409
3223
  */
3410
3224
  reset() {
3411
- this._value = "";
3412
- this._errorMessage = "";
3413
- this._validationActivated = false;
3414
- if (this._debounceTimer) {
3415
- clearTimeout(this._debounceTimer);
3416
- this._debounceTimer = null;
3417
- }
3225
+ super.reset();
3418
3226
  if (this._inputElement) {
3419
3227
  this._inputElement.value = "";
3420
3228
  }
3421
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
+ }
3422
3252
  };
3423
- WfField.styles = i$3`
3424
- :host {
3425
- display: block;
3426
- }
3427
-
3428
- :host([hidden]) {
3429
- display: none;
3430
- }
3431
-
3432
- .wf-field-container {
3433
- display: flex;
3434
- flex-direction: column;
3435
- gap: var(--wf-spacing-2, 8px);
3436
- }
3437
-
3438
- .wf-label {
3439
- font-size: var(--wf-font-size-sm, 0.875rem);
3440
- font-weight: 500;
3441
- color: var(--wf-color-text, #212529);
3442
- }
3443
-
3444
- .wf-label-required::after {
3445
- content: ' *';
3446
- color: var(--wf-color-error, #dc3545);
3447
- }
3448
-
3449
- .wf-input-wrapper {
3450
- position: relative;
3451
- }
3452
-
3453
- /* Style slotted inputs */
3454
- ::slotted(input),
3455
- ::slotted(textarea),
3456
- ::slotted(select) {
3457
- width: 100%;
3458
- padding: var(--wf-spacing-4, 16px);
3459
- font-size: var(--wf-font-size-base, 1rem);
3460
- font-family: inherit;
3461
- background-color: var(--wf-color-surface, #f8f9fa);
3462
- border: 2px solid var(--wf-color-border, #dee2e6);
3463
- border-radius: var(--wf-radius-lg, 12px);
3464
- color: var(--wf-color-text, #212529);
3465
- transition: border-color 150ms ease, box-shadow 150ms ease;
3466
- outline: none;
3467
- box-sizing: border-box;
3468
- }
3469
-
3470
- ::slotted(input::placeholder),
3471
- ::slotted(textarea::placeholder) {
3472
- color: var(--wf-color-text-muted, #6c757d);
3473
- }
3474
-
3475
- ::slotted(input:focus),
3476
- ::slotted(textarea:focus),
3477
- ::slotted(select:focus) {
3478
- border-color: var(--wf-color-primary, #8b5cf6);
3479
- box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
3480
- }
3481
-
3482
- ::slotted(input:disabled),
3483
- ::slotted(textarea:disabled),
3484
- ::slotted(select:disabled) {
3485
- opacity: 0.5;
3486
- cursor: not-allowed;
3487
- }
3488
-
3489
- .wf-error-message {
3490
- font-size: var(--wf-font-size-sm, 0.875rem);
3491
- color: var(--wf-color-error, #dc3545);
3492
- min-height: 20px;
3493
- }
3494
-
3495
- .wf-hint {
3496
- font-size: var(--wf-font-size-sm, 0.875rem);
3497
- color: var(--wf-color-text-muted, #6c757d);
3498
- }
3499
- `;
3500
- __decorateClass$7([
3501
- n2({ type: String })
3502
- ], WfField.prototype, "name", 2);
3503
- __decorateClass$7([
3504
- n2({ type: String })
3505
- ], WfField.prototype, "label", 2);
3506
- __decorateClass$7([
3507
- n2({ type: Boolean })
3508
- ], WfField.prototype, "required", 2);
3509
- __decorateClass$7([
3510
- n2({ type: String })
3511
- ], WfField.prototype, "hint", 2);
3512
- __decorateClass$7([
3513
- r()
3514
- ], WfField.prototype, "_errorMessage", 2);
3515
- __decorateClass$7([
3253
+ __decorateClass$6([
3516
3254
  r()
3517
- ], WfField.prototype, "_value", 2);
3518
- WfField = __decorateClass$7([
3255
+ ], WfField.prototype, "_inputElement", 2);
3256
+ WfField = __decorateClass$6([
3519
3257
  t("wf-field")
3520
3258
  ], WfField);
3521
- var __defProp$6 = Object.defineProperty;
3522
- var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
3523
- var __decorateClass$6 = (decorators, target, key, kind) => {
3524
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
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;
3525
3263
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3526
3264
  if (decorator = decorators[i2])
3527
3265
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3528
- if (kind && result) __defProp$6(target, key, result);
3266
+ if (kind && result) __defProp$5(target, key, result);
3529
3267
  return result;
3530
3268
  };
3531
- let WfEmail = class extends i {
3269
+ let WfEmail = class extends FormInputBase {
3532
3270
  constructor() {
3533
3271
  super(...arguments);
3534
- this.name = "";
3535
- this.label = "";
3536
3272
  this.placeholder = "you@company.com";
3537
- this.required = false;
3538
3273
  this.workEmail = false;
3539
3274
  this.blockedDomains = "";
3540
3275
  this.workEmailMessage = "Please use your work email address";
3541
3276
  this.disabled = false;
3542
- this.hint = "";
3543
- this._errorMessage = "";
3544
- this._value = "";
3545
- this._validationActivated = false;
3546
- this._debounceTimer = null;
3547
- this._validators = [];
3548
- this._handleInput = (e2) => {
3549
- const target = e2.target;
3550
- this._value = target.value;
3551
- if (this._validationActivated) {
3552
- if (this._debounceTimer) {
3553
- clearTimeout(this._debounceTimer);
3554
- }
3555
- this._debounceTimer = setTimeout(() => {
3556
- this.validate();
3557
- }, 300);
3558
- }
3559
- this.dispatchEvent(
3560
- new CustomEvent("wf-change", {
3561
- detail: {
3562
- name: this.name,
3563
- value: this._value
3564
- },
3565
- bubbles: true,
3566
- composed: true
3567
- })
3568
- );
3569
- };
3570
- this._handleBlur = () => {
3571
- this.dispatchEvent(
3572
- new CustomEvent("wf-blur", {
3573
- detail: { name: this.name, value: this._value },
3574
- bubbles: true,
3575
- composed: true
3576
- })
3577
- );
3578
- };
3579
- this._handleFocus = () => {
3580
- this.dispatchEvent(
3581
- new CustomEvent("wf-focus", {
3582
- detail: { name: this.name },
3583
- bubbles: true,
3584
- composed: true
3585
- })
3586
- );
3587
- };
3588
3277
  }
3589
- connectedCallback() {
3590
- super.connectedCallback();
3591
- this._setupValidators();
3278
+ // ============================================
3279
+ // Abstract Method Implementations
3280
+ // ============================================
3281
+ _getValidationTriggerProperties() {
3282
+ return ["required", "workEmail", "blockedDomains"];
3592
3283
  }
3593
- updated(changedProperties) {
3594
- if (changedProperties.has("required") || changedProperties.has("workEmail") || changedProperties.has("blockedDomains")) {
3595
- this._setupValidators();
3596
- }
3284
+ /**
3285
+ * Email uses faster debounce (300ms) for responsive validation
3286
+ */
3287
+ _getDebounceMs() {
3288
+ return 300;
3597
3289
  }
3598
3290
  _setupValidators() {
3599
3291
  this._validators = [];
@@ -3611,6 +3303,9 @@ let WfEmail = class extends i {
3611
3303
  );
3612
3304
  }
3613
3305
  }
3306
+ // ============================================
3307
+ // Render
3308
+ // ============================================
3614
3309
  render() {
3615
3310
  return b`
3616
3311
  <div class="wf-field-container">
@@ -3642,277 +3337,49 @@ let WfEmail = class extends i {
3642
3337
  </div>
3643
3338
  `;
3644
3339
  }
3645
- // ============================================
3646
- // Public API
3647
- // ============================================
3648
- /**
3649
- * Get current value
3650
- */
3651
- get value() {
3652
- return this._value;
3653
- }
3654
- /**
3655
- * Set value
3656
- */
3657
- set value(val) {
3658
- this._value = val;
3659
- }
3660
- /**
3661
- * Validate the field
3662
- */
3663
- async validate() {
3664
- this._validationActivated = true;
3665
- for (const validator of this._validators) {
3666
- try {
3667
- const result = await validator.validate(this._value);
3668
- if (!result.valid) {
3669
- this._errorMessage = result.error ?? validator.message ?? "Validation failed";
3670
- return false;
3671
- }
3672
- } catch (error) {
3673
- console.error("[WfEmail] Validator error:", error);
3674
- this._errorMessage = "Validation error occurred";
3675
- return false;
3676
- }
3677
- }
3678
- this._errorMessage = "";
3679
- return true;
3680
- }
3681
- /**
3682
- * Check if field is valid (sync check)
3683
- */
3684
- get isValid() {
3685
- for (const validator of this._validators) {
3686
- const result = validator.validate(this._value);
3687
- if (result instanceof Promise) {
3688
- console.warn("[WfEmail] Async validator called synchronously");
3689
- continue;
3690
- }
3691
- if (!result.valid) {
3692
- return false;
3693
- }
3694
- }
3695
- return true;
3696
- }
3697
- /**
3698
- * Show error message
3699
- */
3700
- showError(message) {
3701
- this._errorMessage = message;
3702
- }
3703
- /**
3704
- * Clear error message
3705
- */
3706
- clearError() {
3707
- this._errorMessage = "";
3708
- }
3709
- /**
3710
- * Focus the input
3711
- */
3712
- focus() {
3713
- const input = this.shadowRoot?.querySelector("input");
3714
- input?.focus();
3715
- }
3716
- /**
3717
- * Reset field to initial state
3718
- */
3719
- reset() {
3720
- this._value = "";
3721
- this._errorMessage = "";
3722
- this._validationActivated = false;
3723
- if (this._debounceTimer) {
3724
- clearTimeout(this._debounceTimer);
3725
- this._debounceTimer = null;
3726
- }
3727
- }
3728
3340
  };
3729
- WfEmail.styles = i$3`
3730
- :host {
3731
- display: block;
3732
- }
3733
-
3734
- :host([hidden]) {
3735
- display: none;
3736
- }
3737
-
3738
- .wf-field-container {
3739
- display: flex;
3740
- flex-direction: column;
3741
- gap: var(--wf-spacing-2, 8px);
3742
- }
3743
-
3744
- .wf-label {
3745
- font-size: var(--wf-font-size-sm, 0.875rem);
3746
- font-weight: 500;
3747
- color: var(--wf-color-text, #0a0a0a);
3748
- }
3749
-
3750
- .wf-label-required::after {
3751
- content: ' *';
3752
- color: var(--wf-color-error, #dc3545);
3753
- }
3754
-
3755
- .wf-input {
3756
- width: 100%;
3757
- min-height: var(--wf-input-min-height, 56px);
3758
- padding: var(--wf-spacing-4, 16px);
3759
- font-size: var(--wf-font-size-base, 1rem);
3760
- font-weight: 500;
3761
- font-family: inherit;
3762
- background-color: var(--wf-color-surface, #f3f3f5);
3763
- border: 1px solid var(--wf-color-border, #d4d4d4);
3764
- border-radius: var(--wf-radius-md, 8px);
3765
- color: var(--wf-color-text, #0a0a0a);
3766
- transition: border-color 150ms ease, box-shadow 150ms ease;
3767
- outline: none;
3768
- box-sizing: border-box;
3769
- }
3770
-
3771
- .wf-input::placeholder {
3772
- color: var(--wf-color-text-muted, #646464);
3773
- font-weight: 500;
3774
- }
3775
-
3776
- .wf-input:focus {
3777
- border-color: var(--wf-color-primary, #8040f0);
3778
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
3779
- }
3780
-
3781
- .wf-input:disabled {
3782
- opacity: 0.5;
3783
- cursor: not-allowed;
3784
- }
3785
-
3786
- .wf-input.wf-input-error {
3787
- border-color: var(--wf-color-error, #dc3545);
3788
- }
3789
-
3790
- .wf-input.wf-input-error:focus {
3791
- box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
3792
- }
3793
-
3794
- .wf-error-message {
3795
- font-size: var(--wf-font-size-sm, 0.875rem);
3796
- color: var(--wf-color-error, #dc3545);
3797
- }
3798
-
3799
- .wf-hint {
3800
- font-size: var(--wf-font-size-sm, 0.875rem);
3801
- color: var(--wf-color-text-muted, #646464);
3802
- }
3803
- `;
3804
- __decorateClass$6([
3805
- n2({ type: String })
3806
- ], WfEmail.prototype, "name", 2);
3807
- __decorateClass$6([
3808
- n2({ type: String })
3809
- ], WfEmail.prototype, "label", 2);
3810
- __decorateClass$6([
3341
+ __decorateClass$5([
3811
3342
  n2({ type: String })
3812
3343
  ], WfEmail.prototype, "placeholder", 2);
3813
- __decorateClass$6([
3814
- n2({ type: Boolean })
3815
- ], WfEmail.prototype, "required", 2);
3816
- __decorateClass$6([
3344
+ __decorateClass$5([
3817
3345
  n2({ type: Boolean, attribute: "work-email" })
3818
3346
  ], WfEmail.prototype, "workEmail", 2);
3819
- __decorateClass$6([
3347
+ __decorateClass$5([
3820
3348
  n2({ type: String, attribute: "blocked-domains" })
3821
3349
  ], WfEmail.prototype, "blockedDomains", 2);
3822
- __decorateClass$6([
3350
+ __decorateClass$5([
3823
3351
  n2({ type: String, attribute: "work-email-message" })
3824
3352
  ], WfEmail.prototype, "workEmailMessage", 2);
3825
- __decorateClass$6([
3353
+ __decorateClass$5([
3826
3354
  n2({ type: Boolean })
3827
3355
  ], WfEmail.prototype, "disabled", 2);
3828
- __decorateClass$6([
3829
- n2({ type: String })
3830
- ], WfEmail.prototype, "hint", 2);
3831
- __decorateClass$6([
3832
- r()
3833
- ], WfEmail.prototype, "_errorMessage", 2);
3834
- __decorateClass$6([
3835
- r()
3836
- ], WfEmail.prototype, "_value", 2);
3837
- WfEmail = __decorateClass$6([
3356
+ WfEmail = __decorateClass$5([
3838
3357
  t("wf-email")
3839
3358
  ], WfEmail);
3840
- var __defProp$5 = Object.defineProperty;
3841
- var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
3842
- var __decorateClass$5 = (decorators, target, key, kind) => {
3843
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$5(target, key) : target;
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;
3844
3363
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
3845
3364
  if (decorator = decorators[i2])
3846
3365
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
3847
- if (kind && result) __defProp$5(target, key, result);
3366
+ if (kind && result) __defProp$4(target, key, result);
3848
3367
  return result;
3849
3368
  };
3850
- let WfInput = class extends i {
3369
+ let WfInput = class extends FormInputBase {
3851
3370
  constructor() {
3852
3371
  super(...arguments);
3853
- this.name = "";
3854
- this.label = "";
3855
3372
  this.placeholder = "";
3856
3373
  this.type = "text";
3857
- this.required = false;
3858
3374
  this.patternMessage = "Invalid format";
3859
3375
  this.disabled = false;
3860
3376
  this.autocomplete = "";
3861
- this.hint = "";
3862
- this._errorMessage = "";
3863
- this._value = "";
3864
- this._validationActivated = false;
3865
- this._debounceTimer = null;
3866
- this._validators = [];
3867
- this._handleInput = (e2) => {
3868
- const target = e2.target;
3869
- this._value = target.value;
3870
- if (this._validationActivated) {
3871
- if (this._debounceTimer) {
3872
- clearTimeout(this._debounceTimer);
3873
- }
3874
- this._debounceTimer = setTimeout(() => {
3875
- this.validate();
3876
- }, 600);
3877
- }
3878
- this.dispatchEvent(
3879
- new CustomEvent("wf-change", {
3880
- detail: {
3881
- name: this.name,
3882
- value: this._value
3883
- },
3884
- bubbles: true,
3885
- composed: true
3886
- })
3887
- );
3888
- };
3889
- this._handleBlur = () => {
3890
- this.dispatchEvent(
3891
- new CustomEvent("wf-blur", {
3892
- detail: { name: this.name, value: this._value },
3893
- bubbles: true,
3894
- composed: true
3895
- })
3896
- );
3897
- };
3898
- this._handleFocus = () => {
3899
- this.dispatchEvent(
3900
- new CustomEvent("wf-focus", {
3901
- detail: { name: this.name },
3902
- bubbles: true,
3903
- composed: true
3904
- })
3905
- );
3906
- };
3907
3377
  }
3908
- connectedCallback() {
3909
- super.connectedCallback();
3910
- this._setupValidators();
3911
- }
3912
- updated(changedProperties) {
3913
- if (changedProperties.has("required") || changedProperties.has("minlength") || changedProperties.has("maxlength") || changedProperties.has("pattern")) {
3914
- this._setupValidators();
3915
- }
3378
+ // ============================================
3379
+ // Abstract Method Implementations
3380
+ // ============================================
3381
+ _getValidationTriggerProperties() {
3382
+ return ["required", "minlength", "maxlength", "pattern"];
3916
3383
  }
3917
3384
  _setupValidators() {
3918
3385
  this._validators = [];
@@ -3931,6 +3398,9 @@ let WfInput = class extends i {
3931
3398
  );
3932
3399
  }
3933
3400
  }
3401
+ // ============================================
3402
+ // Render
3403
+ // ============================================
3934
3404
  render() {
3935
3405
  return b`
3936
3406
  <div class="wf-field-container">
@@ -3949,238 +3419,56 @@ let WfInput = class extends i {
3949
3419
  placeholder="${this.placeholder}"
3950
3420
  .value="${this._value}"
3951
3421
  ?disabled="${this.disabled}"
3952
- ?required="${this.required}"
3953
- autocomplete="${this.autocomplete || "off"}"
3954
- data-testid="wf-input"
3955
- @input="${this._handleInput}"
3956
- @blur="${this._handleBlur}"
3957
- @focus="${this._handleFocus}"
3958
- />
3959
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
3960
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
3961
- ${this._errorMessage}
3962
- </span>
3963
- </div>
3964
- `;
3965
- }
3966
- // ============================================
3967
- // Public API
3968
- // ============================================
3969
- /**
3970
- * Get current value
3971
- */
3972
- get value() {
3973
- return this._value;
3974
- }
3975
- /**
3976
- * Set value
3977
- */
3978
- set value(val) {
3979
- this._value = val;
3980
- }
3981
- /**
3982
- * Add a custom validator
3983
- */
3984
- addValidator(validator) {
3985
- this._validators.push(validator);
3986
- }
3987
- /**
3988
- * Validate the field
3989
- */
3990
- async validate() {
3991
- this._validationActivated = true;
3992
- for (const validator of this._validators) {
3993
- try {
3994
- const result = await validator.validate(this._value);
3995
- if (!result.valid) {
3996
- this._errorMessage = result.error ?? validator.message ?? "Validation failed";
3997
- return false;
3998
- }
3999
- } catch (error) {
4000
- console.error("[WfInput] Validator error:", error);
4001
- this._errorMessage = "Validation error occurred";
4002
- return false;
4003
- }
4004
- }
4005
- this._errorMessage = "";
4006
- return true;
4007
- }
4008
- /**
4009
- * Check if field is valid (sync check)
4010
- */
4011
- get isValid() {
4012
- for (const validator of this._validators) {
4013
- const result = validator.validate(this._value);
4014
- if (result instanceof Promise) {
4015
- console.warn("[WfInput] Async validator called synchronously");
4016
- continue;
4017
- }
4018
- if (!result.valid) {
4019
- return false;
4020
- }
4021
- }
4022
- return true;
4023
- }
4024
- /**
4025
- * Show error message
4026
- */
4027
- showError(message) {
4028
- this._errorMessage = message;
4029
- }
4030
- /**
4031
- * Clear error message
4032
- */
4033
- clearError() {
4034
- this._errorMessage = "";
4035
- }
4036
- /**
4037
- * Focus the input
4038
- */
4039
- focus() {
4040
- const input = this.shadowRoot?.querySelector("input");
4041
- input?.focus();
4042
- }
4043
- /**
4044
- * Reset field to initial state
4045
- */
4046
- reset() {
4047
- this._value = "";
4048
- this._errorMessage = "";
4049
- this._validationActivated = false;
4050
- if (this._debounceTimer) {
4051
- clearTimeout(this._debounceTimer);
4052
- this._debounceTimer = null;
4053
- }
4054
- }
4055
- };
4056
- WfInput.styles = i$3`
4057
- :host {
4058
- display: block;
4059
- }
4060
-
4061
- :host([hidden]) {
4062
- display: none;
4063
- }
4064
-
4065
- .wf-field-container {
4066
- display: flex;
4067
- flex-direction: column;
4068
- gap: var(--wf-spacing-2, 8px);
4069
- }
4070
-
4071
- .wf-label {
4072
- font-size: var(--wf-font-size-sm, 0.875rem);
4073
- font-weight: 500;
4074
- color: var(--wf-color-text, #0a0a0a);
4075
- }
4076
-
4077
- .wf-label-required::after {
4078
- content: ' *';
4079
- color: var(--wf-color-error, #dc3545);
4080
- }
4081
-
4082
- .wf-input {
4083
- width: 100%;
4084
- min-height: var(--wf-input-min-height, 56px);
4085
- padding: var(--wf-spacing-4, 16px);
4086
- font-size: var(--wf-font-size-base, 1rem);
4087
- font-weight: 400;
4088
- font-family: inherit;
4089
- background-color: var(--wf-color-surface, #f3f3f5);
4090
- border: 1px solid var(--wf-color-border, #d4d4d4);
4091
- border-radius: var(--wf-radius-md, 8px);
4092
- color: var(--wf-color-text, #0a0a0a);
4093
- transition: border-color 150ms ease, box-shadow 150ms ease;
4094
- outline: none;
4095
- box-sizing: border-box;
4096
- }
4097
-
4098
- .wf-input::placeholder {
4099
- color: var(--wf-color-text-muted, #646464);
4100
- font-weight: 500;
4101
- }
4102
-
4103
- .wf-input:focus {
4104
- border-color: var(--wf-color-primary, #8040f0);
4105
- box-shadow: 0 0 0 3px rgba(128, 64, 240, 0.2);
4106
- }
4107
-
4108
- .wf-input:disabled {
4109
- opacity: 0.5;
4110
- cursor: not-allowed;
4111
- }
4112
-
4113
- .wf-input.wf-input-error {
4114
- border-color: var(--wf-color-error, #dc3545);
4115
- }
4116
-
4117
- .wf-input.wf-input-error:focus {
4118
- box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
4119
- }
4120
-
4121
- .wf-error-message {
4122
- font-size: var(--wf-font-size-sm, 0.875rem);
4123
- color: var(--wf-color-error, #dc3545);
4124
- }
4125
-
4126
- .wf-hint {
4127
- font-size: var(--wf-font-size-sm, 0.875rem);
4128
- color: var(--wf-color-text-muted, #646464);
4129
- }
4130
- `;
4131
- __decorateClass$5([
4132
- n2({ type: String })
4133
- ], WfInput.prototype, "name", 2);
4134
- __decorateClass$5([
4135
- n2({ type: String })
4136
- ], WfInput.prototype, "label", 2);
4137
- __decorateClass$5([
3422
+ ?required="${this.required}"
3423
+ autocomplete="${this.autocomplete || "off"}"
3424
+ data-testid="wf-input"
3425
+ @input="${this._handleInput}"
3426
+ @blur="${this._handleBlur}"
3427
+ @focus="${this._handleFocus}"
3428
+ />
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>
3433
+ </div>
3434
+ `;
3435
+ }
3436
+ };
3437
+ __decorateClass$4([
4138
3438
  n2({ type: String })
4139
3439
  ], WfInput.prototype, "placeholder", 2);
4140
- __decorateClass$5([
3440
+ __decorateClass$4([
4141
3441
  n2({ type: String })
4142
3442
  ], WfInput.prototype, "type", 2);
4143
- __decorateClass$5([
4144
- n2({ type: Boolean })
4145
- ], WfInput.prototype, "required", 2);
4146
- __decorateClass$5([
3443
+ __decorateClass$4([
4147
3444
  n2({ type: Number })
4148
3445
  ], WfInput.prototype, "minlength", 2);
4149
- __decorateClass$5([
3446
+ __decorateClass$4([
4150
3447
  n2({ type: Number })
4151
3448
  ], WfInput.prototype, "maxlength", 2);
4152
- __decorateClass$5([
3449
+ __decorateClass$4([
4153
3450
  n2({ type: String })
4154
3451
  ], WfInput.prototype, "pattern", 2);
4155
- __decorateClass$5([
3452
+ __decorateClass$4([
4156
3453
  n2({ type: String, attribute: "pattern-message" })
4157
3454
  ], WfInput.prototype, "patternMessage", 2);
4158
- __decorateClass$5([
3455
+ __decorateClass$4([
4159
3456
  n2({ type: Boolean })
4160
3457
  ], WfInput.prototype, "disabled", 2);
4161
- __decorateClass$5([
3458
+ __decorateClass$4([
4162
3459
  n2({ type: String })
4163
3460
  ], WfInput.prototype, "autocomplete", 2);
4164
- __decorateClass$5([
4165
- n2({ type: String })
4166
- ], WfInput.prototype, "hint", 2);
4167
- __decorateClass$5([
4168
- r()
4169
- ], WfInput.prototype, "_errorMessage", 2);
4170
- __decorateClass$5([
4171
- r()
4172
- ], WfInput.prototype, "_value", 2);
4173
- WfInput = __decorateClass$5([
3461
+ WfInput = __decorateClass$4([
4174
3462
  t("wf-input")
4175
3463
  ], WfInput);
4176
- var __defProp$4 = Object.defineProperty;
4177
- var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
4178
- var __decorateClass$4 = (decorators, target, key, kind) => {
4179
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
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;
4180
3468
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
4181
3469
  if (decorator = decorators[i2])
4182
3470
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
4183
- if (kind && result) __defProp$4(target, key, result);
3471
+ if (kind && result) __defProp$3(target, key, result);
4184
3472
  return result;
4185
3473
  };
4186
3474
  let WfNumber = class extends WfInput {
@@ -4266,113 +3554,49 @@ let WfNumber = class extends WfInput {
4266
3554
  this._value = String(val);
4267
3555
  }
4268
3556
  };
4269
- WfNumber.styles = [
4270
- WfInput.styles,
4271
- i$3`
4272
- /* Hide number input spinners */
4273
- .wf-input::-webkit-outer-spin-button,
4274
- .wf-input::-webkit-inner-spin-button {
4275
- -webkit-appearance: none;
4276
- margin: 0;
4277
- }
4278
-
4279
- .wf-input[type='number'] {
4280
- -moz-appearance: textfield;
4281
- }
4282
- `
4283
- ];
4284
- __decorateClass$4([
3557
+ __decorateClass$3([
4285
3558
  n2({ type: Number })
4286
3559
  ], WfNumber.prototype, "min", 2);
4287
- __decorateClass$4([
3560
+ __decorateClass$3([
4288
3561
  n2({ type: Number })
4289
3562
  ], WfNumber.prototype, "max", 2);
4290
- __decorateClass$4([
3563
+ __decorateClass$3([
4291
3564
  n2({ type: Number })
4292
3565
  ], WfNumber.prototype, "step", 2);
4293
- WfNumber = __decorateClass$4([
3566
+ WfNumber = __decorateClass$3([
4294
3567
  t("wf-number")
4295
3568
  ], WfNumber);
4296
- var __defProp$3 = Object.defineProperty;
4297
- var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
4298
- var __decorateClass$3 = (decorators, target, key, kind) => {
4299
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
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;
4300
3573
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
4301
3574
  if (decorator = decorators[i2])
4302
3575
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
4303
- if (kind && result) __defProp$3(target, key, result);
3576
+ if (kind && result) __defProp$2(target, key, result);
4304
3577
  return result;
4305
3578
  };
4306
- let WfTextarea = class extends i {
3579
+ let WfTextarea = class extends FormInputBase {
4307
3580
  constructor() {
4308
3581
  super(...arguments);
4309
- this.name = "";
4310
- this.label = "";
4311
3582
  this.placeholder = "";
4312
3583
  this.rows = 4;
4313
- this.required = false;
4314
3584
  this.disabled = false;
4315
3585
  this.showCount = false;
4316
- this.hint = "";
4317
- this._errorMessage = "";
4318
- this._value = "";
4319
- this._validationActivated = false;
4320
- this._debounceTimer = null;
4321
- this._validators = [];
4322
- this._handleInput = (e2) => {
4323
- const target = e2.target;
4324
- this._value = target.value;
4325
- if (this._validationActivated) {
4326
- if (this._debounceTimer) {
4327
- clearTimeout(this._debounceTimer);
4328
- }
4329
- this._debounceTimer = setTimeout(() => {
4330
- this.validate();
4331
- }, 600);
4332
- }
4333
- this.dispatchEvent(
4334
- new CustomEvent("wf-change", {
4335
- detail: {
4336
- name: this.name,
4337
- value: this._value
4338
- },
4339
- bubbles: true,
4340
- composed: true
4341
- })
4342
- );
4343
- };
4344
- this._handleBlur = () => {
4345
- this.dispatchEvent(
4346
- new CustomEvent("wf-blur", {
4347
- detail: { name: this.name, value: this._value },
4348
- bubbles: true,
4349
- composed: true
4350
- })
4351
- );
4352
- };
4353
- this._handleFocus = () => {
4354
- this.dispatchEvent(
4355
- new CustomEvent("wf-focus", {
4356
- detail: { name: this.name },
4357
- bubbles: true,
4358
- composed: true
4359
- })
4360
- );
4361
- };
4362
3586
  this._handleKeydown = (e2) => {
4363
3587
  if (e2.key === "Enter") {
4364
3588
  e2.stopPropagation();
4365
3589
  }
4366
3590
  };
4367
3591
  }
4368
- connectedCallback() {
4369
- super.connectedCallback();
4370
- this._setupValidators();
3592
+ // ============================================
3593
+ // Abstract Method Implementations
3594
+ // ============================================
3595
+ _getValidationTriggerProperties() {
3596
+ return ["required", "minlength", "maxlength"];
4371
3597
  }
4372
- updated(changedProperties) {
4373
- if (changedProperties.has("required") || changedProperties.has("minlength") || changedProperties.has("maxlength")) {
4374
- this._setupValidators();
4375
- }
3598
+ _getFocusableSelector() {
3599
+ return "textarea";
4376
3600
  }
4377
3601
  _setupValidators() {
4378
3602
  this._validators = [];
@@ -4386,6 +3610,9 @@ let WfTextarea = class extends i {
4386
3610
  this._validators.push(ValidationController.maxLength(this.maxlength));
4387
3611
  }
4388
3612
  }
3613
+ // ============================================
3614
+ // Render
3615
+ // ============================================
4389
3616
  render() {
4390
3617
  const charCount = this._value.length;
4391
3618
  const isAtLimit = this.maxlength !== void 0 && charCount >= this.maxlength;
@@ -4408,237 +3635,48 @@ let WfTextarea = class extends i {
4408
3635
  ?disabled="${this.disabled}"
4409
3636
  ?required="${this.required}"
4410
3637
  maxlength="${this.maxlength ?? ""}"
4411
- data-testid="wf-textarea"
4412
- @input="${this._handleInput}"
4413
- @blur="${this._handleBlur}"
4414
- @focus="${this._handleFocus}"
4415
- @keydown="${this._handleKeydown}"
4416
- ></textarea>
4417
- ${this.showCount && this.maxlength ? b`<span class="wf-char-count ${isAtLimit ? "wf-char-limit" : ""}" data-testid="wf-counter">
4418
- ${charCount}/${this.maxlength}
4419
- </span>` : ""}
4420
- ${this.hint && !this._errorMessage ? b`<span class="wf-hint">${this.hint}</span>` : ""}
4421
- <span class="wf-error-message" role="alert" aria-live="polite" data-testid="wf-error">
4422
- ${this._errorMessage}
4423
- </span>
4424
- </div>
4425
- `;
4426
- }
4427
- // ============================================
4428
- // Public API
4429
- // ============================================
4430
- /**
4431
- * Get current value
4432
- */
4433
- get value() {
4434
- return this._value;
4435
- }
4436
- /**
4437
- * Set value
4438
- */
4439
- set value(val) {
4440
- this._value = val;
4441
- }
4442
- /**
4443
- * Add a custom validator
4444
- */
4445
- addValidator(validator) {
4446
- this._validators.push(validator);
4447
- }
4448
- /**
4449
- * Validate the field
4450
- */
4451
- async validate() {
4452
- this._validationActivated = true;
4453
- for (const validator of this._validators) {
4454
- try {
4455
- const result = await validator.validate(this._value);
4456
- if (!result.valid) {
4457
- this._errorMessage = result.error ?? validator.message ?? "Validation failed";
4458
- return false;
4459
- }
4460
- } catch (error) {
4461
- console.error("[WfTextarea] Validator error:", error);
4462
- this._errorMessage = "Validation error occurred";
4463
- return false;
4464
- }
4465
- }
4466
- this._errorMessage = "";
4467
- return true;
4468
- }
4469
- /**
4470
- * Check if field is valid (sync check)
4471
- */
4472
- get isValid() {
4473
- for (const validator of this._validators) {
4474
- const result = validator.validate(this._value);
4475
- if (result instanceof Promise) {
4476
- console.warn("[WfTextarea] Async validator called synchronously");
4477
- continue;
4478
- }
4479
- if (!result.valid) {
4480
- return false;
4481
- }
4482
- }
4483
- return true;
4484
- }
4485
- /**
4486
- * Show error message
4487
- */
4488
- showError(message) {
4489
- this._errorMessage = message;
4490
- }
4491
- /**
4492
- * Clear error message
4493
- */
4494
- clearError() {
4495
- this._errorMessage = "";
4496
- }
4497
- /**
4498
- * Focus the textarea
4499
- */
4500
- focus() {
4501
- const textarea = this.shadowRoot?.querySelector("textarea");
4502
- textarea?.focus();
4503
- }
4504
- /**
4505
- * Reset field to initial state
4506
- */
4507
- reset() {
4508
- this._value = "";
4509
- this._errorMessage = "";
4510
- this._validationActivated = false;
4511
- if (this._debounceTimer) {
4512
- clearTimeout(this._debounceTimer);
4513
- this._debounceTimer = null;
4514
- }
4515
- }
4516
- };
4517
- WfTextarea.styles = i$3`
4518
- :host {
4519
- display: block;
4520
- }
4521
-
4522
- :host([hidden]) {
4523
- display: none;
4524
- }
4525
-
4526
- .wf-field-container {
4527
- display: flex;
4528
- flex-direction: column;
4529
- gap: var(--wf-spacing-2, 8px);
4530
- }
4531
-
4532
- .wf-label {
4533
- font-size: var(--wf-font-size-sm, 0.875rem);
4534
- font-weight: 500;
4535
- color: var(--wf-color-text, #212529);
4536
- }
4537
-
4538
- .wf-label-required::after {
4539
- content: ' *';
4540
- color: var(--wf-color-error, #dc3545);
4541
- }
4542
-
4543
- .wf-textarea {
4544
- width: 100%;
4545
- padding: var(--wf-spacing-4, 16px);
4546
- font-size: var(--wf-font-size-base, 1rem);
4547
- font-family: inherit;
4548
- background-color: var(--wf-color-surface, #f8f9fa);
4549
- border: 1.5px solid var(--wf-color-border, #e5e7eb);
4550
- border-radius: var(--wf-radius-lg, 12px);
4551
- color: var(--wf-color-text, #212529);
4552
- transition: border-color 150ms ease, box-shadow 150ms ease;
4553
- outline: none;
4554
- box-sizing: border-box;
4555
- resize: vertical;
4556
- min-height: 100px;
4557
- }
4558
-
4559
- .wf-textarea::placeholder {
4560
- color: var(--wf-color-text-muted, #6c757d);
4561
- }
4562
-
4563
- .wf-textarea:focus {
4564
- border-color: var(--wf-color-primary, #8b5cf6);
4565
- box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
4566
- }
4567
-
4568
- .wf-textarea:disabled {
4569
- opacity: 0.5;
4570
- cursor: not-allowed;
4571
- }
4572
-
4573
- .wf-textarea.wf-textarea-error {
4574
- border-color: var(--wf-color-error, #dc3545);
4575
- }
4576
-
4577
- .wf-textarea.wf-textarea-error:focus {
4578
- box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.2);
4579
- }
4580
-
4581
- .wf-error-message {
4582
- font-size: var(--wf-font-size-sm, 0.875rem);
4583
- color: var(--wf-color-error, #dc3545);
4584
- min-height: 20px;
4585
- }
4586
-
4587
- .wf-hint {
4588
- font-size: var(--wf-font-size-sm, 0.875rem);
4589
- color: var(--wf-color-text-muted, #6c757d);
4590
- }
4591
-
4592
- .wf-char-count {
4593
- font-size: var(--wf-font-size-sm, 0.875rem);
4594
- color: var(--wf-color-text-muted, #6c757d);
4595
- text-align: right;
4596
- }
4597
-
4598
- .wf-char-count.wf-char-limit {
4599
- color: var(--wf-color-error, #dc3545);
4600
- }
4601
- `;
4602
- __decorateClass$3([
4603
- n2({ type: String })
4604
- ], WfTextarea.prototype, "name", 2);
4605
- __decorateClass$3([
4606
- n2({ type: String })
4607
- ], WfTextarea.prototype, "label", 2);
4608
- __decorateClass$3([
3638
+ data-testid="wf-textarea"
3639
+ @input="${this._handleInput}"
3640
+ @blur="${this._handleBlur}"
3641
+ @focus="${this._handleFocus}"
3642
+ @keydown="${this._handleKeydown}"
3643
+ ></textarea>
3644
+ ${this.showCount && this.maxlength ? b`<span class="wf-char-count ${isAtLimit ? "wf-char-limit" : ""}" data-testid="wf-counter">
3645
+ ${charCount}/${this.maxlength}
3646
+ </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>
3651
+ </div>
3652
+ `;
3653
+ }
3654
+ };
3655
+ __decorateClass$2([
4609
3656
  n2({ type: String })
4610
3657
  ], WfTextarea.prototype, "placeholder", 2);
4611
- __decorateClass$3([
3658
+ __decorateClass$2([
4612
3659
  n2({ type: Number })
4613
3660
  ], WfTextarea.prototype, "rows", 2);
4614
- __decorateClass$3([
4615
- n2({ type: Boolean })
4616
- ], WfTextarea.prototype, "required", 2);
4617
- __decorateClass$3([
3661
+ __decorateClass$2([
4618
3662
  n2({ type: Number })
4619
3663
  ], WfTextarea.prototype, "minlength", 2);
4620
- __decorateClass$3([
3664
+ __decorateClass$2([
4621
3665
  n2({ type: Number })
4622
3666
  ], WfTextarea.prototype, "maxlength", 2);
4623
- __decorateClass$3([
3667
+ __decorateClass$2([
4624
3668
  n2({ type: Boolean })
4625
3669
  ], WfTextarea.prototype, "disabled", 2);
4626
- __decorateClass$3([
3670
+ __decorateClass$2([
4627
3671
  n2({ type: Boolean, attribute: "show-count" })
4628
3672
  ], WfTextarea.prototype, "showCount", 2);
4629
- __decorateClass$3([
4630
- n2({ type: String })
4631
- ], WfTextarea.prototype, "hint", 2);
4632
- __decorateClass$3([
4633
- r()
4634
- ], WfTextarea.prototype, "_errorMessage", 2);
4635
- __decorateClass$3([
4636
- r()
4637
- ], WfTextarea.prototype, "_value", 2);
4638
- WfTextarea = __decorateClass$3([
3673
+ WfTextarea = __decorateClass$2([
4639
3674
  t("wf-textarea")
4640
3675
  ], WfTextarea);
4641
3676
  function init(config) {
3677
+ console.warn(
3678
+ '[WizardForm] init() is deprecated. Use the event-based API instead:\n form.addEventListener("wf:submit", (e) => { ... });\n form.addEventListener("wf:success", (e) => { ... });\nSee https://github.com/atomicwork/aw-wizard-forms for migration guide.'
3679
+ );
4642
3680
  const container = typeof config.container === "string" ? document.querySelector(config.container) : config.container;
4643
3681
  if (!container) {
4644
3682
  throw new Error(`[WizardForm] Container not found: ${config.container}`);
@@ -4837,207 +3875,6 @@ function init(config) {
4837
3875
  return instance;
4838
3876
  }
4839
3877
  const init_default = { init };
4840
- var __defProp$2 = Object.defineProperty;
4841
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
4842
- var __decorateClass$2 = (decorators, target, key, kind) => {
4843
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
4844
- for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
4845
- if (decorator = decorators[i2])
4846
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
4847
- if (kind && result) __defProp$2(target, key, result);
4848
- return result;
4849
- };
4850
- const SPACING_SCALE = {
4851
- none: 0,
4852
- xs: 4,
4853
- sm: 8,
4854
- md: 16,
4855
- lg: 24,
4856
- xl: 32
4857
- };
4858
- let WfLayout = class extends i {
4859
- constructor() {
4860
- super(...arguments);
4861
- this.mode = "flex";
4862
- this.direction = "column";
4863
- this.gap = "none";
4864
- this.gapX = "";
4865
- this.gapY = "";
4866
- this.align = "stretch";
4867
- this.justify = "start";
4868
- this.padding = "none";
4869
- this.paddingX = "";
4870
- this.paddingY = "";
4871
- this.wrap = false;
4872
- this.width = "full";
4873
- this.columns = "auto";
4874
- this.minItemWidth = "200px";
4875
- }
4876
- /**
4877
- * Convert spacing value to pixels
4878
- */
4879
- _resolveSpacing(value) {
4880
- if (!value || value === "none") {
4881
- return "0";
4882
- }
4883
- if (value in SPACING_SCALE) {
4884
- return `${SPACING_SCALE[value]}px`;
4885
- }
4886
- const num = parseFloat(value);
4887
- if (!isNaN(num)) {
4888
- return `${num}px`;
4889
- }
4890
- return value;
4891
- }
4892
- /**
4893
- * Get computed gap-x value
4894
- */
4895
- _getGapX() {
4896
- return this._resolveSpacing(this.gapX || this.gap);
4897
- }
4898
- /**
4899
- * Get computed gap-y value
4900
- */
4901
- _getGapY() {
4902
- return this._resolveSpacing(this.gapY || this.gap);
4903
- }
4904
- /**
4905
- * Get computed padding values
4906
- */
4907
- _getPadding() {
4908
- const uniformPadding = this._resolveSpacing(this.padding);
4909
- const px = this.paddingX ? this._resolveSpacing(this.paddingX) : uniformPadding;
4910
- const py = this.paddingY ? this._resolveSpacing(this.paddingY) : uniformPadding;
4911
- return `${py} ${px}`;
4912
- }
4913
- /**
4914
- * Build inline styles based on properties
4915
- */
4916
- _buildStyles() {
4917
- const styles = [];
4918
- if (this.mode === "grid") {
4919
- styles.push("display: grid");
4920
- const cols = parseInt(this.columns, 10);
4921
- if (!isNaN(cols) && cols > 0) {
4922
- styles.push(`grid-template-columns: repeat(${cols}, 1fr)`);
4923
- } else {
4924
- styles.push(
4925
- `grid-template-columns: repeat(auto-fit, minmax(${this.minItemWidth}, 1fr))`
4926
- );
4927
- }
4928
- if (this.align !== "stretch") {
4929
- styles.push(`align-items: ${this.align}`);
4930
- }
4931
- if (this.justify !== "start") {
4932
- styles.push(`justify-content: ${this.justify}`);
4933
- }
4934
- } else {
4935
- styles.push("display: flex");
4936
- styles.push(`flex-direction: ${this.direction}`);
4937
- if (this.wrap) {
4938
- styles.push("flex-wrap: wrap");
4939
- }
4940
- if (this.align !== "stretch") {
4941
- styles.push(`align-items: ${this.align}`);
4942
- }
4943
- if (this.justify !== "start") {
4944
- styles.push(`justify-content: ${this.justify}`);
4945
- }
4946
- }
4947
- const gapX = this._getGapX();
4948
- const gapY = this._getGapY();
4949
- if (gapX !== "0" || gapY !== "0") {
4950
- styles.push(`column-gap: ${gapX}`);
4951
- styles.push(`row-gap: ${gapY}`);
4952
- }
4953
- const padding = this._getPadding();
4954
- if (padding !== "0 0") {
4955
- styles.push(`padding: ${padding}`);
4956
- }
4957
- return styles.join("; ");
4958
- }
4959
- render() {
4960
- return b`
4961
- <div
4962
- class="wf-layout wf-layout--width-${this.width}"
4963
- style="${this._buildStyles()}"
4964
- >
4965
- <slot></slot>
4966
- </div>
4967
- `;
4968
- }
4969
- };
4970
- WfLayout.styles = i$3`
4971
- :host {
4972
- display: block;
4973
- }
4974
-
4975
- :host([hidden]) {
4976
- display: none;
4977
- }
4978
-
4979
- .wf-layout {
4980
- box-sizing: border-box;
4981
- }
4982
-
4983
- /* Width behaviors */
4984
- .wf-layout--width-full {
4985
- width: 100%;
4986
- }
4987
-
4988
- .wf-layout--width-auto {
4989
- width: auto;
4990
- }
4991
-
4992
- .wf-layout--width-fit {
4993
- width: fit-content;
4994
- }
4995
- `;
4996
- __decorateClass$2([
4997
- n2({ type: String })
4998
- ], WfLayout.prototype, "mode", 2);
4999
- __decorateClass$2([
5000
- n2({ type: String })
5001
- ], WfLayout.prototype, "direction", 2);
5002
- __decorateClass$2([
5003
- n2({ type: String })
5004
- ], WfLayout.prototype, "gap", 2);
5005
- __decorateClass$2([
5006
- n2({ type: String, attribute: "gap-x" })
5007
- ], WfLayout.prototype, "gapX", 2);
5008
- __decorateClass$2([
5009
- n2({ type: String, attribute: "gap-y" })
5010
- ], WfLayout.prototype, "gapY", 2);
5011
- __decorateClass$2([
5012
- n2({ type: String })
5013
- ], WfLayout.prototype, "align", 2);
5014
- __decorateClass$2([
5015
- n2({ type: String })
5016
- ], WfLayout.prototype, "justify", 2);
5017
- __decorateClass$2([
5018
- n2({ type: String })
5019
- ], WfLayout.prototype, "padding", 2);
5020
- __decorateClass$2([
5021
- n2({ type: String, attribute: "padding-x" })
5022
- ], WfLayout.prototype, "paddingX", 2);
5023
- __decorateClass$2([
5024
- n2({ type: String, attribute: "padding-y" })
5025
- ], WfLayout.prototype, "paddingY", 2);
5026
- __decorateClass$2([
5027
- n2({ type: Boolean })
5028
- ], WfLayout.prototype, "wrap", 2);
5029
- __decorateClass$2([
5030
- n2({ type: String })
5031
- ], WfLayout.prototype, "width", 2);
5032
- __decorateClass$2([
5033
- n2({ type: String })
5034
- ], WfLayout.prototype, "columns", 2);
5035
- __decorateClass$2([
5036
- n2({ type: String, attribute: "min-item-width" })
5037
- ], WfLayout.prototype, "minItemWidth", 2);
5038
- WfLayout = __decorateClass$2([
5039
- t("wf-layout")
5040
- ], WfLayout);
5041
3878
  var __defProp$1 = Object.defineProperty;
5042
3879
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
5043
3880
  var __decorateClass$1 = (decorators, target, key, kind) => {
@@ -5059,10 +3896,24 @@ let WfProgress = class extends i {
5059
3896
  this._boundHandleStepChange = this._handleStepChange.bind(this);
5060
3897
  this._boundHandleSuccess = this._handleSuccess.bind(this);
5061
3898
  }
3899
+ /**
3900
+ * Disable Shadow DOM - render to Light DOM for external styling
3901
+ */
3902
+ createRenderRoot() {
3903
+ return this;
3904
+ }
5062
3905
  connectedCallback() {
5063
3906
  super.connectedCallback();
5064
3907
  requestAnimationFrame(() => {
5065
3908
  this._connectToWizard();
3909
+ if (this._wizard && this._totalSteps <= 1) {
3910
+ requestAnimationFrame(() => {
3911
+ if (this._wizard) {
3912
+ this._totalSteps = this._wizard.totalSteps || this._totalSteps;
3913
+ this._currentStep = this._wizard.currentStep || this._currentStep;
3914
+ }
3915
+ });
3916
+ }
5066
3917
  });
5067
3918
  }
5068
3919
  disconnectedCallback() {
@@ -5127,36 +3978,6 @@ let WfProgress = class extends i {
5127
3978
  return b`<div class="wf-progress" role="group" aria-label="Form progress">${segments}</div>`;
5128
3979
  }
5129
3980
  };
5130
- WfProgress.styles = i$3`
5131
- :host {
5132
- display: block;
5133
- }
5134
-
5135
- :host([hidden]) {
5136
- display: none;
5137
- }
5138
-
5139
- .wf-progress {
5140
- display: flex;
5141
- gap: var(--wf-spacing-4, 16px);
5142
- }
5143
-
5144
- .wf-progress-segment {
5145
- width: 32px;
5146
- height: 8px;
5147
- background-color: var(--wf-color-progress-inactive, rgba(217, 217, 217, 0.6));
5148
- border-radius: var(--wf-radius-full, 99px);
5149
- transition: background-color 300ms ease;
5150
- }
5151
-
5152
- .wf-progress-segment.completed {
5153
- background-color: var(--wf-color-progress-active, rgba(139, 139, 139, 0.6));
5154
- }
5155
-
5156
- .wf-progress-segment.active {
5157
- background-color: var(--wf-color-progress-active, rgba(139, 139, 139, 0.6));
5158
- }
5159
- `;
5160
3981
  __decorateClass$1([
5161
3982
  n2({ type: String })
5162
3983
  ], WfProgress.prototype, "for", 2);
@@ -5189,6 +4010,12 @@ let WfThankYou = class extends i {
5189
4010
  this.subtitle = "We've received your request.";
5190
4011
  this.hideIcon = false;
5191
4012
  }
4013
+ /**
4014
+ * Disable Shadow DOM - render to Light DOM for external styling
4015
+ */
4016
+ createRenderRoot() {
4017
+ return this;
4018
+ }
5192
4019
  render() {
5193
4020
  return b`
5194
4021
  ${!this.hideIcon ? b`
@@ -5217,53 +4044,6 @@ let WfThankYou = class extends i {
5217
4044
  `;
5218
4045
  }
5219
4046
  };
5220
- WfThankYou.styles = i$3`
5221
- :host {
5222
- display: block;
5223
- text-align: center;
5224
- padding: var(--wf-spacing-8, 48px) var(--wf-spacing-4, 24px);
5225
- }
5226
-
5227
- :host([hidden]) {
5228
- display: none;
5229
- }
5230
-
5231
- .wf-thank-you-icon {
5232
- width: 72px;
5233
- height: 72px;
5234
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
5235
- border-radius: 50%;
5236
- display: flex;
5237
- align-items: center;
5238
- justify-content: center;
5239
- margin: 0 auto var(--wf-spacing-4, 24px);
5240
- box-shadow: 0 10px 25px -5px rgba(16, 185, 129, 0.4);
5241
- }
5242
-
5243
- .wf-thank-you-icon svg {
5244
- width: 36px;
5245
- height: 36px;
5246
- color: white;
5247
- }
5248
-
5249
- .wf-thank-you-title {
5250
- font-size: 28px;
5251
- font-weight: 700;
5252
- color: var(--wf-color-text, #1e293b);
5253
- margin: 0 0 12px 0;
5254
- }
5255
-
5256
- .wf-thank-you-subtitle {
5257
- font-size: 16px;
5258
- color: var(--wf-color-text-muted, #64748b);
5259
- margin: 0 0 24px 0;
5260
- line-height: 1.6;
5261
- }
5262
-
5263
- ::slotted([slot="footer"]) {
5264
- margin-top: var(--wf-spacing-4, 24px);
5265
- }
5266
- `;
5267
4047
  __decorateClass([
5268
4048
  n2({ type: String })
5269
4049
  ], WfThankYou.prototype, "title", 2);
@@ -5276,6 +4056,21 @@ __decorateClass([
5276
4056
  WfThankYou = __decorateClass([
5277
4057
  t("wf-thank-you")
5278
4058
  ], WfThankYou);
4059
+ 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,#d9d9d999);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,#8b8b8b99)}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,#d9d9d999);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,#8b8b8b99)}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}`;
4060
+ function injectGlobalStyles() {
4061
+ if (typeof document === "undefined") {
4062
+ return;
4063
+ }
4064
+ const STYLE_ID = "wf-global-styles";
4065
+ if (document.getElementById(STYLE_ID)) {
4066
+ return;
4067
+ }
4068
+ const style = document.createElement("style");
4069
+ style.id = STYLE_ID;
4070
+ style.textContent = GLOBAL_STYLES;
4071
+ document.head.appendChild(style);
4072
+ }
4073
+ injectGlobalStyles();
5279
4074
  export {
5280
4075
  DEFAULT_BLOCKED_DOMAINS,
5281
4076
  FormStateController,