@almadar/ui 5.28.4 → 5.28.5

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.
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { TraitConfigValue } from '@almadar/core';
3
+ export interface NodeSlotEditorProps {
4
+ /** Current node-slot value (a render-ui pattern config, or nothing). */
5
+ value: TraitConfigValue | undefined;
6
+ /** Fired with the next value. */
7
+ onChange: (next: TraitConfigValue) => void;
8
+ /** Additional CSS classes. */
9
+ className?: string;
10
+ }
11
+ /**
12
+ * NodeSlotEditor — edits a `node` config slot (e.g. `children`/`hud`/`debugPanel`).
13
+ * A node slot renders a nested render-ui pattern, so this picks the pattern TYPE
14
+ * from the known-pattern registry and edits that pattern's props as a tree — instead
15
+ * of the read-only "edit in source" fallback. Self-contained `@almadar/ui` atoms.
16
+ */
17
+ export declare const NodeSlotEditor: React.FC<NodeSlotEditorProps>;
@@ -1,5 +1,6 @@
1
1
  export { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary';
2
2
  export { JsonTreeEditor, type JsonTreeEditorProps } from './JsonTreeEditor';
3
+ export { NodeSlotEditor, type NodeSlotEditorProps } from './NodeSlotEditor';
3
4
  export { FileTree, type FileTreeProps, type FileTreeNode } from './FileTree';
4
5
  export { FormField, type FormFieldProps } from './FormField';
5
6
  export { EmptyState, type EmptyStateProps } from './EmptyState';
@@ -7126,6 +7126,16 @@ var init_Skeleton = __esm({
7126
7126
  Skeleton.displayName = "Skeleton";
7127
7127
  }
7128
7128
  });
7129
+ function getKnownPatterns() {
7130
+ return Object.keys(componentMapping);
7131
+ }
7132
+ var componentMapping;
7133
+ var init_pattern_resolver = __esm({
7134
+ "renderer/pattern-resolver.ts"() {
7135
+ logger.createLogger("almadar:ui:pattern-resolver");
7136
+ componentMapping = {};
7137
+ }
7138
+ });
7129
7139
 
7130
7140
  // renderer/slot-definitions.ts
7131
7141
  function isPortalSlot(slot) {
@@ -9032,7 +9042,7 @@ function getTraitSnapshots() {
9032
9042
  try {
9033
9043
  snapshots.push(getter());
9034
9044
  } catch (err) {
9035
- log3.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
9045
+ log4.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
9036
9046
  }
9037
9047
  }
9038
9048
  return snapshots;
@@ -9110,10 +9120,10 @@ function updateAssetStatus(url, status) {
9110
9120
  window.__orbitalVerification.assetStatus[url] = status;
9111
9121
  }
9112
9122
  }
9113
- var log3;
9123
+ var log4;
9114
9124
  var init_verificationRegistry = __esm({
9115
9125
  "lib/verificationRegistry.ts"() {
9116
- log3 = logger.createLogger("almadar:bridge");
9126
+ log4 = logger.createLogger("almadar:bridge");
9117
9127
  exposeOnWindow();
9118
9128
  }
9119
9129
  });
@@ -11198,7 +11208,7 @@ var init_avl_elk_layout = __esm({
11198
11208
  elk = new ELK__default.default();
11199
11209
  }
11200
11210
  });
