@almadar/ui 5.156.0 → 5.158.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.
- package/dist/{EntityBindingContext-BfZGeDfX.d.cts → EntityBindingContext-Bn3ePJQC.d.cts} +6 -2
- package/dist/{EntityBindingContext-BfZGeDfX.d.ts → EntityBindingContext-Bn3ePJQC.d.ts} +6 -2
- package/dist/avl/index.cjs +283 -43
- package/dist/avl/index.js +283 -43
- package/dist/components/index.cjs +249 -33
- package/dist/components/index.d.cts +46 -6
- package/dist/components/index.d.ts +46 -6
- package/dist/components/index.js +250 -34
- package/dist/providers/index.cjs +251 -35
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +251 -35
- package/dist/runtime/index.cjs +283 -43
- package/dist/runtime/index.d.cts +12 -3
- package/dist/runtime/index.d.ts +12 -3
- package/dist/runtime/index.js +283 -43
- package/package.json +4 -4
|
@@ -3735,13 +3735,33 @@ interface FileTreeNode {
|
|
|
3735
3735
|
/** Detected language for syntax highlighting */
|
|
3736
3736
|
language?: string;
|
|
3737
3737
|
}
|
|
3738
|
+
/** Flat tree row for `items` mode — nested at render time by `parentId`. */
|
|
3739
|
+
interface FileTreeItem {
|
|
3740
|
+
/** Unique node id */
|
|
3741
|
+
id: string;
|
|
3742
|
+
/** Display label */
|
|
3743
|
+
label: string;
|
|
3744
|
+
/** Id of this node's parent; empty/absent marks a root */
|
|
3745
|
+
parentId?: string;
|
|
3746
|
+
/** Icon name override (falls back to folder/file by presence of children) */
|
|
3747
|
+
icon?: string;
|
|
3748
|
+
}
|
|
3738
3749
|
interface FileTreeProps {
|
|
3739
|
-
/** The tree data */
|
|
3740
|
-
tree
|
|
3750
|
+
/** The tree data (pre-nested). Ignored when `items` is provided. */
|
|
3751
|
+
tree?: FileTreeNode[];
|
|
3752
|
+
/** Flat node list, nested by `parentId` at render time — takes precedence
|
|
3753
|
+
* over `tree` when provided. A `parentId` with no matching row renders
|
|
3754
|
+
* that node as a root rather than dropping it. */
|
|
3755
|
+
items?: FileTreeItem[];
|
|
3741
3756
|
/** Currently selected file path */
|
|
3742
3757
|
selectedPath?: string;
|
|
3743
3758
|
/** Called when a file is clicked */
|
|
3744
3759
|
onFileSelect?: (path: string) => void;
|
|
3760
|
+
/** Called when a node is clicked, in flat `items` mode; carries the
|
|
3761
|
+
* selected node's id. Presence-gated: binding this prop is what turns on
|
|
3762
|
+
* the click-to-select affordance, mirroring Badge's `onRemove`.
|
|
3763
|
+
* @offByDefault */
|
|
3764
|
+
onNodeSelect?: (id: string) => void;
|
|
3745
3765
|
/** CSS class */
|
|
3746
3766
|
className?: string;
|
|
3747
3767
|
/** Indent size per level in px (default: 16) */
|
|
@@ -4789,6 +4809,11 @@ declare const OnboardingSpotlight: React__default.FC<OnboardingSpotlightProps>;
|
|
|
4789
4809
|
* Composed from: Box, HStack, VStack, Input, Button, Spinner, Typography atoms
|
|
4790
4810
|
*/
|
|
4791
4811
|
|
|
4812
|
+
/** Relation cardinality vocabulary — mirrors `@almadar/core`'s
|
|
4813
|
+
* `RelationCardinality` (spelled inline: the pattern extractor resolves
|
|
4814
|
+
* components-tree aliases to `enumValues`, but treats core imports as
|
|
4815
|
+
* opaque). `many`/`one-to-many`/`many-to-many` drive multi-value pickers. */
|
|
4816
|
+
type RelationFieldCardinality = "one" | "many" | "one-to-many" | "many-to-one" | "many-to-many";
|
|
4792
4817
|
interface RelationOption {
|
|
4793
4818
|
/** The value to store (typically the ID) */
|
|
4794
4819
|
value: string;
|
|
@@ -6118,6 +6143,12 @@ interface MathCanvasProps {
|
|
|
6118
6143
|
showAxes?: boolean;
|
|
6119
6144
|
showGrid?: boolean;
|
|
6120
6145
|
gridStep?: number;
|
|
6146
|
+
/** Canvas fill color; `var(--token, fallback)` strings resolve against the active theme. Default transparent. */
|
|
6147
|
+
backgroundColor?: string;
|
|
6148
|
+
/** Grid line color; resolves theme tokens (default `var(--color-border, #9ca3af)`). */
|
|
6149
|
+
gridColor?: string;
|
|
6150
|
+
/** Axis line color; resolves theme tokens (default `var(--color-muted-foreground, #374151)`). */
|
|
6151
|
+
axisColor?: string;
|
|
6121
6152
|
/** Draw numeric labels on grid lines (default false). */
|
|
6122
6153
|
showTickLabels?: boolean;
|
|
6123
6154
|
/** Draw each curve's `label` at its last in-range sample (default false). */
|
|
@@ -10721,6 +10752,13 @@ declare const StatCard: React__default.FC<StatCardProps>;
|
|
|
10721
10752
|
* Extends DisplayStateProps (see ./types.ts) and declares `entity?: EntityRow`.
|
|
10722
10753
|
*/
|
|
10723
10754
|
|
|
10755
|
+
/** Relation descriptor injected onto a display field — target entity +
|
|
10756
|
+
* cardinality, mirroring the `.lolo` `{type:"relation", relation:{...}}`
|
|
10757
|
+
* descriptor. */
|
|
10758
|
+
interface DetailRelationMeta {
|
|
10759
|
+
entity: string;
|
|
10760
|
+
cardinality?: RelationFieldCardinality;
|
|
10761
|
+
}
|
|
10724
10762
|
interface DetailField {
|
|
10725
10763
|
label: string;
|
|
10726
10764
|
value: React__default.ReactNode;
|
|
@@ -10756,12 +10794,12 @@ type FieldDef$2 = string | {
|
|
|
10756
10794
|
header?: string;
|
|
10757
10795
|
type?: string;
|
|
10758
10796
|
values?: readonly string[];
|
|
10759
|
-
relation?:
|
|
10797
|
+
relation?: DetailRelationMeta;
|
|
10760
10798
|
} | {
|
|
10761
10799
|
name: string;
|
|
10762
10800
|
type: string;
|
|
10763
10801
|
values?: readonly string[];
|
|
10764
|
-
relation?:
|
|
10802
|
+
relation?: DetailRelationMeta;
|
|
10765
10803
|
};
|
|
10766
10804
|
interface DetailPanelStatus {
|
|
10767
10805
|
label: string;
|
|
@@ -10889,8 +10927,10 @@ interface RelationConfig {
|
|
|
10889
10927
|
entity: string;
|
|
10890
10928
|
/** Field on target entity to display (defaults to 'name') */
|
|
10891
10929
|
displayField?: string;
|
|
10892
|
-
/** Cardinality
|
|
10893
|
-
|
|
10930
|
+
/** Cardinality of the relation — many-valued spellings drive the
|
|
10931
|
+
* multi-select picker below; anything else (including absent) stays
|
|
10932
|
+
* single-select. */
|
|
10933
|
+
cardinality?: RelationFieldCardinality;
|
|
10894
10934
|
}
|
|
10895
10935
|
/**
|
|
10896
10936
|
* Validation-rule bundle for a schema field. Only `enum` is actually read
|
package/dist/components/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { useTranslate } from '@almadar/ui/hooks';
|
|
|
12
12
|
import { useUISlots, useTheme } from '@almadar/ui/context';
|
|
13
13
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
14
14
|
import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
|
|
15
|
-
import { mergeEntityFrame, isFileValue, isInlineTrait, isRenderBindingMarker, ANIMATION_NAMES } from '@almadar/core';
|
|
15
|
+
import { mergeEntityFrame, isFileValue, isInlineTrait, isSecretConfigType, isRenderBindingMarker, ANIMATION_NAMES } from '@almadar/core';
|
|
16
16
|
import { createPortal } from 'react-dom';
|
|
17
17
|
import { wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
18
18
|
import { Link, Outlet, useLocation } from 'react-router-dom';
|
|
@@ -6286,11 +6286,32 @@ function isPlainObject(value) {
|
|
|
6286
6286
|
if (typeof value === "function") return false;
|
|
6287
6287
|
return true;
|
|
6288
6288
|
}
|
|
6289
|
+
function subtreeHasMarker(value) {
|
|
6290
|
+
const cached = markerPresenceCache.get(value);
|
|
6291
|
+
if (cached !== void 0) return cached;
|
|
6292
|
+
let found = false;
|
|
6293
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
6294
|
+
for (const child of children) {
|
|
6295
|
+
if (isRenderBindingMarker(child)) {
|
|
6296
|
+
found = true;
|
|
6297
|
+
break;
|
|
6298
|
+
}
|
|
6299
|
+
if (Array.isArray(child) || isPlainObject(child)) {
|
|
6300
|
+
if (subtreeHasMarker(child)) {
|
|
6301
|
+
found = true;
|
|
6302
|
+
break;
|
|
6303
|
+
}
|
|
6304
|
+
}
|
|
6305
|
+
}
|
|
6306
|
+
markerPresenceCache.set(value, found);
|
|
6307
|
+
return found;
|
|
6308
|
+
}
|
|
6289
6309
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
6290
6310
|
if (isRenderBindingMarker(value)) {
|
|
6291
6311
|
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
6292
6312
|
}
|
|
6293
6313
|
if (Array.isArray(value)) {
|
|
6314
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
6294
6315
|
const out = [];
|
|
6295
6316
|
let changed = false;
|
|
6296
6317
|
for (const item of value) {
|
|
@@ -6308,6 +6329,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
6308
6329
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
6309
6330
|
}
|
|
6310
6331
|
if (isPlainObject(value)) {
|
|
6332
|
+
if (!subtreeHasMarker(value)) return { resolved: value, changed: false };
|
|
6311
6333
|
const sourceTrait = value._sourceTrait;
|
|
6312
6334
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
6313
6335
|
return { resolved: value, changed: false };
|
|
@@ -6333,9 +6355,11 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
6333
6355
|
}
|
|
6334
6356
|
return changed ? out : props;
|
|
6335
6357
|
}
|
|
6358
|
+
var markerPresenceCache;
|
|
6336
6359
|
var init_resolve_render_bindings = __esm({
|
|
6337
6360
|
"lib/resolve-render-bindings.ts"() {
|
|
6338
6361
|
"use client";
|
|
6362
|
+
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
6339
6363
|
}
|
|
6340
6364
|
});
|
|
6341
6365
|
var sizeClasses6, minWidthClasses, lookStyles2, Modal;
|
|
@@ -8614,6 +8638,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
|
|
|
8614
8638
|
case "path": {
|
|
8615
8639
|
if (!shape.path) break;
|
|
8616
8640
|
const p = new Path2D(shape.path);
|
|
8641
|
+
ctx.lineJoin = "round";
|
|
8642
|
+
ctx.lineCap = "round";
|
|
8617
8643
|
if (fill) {
|
|
8618
8644
|
ctx.fillStyle = fill;
|
|
8619
8645
|
ctx.fill(p);
|
|
@@ -8822,7 +8848,7 @@ var init_LearningCanvas = __esm({
|
|
|
8822
8848
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
8823
8849
|
ctx.clearRect(0, 0, width, height);
|
|
8824
8850
|
if (backgroundColor) {
|
|
8825
|
-
ctx.fillStyle = backgroundColor;
|
|
8851
|
+
ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
|
|
8826
8852
|
ctx.fillRect(0, 0, width, height);
|
|
8827
8853
|
}
|
|
8828
8854
|
for (const shape of derivedShapes) {
|
|
@@ -25435,6 +25461,7 @@ function currentValue(decl, override) {
|
|
|
25435
25461
|
function TextLikeControl({
|
|
25436
25462
|
field,
|
|
25437
25463
|
numeric,
|
|
25464
|
+
secret,
|
|
25438
25465
|
value,
|
|
25439
25466
|
onCommit
|
|
25440
25467
|
}) {
|
|
@@ -25452,7 +25479,7 @@ function TextLikeControl({
|
|
|
25452
25479
|
return /* @__PURE__ */ jsx(
|
|
25453
25480
|
Input,
|
|
25454
25481
|
{
|
|
25455
|
-
inputType: numeric ? "number" : "text",
|
|
25482
|
+
inputType: secret ? "password" : numeric ? "number" : "text",
|
|
25456
25483
|
value: draft,
|
|
25457
25484
|
onChange: (e) => setDraft(e.target.value),
|
|
25458
25485
|
onBlur: commit,
|
|
@@ -25513,6 +25540,8 @@ function FieldControl({
|
|
|
25513
25540
|
);
|
|
25514
25541
|
} else if (decl.type === "number") {
|
|
25515
25542
|
control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
|
|
25543
|
+
} else if (isSecretConfigType(decl.type)) {
|
|
25544
|
+
control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, secret: true, value, onCommit: onChange });
|
|
25516
25545
|
} else if (decl.type === "string") {
|
|
25517
25546
|
control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
|
|
25518
25547
|
} else if (decl.type === "node") {
|
|
@@ -25552,7 +25581,7 @@ var init_PropertyInspector = __esm({
|
|
|
25552
25581
|
init_JsonTreeEditor();
|
|
25553
25582
|
init_NodeSlotEditor();
|
|
25554
25583
|
TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
|
|
25555
|
-
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset"]);
|
|
25584
|
+
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset", "secret"]);
|
|
25556
25585
|
PropertyInspector = ({
|
|
25557
25586
|
config,
|
|
25558
25587
|
values,
|
|
@@ -25710,7 +25739,7 @@ function fileIcon(name) {
|
|
|
25710
25739
|
return "file";
|
|
25711
25740
|
}
|
|
25712
25741
|
}
|
|
25713
|
-
var TreeNodeItem, FileTree;
|
|
25742
|
+
var TreeNodeItem, FlatTreeNodeItem, FileTree;
|
|
25714
25743
|
var init_FileTree = __esm({
|
|
25715
25744
|
"components/core/molecules/FileTree.tsx"() {
|
|
25716
25745
|
"use client";
|
|
@@ -25795,14 +25824,101 @@ var init_FileTree = __esm({
|
|
|
25795
25824
|
)) })
|
|
25796
25825
|
] });
|
|
25797
25826
|
};
|
|
25827
|
+
FlatTreeNodeItem = ({
|
|
25828
|
+
item,
|
|
25829
|
+
depth,
|
|
25830
|
+
indent,
|
|
25831
|
+
childrenByParent,
|
|
25832
|
+
onNodeSelect,
|
|
25833
|
+
defaultExpanded = false
|
|
25834
|
+
}) => {
|
|
25835
|
+
const [expanded, setExpanded] = useState(defaultExpanded || depth < 1);
|
|
25836
|
+
const children = childrenByParent.get(item.id);
|
|
25837
|
+
const hasChildren = !!children && children.length > 0;
|
|
25838
|
+
const handleClick = useCallback(() => {
|
|
25839
|
+
if (hasChildren) setExpanded((prev) => !prev);
|
|
25840
|
+
onNodeSelect?.(item.id);
|
|
25841
|
+
}, [hasChildren, item.id, onNodeSelect]);
|
|
25842
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25843
|
+
/* @__PURE__ */ jsxs(
|
|
25844
|
+
Box,
|
|
25845
|
+
{
|
|
25846
|
+
className: "flex items-center gap-1.5 py-0.5 px-2 cursor-pointer rounded-sm transition-colors hover:bg-muted",
|
|
25847
|
+
style: { paddingLeft: depth * indent + 8 },
|
|
25848
|
+
onClick: handleClick,
|
|
25849
|
+
role: "treeitem",
|
|
25850
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
25851
|
+
children: [
|
|
25852
|
+
hasChildren ? /* @__PURE__ */ jsx(
|
|
25853
|
+
Icon,
|
|
25854
|
+
{
|
|
25855
|
+
name: expanded ? "chevron-down" : "chevron-right",
|
|
25856
|
+
size: "xs",
|
|
25857
|
+
className: "text-[var(--color-muted-foreground)] flex-shrink-0"
|
|
25858
|
+
}
|
|
25859
|
+
) : /* @__PURE__ */ jsx(Box, { style: { width: 12, flexShrink: 0 } }),
|
|
25860
|
+
/* @__PURE__ */ jsx(
|
|
25861
|
+
Icon,
|
|
25862
|
+
{
|
|
25863
|
+
name: item.icon ?? (hasChildren ? expanded ? "folder-open" : "folder" : "file"),
|
|
25864
|
+
size: "xs",
|
|
25865
|
+
className: hasChildren ? "text-[var(--color-warning)]" : "text-[var(--color-muted-foreground)]"
|
|
25866
|
+
}
|
|
25867
|
+
),
|
|
25868
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "truncate font-mono text-xs", children: item.label })
|
|
25869
|
+
]
|
|
25870
|
+
}
|
|
25871
|
+
),
|
|
25872
|
+
hasChildren && expanded && /* @__PURE__ */ jsx(Box, { role: "group", children: children.map((child) => /* @__PURE__ */ jsx(
|
|
25873
|
+
FlatTreeNodeItem,
|
|
25874
|
+
{
|
|
25875
|
+
item: child,
|
|
25876
|
+
depth: depth + 1,
|
|
25877
|
+
indent,
|
|
25878
|
+
childrenByParent,
|
|
25879
|
+
onNodeSelect
|
|
25880
|
+
},
|
|
25881
|
+
child.id
|
|
25882
|
+
)) })
|
|
25883
|
+
] });
|
|
25884
|
+
};
|
|
25798
25885
|
FileTree = ({
|
|
25799
25886
|
tree,
|
|
25887
|
+
items,
|
|
25800
25888
|
selectedPath,
|
|
25801
25889
|
onFileSelect,
|
|
25890
|
+
onNodeSelect,
|
|
25802
25891
|
className,
|
|
25803
25892
|
indent = 16
|
|
25804
25893
|
}) => {
|
|
25805
|
-
if (
|
|
25894
|
+
if (items) {
|
|
25895
|
+
if (items.length === 0) return null;
|
|
25896
|
+
const ids = new Set(items.map((node) => node.id));
|
|
25897
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
25898
|
+
const roots = [];
|
|
25899
|
+
for (const item of items) {
|
|
25900
|
+
if (item.parentId && ids.has(item.parentId)) {
|
|
25901
|
+
const siblings = childrenByParent.get(item.parentId);
|
|
25902
|
+
if (siblings) siblings.push(item);
|
|
25903
|
+
else childrenByParent.set(item.parentId, [item]);
|
|
25904
|
+
} else {
|
|
25905
|
+
roots.push(item);
|
|
25906
|
+
}
|
|
25907
|
+
}
|
|
25908
|
+
return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: roots.map((item) => /* @__PURE__ */ jsx(
|
|
25909
|
+
FlatTreeNodeItem,
|
|
25910
|
+
{
|
|
25911
|
+
item,
|
|
25912
|
+
depth: 0,
|
|
25913
|
+
indent,
|
|
25914
|
+
childrenByParent,
|
|
25915
|
+
onNodeSelect,
|
|
25916
|
+
defaultExpanded: true
|
|
25917
|
+
},
|
|
25918
|
+
item.id
|
|
25919
|
+
)) });
|
|
25920
|
+
}
|
|
25921
|
+
if (!tree || tree.length === 0) return null;
|
|
25806
25922
|
return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
|
|
25807
25923
|
TreeNodeItem,
|
|
25808
25924
|
{
|
|
@@ -27455,7 +27571,7 @@ var init_debug = __esm({
|
|
|
27455
27571
|
createLogger("almadar:ui:debug:game-state");
|
|
27456
27572
|
}
|
|
27457
27573
|
});
|
|
27458
|
-
var isRelationsDebugEnabled, RelationSelect;
|
|
27574
|
+
var isRelationsDebugEnabled, MANY_CARDINALITIES, RelationSelect;
|
|
27459
27575
|
var init_RelationSelect = __esm({
|
|
27460
27576
|
"components/core/molecules/RelationSelect.tsx"() {
|
|
27461
27577
|
"use client";
|
|
@@ -27469,6 +27585,11 @@ var init_RelationSelect = __esm({
|
|
|
27469
27585
|
init_Typography();
|
|
27470
27586
|
init_debug();
|
|
27471
27587
|
isRelationsDebugEnabled = () => isDebugEnabled();
|
|
27588
|
+
MANY_CARDINALITIES = [
|
|
27589
|
+
"many",
|
|
27590
|
+
"one-to-many",
|
|
27591
|
+
"many-to-many"
|
|
27592
|
+
];
|
|
27472
27593
|
RelationSelect = ({
|
|
27473
27594
|
value,
|
|
27474
27595
|
onChange,
|
|
@@ -31540,6 +31661,9 @@ var init_MathCanvas = __esm({
|
|
|
31540
31661
|
showAxes = true,
|
|
31541
31662
|
showGrid = true,
|
|
31542
31663
|
gridStep = 1,
|
|
31664
|
+
backgroundColor,
|
|
31665
|
+
gridColor = "var(--color-border, #9ca3af)",
|
|
31666
|
+
axisColor = "var(--color-muted-foreground, #374151)",
|
|
31543
31667
|
showTickLabels = false,
|
|
31544
31668
|
showCurveLabels = false,
|
|
31545
31669
|
curves = [],
|
|
@@ -31562,17 +31686,21 @@ var init_MathCanvas = __esm({
|
|
|
31562
31686
|
error
|
|
31563
31687
|
}) => {
|
|
31564
31688
|
const eventBus = useEventBus();
|
|
31689
|
+
const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
|
|
31690
|
+
const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
|
|
31691
|
+
const stableKeyMap = useMemo(() => keyMap, [keyMapKey]);
|
|
31692
|
+
const stableKeyUpMap = useMemo(() => keyUpMap, [keyUpMapKey]);
|
|
31565
31693
|
useEffect(() => {
|
|
31566
|
-
if (!
|
|
31694
|
+
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
31567
31695
|
const onDown = (e) => {
|
|
31568
|
-
const ev =
|
|
31696
|
+
const ev = stableKeyMap?.[e.code];
|
|
31569
31697
|
if (ev) {
|
|
31570
31698
|
eventBus.emit(`UI:${ev}`, {});
|
|
31571
31699
|
e.preventDefault();
|
|
31572
31700
|
}
|
|
31573
31701
|
};
|
|
31574
31702
|
const onUp = (e) => {
|
|
31575
|
-
const ev =
|
|
31703
|
+
const ev = stableKeyUpMap?.[e.code];
|
|
31576
31704
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
31577
31705
|
};
|
|
31578
31706
|
window.addEventListener("keydown", onDown);
|
|
@@ -31581,7 +31709,7 @@ var init_MathCanvas = __esm({
|
|
|
31581
31709
|
window.removeEventListener("keydown", onDown);
|
|
31582
31710
|
window.removeEventListener("keyup", onUp);
|
|
31583
31711
|
};
|
|
31584
|
-
}, [
|
|
31712
|
+
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
31585
31713
|
const derivedShapes = useMemo(() => {
|
|
31586
31714
|
const out = [];
|
|
31587
31715
|
const margin = 24;
|
|
@@ -31594,11 +31722,11 @@ var init_MathCanvas = __esm({
|
|
|
31594
31722
|
if (showGrid) {
|
|
31595
31723
|
for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
|
|
31596
31724
|
const px = mapX(x);
|
|
31597
|
-
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color:
|
|
31725
|
+
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
31598
31726
|
}
|
|
31599
31727
|
for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
|
|
31600
31728
|
const py = mapY(y);
|
|
31601
|
-
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color:
|
|
31729
|
+
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
|
|
31602
31730
|
}
|
|
31603
31731
|
}
|
|
31604
31732
|
if (showTickLabels) {
|
|
@@ -31669,8 +31797,8 @@ var init_MathCanvas = __esm({
|
|
|
31669
31797
|
});
|
|
31670
31798
|
}
|
|
31671
31799
|
if (showAxes) {
|
|
31672
|
-
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color:
|
|
31673
|
-
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color:
|
|
31800
|
+
out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
|
|
31801
|
+
out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
|
|
31674
31802
|
}
|
|
31675
31803
|
for (const guide of guides) {
|
|
31676
31804
|
const color = guide.color ?? "#9ca3af";
|
|
@@ -31693,23 +31821,36 @@ var init_MathCanvas = __esm({
|
|
|
31693
31821
|
}
|
|
31694
31822
|
for (const curve of curves) {
|
|
31695
31823
|
if (!curve.samples || curve.samples.length < 2) continue;
|
|
31824
|
+
let d = "";
|
|
31825
|
+
let penDown = false;
|
|
31696
31826
|
let lastInRange;
|
|
31697
31827
|
for (let i = 1; i < curve.samples.length; i++) {
|
|
31698
31828
|
const a = curve.samples[i - 1];
|
|
31699
31829
|
const b = curve.samples[i];
|
|
31700
|
-
if (a.x < xMin
|
|
31701
|
-
|
|
31702
|
-
|
|
31703
|
-
|
|
31704
|
-
|
|
31705
|
-
|
|
31706
|
-
|
|
31707
|
-
|
|
31708
|
-
|
|
31709
|
-
|
|
31710
|
-
|
|
31711
|
-
|
|
31712
|
-
|
|
31830
|
+
if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
|
|
31831
|
+
penDown = false;
|
|
31832
|
+
continue;
|
|
31833
|
+
}
|
|
31834
|
+
const clip = (p, q, xLim) => {
|
|
31835
|
+
const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
|
|
31836
|
+
return { x: xLim, y: p.y + t * (q.y - p.y) };
|
|
31837
|
+
};
|
|
31838
|
+
const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
|
|
31839
|
+
const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
|
|
31840
|
+
const pax = mapX(ca.x);
|
|
31841
|
+
const pay = mapY(ca.y);
|
|
31842
|
+
d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
|
|
31843
|
+
penDown = true;
|
|
31844
|
+
if (b.x >= xMin && b.x <= xMax) lastInRange = b;
|
|
31845
|
+
}
|
|
31846
|
+
if (!d) continue;
|
|
31847
|
+
out.push({
|
|
31848
|
+
type: "path",
|
|
31849
|
+
path: d,
|
|
31850
|
+
color: curve.color ?? "#2563eb",
|
|
31851
|
+
lineWidth: 2,
|
|
31852
|
+
dash: curve.dash
|
|
31853
|
+
});
|
|
31713
31854
|
if (showCurveLabels && curve.label && lastInRange) {
|
|
31714
31855
|
out.push({
|
|
31715
31856
|
type: "text",
|
|
@@ -31824,6 +31965,8 @@ var init_MathCanvas = __esm({
|
|
|
31824
31965
|
showAxes,
|
|
31825
31966
|
showGrid,
|
|
31826
31967
|
gridStep,
|
|
31968
|
+
gridColor,
|
|
31969
|
+
axisColor,
|
|
31827
31970
|
showTickLabels,
|
|
31828
31971
|
showCurveLabels,
|
|
31829
31972
|
curves,
|
|
@@ -31843,6 +31986,7 @@ var init_MathCanvas = __esm({
|
|
|
31843
31986
|
{
|
|
31844
31987
|
width,
|
|
31845
31988
|
height,
|
|
31989
|
+
backgroundColor,
|
|
31846
31990
|
shapes: derivedShapes,
|
|
31847
31991
|
readouts,
|
|
31848
31992
|
traces,
|
|
@@ -44227,6 +44371,9 @@ function determineInputType(field) {
|
|
|
44227
44371
|
if (field.type === "relation" || field.relation) {
|
|
44228
44372
|
return "relation";
|
|
44229
44373
|
}
|
|
44374
|
+
if (field.type === "array") {
|
|
44375
|
+
return "array";
|
|
44376
|
+
}
|
|
44230
44377
|
if (field.type === "enum" || field.values || getEnumOptions(field).length > 0) {
|
|
44231
44378
|
return "select";
|
|
44232
44379
|
}
|
|
@@ -44302,6 +44449,7 @@ var init_Form = __esm({
|
|
|
44302
44449
|
init_Typography();
|
|
44303
44450
|
init_Icon();
|
|
44304
44451
|
init_RelationSelect();
|
|
44452
|
+
init_TagInput();
|
|
44305
44453
|
init_UploadDropZone();
|
|
44306
44454
|
init_Alert();
|
|
44307
44455
|
init_useEventBus();
|
|
@@ -44381,7 +44529,7 @@ var init_Form = __esm({
|
|
|
44381
44529
|
values: "values" in f3 ? f3.values : void 0,
|
|
44382
44530
|
min: f3.min,
|
|
44383
44531
|
max: f3.max,
|
|
44384
|
-
relation: "relation" in f3 ? { entity: f3.relation.entity } : void 0
|
|
44532
|
+
relation: "relation" in f3 ? { entity: f3.relation.entity, cardinality: f3.relation.cardinality } : void 0
|
|
44385
44533
|
})
|
|
44386
44534
|
);
|
|
44387
44535
|
}, [entity, fields]);
|
|
@@ -44616,7 +44764,7 @@ var init_Form = __esm({
|
|
|
44616
44764
|
values: "values" in entityField ? entityField.values : void 0,
|
|
44617
44765
|
min: entityField.min,
|
|
44618
44766
|
max: entityField.max,
|
|
44619
|
-
relation: "relation" in entityField ? { entity: entityField.relation.entity } : void 0
|
|
44767
|
+
relation: "relation" in entityField ? { entity: entityField.relation.entity, cardinality: entityField.relation.cardinality } : void 0
|
|
44620
44768
|
};
|
|
44621
44769
|
}
|
|
44622
44770
|
return { name: field, type: "string" };
|
|
@@ -44728,6 +44876,22 @@ var init_Form = __esm({
|
|
|
44728
44876
|
case "relation": {
|
|
44729
44877
|
const relationOptions = relationsData[fieldName] || [];
|
|
44730
44878
|
const relationLoading = relationsLoading[fieldName] || false;
|
|
44879
|
+
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
44880
|
+
const selectedValues = Array.isArray(currentValue2) ? currentValue2.map((v) => String(v)) : [];
|
|
44881
|
+
return /* @__PURE__ */ jsx(
|
|
44882
|
+
Select,
|
|
44883
|
+
{
|
|
44884
|
+
...commonProps,
|
|
44885
|
+
multiple: true,
|
|
44886
|
+
searchable: true,
|
|
44887
|
+
clearable: true,
|
|
44888
|
+
options: [...relationOptions],
|
|
44889
|
+
value: selectedValues,
|
|
44890
|
+
onValueChange: (value) => handleChange(fieldName, Array.isArray(value) ? value : [value]),
|
|
44891
|
+
placeholder: field.placeholder || `Select ${label}...`
|
|
44892
|
+
}
|
|
44893
|
+
);
|
|
44894
|
+
}
|
|
44731
44895
|
return /* @__PURE__ */ jsx(
|
|
44732
44896
|
RelationSelect,
|
|
44733
44897
|
{
|
|
@@ -44742,6 +44906,18 @@ var init_Form = __esm({
|
|
|
44742
44906
|
}
|
|
44743
44907
|
);
|
|
44744
44908
|
}
|
|
44909
|
+
case "array": {
|
|
44910
|
+
const arrayValue = Array.isArray(currentValue2) ? currentValue2.map((v) => String(v)) : currentValue2 != null && currentValue2 !== "" ? [String(currentValue2)] : [];
|
|
44911
|
+
return /* @__PURE__ */ jsx(
|
|
44912
|
+
TagInput,
|
|
44913
|
+
{
|
|
44914
|
+
placeholder: field.placeholder,
|
|
44915
|
+
disabled: isLoading,
|
|
44916
|
+
value: arrayValue,
|
|
44917
|
+
onChange: (next) => handleChange(fieldName, [...next])
|
|
44918
|
+
}
|
|
44919
|
+
);
|
|
44920
|
+
}
|
|
44745
44921
|
case "number":
|
|
44746
44922
|
return /* @__PURE__ */ jsx(
|
|
44747
44923
|
Input,
|
|
@@ -50291,7 +50467,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
50291
50467
|
enriched.values = entityField.enumValues;
|
|
50292
50468
|
}
|
|
50293
50469
|
if (entityField.relation) {
|
|
50294
|
-
enriched.relation =
|
|
50470
|
+
enriched.relation = {
|
|
50471
|
+
entity: entityField.relation.entity,
|
|
50472
|
+
cardinality: entityField.relation.cardinality
|
|
50473
|
+
};
|
|
50295
50474
|
}
|
|
50296
50475
|
return enriched;
|
|
50297
50476
|
}
|
|
@@ -50319,7 +50498,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
50319
50498
|
}
|
|
50320
50499
|
}
|
|
50321
50500
|
if (!obj.relation && entityField.relation) {
|
|
50322
|
-
enriched.relation =
|
|
50501
|
+
enriched.relation = {
|
|
50502
|
+
entity: entityField.relation.entity,
|
|
50503
|
+
cardinality: entityField.relation.cardinality
|
|
50504
|
+
};
|
|
50323
50505
|
}
|
|
50324
50506
|
return enriched;
|
|
50325
50507
|
}
|
|
@@ -50334,7 +50516,12 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
50334
50516
|
const meta = { type: entityField.type };
|
|
50335
50517
|
const values = entityField.values ?? entityField.enumValues;
|
|
50336
50518
|
if (values && values.length > 0) meta.values = values;
|
|
50337
|
-
if (entityField.relation)
|
|
50519
|
+
if (entityField.relation) {
|
|
50520
|
+
meta.relation = {
|
|
50521
|
+
entity: entityField.relation.entity,
|
|
50522
|
+
cardinality: entityField.relation.cardinality
|
|
50523
|
+
};
|
|
50524
|
+
}
|
|
50338
50525
|
return meta;
|
|
50339
50526
|
};
|
|
50340
50527
|
return fields.map((field) => {
|
|
@@ -50888,6 +51075,32 @@ function isPlainConfigObject(value) {
|
|
|
50888
51075
|
const proto = Object.getPrototypeOf(value);
|
|
50889
51076
|
return proto === Object.prototype || proto === null;
|
|
50890
51077
|
}
|
|
51078
|
+
function subtreeHasTraitRef(value) {
|
|
51079
|
+
const cached = traitRefPresenceCache.get(value);
|
|
51080
|
+
if (cached !== void 0) return cached;
|
|
51081
|
+
let found = false;
|
|
51082
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
51083
|
+
for (const child of children) {
|
|
51084
|
+
if (typeof child === "string" && TRAIT_BINDING_RE.test(child)) {
|
|
51085
|
+
found = true;
|
|
51086
|
+
break;
|
|
51087
|
+
}
|
|
51088
|
+
if (isRenderBindingMarker(child)) continue;
|
|
51089
|
+
if (Array.isArray(child)) {
|
|
51090
|
+
if (subtreeHasTraitRef(child)) {
|
|
51091
|
+
found = true;
|
|
51092
|
+
break;
|
|
51093
|
+
}
|
|
51094
|
+
} else if (child !== null && typeof child === "object" && isPlainConfigObject(child)) {
|
|
51095
|
+
if (subtreeHasTraitRef(child)) {
|
|
51096
|
+
found = true;
|
|
51097
|
+
break;
|
|
51098
|
+
}
|
|
51099
|
+
}
|
|
51100
|
+
}
|
|
51101
|
+
traitRefPresenceCache.set(value, found);
|
|
51102
|
+
return found;
|
|
51103
|
+
}
|
|
50891
51104
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
50892
51105
|
if (isRenderBindingMarker(value)) return value;
|
|
50893
51106
|
if (typeof value === "string") {
|
|
@@ -50902,11 +51115,13 @@ function substituteTraitRefsDeep(value, pathKey) {
|
|
|
50902
51115
|
return value;
|
|
50903
51116
|
}
|
|
50904
51117
|
if (Array.isArray(value)) {
|
|
51118
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
50905
51119
|
return value.map(
|
|
50906
51120
|
(item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
|
|
50907
51121
|
);
|
|
50908
51122
|
}
|
|
50909
51123
|
if (typeof value === "object" && isPlainConfigObject(value)) {
|
|
51124
|
+
if (!subtreeHasTraitRef(value)) return value;
|
|
50910
51125
|
const out = {};
|
|
50911
51126
|
for (const [k, v] of Object.entries(value)) {
|
|
50912
51127
|
out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
|
|
@@ -51195,7 +51410,7 @@ function UISlotRenderer({
|
|
|
51195
51410
|
}
|
|
51196
51411
|
return wrapped;
|
|
51197
51412
|
}
|
|
51198
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
51413
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
|
|
51199
51414
|
var init_UISlotRenderer = __esm({
|
|
51200
51415
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
51201
51416
|
"use client";
|
|
@@ -51269,6 +51484,7 @@ var init_UISlotRenderer = __esm({
|
|
|
51269
51484
|
"alert",
|
|
51270
51485
|
"dialog"
|
|
51271
51486
|
]);
|
|
51487
|
+
traitRefPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
51272
51488
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
51273
51489
|
}
|
|
51274
51490
|
});
|