@almadar/ui 4.29.0 → 4.29.1

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.
@@ -182,7 +182,7 @@ var init_types = __esm({
182
182
  }
183
183
  });
184
184
 
185
- // node_modules/clsx/dist/clsx.mjs
185
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
186
186
  function r(e) {
187
187
  var t, f, n = "";
188
188
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -197,11 +197,11 @@ function clsx() {
197
197
  return n;
198
198
  }
199
199
  var init_clsx = __esm({
200
- "node_modules/clsx/dist/clsx.mjs"() {
200
+ "node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs"() {
201
201
  }
202
202
  });
203
203
 
204
- // node_modules/tailwind-merge/dist/bundle-mjs.mjs
204
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
205
205
  function twJoin() {
206
206
  let index = 0;
207
207
  let argument;
@@ -245,7 +245,7 @@ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
245
245
  }
246
246
  var CLASS_PART_SEPARATOR, createClassGroupUtils, getGroupRecursive, arbitraryPropertyRegex, getGroupIdForArbitraryProperty, createClassMap, processClassesRecursively, getPart, isThemeGetter, getPrefixedClassGroupEntries, createLruCache, IMPORTANT_MODIFIER, createParseClassName, sortModifiers, createConfigUtils, SPLIT_CLASSES_REGEX, mergeClassList, toValue, fromTheme, arbitraryValueRegex, fractionRegex, stringLengths, tshirtUnitRegex, lengthUnitRegex, colorFunctionRegex, shadowRegex, imageRegex, isLength, isArbitraryLength, isNumber, isArbitraryNumber, isInteger, isPercent, isArbitraryValue, isTshirtSize, sizeLabels, isArbitrarySize, isArbitraryPosition, imageLabels, isArbitraryImage, isArbitraryShadow, isAny, getIsArbitraryValue, isLengthOnly, isNever, isShadow, isImage, getDefaultConfig, twMerge;
247
247
  var init_bundle_mjs = __esm({
248
- "node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
248
+ "node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
249
249
  CLASS_PART_SEPARATOR = "-";
250
250
  createClassGroupUtils = (config) => {
251
251
  const classMap = createClassMap(config);
@@ -12838,9 +12838,9 @@ var init_ScaledDiagram = __esm({
12838
12838
  }
12839
12839
  });
12840
12840
 
12841
- // node_modules/katex/dist/katex.min.css
12841
+ // node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css
12842
12842
  var init_katex_min = __esm({
12843
- "node_modules/katex/dist/katex.min.css"() {
12843
+ "node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css"() {
12844
12844
  }
12845
12845
  });
12846
12846
  var MarkdownContent;
@@ -29334,6 +29334,8 @@ var init_Form = __esm({
29334
29334
  const [collapsedSections, setCollapsedSections] = React118__namespace.default.useState(
29335
29335
  /* @__PURE__ */ new Set()
29336
29336
  );
29337
+ const [submitError, setSubmitError] = React118__namespace.default.useState(null);
29338
+ const formRef = React118__namespace.default.useRef(null);
29337
29339
  const formMode = props.mode;
29338
29340
  const mountedRef = React118__namespace.default.useRef(false);
29339
29341
  if (!mountedRef.current) {
@@ -29459,6 +29461,7 @@ var init_Form = __esm({
29459
29461
  };
29460
29462
  const handleSubmit = (e) => {
29461
29463
  e.preventDefault();
29464
+ setSubmitError(null);
29462
29465
  debug("forms", "submit-enter", {
29463
29466
  mode: formMode,
29464
29467
  submitEvent,
@@ -29476,6 +29479,37 @@ var init_Form = __esm({
29476
29479
  eventBus.emit(`UI:${onSubmit}`, payload);
29477
29480
  }
29478
29481
  };
29482
+ const handleInvalid = (e) => {
29483
+ const target = e.target;
29484
+ const fieldName = target.getAttribute("data-field-name") ?? target.name ?? "";
29485
+ const fieldMessage = target.validationMessage || "Invalid value";
29486
+ debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
29487
+ queueMicrotask(() => {
29488
+ const form = formRef.current;
29489
+ if (!form) return;
29490
+ const invalidEls = Array.from(
29491
+ form.querySelectorAll(
29492
+ ":invalid"
29493
+ )
29494
+ );
29495
+ if (invalidEls.length === 0) return;
29496
+ const missing = invalidEls.map(
29497
+ (el) => el.getAttribute("data-field-name") ?? el.name ?? ""
29498
+ );
29499
+ const messages = invalidEls.map((el) => ({
29500
+ field: el.getAttribute("data-field-name") ?? el.name ?? "",
29501
+ message: el.validationMessage
29502
+ }));
29503
+ const summary = missing.length === 1 ? `${missing[0]}: ${messages[0]?.message}` : `Please fix ${missing.length} fields: ${missing.join(", ")}`;
29504
+ setSubmitError(summary);
29505
+ eventBus.emit("UI:VALIDATION_FAILED", {
29506
+ submitEvent,
29507
+ missing,
29508
+ messages,
29509
+ summary
29510
+ });
29511
+ });
29512
+ };
29479
29513
  const handleCancel = () => {
29480
29514
  eventBus.emit(`UI:${cancelEvent}`);
29481
29515
  eventBus.emit("UI:CLOSE");
@@ -29579,7 +29613,8 @@ var init_Form = __esm({
29579
29613
  "data-field-name": fieldName,
29580
29614
  required: field.required,
29581
29615
  disabled: isLoading,
29582
- placeholder: field.placeholder
29616
+ placeholder: field.placeholder,
29617
+ pattern: field.pattern
29583
29618
  };
29584
29619
  switch (inputType) {
29585
29620
  case "checkbox":
@@ -29675,7 +29710,9 @@ var init_Form = __esm({
29675
29710
  ...commonProps,
29676
29711
  type: "email",
29677
29712
  value: String(currentValue),
29678
- onChange: (e) => handleChange(fieldName, e.target.value)
29713
+ onChange: (e) => handleChange(fieldName, e.target.value),
29714
+ minLength: field.min,
29715
+ maxLength: field.max
29679
29716
  }
29680
29717
  );
29681
29718
  case "url":
@@ -29685,7 +29722,9 @@ var init_Form = __esm({
29685
29722
  ...commonProps,
29686
29723
  type: "url",
29687
29724
  value: String(currentValue),
29688
- onChange: (e) => handleChange(fieldName, e.target.value)
29725
+ onChange: (e) => handleChange(fieldName, e.target.value),
29726
+ minLength: field.min,
29727
+ maxLength: field.max
29689
29728
  }
29690
29729
  );
29691
29730
  case "password":
@@ -29695,7 +29734,9 @@ var init_Form = __esm({
29695
29734
  ...commonProps,
29696
29735
  type: "password",
29697
29736
  value: String(currentValue),
29698
- onChange: (e) => handleChange(fieldName, e.target.value)
29737
+ onChange: (e) => handleChange(fieldName, e.target.value),
29738
+ minLength: field.min,
29739
+ maxLength: field.max
29699
29740
  }
29700
29741
  );
29701
29742
  case "text":
@@ -29708,8 +29749,7 @@ var init_Form = __esm({
29708
29749
  value: String(currentValue),
29709
29750
  onChange: (e) => handleChange(fieldName, e.target.value),
29710
29751
  minLength: field.min,
29711
- maxLength: field.max,
29712
- pattern: field.pattern
29752
+ maxLength: field.max
29713
29753
  }
29714
29754
  );
29715
29755
  }
@@ -29717,12 +29757,14 @@ var init_Form = __esm({
29717
29757
  return /* @__PURE__ */ jsxRuntime.jsxs(
29718
29758
  "form",
29719
29759
  {
29720
- noValidate: true,
29760
+ ref: formRef,
29721
29761
  "data-pattern": "form-section",
29722
29762
  className: cn(layoutStyles[layout], gapStyles8[gap], className),
29723
29763
  onSubmit: handleSubmit,
29764
+ onInvalid: handleInvalid,
29724
29765
  ...props,
29725
29766
  children: [
29767
+ submitError && /* @__PURE__ */ jsxRuntime.jsx(Alert, { variant: "error", className: "mb-4", children: submitError }),
29726
29768
  error && /* @__PURE__ */ jsxRuntime.jsx(Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
29727
29769
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
29728
29770
  schemaFields,
@@ -49603,6 +49645,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49603
49645
  }
49604
49646
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
49605
49647
  const unsubscribes = [];
49648
+ const subscribedBusKeys = /* @__PURE__ */ new Set();
49606
49649
  for (const binding of traitBindings) {
49607
49650
  const traitName = binding.trait.name;
49608
49651
  const orbitalName = orbitalsByTrait?.[traitName];
@@ -49613,6 +49656,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49613
49656
  continue;
49614
49657
  }
49615
49658
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
49659
+ if (subscribedBusKeys.has(selfBusKey)) continue;
49660
+ subscribedBusKeys.add(selfBusKey);
49616
49661
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
49617
49662
  const unsub = eventBus.on(selfBusKey, (event) => {
49618
49663
  if (event.source && event.source.dispatched) {
@@ -1,4 +1,4 @@
1
- /* node_modules/katex/dist/katex.min.css */
1
+ /* node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css */
2
2
  @font-face {
3
3
  font-display: block;
4
4
  font-family: KaTeX_AMS;
package/dist/avl/index.js CHANGED
@@ -136,7 +136,7 @@ var init_types = __esm({
136
136
  }
137
137
  });
138
138
 
139
- // node_modules/clsx/dist/clsx.mjs
139
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
140
140
  function r(e) {
141
141
  var t, f, n = "";
142
142
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -151,11 +151,11 @@ function clsx() {
151
151
  return n;
152
152
  }
153
153
  var init_clsx = __esm({
154
- "node_modules/clsx/dist/clsx.mjs"() {
154
+ "node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs"() {
155
155
  }
156
156
  });
157
157
 
158
- // node_modules/tailwind-merge/dist/bundle-mjs.mjs
158
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
159
159
  function twJoin() {
160
160
  let index = 0;
161
161
  let argument;
@@ -199,7 +199,7 @@ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
199
199
  }
200
200
  var CLASS_PART_SEPARATOR, createClassGroupUtils, getGroupRecursive, arbitraryPropertyRegex, getGroupIdForArbitraryProperty, createClassMap, processClassesRecursively, getPart, isThemeGetter, getPrefixedClassGroupEntries, createLruCache, IMPORTANT_MODIFIER, createParseClassName, sortModifiers, createConfigUtils, SPLIT_CLASSES_REGEX, mergeClassList, toValue, fromTheme, arbitraryValueRegex, fractionRegex, stringLengths, tshirtUnitRegex, lengthUnitRegex, colorFunctionRegex, shadowRegex, imageRegex, isLength, isArbitraryLength, isNumber, isArbitraryNumber, isInteger, isPercent, isArbitraryValue, isTshirtSize, sizeLabels, isArbitrarySize, isArbitraryPosition, imageLabels, isArbitraryImage, isArbitraryShadow, isAny, getIsArbitraryValue, isLengthOnly, isNever, isShadow, isImage, getDefaultConfig, twMerge;
201
201
  var init_bundle_mjs = __esm({
202
- "node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
202
+ "node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
203
203
  CLASS_PART_SEPARATOR = "-";
204
204
  createClassGroupUtils = (config) => {
205
205
  const classMap = createClassMap(config);
@@ -12792,9 +12792,9 @@ var init_ScaledDiagram = __esm({
12792
12792
  }
12793
12793
  });
12794
12794
 
12795
- // node_modules/katex/dist/katex.min.css
12795
+ // node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css
12796
12796
  var init_katex_min = __esm({
12797
- "node_modules/katex/dist/katex.min.css"() {
12797
+ "node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css"() {
12798
12798
  }
12799
12799
  });
12800
12800
  var MarkdownContent;
@@ -29288,6 +29288,8 @@ var init_Form = __esm({
29288
29288
  const [collapsedSections, setCollapsedSections] = React118__default.useState(
29289
29289
  /* @__PURE__ */ new Set()
29290
29290
  );
29291
+ const [submitError, setSubmitError] = React118__default.useState(null);
29292
+ const formRef = React118__default.useRef(null);
29291
29293
  const formMode = props.mode;
29292
29294
  const mountedRef = React118__default.useRef(false);
29293
29295
  if (!mountedRef.current) {
@@ -29413,6 +29415,7 @@ var init_Form = __esm({
29413
29415
  };
29414
29416
  const handleSubmit = (e) => {
29415
29417
  e.preventDefault();
29418
+ setSubmitError(null);
29416
29419
  debug("forms", "submit-enter", {
29417
29420
  mode: formMode,
29418
29421
  submitEvent,
@@ -29430,6 +29433,37 @@ var init_Form = __esm({
29430
29433
  eventBus.emit(`UI:${onSubmit}`, payload);
29431
29434
  }
29432
29435
  };
29436
+ const handleInvalid = (e) => {
29437
+ const target = e.target;
29438
+ const fieldName = target.getAttribute("data-field-name") ?? target.name ?? "";
29439
+ const fieldMessage = target.validationMessage || "Invalid value";
29440
+ debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
29441
+ queueMicrotask(() => {
29442
+ const form = formRef.current;
29443
+ if (!form) return;
29444
+ const invalidEls = Array.from(
29445
+ form.querySelectorAll(
29446
+ ":invalid"
29447
+ )
29448
+ );
29449
+ if (invalidEls.length === 0) return;
29450
+ const missing = invalidEls.map(
29451
+ (el) => el.getAttribute("data-field-name") ?? el.name ?? ""
29452
+ );
29453
+ const messages = invalidEls.map((el) => ({
29454
+ field: el.getAttribute("data-field-name") ?? el.name ?? "",
29455
+ message: el.validationMessage
29456
+ }));
29457
+ const summary = missing.length === 1 ? `${missing[0]}: ${messages[0]?.message}` : `Please fix ${missing.length} fields: ${missing.join(", ")}`;
29458
+ setSubmitError(summary);
29459
+ eventBus.emit("UI:VALIDATION_FAILED", {
29460
+ submitEvent,
29461
+ missing,
29462
+ messages,
29463
+ summary
29464
+ });
29465
+ });
29466
+ };
29433
29467
  const handleCancel = () => {
29434
29468
  eventBus.emit(`UI:${cancelEvent}`);
29435
29469
  eventBus.emit("UI:CLOSE");
@@ -29533,7 +29567,8 @@ var init_Form = __esm({
29533
29567
  "data-field-name": fieldName,
29534
29568
  required: field.required,
29535
29569
  disabled: isLoading,
29536
- placeholder: field.placeholder
29570
+ placeholder: field.placeholder,
29571
+ pattern: field.pattern
29537
29572
  };
29538
29573
  switch (inputType) {
29539
29574
  case "checkbox":
@@ -29629,7 +29664,9 @@ var init_Form = __esm({
29629
29664
  ...commonProps,
29630
29665
  type: "email",
29631
29666
  value: String(currentValue),
29632
- onChange: (e) => handleChange(fieldName, e.target.value)
29667
+ onChange: (e) => handleChange(fieldName, e.target.value),
29668
+ minLength: field.min,
29669
+ maxLength: field.max
29633
29670
  }
29634
29671
  );
29635
29672
  case "url":
@@ -29639,7 +29676,9 @@ var init_Form = __esm({
29639
29676
  ...commonProps,
29640
29677
  type: "url",
29641
29678
  value: String(currentValue),
29642
- onChange: (e) => handleChange(fieldName, e.target.value)
29679
+ onChange: (e) => handleChange(fieldName, e.target.value),
29680
+ minLength: field.min,
29681
+ maxLength: field.max
29643
29682
  }
29644
29683
  );
29645
29684
  case "password":
@@ -29649,7 +29688,9 @@ var init_Form = __esm({
29649
29688
  ...commonProps,
29650
29689
  type: "password",
29651
29690
  value: String(currentValue),
29652
- onChange: (e) => handleChange(fieldName, e.target.value)
29691
+ onChange: (e) => handleChange(fieldName, e.target.value),
29692
+ minLength: field.min,
29693
+ maxLength: field.max
29653
29694
  }
29654
29695
  );
29655
29696
  case "text":
@@ -29662,8 +29703,7 @@ var init_Form = __esm({
29662
29703
  value: String(currentValue),
29663
29704
  onChange: (e) => handleChange(fieldName, e.target.value),
29664
29705
  minLength: field.min,
29665
- maxLength: field.max,
29666
- pattern: field.pattern
29706
+ maxLength: field.max
29667
29707
  }
29668
29708
  );
29669
29709
  }
@@ -29671,12 +29711,14 @@ var init_Form = __esm({
29671
29711
  return /* @__PURE__ */ jsxs(
29672
29712
  "form",
29673
29713
  {
29674
- noValidate: true,
29714
+ ref: formRef,
29675
29715
  "data-pattern": "form-section",
29676
29716
  className: cn(layoutStyles[layout], gapStyles8[gap], className),
29677
29717
  onSubmit: handleSubmit,
29718
+ onInvalid: handleInvalid,
29678
29719
  ...props,
29679
29720
  children: [
29721
+ submitError && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: submitError }),
29680
29722
  error && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
29681
29723
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
29682
29724
  schemaFields,
@@ -49557,6 +49599,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49557
49599
  }
49558
49600
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
49559
49601
  const unsubscribes = [];
49602
+ const subscribedBusKeys = /* @__PURE__ */ new Set();
49560
49603
  for (const binding of traitBindings) {
49561
49604
  const traitName = binding.trait.name;
49562
49605
  const orbitalName = orbitalsByTrait?.[traitName];
@@ -49567,6 +49610,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49567
49610
  continue;
49568
49611
  }
49569
49612
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
49613
+ if (subscribedBusKeys.has(selfBusKey)) continue;
49614
+ subscribedBusKeys.add(selfBusKey);
49570
49615
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
49571
49616
  const unsub = eventBus.on(selfBusKey, (event) => {
49572
49617
  if (event.source && event.source.dispatched) {
@@ -8974,9 +8974,9 @@ var init_ScaledDiagram = __esm({
8974
8974
  }
8975
8975
  });
8976
8976
 
8977
- // node_modules/katex/dist/katex.min.css
8977
+ // node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css
8978
8978
  var init_katex_min = __esm({
8979
- "node_modules/katex/dist/katex.min.css"() {
8979
+ "node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css"() {
8980
8980
  }
8981
8981
  });
8982
8982
  exports.MarkdownContent = void 0;
@@ -27962,6 +27962,8 @@ var init_Form = __esm({
27962
27962
  const [collapsedSections, setCollapsedSections] = React109__namespace.default.useState(
27963
27963
  /* @__PURE__ */ new Set()
27964
27964
  );
27965
+ const [submitError, setSubmitError] = React109__namespace.default.useState(null);
27966
+ const formRef = React109__namespace.default.useRef(null);
27965
27967
  const formMode = props.mode;
27966
27968
  const mountedRef = React109__namespace.default.useRef(false);
27967
27969
  if (!mountedRef.current) {
@@ -28087,6 +28089,7 @@ var init_Form = __esm({
28087
28089
  };
28088
28090
  const handleSubmit = (e) => {
28089
28091
  e.preventDefault();
28092
+ setSubmitError(null);
28090
28093
  debug("forms", "submit-enter", {
28091
28094
  mode: formMode,
28092
28095
  submitEvent,
@@ -28104,6 +28107,37 @@ var init_Form = __esm({
28104
28107
  eventBus.emit(`UI:${onSubmit}`, payload);
28105
28108
  }
28106
28109
  };
28110
+ const handleInvalid = (e) => {
28111
+ const target = e.target;
28112
+ const fieldName = target.getAttribute("data-field-name") ?? target.name ?? "";
28113
+ const fieldMessage = target.validationMessage || "Invalid value";
28114
+ debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
28115
+ queueMicrotask(() => {
28116
+ const form = formRef.current;
28117
+ if (!form) return;
28118
+ const invalidEls = Array.from(
28119
+ form.querySelectorAll(
28120
+ ":invalid"
28121
+ )
28122
+ );
28123
+ if (invalidEls.length === 0) return;
28124
+ const missing = invalidEls.map(
28125
+ (el) => el.getAttribute("data-field-name") ?? el.name ?? ""
28126
+ );
28127
+ const messages = invalidEls.map((el) => ({
28128
+ field: el.getAttribute("data-field-name") ?? el.name ?? "",
28129
+ message: el.validationMessage
28130
+ }));
28131
+ const summary = missing.length === 1 ? `${missing[0]}: ${messages[0]?.message}` : `Please fix ${missing.length} fields: ${missing.join(", ")}`;
28132
+ setSubmitError(summary);
28133
+ eventBus.emit("UI:VALIDATION_FAILED", {
28134
+ submitEvent,
28135
+ missing,
28136
+ messages,
28137
+ summary
28138
+ });
28139
+ });
28140
+ };
28107
28141
  const handleCancel = () => {
28108
28142
  eventBus.emit(`UI:${cancelEvent}`);
28109
28143
  eventBus.emit("UI:CLOSE");
@@ -28207,7 +28241,8 @@ var init_Form = __esm({
28207
28241
  "data-field-name": fieldName,
28208
28242
  required: field.required,
28209
28243
  disabled: isLoading,
28210
- placeholder: field.placeholder
28244
+ placeholder: field.placeholder,
28245
+ pattern: field.pattern
28211
28246
  };
28212
28247
  switch (inputType) {
28213
28248
  case "checkbox":
@@ -28303,7 +28338,9 @@ var init_Form = __esm({
28303
28338
  ...commonProps,
28304
28339
  type: "email",
28305
28340
  value: String(currentValue),
28306
- onChange: (e) => handleChange(fieldName, e.target.value)
28341
+ onChange: (e) => handleChange(fieldName, e.target.value),
28342
+ minLength: field.min,
28343
+ maxLength: field.max
28307
28344
  }
28308
28345
  );
28309
28346
  case "url":
@@ -28313,7 +28350,9 @@ var init_Form = __esm({
28313
28350
  ...commonProps,
28314
28351
  type: "url",
28315
28352
  value: String(currentValue),
28316
- onChange: (e) => handleChange(fieldName, e.target.value)
28353
+ onChange: (e) => handleChange(fieldName, e.target.value),
28354
+ minLength: field.min,
28355
+ maxLength: field.max
28317
28356
  }
28318
28357
  );
28319
28358
  case "password":
@@ -28323,7 +28362,9 @@ var init_Form = __esm({
28323
28362
  ...commonProps,
28324
28363
  type: "password",
28325
28364
  value: String(currentValue),
28326
- onChange: (e) => handleChange(fieldName, e.target.value)
28365
+ onChange: (e) => handleChange(fieldName, e.target.value),
28366
+ minLength: field.min,
28367
+ maxLength: field.max
28327
28368
  }
28328
28369
  );
28329
28370
  case "text":
@@ -28336,8 +28377,7 @@ var init_Form = __esm({
28336
28377
  value: String(currentValue),
28337
28378
  onChange: (e) => handleChange(fieldName, e.target.value),
28338
28379
  minLength: field.min,
28339
- maxLength: field.max,
28340
- pattern: field.pattern
28380
+ maxLength: field.max
28341
28381
  }
28342
28382
  );
28343
28383
  }
@@ -28345,12 +28385,14 @@ var init_Form = __esm({
28345
28385
  return /* @__PURE__ */ jsxRuntime.jsxs(
28346
28386
  "form",
28347
28387
  {
28348
- noValidate: true,
28388
+ ref: formRef,
28349
28389
  "data-pattern": "form-section",
28350
28390
  className: cn(layoutStyles[layout], gapStyles8[gap], className),
28351
28391
  onSubmit: handleSubmit,
28392
+ onInvalid: handleInvalid,
28352
28393
  ...props,
28353
28394
  children: [
28395
+ submitError && /* @__PURE__ */ jsxRuntime.jsx(exports.Alert, { variant: "error", className: "mb-4", children: submitError }),
28354
28396
  error && /* @__PURE__ */ jsxRuntime.jsx(exports.Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
28355
28397
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
28356
28398
  schemaFields,
@@ -1,4 +1,4 @@
1
- /* node_modules/katex/dist/katex.min.css */
1
+ /* node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css */
2
2
  @font-face {
3
3
  font-display: block;
4
4
  font-family: KaTeX_AMS;
@@ -8929,9 +8929,9 @@ var init_ScaledDiagram = __esm({
8929
8929
  }
8930
8930
  });
8931
8931
 
8932
- // node_modules/katex/dist/katex.min.css
8932
+ // node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css
8933
8933
  var init_katex_min = __esm({
8934
- "node_modules/katex/dist/katex.min.css"() {
8934
+ "node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css"() {
8935
8935
  }
8936
8936
  });
8937
8937
  var MarkdownContent;
@@ -27917,6 +27917,8 @@ var init_Form = __esm({
27917
27917
  const [collapsedSections, setCollapsedSections] = React109__default.useState(
27918
27918
  /* @__PURE__ */ new Set()
27919
27919
  );
27920
+ const [submitError, setSubmitError] = React109__default.useState(null);
27921
+ const formRef = React109__default.useRef(null);
27920
27922
  const formMode = props.mode;
27921
27923
  const mountedRef = React109__default.useRef(false);
27922
27924
  if (!mountedRef.current) {
@@ -28042,6 +28044,7 @@ var init_Form = __esm({
28042
28044
  };
28043
28045
  const handleSubmit = (e) => {
28044
28046
  e.preventDefault();
28047
+ setSubmitError(null);
28045
28048
  debug("forms", "submit-enter", {
28046
28049
  mode: formMode,
28047
28050
  submitEvent,
@@ -28059,6 +28062,37 @@ var init_Form = __esm({
28059
28062
  eventBus.emit(`UI:${onSubmit}`, payload);
28060
28063
  }
28061
28064
  };
28065
+ const handleInvalid = (e) => {
28066
+ const target = e.target;
28067
+ const fieldName = target.getAttribute("data-field-name") ?? target.name ?? "";
28068
+ const fieldMessage = target.validationMessage || "Invalid value";
28069
+ debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
28070
+ queueMicrotask(() => {
28071
+ const form = formRef.current;
28072
+ if (!form) return;
28073
+ const invalidEls = Array.from(
28074
+ form.querySelectorAll(
28075
+ ":invalid"
28076
+ )
28077
+ );
28078
+ if (invalidEls.length === 0) return;
28079
+ const missing = invalidEls.map(
28080
+ (el) => el.getAttribute("data-field-name") ?? el.name ?? ""
28081
+ );
28082
+ const messages = invalidEls.map((el) => ({
28083
+ field: el.getAttribute("data-field-name") ?? el.name ?? "",
28084
+ message: el.validationMessage
28085
+ }));
28086
+ const summary = missing.length === 1 ? `${missing[0]}: ${messages[0]?.message}` : `Please fix ${missing.length} fields: ${missing.join(", ")}`;
28087
+ setSubmitError(summary);
28088
+ eventBus.emit("UI:VALIDATION_FAILED", {
28089
+ submitEvent,
28090
+ missing,
28091
+ messages,
28092
+ summary
28093
+ });
28094
+ });
28095
+ };
28062
28096
  const handleCancel = () => {
28063
28097
  eventBus.emit(`UI:${cancelEvent}`);
28064
28098
  eventBus.emit("UI:CLOSE");
@@ -28162,7 +28196,8 @@ var init_Form = __esm({
28162
28196
  "data-field-name": fieldName,
28163
28197
  required: field.required,
28164
28198
  disabled: isLoading,
28165
- placeholder: field.placeholder
28199
+ placeholder: field.placeholder,
28200
+ pattern: field.pattern
28166
28201
  };
28167
28202
  switch (inputType) {
28168
28203
  case "checkbox":
@@ -28258,7 +28293,9 @@ var init_Form = __esm({
28258
28293
  ...commonProps,
28259
28294
  type: "email",
28260
28295
  value: String(currentValue),
28261
- onChange: (e) => handleChange(fieldName, e.target.value)
28296
+ onChange: (e) => handleChange(fieldName, e.target.value),
28297
+ minLength: field.min,
28298
+ maxLength: field.max
28262
28299
  }
28263
28300
  );
28264
28301
  case "url":
@@ -28268,7 +28305,9 @@ var init_Form = __esm({
28268
28305
  ...commonProps,
28269
28306
  type: "url",
28270
28307
  value: String(currentValue),
28271
- onChange: (e) => handleChange(fieldName, e.target.value)
28308
+ onChange: (e) => handleChange(fieldName, e.target.value),
28309
+ minLength: field.min,
28310
+ maxLength: field.max
28272
28311
  }
28273
28312
  );
28274
28313
  case "password":
@@ -28278,7 +28317,9 @@ var init_Form = __esm({
28278
28317
  ...commonProps,
28279
28318
  type: "password",
28280
28319
  value: String(currentValue),
28281
- onChange: (e) => handleChange(fieldName, e.target.value)
28320
+ onChange: (e) => handleChange(fieldName, e.target.value),
28321
+ minLength: field.min,
28322
+ maxLength: field.max
28282
28323
  }
28283
28324
  );
28284
28325
  case "text":
@@ -28291,8 +28332,7 @@ var init_Form = __esm({
28291
28332
  value: String(currentValue),
28292
28333
  onChange: (e) => handleChange(fieldName, e.target.value),
28293
28334
  minLength: field.min,
28294
- maxLength: field.max,
28295
- pattern: field.pattern
28335
+ maxLength: field.max
28296
28336
  }
28297
28337
  );
28298
28338
  }
@@ -28300,12 +28340,14 @@ var init_Form = __esm({
28300
28340
  return /* @__PURE__ */ jsxs(
28301
28341
  "form",
28302
28342
  {
28303
- noValidate: true,
28343
+ ref: formRef,
28304
28344
  "data-pattern": "form-section",
28305
28345
  className: cn(layoutStyles[layout], gapStyles8[gap], className),
28306
28346
  onSubmit: handleSubmit,
28347
+ onInvalid: handleInvalid,
28307
28348
  ...props,
28308
28349
  children: [
28350
+ submitError && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: submitError }),
28309
28351
  error && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
28310
28352
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
28311
28353
  schemaFields,
@@ -27,7 +27,7 @@ function _interopNamespace(e) {
27
27
  var React5__default = /*#__PURE__*/_interopDefault(React5);
28
28
  var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
29
29
 
30
- // node_modules/clsx/dist/clsx.mjs
30
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
31
31
  function r(e) {
32
32
  var t, f, n = "";
33
33
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -42,7 +42,7 @@ function clsx() {
42
42
  return n;
43
43
  }
44
44
 
45
- // node_modules/tailwind-merge/dist/bundle-mjs.mjs
45
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
46
46
  var CLASS_PART_SEPARATOR = "-";
47
47
  var createClassGroupUtils = (config) => {
48
48
  const classMap = createClassMap(config);