@almadar/ui 4.50.20 → 4.50.22

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.
@@ -38135,6 +38135,7 @@ var init_Form = __esm({
38135
38135
  submitLabel,
38136
38136
  cancelLabel,
38137
38137
  showCancel,
38138
+ showSubmit = true,
38138
38139
  title,
38139
38140
  submitEvent = "SAVE",
38140
38141
  cancelEvent = "CANCEL",
@@ -38621,8 +38622,8 @@ var init_Form = __esm({
38621
38622
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
38622
38623
  schemaFields,
38623
38624
  children,
38624
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
38625
- /* @__PURE__ */ jsxRuntime.jsx(
38625
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
38626
+ showSubmit && /* @__PURE__ */ jsxRuntime.jsx(
38626
38627
  Button,
38627
38628
  {
38628
38629
  type: "submit",
@@ -60188,7 +60189,7 @@ function findPatternInTree(root, path) {
60188
60189
  }
60189
60190
  var FIELD_TYPE_OPTIONS = core.FieldTypeSchema.options.map((v) => ({ value: v, label: v }));
60190
60191
  var EFFECT_TYPE_OPTIONS = Object.keys(exports.EFFECT_TYPE_TO_CATEGORY).map((v) => ({ value: v, label: v }));
60191
- function OrbInspector({ node, schema, editable = false, userType = "builder", onSchemaChange, onClose }) {
60192
+ function OrbInspector({ node, schema, editable = false, userType = "builder", themeManifest, onSchemaChange, onClose }) {
60192
60193
  const { selected: selectedPattern } = React93.useContext(PatternSelectionContext);
60193
60194
  const [activeTab, setActiveTab] = React93.useState("inspector");
60194
60195
  const eventBus = useEventBus();
@@ -60251,8 +60252,18 @@ function OrbInspector({ node, schema, editable = false, userType = "builder", on
60251
60252
  }, [schema, orbitalName, traitName, transitionEvent, isExpanded]);
60252
60253
  const handlePropChange = React93.useCallback((propName, value) => {
60253
60254
  if (!editable) return;
60254
- eventBus.emit("UI:PROP_CHANGE", { propName, value });
60255
- }, [editable, eventBus]);
60255
+ eventBus.emit("UI:PROP_CHANGE", {
60256
+ propName,
60257
+ value,
60258
+ selection: {
60259
+ sourceSchemaName: selectedPattern?.nodeData.sourceSchemaName,
60260
+ patternPath: selectedPattern?.patternId,
60261
+ orbitalName,
60262
+ traitName,
60263
+ transitionEvent
60264
+ }
60265
+ });
60266
+ }, [editable, eventBus, selectedPattern, orbitalName, traitName, transitionEvent]);
60256
60267
  const handleAddField = React93.useCallback(() => {
60257
60268
  eventBus.emit("UI:ADD_FIELD", {});
60258
60269
  }, [eventBus]);
@@ -60324,18 +60335,21 @@ function OrbInspector({ node, schema, editable = false, userType = "builder", on
60324
60335
  }
60325
60336
  ) })
60326
60337
  ) : activeTab === "styles" ? (
60327
- /* ── Styles Tab (read-only in Phase 2) ──
60328
- Phase 2 ships a token-only viewer with no editing. The proper
60329
- tokenContract on PatternDefinition lands in Phase 6; until then
60330
- we fall back to a static map of well-known atoms keyed by
60331
- pattern type. Patterns missing from the map render a placeholder
60332
- so the gap is visible rather than silently empty. */
60338
+ /* ── Styles Tab ──
60339
+ Variant + size pills are clickable when `editable` and emit
60340
+ `UI:PROP_CHANGE` with the selection context. The page-level
60341
+ dispatcher routes those events to the project schemaEditor or
60342
+ to the theme manifest based on `selection.sourceSchemaName`. */
60333
60343
  /* @__PURE__ */ jsxRuntime.jsx(
60334
- StylesTabReadOnly,
60344
+ StylesTab,
60335
60345
  {
60336
60346
  patternType,
60337
60347
  patternDef,
60338
- patternConfig
60348
+ patternConfig,
60349
+ editable,
60350
+ onPropChange: handlePropChange,
60351
+ themeManifest,
60352
+ isDesignSystem: selectedPattern?.nodeData.sourceSchemaName === "__design_system__"
60339
60353
  }
60340
60354
  )
60341
60355
  ) : (
@@ -60617,7 +60631,7 @@ var PHASE_2_TOKEN_FALLBACK = {
60617
60631
  modal: ["--color-card", "--shadow-lg", "--radius-lg"],
60618
60632
  toast: ["--color-card", "--shadow-lg", "--radius-md"]
60619
60633
  };
60620
- function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60634
+ function StylesTab({ patternType, patternDef, patternConfig, editable, onPropChange, themeManifest, isDesignSystem }) {
60621
60635
  const { t } = useTranslate();
60622
60636
  if (!patternType) {
60623
60637
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-muted-foreground text-[11px]", children: t("Select a pattern to view its style tokens.") }) });
@@ -60651,7 +60665,9 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60651
60665
  return /* @__PURE__ */ jsxRuntime.jsx(
60652
60666
  Box,
60653
60667
  {
60654
- className: "rounded px-2 py-0.5 text-[11px] font-mono",
60668
+ as: editable ? "button" : "div",
60669
+ onClick: editable ? () => onPropChange("variant", variant) : void 0,
60670
+ className: `rounded px-2 py-0.5 text-[11px] font-mono ${editable ? "cursor-pointer hover:opacity-80 transition-opacity" : ""}`,
60655
60671
  style: {
60656
60672
  backgroundColor: isActive ? "var(--color-primary)" : "var(--color-muted)",
60657
60673
  color: isActive ? "var(--color-primary-foreground)" : "var(--color-muted-foreground)"
@@ -60669,7 +60685,9 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60669
60685
  return /* @__PURE__ */ jsxRuntime.jsx(
60670
60686
  Box,
60671
60687
  {
60672
- className: "rounded px-2 py-0.5 text-[11px] font-mono",
60688
+ as: editable ? "button" : "div",
60689
+ onClick: editable ? () => onPropChange("size", size) : void 0,
60690
+ className: `rounded px-2 py-0.5 text-[11px] font-mono ${editable ? "cursor-pointer hover:opacity-80 transition-opacity" : ""}`,
60673
60691
  style: {
60674
60692
  backgroundColor: isActive ? "var(--color-primary)" : "var(--color-muted)",
60675
60693
  color: isActive ? "var(--color-primary-foreground)" : "var(--color-muted-foreground)"
@@ -60679,7 +60697,58 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60679
60697
  size
60680
60698
  );
60681
60699
  }) })
60682
- ] })
60700
+ ] }),
60701
+ isDesignSystem && themeManifest && editable && /* @__PURE__ */ jsxRuntime.jsx(TokenEditorSection, { themeManifest, onPropChange })
60702
+ ] });
60703
+ }
60704
+ var TOKEN_GROUPS = [
60705
+ { group: "colors", label: "Colors" },
60706
+ { group: "radii", label: "Radii" },
60707
+ { group: "spacing", label: "Spacing" },
60708
+ { group: "shadows", label: "Shadows" }
60709
+ ];
60710
+ function TokenEditorSection({ themeManifest, onPropChange }) {
60711
+ const tokens = themeManifest.tokens ?? {};
60712
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-3 pt-2 border-t border-border/40", children: [
60713
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Project theme tokens" }),
60714
+ TOKEN_GROUPS.map(({ group, label }) => {
60715
+ const entries = Object.entries(tokens[group] ?? {});
60716
+ if (entries.length === 0) return null;
60717
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-1.5", children: [
60718
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-[10px] font-mono text-muted-foreground", children: label }),
60719
+ entries.map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsx(
60720
+ TokenRow,
60721
+ {
60722
+ group,
60723
+ tokenKey: key,
60724
+ value: String(value),
60725
+ isColor: group === "colors",
60726
+ onPropChange
60727
+ },
60728
+ key
60729
+ ))
60730
+ ] }, group);
60731
+ })
60732
+ ] });
60733
+ }
60734
+ function TokenRow({ group, tokenKey, value, isColor, onPropChange }) {
60735
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-2", children: [
60736
+ isColor && /* @__PURE__ */ jsxRuntime.jsx(
60737
+ Box,
60738
+ {
60739
+ className: "w-4 h-4 rounded border border-border/40 shrink-0",
60740
+ style: { backgroundColor: value }
60741
+ }
60742
+ ),
60743
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "font-mono text-[11px] text-muted-foreground w-24 shrink-0 truncate", children: tokenKey }),
60744
+ /* @__PURE__ */ jsxRuntime.jsx(
60745
+ Input,
60746
+ {
60747
+ value,
60748
+ onChange: (e) => onPropChange(`__token__.${group}.${tokenKey}`, e.target.value),
60749
+ className: "flex-1 text-[11px] font-mono"
60750
+ }
60751
+ )
60683
60752
  ] });