11201
- var log4, SWIM_GUTTER, CENTER_W; exports.BehaviorView = void 0;
11211
+ var log5, SWIM_GUTTER, CENTER_W; exports.BehaviorView = void 0;
11202
11212
  var init_BehaviorView = __esm({
11203
11213
  "components/avl/molecules/BehaviorView.tsx"() {
11204
11214
  "use client";
@@ -11207,7 +11217,7 @@ var init_BehaviorView = __esm({
11207
11217
  init_AvlSwimLane();
11208
11218
  init_types();
11209
11219
  init_avl_elk_layout();
11210
- log4 = logger.createLogger("almadar:ui:avl:behavior-view");
11220
+ log5 = logger.createLogger("almadar:ui:avl:behavior-view");
11211
11221
  SWIM_GUTTER = 120;
11212
11222
  CENTER_W = 360;
11213
11223
  exports.BehaviorView = ({ data }) => {
@@ -11218,7 +11228,7 @@ var init_BehaviorView = __esm({
11218
11228
  const dataKey = React74.useMemo(() => JSON.stringify(traitData), [traitData]);
11219
11229
  React74.useEffect(() => {
11220
11230
  if (!traitData) return;
11221
- computeTraitLayout(traitData).then(setLayout).catch((err) => log4.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
11231
+ computeTraitLayout(traitData).then(setLayout).catch((err) => log5.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
11222
11232
  }, [dataKey]);
11223
11233
  if (!traitData) {
11224
11234
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("avl.noTraitData") });
@@ -11725,7 +11735,7 @@ function generateDiff(oldVal, newVal) {
11725
11735
  }
11726
11736
  return diff;
11727
11737
  }
11728
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS; exports.CodeBlock = void 0;
11738
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log6, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS; exports.CodeBlock = void 0;
11729
11739
  var init_CodeBlock = __esm({
11730
11740
  "components/core/molecules/markdown/CodeBlock.tsx"() {
11731
11741
  init_cn();
@@ -11808,7 +11818,7 @@ var init_CodeBlock = __esm({
11808
11818
  "lolo-op-async": { color: syntax.ORB_COLORS.dark.async }
11809
11819
  };
11810
11820
  loloStyle = { ...dark__default.default, ...loloStyleOverrides };
11811
- log5 = logger.createLogger("almadar:ui:markdown-code");
11821
+ log6 = logger.createLogger("almadar:ui:markdown-code");
11812
11822
  CODE_LANGUAGES = [
11813
11823
  "text",
11814
11824
  "json",
@@ -12072,7 +12082,7 @@ var init_CodeBlock = __esm({
12072
12082
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
12073
12083
  setTimeout(() => setCopied(false), 2e3);
12074
12084
  } catch (err) {
12075
- log5.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
12085
+ log6.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
12076
12086
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
12077
12087
  }
12078
12088
  };
@@ -15740,14 +15750,14 @@ function useSafeEventBus2() {
15740
15750
  } };
15741
15751
  }
15742
15752
  }
15743
- var log6, lookStyles4; exports.ButtonGroup = void 0;
15753
+ var log7, lookStyles4; exports.ButtonGroup = void 0;
15744
15754
  var init_ButtonGroup = __esm({
15745
15755
  "components/core/molecules/ButtonGroup.tsx"() {
15746
15756
  "use client";
15747
15757
  init_cn();
15748
15758
  init_atoms2();
15749
15759
  init_useEventBus();
15750
- log6 = logger.createLogger("almadar:ui:button-group");
15760
+ log7 = logger.createLogger("almadar:ui:button-group");
15751
15761
  lookStyles4 = {
15752
15762
  "right-aligned-buttons": "",
15753
15763
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -15828,7 +15838,7 @@ var init_ButtonGroup = __esm({
15828
15838
  {
15829
15839
  variant: "ghost",
15830
15840
  onClick: () => {
15831
- log6.debug("Filter clicked", { field: filter.field });
15841
+ log7.debug("Filter clicked", { field: filter.field });
15832
15842
  },
15833
15843
  children: filter.label
15834
15844
  },
@@ -22521,6 +22531,65 @@ var init_JsonTreeEditor = __esm({
22521
22531
  };
22522
22532
  }
22523
22533
  });
22534
+ function normalize(value) {
22535
+ const wasArray = Array.isArray(value);
22536
+ const pattern = wasArray ? value[0] : value;
22537
+ const type = isObj2(pattern) && typeof pattern["type"] === "string" ? pattern["type"] : "";
22538
+ const props = {};
22539
+ if (isObj2(pattern)) {
22540
+ for (const [k, v] of Object.entries(pattern)) if (k !== "type") props[k] = v;
22541
+ }
22542
+ return { type, props, wasArray };
22543
+ }
22544
+ var isObj2; exports.NodeSlotEditor = void 0;
22545
+ var init_NodeSlotEditor = __esm({
22546
+ "components/core/molecules/NodeSlotEditor.tsx"() {
22547
+ "use client";
22548
+ init_Stack();
22549
+ init_Select();
22550
+ init_Typography();
22551
+ init_JsonTreeEditor();
22552
+ init_pattern_resolver();
22553
+ init_cn();
22554
+ isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
22555
+ exports.NodeSlotEditor = ({ value, onChange, className }) => {
22556
+ const { type, props, wasArray } = normalize(value);
22557
+ const patterns = React74__namespace.default.useMemo(() => {
22558
+ try {
22559
+ return [...getKnownPatterns()].sort();
22560
+ } catch {
22561
+ return [];
22562
+ }
22563
+ }, []);
22564
+ const options = React74__namespace.default.useMemo(
22565
+ () => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((p2) => ({ value: p2, label: p2 }))],
22566
+ [patterns]
22567
+ );
22568
+ const emit = (nextType, nextProps) => {
22569
+ if (!nextType) {
22570
+ onChange(wasArray ? [] : {});
22571
+ return;
22572
+ }
22573
+ const pattern = { type: nextType, ...nextProps };
22574
+ onChange(wasArray || value === void 0 ? [pattern] : pattern);
22575
+ };
22576
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: cn("w-full", className), children: [
22577
+ /* @__PURE__ */ jsxRuntime.jsx(
22578
+ exports.Select,
22579
+ {
22580
+ options,
22581
+ value: type,
22582
+ onChange: (e) => emit(e.target.value, props)
22583
+ }
22584
+ ),
22585
+ type !== "" && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "pl-1", children: [
22586
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "props" }),
22587
+ /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: props, onChange: (next) => emit(type, isObj2(next) ? next : {}) })
22588
+ ] })
22589
+ ] });
22590
+ };
22591
+ }
22592
+ });
22524
22593
  function fileIcon(name) {
22525
22594
  const ext = name.split(".").pop()?.toLowerCase() ?? "";
22526
22595
  switch (ext) {
@@ -23869,9 +23938,9 @@ function debug(...args) {
23869
23938
  const [first, ...rest] = args;
23870
23939
  const message = typeof first === "string" ? first : "<debug>";
23871
23940
  if (rest.length === 0 && typeof first === "string") {
23872
- log7.debug(message);
23941
+ log8.debug(message);
23873
23942
  } else {
23874
- log7.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
23943
+ log8.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
23875
23944
  }
23876
23945
  }
23877
23946
  function debugGroup(label) {
@@ -23899,11 +23968,11 @@ function toLogMetaValue(v) {
23899
23968
  }
23900
23969
  return String(v);
23901
23970
  }
23902
- var NAMESPACE, log7;
23971
+ var NAMESPACE, log8;
23903
23972
  var init_debug = __esm({
23904
23973
  "lib/debug.ts"() {
23905
23974
  NAMESPACE = "almadar:ui:debug";
23906
- log7 = logger.createLogger(NAMESPACE);
23975
+ log8 = logger.createLogger(NAMESPACE);
23907
23976
  logger.createLogger("almadar:ui:debug:input");
23908
23977
  logger.createLogger("almadar:ui:debug:collision");
23909
23978
  logger.createLogger("almadar:ui:debug:physics");
@@ -35284,6 +35353,8 @@ function FieldControl({
35284
35353
  control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
35285
35354
  } else if (decl.type === "string") {
35286
35355
  control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
35356
+ } else if (decl.type === "node") {
35357
+ control = /* @__PURE__ */ jsxRuntime.jsx(exports.NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
35287
35358
  } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
35288
35359
  const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
35289
35360
  control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
@@ -35317,6 +35388,7 @@ var init_PropertyInspector = __esm({
35317
35388
  init_IconPicker();
35318
35389
  init_AssetPicker();
35319
35390
  init_JsonTreeEditor();
35391
+ init_NodeSlotEditor();
35320
35392
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
35321
35393
  SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
35322
35394
  exports.PropertyInspector = ({
@@ -37213,6 +37285,7 @@ var init_molecules2 = __esm({
37213
37285
  "components/core/molecules/index.ts"() {
37214
37286
  init_ErrorBoundary();
37215
37287
  init_JsonTreeEditor();
37288
+ init_NodeSlotEditor();
37216
37289
  init_FileTree();
37217
37290
  init_FormField();
37218
37291
  init_EmptyState();
@@ -43414,7 +43487,7 @@ function getAllEvents(traits2) {
43414
43487
  function EventDispatcherTab({ traits: traits2, schema }) {
43415
43488
  const eventBus = useEventBus();
43416
43489
  const { t } = hooks.useTranslate();
43417
- const [log8, setLog] = React74__namespace.useState([]);
43490
+ const [log9, setLog] = React74__namespace.useState([]);
43418
43491
  const prevStatesRef = React74__namespace.useRef(/* @__PURE__ */ new Map());
43419
43492
  React74__namespace.useEffect(() => {
43420
43493
  for (const trait of traits2) {
@@ -43478,9 +43551,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
43478
43551
  /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
43479
43552
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
43480
43553
  ] }),
43481
- log8.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
43554
+ log9.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
43482
43555
  /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
43483
- /* @__PURE__ */ jsxRuntime.jsx(exports.Stack, { gap: "xs", children: log8.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "small", className: "font-mono text-xs", children: [
43556
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Stack, { gap: "xs", children: log9.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "small", className: "font-mono text-xs", children: [
43484
43557
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-purple-400", children: entry.traitName }),
43485
43558
  " ",
43486
43559
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -7078,6 +7078,16 @@ var init_Skeleton = __esm({
7078
7078
  Skeleton.displayName = "Skeleton";
7079
7079
  }
7080
7080
  });
7081
+ function getKnownPatterns() {
7082
+ return Object.keys(componentMapping);
7083
+ }
7084
+ var componentMapping;
7085
+ var init_pattern_resolver = __esm({
7086
+ "renderer/pattern-resolver.ts"() {
7087
+ createLogger("almadar:ui:pattern-resolver");
7088
+ componentMapping = {};
7089
+ }
7090
+ });
7081
7091
 
7082
7092
  // renderer/slot-definitions.ts
7083
7093
  function isPortalSlot(slot) {
@@ -8984,7 +8994,7 @@ function getTraitSnapshots() {
8984
8994
  try {
8985
8995
  snapshots.push(getter());
8986
8996
  } catch (err) {
8987
- log3.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
8997
+ log4.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
8988
8998
  }
8989
8999
  }
8990
9000
  return snapshots;
@@ -9062,10 +9072,10 @@ function updateAssetStatus(url, status) {
9062
9072
  window.__orbitalVerification.assetStatus[url] = status;
9063
9073
  }
9064
9074
  }
9065
- var log3;
9075
+ var log4;
9066
9076
  var init_verificationRegistry = __esm({
9067
9077
  "lib/verificationRegistry.ts"() {
9068
- log3 = createLogger("almadar:bridge");
9078
+ log4 = createLogger("almadar:bridge");
9069
9079
  exposeOnWindow();
9070
9080
  }
9071
9081
  });
@@ -11150,7 +11160,7 @@ var init_avl_elk_layout = __esm({
11150
11160
  elk = new ELK();
11151
11161
  }
11152
11162
  });
11153
- var log4, SWIM_GUTTER, CENTER_W, BehaviorView;
11163
+ var log5, SWIM_GUTTER, CENTER_W, BehaviorView;
11154
11164
  var init_BehaviorView = __esm({
11155
11165
  "components/avl/molecules/BehaviorView.tsx"() {
11156
11166
  "use client";
@@ -11159,7 +11169,7 @@ var init_BehaviorView = __esm({
11159
11169
  init_AvlSwimLane();
11160
11170
  init_types();
11161
11171
  init_avl_elk_layout();
11162
- log4 = createLogger("almadar:ui:avl:behavior-view");
11172
+ log5 = createLogger("almadar:ui:avl:behavior-view");
11163
11173
  SWIM_GUTTER = 120;
11164
11174
  CENTER_W = 360;
11165
11175
  BehaviorView = ({ data }) => {
@@ -11170,7 +11180,7 @@ var init_BehaviorView = __esm({
11170
11180
  const dataKey = useMemo(() => JSON.stringify(traitData), [traitData]);
11171
11181
  useEffect(() => {
11172
11182
  if (!traitData) return;
11173
- computeTraitLayout(traitData).then(setLayout).catch((err) => log4.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
11183
+ computeTraitLayout(traitData).then(setLayout).catch((err) => log5.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
11174
11184
  }, [dataKey]);
11175
11185
  if (!traitData) {
11176
11186
  return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("avl.noTraitData") });
@@ -11677,7 +11687,7 @@ function generateDiff(oldVal, newVal) {
11677
11687
  }
11678
11688
  return diff;
11679
11689
  }
11680
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
11690
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log6, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
11681
11691
  var init_CodeBlock = __esm({
11682
11692
  "components/core/molecules/markdown/CodeBlock.tsx"() {
11683
11693
  init_cn();
@@ -11760,7 +11770,7 @@ var init_CodeBlock = __esm({
11760
11770
  "lolo-op-async": { color: ORB_COLORS.dark.async }
11761
11771
  };
11762
11772
  loloStyle = { ...dark, ...loloStyleOverrides };
11763
- log5 = createLogger("almadar:ui:markdown-code");
11773
+ log6 = createLogger("almadar:ui:markdown-code");
11764
11774
  CODE_LANGUAGES = [
11765
11775
  "text",
11766
11776
  "json",
@@ -12024,7 +12034,7 @@ var init_CodeBlock = __esm({
12024
12034
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
12025
12035
  setTimeout(() => setCopied(false), 2e3);
12026
12036
  } catch (err) {
12027
- log5.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
12037
+ log6.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
12028
12038
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
12029
12039
  }
12030
12040
  };
@@ -15692,14 +15702,14 @@ function useSafeEventBus2() {
15692
15702
  } };
15693
15703
  }
15694
15704
  }
15695
- var log6, lookStyles4, ButtonGroup;
15705
+ var log7, lookStyles4, ButtonGroup;
15696
15706
  var init_ButtonGroup = __esm({
15697
15707
  "components/core/molecules/ButtonGroup.tsx"() {
15698
15708
  "use client";
15699
15709
  init_cn();
15700
15710
  init_atoms2();
15701
15711
  init_useEventBus();
15702
- log6 = createLogger("almadar:ui:button-group");
15712
+ log7 = createLogger("almadar:ui:button-group");
15703
15713
  lookStyles4 = {
15704
15714
  "right-aligned-buttons": "",
15705
15715
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -15780,7 +15790,7 @@ var init_ButtonGroup = __esm({
15780
15790
  {
15781
15791
  variant: "ghost",
15782
15792
  onClick: () => {
15783
- log6.debug("Filter clicked", { field: filter.field });
15793
+ log7.debug("Filter clicked", { field: filter.field });
15784
15794
  },
15785
15795
  children: filter.label
15786
15796
  },
@@ -22473,6 +22483,65 @@ var init_JsonTreeEditor = __esm({
22473
22483
  };
22474
22484
  }
22475
22485
  });
22486
+ function normalize(value) {
22487
+ const wasArray = Array.isArray(value);
22488
+ const pattern = wasArray ? value[0] : value;
22489
+ const type = isObj2(pattern) && typeof pattern["type"] === "string" ? pattern["type"] : "";
22490
+ const props = {};
22491
+ if (isObj2(pattern)) {
22492
+ for (const [k, v] of Object.entries(pattern)) if (k !== "type") props[k] = v;
22493
+ }
22494
+ return { type, props, wasArray };
22495
+ }
22496
+ var isObj2, NodeSlotEditor;
22497
+ var init_NodeSlotEditor = __esm({
22498
+ "components/core/molecules/NodeSlotEditor.tsx"() {
22499
+ "use client";
22500
+ init_Stack();
22501
+ init_Select();
22502
+ init_Typography();
22503
+ init_JsonTreeEditor();
22504
+ init_pattern_resolver();
22505
+ init_cn();
22506
+ isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
22507
+ NodeSlotEditor = ({ value, onChange, className }) => {
22508
+ const { type, props, wasArray } = normalize(value);
22509
+ const patterns = React74__default.useMemo(() => {
22510
+ try {
22511
+ return [...getKnownPatterns()].sort();
22512
+ } catch {
22513
+ return [];
22514
+ }
22515
+ }, []);
22516
+ const options = React74__default.useMemo(
22517
+ () => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((p2) => ({ value: p2, label: p2 }))],
22518
+ [patterns]
22519
+ );
22520
+ const emit = (nextType, nextProps) => {
22521
+ if (!nextType) {
22522
+ onChange(wasArray ? [] : {});
22523
+ return;
22524
+ }
22525
+ const pattern = { type: nextType, ...nextProps };
22526
+ onChange(wasArray || value === void 0 ? [pattern] : pattern);
22527
+ };
22528
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
22529
+ /* @__PURE__ */ jsx(
22530
+ Select,
22531
+ {
22532
+ options,
22533
+ value: type,
22534
+ onChange: (e) => emit(e.target.value, props)
22535
+ }
22536
+ ),
22537
+ type !== "" && /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "pl-1", children: [
22538
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: "props" }),
22539
+ /* @__PURE__ */ jsx(JsonTreeEditor, { value: props, onChange: (next) => emit(type, isObj2(next) ? next : {}) })
22540
+ ] })
22541
+ ] });
22542
+ };
22543
+ }
22544
+ });
22476
22545
  function fileIcon(name) {
22477
22546
  const ext = name.split(".").pop()?.toLowerCase() ?? "";
22478
22547
  switch (ext) {
@@ -23821,9 +23890,9 @@ function debug(...args) {
23821
23890
  const [first, ...rest] = args;
23822
23891
  const message = typeof first === "string" ? first : "<debug>";
23823
23892
  if (rest.length === 0 && typeof first === "string") {
23824
- log7.debug(message);
23893
+ log8.debug(message);
23825
23894
  } else {
23826
- log7.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
23895
+ log8.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
23827
23896
  }
23828
23897
  }
23829
23898
  function debugGroup(label) {
@@ -23851,11 +23920,11 @@ function toLogMetaValue(v) {
23851
23920
  }
23852
23921
  return String(v);
23853
23922
  }
23854
- var NAMESPACE, log7;
23923
+ var NAMESPACE, log8;
23855
23924
  var init_debug = __esm({
23856
23925
  "lib/debug.ts"() {
23857
23926
  NAMESPACE = "almadar:ui:debug";
23858
- log7 = createLogger(NAMESPACE);
23927
+ log8 = createLogger(NAMESPACE);
23859
23928
  createLogger("almadar:ui:debug:input");
23860
23929
  createLogger("almadar:ui:debug:collision");
23861
23930
  createLogger("almadar:ui:debug:physics");
@@ -35236,6 +35305,8 @@ function FieldControl({
35236
35305
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
35237
35306
  } else if (decl.type === "string") {
35238
35307
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
35308
+ } else if (decl.type === "node") {
35309
+ control = /* @__PURE__ */ jsx(NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
35239
35310
  } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
35240
35311
  const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
35241
35312
  control = /* @__PURE__ */ jsx(JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
@@ -35269,6 +35340,7 @@ var init_PropertyInspector = __esm({
35269
35340
  init_IconPicker();
35270
35341
  init_AssetPicker();
35271
35342
  init_JsonTreeEditor();
35343
+ init_NodeSlotEditor();
35272
35344
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
35273
35345
  SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
35274
35346
  PropertyInspector = ({
@@ -37165,6 +37237,7 @@ var init_molecules2 = __esm({
37165
37237
  "components/core/molecules/index.ts"() {
37166
37238
  init_ErrorBoundary();
37167
37239
  init_JsonTreeEditor();
37240
+ init_NodeSlotEditor();
37168
37241
  init_FileTree();
37169
37242
  init_FormField();
37170
37243
  init_EmptyState();
@@ -43366,7 +43439,7 @@ function getAllEvents(traits2) {
43366
43439
  function EventDispatcherTab({ traits: traits2, schema }) {
43367
43440
  const eventBus = useEventBus();
43368
43441
  const { t } = useTranslate();
43369
- const [log8, setLog] = React74.useState([]);
43442
+ const [log9, setLog] = React74.useState([]);
43370
43443
  const prevStatesRef = React74.useRef(/* @__PURE__ */ new Map());
43371
43444
  React74.useEffect(() => {
43372
43445
  for (const trait of traits2) {
@@ -43430,9 +43503,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
43430
43503
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
43431
43504
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
43432
43505
  ] }),
43433
- log8.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
43506
+ log9.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
43434
43507
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
43435
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log8.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
43508
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log9.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
43436
43509
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
43437
43510
  " ",
43438
43511
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -49835,4 +49908,4 @@ init_AboutPageTemplate();
49835
49908
  // components/index.ts
49836
49909
  init_cn();
49837
49910
 
49838
- export { ALL_PRESETS, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HealthPanel, HeroOrganism, HeroSection, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, drawSprite, generateCombatMessage, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, mapBookData, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, springOscillator, tickAnimationState, toCodeLanguage, transitionAnimation, useAnchorRect, useBattleState, useCamera, useGameAudio, useGameAudioContext, useImageCache, usePhysics2D, useSpriteAnimations };
49911
+ export { ALL_PRESETS, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HealthPanel, HeroOrganism, HeroSection, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, drawSprite, generateCombatMessage, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, mapBookData, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, springOscillator, tickAnimationState, toCodeLanguage, transitionAnimation, useAnchorRect, useBattleState, useCamera, useGameAudio, useGameAudioContext, useImageCache, usePhysics2D, useSpriteAnimations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.28.4",
3
+ "version": "5.28.5",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [