@almadar/ui 4.29.0 → 4.30.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.
@@ -9450,9 +9450,9 @@ var init_ScaledDiagram = __esm({
9450
9450
  }
9451
9451
  });
9452
9452
 
9453
- // node_modules/katex/dist/katex.min.css
9453
+ // node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css
9454
9454
  var init_katex_min = __esm({
9455
- "node_modules/katex/dist/katex.min.css"() {
9455
+ "node_modules/.pnpm/katex@0.16.45/node_modules/katex/dist/katex.min.css"() {
9456
9456
  }
9457
9457
  });
9458
9458
  var MarkdownContent;
@@ -25613,6 +25613,8 @@ var init_Form = __esm({
25613
25613
  const [collapsedSections, setCollapsedSections] = React104__default.useState(
25614
25614
  /* @__PURE__ */ new Set()
25615
25615
  );
25616
+ const [submitError, setSubmitError] = React104__default.useState(null);
25617
+ const formRef = React104__default.useRef(null);
25616
25618
  const formMode = props.mode;
25617
25619
  const mountedRef = React104__default.useRef(false);
25618
25620
  if (!mountedRef.current) {
@@ -25738,6 +25740,7 @@ var init_Form = __esm({
25738
25740
  };
25739
25741
  const handleSubmit = (e) => {
25740
25742
  e.preventDefault();
25743
+ setSubmitError(null);
25741
25744
  debug("forms", "submit-enter", {
25742
25745
  mode: formMode,
25743
25746
  submitEvent,
@@ -25755,6 +25758,37 @@ var init_Form = __esm({
25755
25758
  eventBus.emit(`UI:${onSubmit}`, payload);
25756
25759
  }
25757
25760
  };
25761
+ const handleInvalid = (e) => {
25762
+ const target = e.target;
25763
+ const fieldName = target.getAttribute("data-field-name") ?? target.name ?? "";
25764
+ const fieldMessage = target.validationMessage || "Invalid value";
25765
+ debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
25766
+ queueMicrotask(() => {
25767
+ const form = formRef.current;
25768
+ if (!form) return;
25769
+ const invalidEls = Array.from(
25770
+ form.querySelectorAll(
25771
+ ":invalid"
25772
+ )
25773
+ );
25774
+ if (invalidEls.length === 0) return;
25775
+ const missing = invalidEls.map(
25776
+ (el) => el.getAttribute("data-field-name") ?? el.name ?? ""
25777
+ );
25778
+ const messages = invalidEls.map((el) => ({
25779
+ field: el.getAttribute("data-field-name") ?? el.name ?? "",
25780
+ message: el.validationMessage
25781
+ }));
25782
+ const summary = missing.length === 1 ? `${missing[0]}: ${messages[0]?.message}` : `Please fix ${missing.length} fields: ${missing.join(", ")}`;
25783
+ setSubmitError(summary);
25784
+ eventBus.emit("UI:VALIDATION_FAILED", {
25785
+ submitEvent,
25786
+ missing,
25787
+ messages,
25788
+ summary
25789
+ });
25790
+ });
25791
+ };
25758
25792
  const handleCancel = () => {
25759
25793
  eventBus.emit(`UI:${cancelEvent}`);
25760
25794
  eventBus.emit("UI:CLOSE");
@@ -25858,7 +25892,8 @@ var init_Form = __esm({
25858
25892
  "data-field-name": fieldName,
25859
25893
  required: field.required,
25860
25894
  disabled: isLoading,
25861
- placeholder: field.placeholder
25895
+ placeholder: field.placeholder,
25896
+ pattern: field.pattern
25862
25897
  };
25863
25898
  switch (inputType) {
25864
25899
  case "checkbox":
@@ -25954,7 +25989,9 @@ var init_Form = __esm({
25954
25989
  ...commonProps,
25955
25990
  type: "email",
25956
25991
  value: String(currentValue),
25957
- onChange: (e) => handleChange(fieldName, e.target.value)
25992
+ onChange: (e) => handleChange(fieldName, e.target.value),
25993
+ minLength: field.min,
25994
+ maxLength: field.max
25958
25995
  }
25959
25996
  );
25960
25997
  case "url":
@@ -25964,7 +26001,9 @@ var init_Form = __esm({
25964
26001
  ...commonProps,
25965
26002
  type: "url",
25966
26003
  value: String(currentValue),
25967
- onChange: (e) => handleChange(fieldName, e.target.value)
26004
+ onChange: (e) => handleChange(fieldName, e.target.value),
26005
+ minLength: field.min,
26006
+ maxLength: field.max
25968
26007
  }
25969
26008
  );
25970
26009
  case "password":
@@ -25974,7 +26013,9 @@ var init_Form = __esm({
25974
26013
  ...commonProps,
25975
26014
  type: "password",
25976
26015
  value: String(currentValue),
25977
- onChange: (e) => handleChange(fieldName, e.target.value)
26016
+ onChange: (e) => handleChange(fieldName, e.target.value),
26017
+ minLength: field.min,
26018
+ maxLength: field.max
25978
26019
  }
25979
26020
  );
25980
26021
  case "text":
@@ -25987,8 +26028,7 @@ var init_Form = __esm({
25987
26028
  value: String(currentValue),
25988
26029
  onChange: (e) => handleChange(fieldName, e.target.value),
25989
26030
  minLength: field.min,
25990
- maxLength: field.max,
25991
- pattern: field.pattern
26031
+ maxLength: field.max
25992
26032
  }
25993
26033
  );
25994
26034
  }
@@ -25996,12 +26036,14 @@ var init_Form = __esm({
25996
26036
  return /* @__PURE__ */ jsxs(
25997
26037
  "form",
25998
26038
  {
25999
- noValidate: true,
26039
+ ref: formRef,
26000
26040
  "data-pattern": "form-section",
26001
26041
  className: cn(layoutStyles[layout], gapStyles8[gap], className),
26002
26042
  onSubmit: handleSubmit,
26043
+ onInvalid: handleInvalid,
26003
26044
  ...props,
26004
26045
  children: [
26046
+ submitError && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: submitError }),
26005
26047
  error && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
26006
26048
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
26007
26049
  schemaFields,
@@ -35741,7 +35783,18 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
35741
35783
  orbitalsByTrait: JSON.stringify(orbitalsByTrait ?? null)
35742
35784
  });
35743
35785
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
35744
- const results = currentManager.sendEvent(normalizedEvent, payload);
35786
+ const entityByTrait = {};
35787
+ for (const [name, fields] of traitFieldStatesRef.current) {
35788
+ if (fields && Object.keys(fields).length > 0) {
35789
+ entityByTrait[name] = fields;
35790
+ }
35791
+ }
35792
+ const results = currentManager.sendEvent(
35793
+ normalizedEvent,
35794
+ payload,
35795
+ void 0,
35796
+ entityByTrait
35797
+ );
35745
35798
  crossTraitLog.debug("processEvent:results", {
35746
35799
  event: normalizedEvent,
35747
35800
  executedCount: results.length,
@@ -36061,6 +36114,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
36061
36114
  }
36062
36115
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
36063
36116
  const unsubscribes = [];
36117
+ const subscribedBusKeys = /* @__PURE__ */ new Set();
36064
36118
  for (const binding of traitBindings) {
36065
36119
  const traitName = binding.trait.name;
36066
36120
  const orbitalName = orbitalsByTrait?.[traitName];
@@ -36071,6 +36125,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
36071
36125
  continue;
36072
36126
  }
36073
36127
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
36128
+ if (subscribedBusKeys.has(selfBusKey)) continue;
36129
+ subscribedBusKeys.add(selfBusKey);
36074
36130
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
36075
36131
  const unsub = eventBus.on(selfBusKey, (event) => {
36076
36132
  if (event.source && event.source.dispatched) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.29.0",
3
+ "version": "4.30.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -121,18 +121,11 @@
121
121
  "registry": "https://registry.npmjs.org",
122
122
  "access": "public"
123
123
  },
124
- "scripts": {
125
- "build": "tsup && tsc -p tsconfig.build.json",
126
- "build:watch": "tsup --watch",
127
- "storybook": "storybook dev -p 6006",
128
- "build-storybook": "storybook build -o storybook-static",
129
- "typecheck": "tsc --noEmit"
130
- },
131
124
  "dependencies": {
132
125
  "@almadar/core": ">=7.12.0",
133
126
  "@almadar/evaluator": ">=2.9.2",
134
127
  "@almadar/patterns": "^2.21.0",
135
- "@almadar/runtime": "^6.0.0",
128
+ "@almadar/runtime": "^6.2.0",
136
129
  "@almadar/std": ">=6.4.1",
137
130
  "@almadar/syntax": ">=1.3.1",
138
131
  "@xyflow/react": "12.10.1",
@@ -219,10 +212,11 @@
219
212
  "hooks"
220
213
  ],
221
214
  "homepage": "https://github.com/almadar-io/almadar#readme",
222
- "pnpm": {
223
- "overrides": {
224
- "@types/react": "^19.0.0",
225
- "@types/react-dom": "^19.0.0"
226
- }
215
+ "scripts": {
216
+ "build": "tsup && tsc -p tsconfig.build.json",
217
+ "build:watch": "tsup --watch",
218
+ "storybook": "storybook dev -p 6006",
219
+ "build-storybook": "storybook build -o storybook-static",
220
+ "typecheck": "tsc --noEmit"
227
221
  }
228
- }
222
+ }