60684
60753
  }
60685
60754
 
@@ -60726,7 +60795,8 @@ function FlowCanvasInner({
60726
60795
  composeLevel,
60727
60796
  behaviorEntries,
60728
60797
  behaviorWires,
60729
- userType = "builder"
60798
+ userType = "builder",
60799
+ themeManifest
60730
60800
  }) {
60731
60801
  const NODE_TYPES2 = React93.useMemo(() => ({
60732
60802
  preview: OrbPreviewNode,
@@ -61023,6 +61093,7 @@ function FlowCanvasInner({
61023
61093
  schema: parsedSchema,
61024
61094
  editable,
61025
61095
  userType,
61096
+ themeManifest,
61026
61097
  onSchemaChange,
61027
61098
  onClose: handleClosePanel
61028
61099
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { OrbitalSchema, UISlot, Expression, EntityPersistence, EventPayloadField } from '@almadar/core';
3
+ import { OrbitalSchema, UISlot, Expression, EntityPersistence, EventPayloadField, ThemeDefinition } from '@almadar/core';
4
4
  import { Node, Edge, NodeProps, EdgeProps } from '@xyflow/react';
5
5
 
6
6
  /**
@@ -1204,10 +1204,18 @@ interface OrbInspectorProps {
1204
1204
  * gets.
1205
1205
  */
1206
1206
  userType?: 'builder' | 'designer' | 'architect';
1207
+ /**
1208
+ * Project theme tokens (Design System tab only). When provided AND the
1209
+ * selection originates from the synthesized `__design_system__` schema,
1210
+ * the Styles tab renders an editable token-row list; edits emit
1211
+ * `UI:PROP_CHANGE` with `propName: '__token__.<group>.<key>'` and the
1212
+ * page-level dispatcher routes them to `themeManifest.setToken`.
1213
+ */
1214
+ themeManifest?: ThemeDefinition;
1207
1215
  onSchemaChange?: (schema: OrbitalSchema) => void;
1208
1216
  onClose: () => void;
1209
1217
  }
1210
- declare function OrbInspector({ node, schema, editable, userType, onSchemaChange, onClose }: OrbInspectorProps): React__default.ReactElement;
1218
+ declare function OrbInspector({ node, schema, editable, userType, themeManifest, onSchemaChange, onClose }: OrbInspectorProps): React__default.ReactElement;
1211
1219
  declare namespace OrbInspector {
1212
1220
  var displayName: string;
1213
1221
  }
@@ -1335,6 +1343,12 @@ interface FlowCanvasProps {
1335
1343
  * everything. Default `'builder'` preserves pre-Phase-2 behavior.
1336
1344
  */
1337
1345
  userType?: 'builder' | 'designer' | 'architect';
1346
+ /**
1347
+ * Project theme tokens (Design System tab only). Forwarded to `OrbInspector`
1348
+ * so the Styles tab can render an editable token list when the selection
1349
+ * originates from the synthesized `__design_system__` schema.
1350
+ */
1351
+ themeManifest?: ThemeDefinition;
1338
1352
  }
1339
1353
  declare const FlowCanvas: React__default.FC<FlowCanvasProps>;
1340
1354
 
package/dist/avl/index.js CHANGED
@@ -38089,6 +38089,7 @@ var init_Form = __esm({
38089
38089
  submitLabel,
38090
38090
  cancelLabel,
38091
38091
  showCancel,
38092
+ showSubmit = true,
38092
38093
  title,
38093
38094
  submitEvent = "SAVE",
38094
38095
  cancelEvent = "CANCEL",
@@ -38575,8 +38576,8 @@ var init_Form = __esm({
38575
38576
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
38576
38577
  schemaFields,
38577
38578
  children,
38578
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
38579
- /* @__PURE__ */ jsx(
38579
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
38580
+ showSubmit && /* @__PURE__ */ jsx(
38580
38581
  Button,
38581
38582
  {
38582
38583
  type: "submit",
@@ -60142,7 +60143,7 @@ function findPatternInTree(root, path) {
60142
60143
  }
60143
60144
  var FIELD_TYPE_OPTIONS = FieldTypeSchema.options.map((v) => ({ value: v, label: v }));
60144
60145
  var EFFECT_TYPE_OPTIONS = Object.keys(EFFECT_TYPE_TO_CATEGORY).map((v) => ({ value: v, label: v }));
60145
- function OrbInspector({ node, schema, editable = false, userType = "builder", onSchemaChange, onClose }) {
60146
+ function OrbInspector({ node, schema, editable = false, userType = "builder", themeManifest, onSchemaChange, onClose }) {
60146
60147
  const { selected: selectedPattern } = useContext(PatternSelectionContext);
60147
60148
  const [activeTab, setActiveTab] = useState("inspector");
60148
60149
  const eventBus = useEventBus();
@@ -60205,8 +60206,18 @@ function OrbInspector({ node, schema, editable = false, userType = "builder", on
60205
60206
  }, [schema, orbitalName, traitName, transitionEvent, isExpanded]);
60206
60207
  const handlePropChange = useCallback((propName, value) => {
60207
60208
  if (!editable) return;
60208
- eventBus.emit("UI:PROP_CHANGE", { propName, value });
60209
- }, [editable, eventBus]);
60209
+ eventBus.emit("UI:PROP_CHANGE", {
60210
+ propName,
60211
+ value,
60212
+ selection: {
60213
+ sourceSchemaName: selectedPattern?.nodeData.sourceSchemaName,
60214
+ patternPath: selectedPattern?.patternId,
60215
+ orbitalName,
60216
+ traitName,
60217
+ transitionEvent
60218
+ }
60219
+ });
60220
+ }, [editable, eventBus, selectedPattern, orbitalName, traitName, transitionEvent]);
60210
60221
  const handleAddField = useCallback(() => {
60211
60222
  eventBus.emit("UI:ADD_FIELD", {});
60212
60223
  }, [eventBus]);
@@ -60278,18 +60289,21 @@ function OrbInspector({ node, schema, editable = false, userType = "builder", on
60278
60289
  }
60279
60290
  ) })
60280
60291
  ) : activeTab === "styles" ? (
60281
- /* ── Styles Tab (read-only in Phase 2) ──
60282
- Phase 2 ships a token-only viewer with no editing. The proper
60283
- tokenContract on PatternDefinition lands in Phase 6; until then
60284
- we fall back to a static map of well-known atoms keyed by
60285
- pattern type. Patterns missing from the map render a placeholder
60286
- so the gap is visible rather than silently empty. */
60292
+ /* ── Styles Tab ──
60293
+ Variant + size pills are clickable when `editable` and emit
60294
+ `UI:PROP_CHANGE` with the selection context. The page-level
60295
+ dispatcher routes those events to the project schemaEditor or
60296
+ to the theme manifest based on `selection.sourceSchemaName`. */
60287
60297
  /* @__PURE__ */ jsx(
60288
- StylesTabReadOnly,
60298
+ StylesTab,
60289
60299
  {
60290
60300
  patternType,
60291
60301
  patternDef,
60292
- patternConfig
60302
+ patternConfig,
60303
+ editable,
60304
+ onPropChange: handlePropChange,
60305
+ themeManifest,
60306
+ isDesignSystem: selectedPattern?.nodeData.sourceSchemaName === "__design_system__"
60293
60307
  }
60294
60308
  )
60295
60309
  ) : (
@@ -60571,7 +60585,7 @@ var PHASE_2_TOKEN_FALLBACK = {
60571
60585
  modal: ["--color-card", "--shadow-lg", "--radius-lg"],
60572
60586
  toast: ["--color-card", "--shadow-lg", "--radius-md"]
60573
60587
  };
60574
- function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60588
+ function StylesTab({ patternType, patternDef, patternConfig, editable, onPropChange, themeManifest, isDesignSystem }) {
60575
60589
  const { t } = useTranslate();
60576
60590
  if (!patternType) {
60577
60591
  return /* @__PURE__ */ jsx(Box, { className: "p-4", children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[11px]", children: t("Select a pattern to view its style tokens.") }) });
@@ -60605,7 +60619,9 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60605
60619
  return /* @__PURE__ */ jsx(
60606
60620
  Box,
60607
60621
  {
60608
- className: "rounded px-2 py-0.5 text-[11px] font-mono",
60622
+ as: editable ? "button" : "div",
60623
+ onClick: editable ? () => onPropChange("variant", variant) : void 0,
60624
+ className: `rounded px-2 py-0.5 text-[11px] font-mono ${editable ? "cursor-pointer hover:opacity-80 transition-opacity" : ""}`,
60609
60625
  style: {
60610
60626
  backgroundColor: isActive ? "var(--color-primary)" : "var(--color-muted)",
60611
60627
  color: isActive ? "var(--color-primary-foreground)" : "var(--color-muted-foreground)"
@@ -60623,7 +60639,9 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60623
60639
  return /* @__PURE__ */ jsx(
60624
60640
  Box,
60625
60641
  {
60626
- className: "rounded px-2 py-0.5 text-[11px] font-mono",
60642
+ as: editable ? "button" : "div",
60643
+ onClick: editable ? () => onPropChange("size", size) : void 0,
60644
+ className: `rounded px-2 py-0.5 text-[11px] font-mono ${editable ? "cursor-pointer hover:opacity-80 transition-opacity" : ""}`,
60627
60645
  style: {
60628
60646
  backgroundColor: isActive ? "var(--color-primary)" : "var(--color-muted)",
60629
60647
  color: isActive ? "var(--color-primary-foreground)" : "var(--color-muted-foreground)"
@@ -60633,7 +60651,58 @@ function StylesTabReadOnly({ patternType, patternDef, patternConfig }) {
60633
60651
  size
60634
60652
  );
60635
60653
  }) })
60636
- ] })
60654
+ ] }),
60655
+ isDesignSystem && themeManifest && editable && /* @__PURE__ */ jsx(TokenEditorSection, { themeManifest, onPropChange })
60656
+ ] });
60657
+ }
60658
+ var TOKEN_GROUPS = [
60659
+ { group: "colors", label: "Colors" },
60660
+ { group: "radii", label: "Radii" },
60661
+ { group: "spacing", label: "Spacing" },
60662
+ { group: "shadows", label: "Shadows" }
60663
+ ];
60664
+ function TokenEditorSection({ themeManifest, onPropChange }) {
60665
+ const tokens = themeManifest.tokens ?? {};
60666
+ return /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-3 pt-2 border-t border-border/40", children: [
60667
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Project theme tokens" }),
60668
+ TOKEN_GROUPS.map(({ group, label }) => {
60669
+ const entries = Object.entries(tokens[group] ?? {});
60670
+ if (entries.length === 0) return null;
60671
+ return /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1.5", children: [
60672
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[10px] font-mono text-muted-foreground", children: label }),
60673
+ entries.map(([key, value]) => /* @__PURE__ */ jsx(
60674
+ TokenRow,
60675
+ {
60676
+ group,
60677
+ tokenKey: key,
60678
+ value: String(value),
60679
+ isColor: group === "colors",
60680
+ onPropChange
60681
+ },
60682
+ key
60683
+ ))
60684
+ ] }, group);
60685
+ })
60686
+ ] });
60687
+ }
60688
+ function TokenRow({ group, tokenKey, value, isColor, onPropChange }) {
60689
+ return /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
60690
+ isColor && /* @__PURE__ */ jsx(
60691
+ Box,
60692
+ {
60693
+ className: "w-4 h-4 rounded border border-border/40 shrink-0",
60694
+ style: { backgroundColor: value }
60695
+ }
60696
+ ),
60697
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-mono text-[11px] text-muted-foreground w-24 shrink-0 truncate", children: tokenKey }),
60698
+ /* @__PURE__ */ jsx(
60699
+ Input,
60700
+ {
60701
+ value,
60702
+ onChange: (e) => onPropChange(`__token__.${group}.${tokenKey}`, e.target.value),
60703
+ className: "flex-1 text-[11px] font-mono"
60704
+ }
60705
+ )
60637
60706
  ] });
60638
60707
  }
60639
60708
 
@@ -60680,7 +60749,8 @@ function FlowCanvasInner({
60680
60749
  composeLevel,
60681
60750
  behaviorEntries,
60682
60751
  behaviorWires,
60683
- userType = "builder"
60752
+ userType = "builder",
60753
+ themeManifest
60684
60754
  }) {
60685
60755
  const NODE_TYPES2 = useMemo(() => ({
60686
60756
  preview: OrbPreviewNode,
@@ -60977,6 +61047,7 @@ function FlowCanvasInner({
60977
61047
  schema: parsedSchema,
60978
61048
  editable,
60979
61049
  userType,
61050
+ themeManifest,
60980
61051
  onSchemaChange,
60981
61052
  onClose: handleClosePanel
60982
61053
  }
@@ -34190,6 +34190,7 @@ var init_Form = __esm({
34190
34190
  submitLabel,
34191
34191
  cancelLabel,
34192
34192
  showCancel,
34193
+ showSubmit = true,
34193
34194
  title,
34194
34195
  submitEvent = "SAVE",
34195
34196
  cancelEvent = "CANCEL",
@@ -34676,8 +34677,8 @@ var init_Form = __esm({
34676
34677
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
34677
34678
  schemaFields,
34678
34679
  children,
34679
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", className: "pt-4", children: [
34680
- /* @__PURE__ */ jsxRuntime.jsx(
34680
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", className: "pt-4", children: [
34681
+ showSubmit && /* @__PURE__ */ jsxRuntime.jsx(
34681
34682
  exports.Button,
34682
34683
  {
34683
34684
  type: "submit",
@@ -34144,6 +34144,7 @@ var init_Form = __esm({
34144
34144
  submitLabel,
34145
34145
  cancelLabel,
34146
34146
  showCancel,
34147
+ showSubmit = true,
34147
34148
  title,
34148
34149
  submitEvent = "SAVE",
34149
34150
  cancelEvent = "CANCEL",
@@ -34630,8 +34631,8 @@ var init_Form = __esm({
34630
34631
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
34631
34632
  schemaFields,
34632
34633
  children,
34633
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
34634
- /* @__PURE__ */ jsx(
34634
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
34635
+ showSubmit && /* @__PURE__ */ jsx(
34635
34636
  Button,
34636
34637
  {
34637
34638
  type: "submit",
@@ -176,6 +176,8 @@ export interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement
176
176
  cancelLabel?: string;
177
177
  /** Show cancel button (defaults to true for schema forms) */
178
178
  showCancel?: boolean;
179
+ /** Show submit button (defaults to true for schema forms). Set false when a parent atom owns the submit action externally (e.g. wizard footers). */
180
+ showSubmit?: boolean;
179
181
  /** Form title (used by ModalSlot to extract title) */
180
182
  title?: string;
181
183
  /** Event to dispatch on successful submit (defaults to 'SAVE') */
@@ -12,7 +12,7 @@
12
12
  * Escape to go back. AVL overlays on hover (future).
13
13
  */
14
14
  import React from 'react';
15
- import type { OrbitalSchema } from '@almadar/core';
15
+ import type { OrbitalSchema, ThemeDefinition } from '@almadar/core';
16
16
  import type { ViewLevel, PreviewNodeData } from '../../molecules/avl/avl-preview-types';
17
17
  import type { ComposeViewLevel, BehaviorCanvasEntry, BehaviorWireEdgeData } from '../../molecules/avl/avl-behavior-compose-types';
18
18
  export interface FlowCanvasProps {
@@ -124,5 +124,11 @@ export interface FlowCanvasProps {
124
124
  * everything. Default `'builder'` preserves pre-Phase-2 behavior.
125
125
  */
126
126
  userType?: 'builder' | 'designer' | 'architect';
127
+ /**
128
+ * Project theme tokens (Design System tab only). Forwarded to `OrbInspector`
129
+ * so the Styles tab can render an editable token list when the selection
130
+ * originates from the synthesized `__design_system__` schema.
131
+ */
132
+ themeManifest?: ThemeDefinition;
127
133
  }
128
134
  export declare const FlowCanvas: React.FC<FlowCanvasProps>;
@@ -14,7 +14,7 @@
14
14
  * When `editable` is true, inspector fields become inputs.
15
15
  */
16
16
  import React from 'react';
17
- import type { OrbitalSchema } from '@almadar/core';
17
+ import type { OrbitalSchema, ThemeDefinition } from '@almadar/core';
18
18
  import type { PreviewNodeData } from '../../molecules/avl/avl-preview-types';
19
19
  export interface OrbInspectorProps {
20
20
  node: PreviewNodeData;
@@ -28,10 +28,18 @@ export interface OrbInspectorProps {
28
28
  * gets.
29
29
  */
30
30
  userType?: 'builder' | 'designer' | 'architect';
31
+ /**
32
+ * Project theme tokens (Design System tab only). When provided AND the
33
+ * selection originates from the synthesized `__design_system__` schema,
34
+ * the Styles tab renders an editable token-row list; edits emit
35
+ * `UI:PROP_CHANGE` with `propName: '__token__.<group>.<key>'` and the
36
+ * page-level dispatcher routes them to `themeManifest.setToken`.
37
+ */
38
+ themeManifest?: ThemeDefinition;
31
39
  onSchemaChange?: (schema: OrbitalSchema) => void;
32
40
  onClose: () => void;
33
41
  }
34
- export declare function OrbInspector({ node, schema, editable, userType, onSchemaChange, onClose }: OrbInspectorProps): React.ReactElement;
42
+ export declare function OrbInspector({ node, schema, editable, userType, themeManifest, onSchemaChange, onClose }: OrbInspectorProps): React.ReactElement;
35
43
  export declare namespace OrbInspector {
36
44
  var displayName: string;
37
45
  }
@@ -34950,6 +34950,7 @@ var init_Form = __esm({
34950
34950
  submitLabel,
34951
34951
  cancelLabel,
34952
34952
  showCancel,
34953
+ showSubmit = true,
34953
34954
  title,
34954
34955
  submitEvent = "SAVE",
34955
34956
  cancelEvent = "CANCEL",
@@ -35436,8 +35437,8 @@ var init_Form = __esm({
35436
35437
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
35437
35438
  schemaFields,
35438
35439
  children,
35439
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35440
- /* @__PURE__ */ jsxRuntime.jsx(
35440
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35441
+ showSubmit && /* @__PURE__ */ jsxRuntime.jsx(
35441
35442
  Button,
35442
35443
  {
35443
35444
  type: "submit",
@@ -34904,6 +34904,7 @@ var init_Form = __esm({
34904
34904
  submitLabel,
34905
34905
  cancelLabel,
34906
34906
  showCancel,
34907
+ showSubmit = true,
34907
34908
  title,
34908
34909
  submitEvent = "SAVE",
34909
34910
  cancelEvent = "CANCEL",
@@ -35390,8 +35391,8 @@ var init_Form = __esm({
35390
35391
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
35391
35392
  schemaFields,
35392
35393
  children,
35393
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35394
- /* @__PURE__ */ jsx(
35394
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35395
+ showSubmit && /* @__PURE__ */ jsx(
35395
35396
  Button,
35396
35397
  {
35397
35398
  type: "submit",
@@ -34517,6 +34517,7 @@ var init_Form = __esm({
34517
34517
  submitLabel,
34518
34518
  cancelLabel,
34519
34519
  showCancel,
34520
+ showSubmit = true,
34520
34521
  title,
34521
34522
  submitEvent = "SAVE",
34522
34523
  cancelEvent = "CANCEL",
@@ -35003,8 +35004,8 @@ var init_Form = __esm({
35003
35004
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
35004
35005
  schemaFields,
35005
35006
  children,
35006
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35007
- /* @__PURE__ */ jsxRuntime.jsx(
35007
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "pt-4", children: [
35008
+ showSubmit && /* @__PURE__ */ jsxRuntime.jsx(
35008
35009
  Button,
35009
35010
  {
35010
35011
  type: "submit",
@@ -34471,6 +34471,7 @@ var init_Form = __esm({
34471
34471
  submitLabel,
34472
34472
  cancelLabel,
34473
34473
  showCancel,
34474
+ showSubmit = true,
34474
34475
  title,
34475
34476
  submitEvent = "SAVE",
34476
34477
  cancelEvent = "CANCEL",
@@ -34957,8 +34958,8 @@ var init_Form = __esm({
34957
34958
  sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
34958
34959
  schemaFields,
34959
34960
  children,
34960
- (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
34961
- /* @__PURE__ */ jsx(
34961
+ (schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && (showSubmit || shouldShowCancel) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
34962
+ showSubmit && /* @__PURE__ */ jsx(
34962
34963
  Button,
34963
34964
  {
34964
34965
  type: "submit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.50.20",
3
+ "version": "4.50.22",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [