@almadar/ui 5.28.0 → 5.28.2

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.
@@ -1,7 +1,4 @@
1
1
  export { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary';
2
- export { ArrayEditor, type ArrayEditorProps } from './ArrayEditor';
3
- export { ObjectEditor, type ObjectEditorProps } from './ObjectEditor';
4
- export { MapEditor, type MapEditorProps } from './MapEditor';
5
2
  export { JsonTreeEditor, type JsonTreeEditorProps } from './JsonTreeEditor';
6
3
  export { FileTree, type FileTreeProps, type FileTreeNode } from './FileTree';
7
4
  export { FormField, type FormFieldProps } from './FormField';
@@ -22224,422 +22224,6 @@ var init_DataList = __esm({
22224
22224
  DataList.displayName = "DataList";
22225
22225
  }
22226
22226
  });
22227
- function isTraitConfigObject(v) {
22228
- return v !== null && typeof v === "object" && !Array.isArray(v);
22229
- }
22230
- function LeafControl({
22231
- value,
22232
- onChange
22233
- }) {
22234
- if (typeof value === "boolean") {
22235
- return /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value, onChange: (c) => onChange(c) });
22236
- }
22237
- if (typeof value === "number") {
22238
- const [draft2, setDraft2] = React74__namespace.default.useState(String(value));
22239
- React74__namespace.default.useEffect(() => setDraft2(String(value)), [value]);
22240
- const commit2 = () => {
22241
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22242
- onChange(Number.isNaN(n) ? 0 : n);
22243
- };
22244
- return /* @__PURE__ */ jsxRuntime.jsx(
22245
- exports.Input,
22246
- {
22247
- inputType: "number",
22248
- value: draft2,
22249
- onChange: (e) => setDraft2(e.target.value),
22250
- onBlur: commit2,
22251
- onKeyDown: (e) => {
22252
- if (e.key === "Enter") commit2();
22253
- }
22254
- }
22255
- );
22256
- }
22257
- if (isTraitConfigObject(value)) {
22258
- const [draft2, setDraft2] = React74__namespace.default.useState(JSON.stringify(value));
22259
- React74__namespace.default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22260
- const commit2 = () => {
22261
- try {
22262
- const parsed = JSON.parse(draft2);
22263
- onChange(parsed);
22264
- } catch {
22265
- }
22266
- };
22267
- return /* @__PURE__ */ jsxRuntime.jsx(
22268
- exports.Input,
22269
- {
22270
- inputType: "text",
22271
- value: draft2,
22272
- onChange: (e) => setDraft2(e.target.value),
22273
- onBlur: commit2,
22274
- onKeyDown: (e) => {
22275
- if (e.key === "Enter") commit2();
22276
- }
22277
- }
22278
- );
22279
- }
22280
- if (Array.isArray(value)) {
22281
- const [draft2, setDraft2] = React74__namespace.default.useState(JSON.stringify(value));
22282
- React74__namespace.default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22283
- const commit2 = () => {
22284
- try {
22285
- const parsed = JSON.parse(draft2);
22286
- onChange(parsed);
22287
- } catch {
22288
- }
22289
- };
22290
- return /* @__PURE__ */ jsxRuntime.jsx(
22291
- exports.Input,
22292
- {
22293
- inputType: "text",
22294
- value: draft2,
22295
- onChange: (e) => setDraft2(e.target.value),
22296
- onBlur: commit2,
22297
- onKeyDown: (e) => {
22298
- if (e.key === "Enter") commit2();
22299
- }
22300
- }
22301
- );
22302
- }
22303
- const strVal = value === null ? "" : String(value);
22304
- const [draft, setDraft] = React74__namespace.default.useState(strVal);
22305
- React74__namespace.default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22306
- const commit = () => {
22307
- onChange(draft);
22308
- };
22309
- return /* @__PURE__ */ jsxRuntime.jsx(
22310
- exports.Input,
22311
- {
22312
- inputType: "text",
22313
- value: draft,
22314
- onChange: (e) => setDraft(e.target.value),
22315
- onBlur: commit,
22316
- onKeyDown: (e) => {
22317
- if (e.key === "Enter") commit();
22318
- }
22319
- }
22320
- );
22321
- }
22322
- function cloneElement(template) {
22323
- if (isTraitConfigObject(template)) {
22324
- const blank = {};
22325
- for (const k of Object.keys(template)) blank[k] = null;
22326
- return blank;
22327
- }
22328
- if (Array.isArray(template)) return [];
22329
- if (typeof template === "boolean") return false;
22330
- if (typeof template === "number") return 0;
22331
- return "";
22332
- }
22333
- exports.ArrayEditor = void 0;
22334
- var init_ArrayEditor = __esm({
22335
- "components/core/molecules/ArrayEditor.tsx"() {
22336
- "use client";
22337
- init_Stack();
22338
- init_Button();
22339
- init_Switch();
22340
- init_Input();
22341
- init_cn();
22342
- exports.ArrayEditor = ({ value, onChange, className }) => {
22343
- const arr = value;
22344
- const update = (idx, next) => {
22345
- const copy = [...arr];
22346
- copy[idx] = next;
22347
- onChange(copy);
22348
- };
22349
- const remove = (idx) => {
22350
- onChange(arr.filter((_, i) => i !== idx));
22351
- };
22352
- const add = () => {
22353
- const template = arr.length > 0 ? arr[0] : "";
22354
- onChange([...arr, cloneElement(template)]);
22355
- };
22356
- return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: cn("w-full", className), children: [
22357
- arr.map((elem, idx) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
22358
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(LeafControl, { value: elem, onChange: (next) => update(idx, next) }) }),
22359
- /* @__PURE__ */ jsxRuntime.jsx(
22360
- exports.Button,
22361
- {
22362
- variant: "ghost",
22363
- size: "sm",
22364
- icon: "trash-2",
22365
- onClick: () => remove(idx),
22366
- "aria-label": "Remove item"
22367
- }
22368
- )
22369
- ] }, idx)),
22370
- /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add item", onClick: add })
22371
- ] });
22372
- };
22373
- }
22374
- });
22375
- function isTraitConfigObject2(v) {
22376
- return v !== null && typeof v === "object" && !Array.isArray(v);
22377
- }
22378
- function ScalarControl({
22379
- fieldKey,
22380
- value,
22381
- onFieldChange
22382
- }) {
22383
- if (typeof value === "boolean") {
22384
- return /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value, onChange: (c) => onFieldChange(fieldKey, c) });
22385
- }
22386
- if (typeof value === "number") {
22387
- const [draft2, setDraft2] = React74__namespace.default.useState(String(value));
22388
- React74__namespace.default.useEffect(() => setDraft2(String(value)), [value]);
22389
- const commit2 = () => {
22390
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22391
- onFieldChange(fieldKey, Number.isNaN(n) ? 0 : n);
22392
- };
22393
- return /* @__PURE__ */ jsxRuntime.jsx(
22394
- exports.Input,
22395
- {
22396
- inputType: "number",
22397
- value: draft2,
22398
- onChange: (e) => setDraft2(e.target.value),
22399
- onBlur: commit2,
22400
- onKeyDown: (e) => {
22401
- if (e.key === "Enter") commit2();
22402
- }
22403
- }
22404
- );
22405
- }
22406
- if (isTraitConfigObject2(value)) {
22407
- const [draft2, setDraft2] = React74__namespace.default.useState(JSON.stringify(value));
22408
- React74__namespace.default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22409
- const commit2 = () => {
22410
- try {
22411
- onFieldChange(fieldKey, JSON.parse(draft2));
22412
- } catch {
22413
- }
22414
- };
22415
- return /* @__PURE__ */ jsxRuntime.jsx(
22416
- exports.Input,
22417
- {
22418
- inputType: "text",
22419
- value: draft2,
22420
- onChange: (e) => setDraft2(e.target.value),
22421
- onBlur: commit2,
22422
- onKeyDown: (e) => {
22423
- if (e.key === "Enter") commit2();
22424
- }
22425
- }
22426
- );
22427
- }
22428
- if (Array.isArray(value)) {
22429
- const [draft2, setDraft2] = React74__namespace.default.useState(JSON.stringify(value));
22430
- React74__namespace.default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22431
- const commit2 = () => {
22432
- try {
22433
- onFieldChange(fieldKey, JSON.parse(draft2));
22434
- } catch {
22435
- }
22436
- };
22437
- return /* @__PURE__ */ jsxRuntime.jsx(
22438
- exports.Input,
22439
- {
22440
- inputType: "text",
22441
- value: draft2,
22442
- onChange: (e) => setDraft2(e.target.value),
22443
- onBlur: commit2,
22444
- onKeyDown: (e) => {
22445
- if (e.key === "Enter") commit2();
22446
- }
22447
- }
22448
- );
22449
- }
22450
- const [draft, setDraft] = React74__namespace.default.useState(value === null ? "" : String(value));
22451
- React74__namespace.default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22452
- const commit = () => {
22453
- onFieldChange(fieldKey, draft);
22454
- };
22455
- return /* @__PURE__ */ jsxRuntime.jsx(
22456
- exports.Input,
22457
- {
22458
- inputType: "text",
22459
- value: draft,
22460
- onChange: (e) => setDraft(e.target.value),
22461
- onBlur: commit,
22462
- onKeyDown: (e) => {
22463
- if (e.key === "Enter") commit();
22464
- }
22465
- }
22466
- );
22467
- }
22468
- exports.ObjectEditor = void 0;
22469
- var init_ObjectEditor = __esm({
22470
- "components/core/molecules/ObjectEditor.tsx"() {
22471
- "use client";
22472
- init_Stack();
22473
- init_Typography();
22474
- init_Switch();
22475
- init_Input();
22476
- init_cn();
22477
- exports.ObjectEditor = ({ value, onChange, className }) => {
22478
- const entries = Object.entries(value);
22479
- const handleFieldChange = (k, next) => {
22480
- onChange({ ...value, [k]: next });
22481
- };
22482
- if (entries.length === 0) {
22483
- return /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "Empty object" });
22484
- }
22485
- return /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "xs", className: cn("w-full", className), children: entries.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", align: "center", children: [
22486
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-24 shrink-0 truncate", title: k, children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: k }) }),
22487
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ScalarControl, { fieldKey: k, value: v, onFieldChange: handleFieldChange }) })
22488
- ] }, k)) });
22489
- };
22490
- }
22491
- });
22492
- function isTraitConfigObject3(v) {
22493
- return v !== null && typeof v === "object" && !Array.isArray(v);
22494
- }
22495
- function ValueControl({
22496
- value,
22497
- onChange
22498
- }) {
22499
- if (typeof value === "boolean") {
22500
- return /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value, onChange: (c) => onChange(c) });
22501
- }
22502
- if (typeof value === "number") {
22503
- const [draft2, setDraft2] = React74__namespace.default.useState(String(value));
22504
- React74__namespace.default.useEffect(() => setDraft2(String(value)), [value]);
22505
- const commit2 = () => {
22506
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22507
- onChange(Number.isNaN(n) ? 0 : n);
22508
- };
22509
- return /* @__PURE__ */ jsxRuntime.jsx(
22510
- exports.Input,
22511
- {
22512
- inputType: "number",
22513
- value: draft2,
22514
- onChange: (e) => setDraft2(e.target.value),
22515
- onBlur: commit2,
22516
- onKeyDown: (e) => {
22517
- if (e.key === "Enter") commit2();
22518
- }
22519
- }
22520
- );
22521
- }
22522
- if (isTraitConfigObject3(value) || Array.isArray(value)) {
22523
- const [draft2, setDraft2] = React74__namespace.default.useState(JSON.stringify(value));
22524
- React74__namespace.default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22525
- const commit2 = () => {
22526
- try {
22527
- onChange(JSON.parse(draft2));
22528
- } catch {
22529
- }
22530
- };
22531
- return /* @__PURE__ */ jsxRuntime.jsx(
22532
- exports.Input,
22533
- {
22534
- inputType: "text",
22535
- value: draft2,
22536
- onChange: (e) => setDraft2(e.target.value),
22537
- onBlur: commit2,
22538
- onKeyDown: (e) => {
22539
- if (e.key === "Enter") commit2();
22540
- }
22541
- }
22542
- );
22543
- }
22544
- const [draft, setDraft] = React74__namespace.default.useState(value === null ? "" : String(value));
22545
- React74__namespace.default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22546
- const commit = () => {
22547
- onChange(draft);
22548
- };
22549
- return /* @__PURE__ */ jsxRuntime.jsx(
22550
- exports.Input,
22551
- {
22552
- inputType: "text",
22553
- value: draft,
22554
- onChange: (e) => setDraft(e.target.value),
22555
- onBlur: commit,
22556
- onKeyDown: (e) => {
22557
- if (e.key === "Enter") commit();
22558
- }
22559
- }
22560
- );
22561
- }
22562
- function KeyInput({
22563
- currentKey,
22564
- onRename
22565
- }) {
22566
- const [draft, setDraft] = React74__namespace.default.useState(currentKey);
22567
- React74__namespace.default.useEffect(() => setDraft(currentKey), [currentKey]);
22568
- const commit = () => {
22569
- const trimmed = draft.trim();
22570
- if (trimmed !== "" && trimmed !== currentKey) onRename(trimmed);
22571
- else setDraft(currentKey);
22572
- };
22573
- return /* @__PURE__ */ jsxRuntime.jsx(
22574
- exports.Input,
22575
- {
22576
- inputType: "text",
22577
- value: draft,
22578
- onChange: (e) => setDraft(e.target.value),
22579
- onBlur: commit,
22580
- onKeyDown: (e) => {
22581
- if (e.key === "Enter") commit();
22582
- },
22583
- className: "w-24 shrink-0 font-mono text-xs",
22584
- placeholder: "key"
22585
- }
22586
- );
22587
- }
22588
- exports.MapEditor = void 0;
22589
- var init_MapEditor = __esm({
22590
- "components/core/molecules/MapEditor.tsx"() {
22591
- "use client";
22592
- init_Stack();
22593
- init_Button();
22594
- init_Input();
22595
- init_Switch();
22596
- init_cn();
22597
- exports.MapEditor = ({ value, onChange, className }) => {
22598
- const entries = Object.entries(value);
22599
- const updateKey = (oldKey, newKey) => {
22600
- const next = {};
22601
- for (const [k, v] of Object.entries(value)) {
22602
- next[k === oldKey ? newKey : k] = v;
22603
- }
22604
- onChange(next);
22605
- };
22606
- const updateValue = (k, next) => {
22607
- onChange({ ...value, [k]: next });
22608
- };
22609
- const remove = (k) => {
22610
- const next = { ...value };
22611
- delete next[k];
22612
- onChange(next);
22613
- };
22614
- const add = () => {
22615
- let key = "key";
22616
- let i = 1;
22617
- while (key in value) {
22618
- key = `key${i}`;
22619
- i++;
22620
- }
22621
- onChange({ ...value, [key]: "" });
22622
- };
22623
- return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: cn("w-full", className), children: [
22624
- entries.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
22625
- /* @__PURE__ */ jsxRuntime.jsx(KeyInput, { currentKey: k, onRename: (newKey) => updateKey(k, newKey) }),
22626
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ValueControl, { value: v, onChange: (next) => updateValue(k, next) }) }),
22627
- /* @__PURE__ */ jsxRuntime.jsx(
22628
- exports.Button,
22629
- {
22630
- variant: "ghost",
22631
- size: "sm",
22632
- icon: "trash-2",
22633
- onClick: () => remove(k),
22634
- "aria-label": "Remove entry"
22635
- }
22636
- )
22637
- ] }, k)),
22638
- /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add entry", onClick: add })
22639
- ] });
22640
- };
22641
- }
22642
- });
22643
22227
  function kindOf(v) {
22644
22228
  if (v === null) return "null";
22645
22229
  if (isArr(v)) return "array";
@@ -22675,7 +22259,7 @@ function templateFrom(arr) {
22675
22259
  if (isArr(first)) return [];
22676
22260
  return emptyOf(kindOf(first));
22677
22261
  }
22678
- function ScalarControl2({
22262
+ function ScalarControl({
22679
22263
  value,
22680
22264
  onChange
22681
22265
  }) {
@@ -22736,7 +22320,7 @@ function ValueNode({
22736
22320
  if (kind === "object" || kind === "array") {
22737
22321
  return /* @__PURE__ */ jsxRuntime.jsx(ContainerNode, { value, onChange, depth });
22738
22322
  }
22739
- return /* @__PURE__ */ jsxRuntime.jsx(ScalarControl2, { value, onChange });
22323
+ return /* @__PURE__ */ jsxRuntime.jsx(ScalarControl, { value, onChange });
22740
22324
  }
22741
22325
  function Row({
22742
22326
  rowKey,
@@ -22751,10 +22335,10 @@ function Row({
22751
22335
  const [keyDraft, setKeyDraft] = React74__namespace.default.useState(rowKey);
22752
22336
  React74__namespace.default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
22753
22337
  const container = isObj(value) || isArr(value);
22754
- return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "group", children: [
22755
- /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", className: "py-0.5", children: [
22338
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "group w-max min-w-full", children: [
22339
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
22756
22340
  /* @__PURE__ */ jsxRuntime.jsx(KindSelect, { kind: kindOf(value), onChange: onChangeKind }),
22757
- isArrayItem ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", className: "w-7 shrink-0 font-mono", children: rowKey }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-28 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
22341
+ isArrayItem ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", className: "w-6 shrink-0 font-mono", children: rowKey }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
22758
22342
  exports.Input,
22759
22343
  {
22760
22344
  inputType: "text",
@@ -22767,8 +22351,7 @@ function Row({
22767
22351
  className: "font-mono"
22768
22352
  }
22769
22353
  ) }),
22770
- !container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) }),
22771
- container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
22354
+ !container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-48 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) }),
22772
22355
  /* @__PURE__ */ jsxRuntime.jsx(
22773
22356
  exports.Button,
22774
22357
  {
@@ -22777,11 +22360,11 @@ function Row({
22777
22360
  icon: "x",
22778
22361
  onClick: onRemove,
22779
22362
  "aria-label": "Remove",
22780
- className: "opacity-0 group-hover:opacity-100 transition-opacity"
22363
+ className: "shrink-0 text-muted-foreground hover:text-error"
22781
22364
  }
22782
22365
  )
22783
22366
  ] }),
22784
- container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-3", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) })
22367
+ container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) })
22785
22368
  ] });
22786
22369
  }
22787
22370
  function ContainerNode({
@@ -22848,7 +22431,7 @@ function ContainerNode({
22848
22431
  exports.VStack,
22849
22432
  {
22850
22433
  gap: "none",
22851
- className: cn("ml-2 pl-2 border-l-[length:var(--border-width-thin)] border-border"),
22434
+ className: cn("ml-1.5 pl-1.5 w-max min-w-full border-l-[length:var(--border-width-thin)] border-border"),
22852
22435
  children: [
22853
22436
  entries.map(([k, v], idx) => /* @__PURE__ */ jsxRuntime.jsx(
22854
22437
  Row,
@@ -22896,15 +22479,15 @@ var init_JsonTreeEditor = __esm({
22896
22479
  TYPE_LABEL = {
22897
22480
  object: "{}",
22898
22481
  array: "[]",
22899
- string: "abc",
22900
- number: "123",
22901
- boolean: "on/off",
22482
+ string: "txt",
22483
+ number: "num",
22484
+ boolean: "y/n",
22902
22485
  null: "\u2014"
22903
22486
  };
22904
22487
  KIND_OPTIONS = ["string", "number", "boolean", "object", "array"];
22905
22488
  exports.JsonTreeEditor = ({ value, onChange, className }) => {
22906
22489
  const root = value ?? "";
22907
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value: root, onChange, depth: 0 }) });
22490
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-x-auto rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value: root, onChange, depth: 0 }) });
22908
22491
  };
22909
22492
  }
22910
22493
  });
@@ -35629,7 +35212,7 @@ function TextLikeControl({
35629
35212
  }
35630
35213
  );
35631
35214
  }
35632
- function isTraitConfigObject4(v) {
35215
+ function isTraitConfigObject(v) {
35633
35216
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
35634
35217
  }
35635
35218
  function FieldControl({
@@ -35671,8 +35254,8 @@ function FieldControl({
35671
35254
  } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
35672
35255
  const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
35673
35256
  control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
35674
- } else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject4(effectiveValue)) {
35675
- const obj = isTraitConfigObject4(effectiveValue) ? effectiveValue : {};
35257
+ } else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
35258
+ const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
35676
35259
  control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
35677
35260
  } else {
35678
35261
  control = /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
@@ -37596,9 +37179,6 @@ var init_GraphCanvas = __esm({
37596
37179
  var init_molecules2 = __esm({
37597
37180
  "components/core/molecules/index.ts"() {
37598
37181
  init_ErrorBoundary();
37599
- init_ArrayEditor();
37600
- init_ObjectEditor();
37601
- init_MapEditor();
37602
37182
  init_JsonTreeEditor();
37603
37183
  init_FileTree();
37604
37184
  init_FormField();
@@ -22176,422 +22176,6 @@ var init_DataList = __esm({
22176
22176
  DataList.displayName = "DataList";
22177
22177
  }
22178
22178
  });
22179
- function isTraitConfigObject(v) {
22180
- return v !== null && typeof v === "object" && !Array.isArray(v);
22181
- }
22182
- function LeafControl({
22183
- value,
22184
- onChange
22185
- }) {
22186
- if (typeof value === "boolean") {
22187
- return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onChange(c) });
22188
- }
22189
- if (typeof value === "number") {
22190
- const [draft2, setDraft2] = React74__default.useState(String(value));
22191
- React74__default.useEffect(() => setDraft2(String(value)), [value]);
22192
- const commit2 = () => {
22193
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22194
- onChange(Number.isNaN(n) ? 0 : n);
22195
- };
22196
- return /* @__PURE__ */ jsx(
22197
- Input,
22198
- {
22199
- inputType: "number",
22200
- value: draft2,
22201
- onChange: (e) => setDraft2(e.target.value),
22202
- onBlur: commit2,
22203
- onKeyDown: (e) => {
22204
- if (e.key === "Enter") commit2();
22205
- }
22206
- }
22207
- );
22208
- }
22209
- if (isTraitConfigObject(value)) {
22210
- const [draft2, setDraft2] = React74__default.useState(JSON.stringify(value));
22211
- React74__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22212
- const commit2 = () => {
22213
- try {
22214
- const parsed = JSON.parse(draft2);
22215
- onChange(parsed);
22216
- } catch {
22217
- }
22218
- };
22219
- return /* @__PURE__ */ jsx(
22220
- Input,
22221
- {
22222
- inputType: "text",
22223
- value: draft2,
22224
- onChange: (e) => setDraft2(e.target.value),
22225
- onBlur: commit2,
22226
- onKeyDown: (e) => {
22227
- if (e.key === "Enter") commit2();
22228
- }
22229
- }
22230
- );
22231
- }
22232
- if (Array.isArray(value)) {
22233
- const [draft2, setDraft2] = React74__default.useState(JSON.stringify(value));
22234
- React74__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22235
- const commit2 = () => {
22236
- try {
22237
- const parsed = JSON.parse(draft2);
22238
- onChange(parsed);
22239
- } catch {
22240
- }
22241
- };
22242
- return /* @__PURE__ */ jsx(
22243
- Input,
22244
- {
22245
- inputType: "text",
22246
- value: draft2,
22247
- onChange: (e) => setDraft2(e.target.value),
22248
- onBlur: commit2,
22249
- onKeyDown: (e) => {
22250
- if (e.key === "Enter") commit2();
22251
- }
22252
- }
22253
- );
22254
- }
22255
- const strVal = value === null ? "" : String(value);
22256
- const [draft, setDraft] = React74__default.useState(strVal);
22257
- React74__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22258
- const commit = () => {
22259
- onChange(draft);
22260
- };
22261
- return /* @__PURE__ */ jsx(
22262
- Input,
22263
- {
22264
- inputType: "text",
22265
- value: draft,
22266
- onChange: (e) => setDraft(e.target.value),
22267
- onBlur: commit,
22268
- onKeyDown: (e) => {
22269
- if (e.key === "Enter") commit();
22270
- }
22271
- }
22272
- );
22273
- }
22274
- function cloneElement(template) {
22275
- if (isTraitConfigObject(template)) {
22276
- const blank = {};
22277
- for (const k of Object.keys(template)) blank[k] = null;
22278
- return blank;
22279
- }
22280
- if (Array.isArray(template)) return [];
22281
- if (typeof template === "boolean") return false;
22282
- if (typeof template === "number") return 0;
22283
- return "";
22284
- }
22285
- var ArrayEditor;
22286
- var init_ArrayEditor = __esm({
22287
- "components/core/molecules/ArrayEditor.tsx"() {
22288
- "use client";
22289
- init_Stack();
22290
- init_Button();
22291
- init_Switch();
22292
- init_Input();
22293
- init_cn();
22294
- ArrayEditor = ({ value, onChange, className }) => {
22295
- const arr = value;
22296
- const update = (idx, next) => {
22297
- const copy = [...arr];
22298
- copy[idx] = next;
22299
- onChange(copy);
22300
- };
22301
- const remove = (idx) => {
22302
- onChange(arr.filter((_, i) => i !== idx));
22303
- };
22304
- const add = () => {
22305
- const template = arr.length > 0 ? arr[0] : "";
22306
- onChange([...arr, cloneElement(template)]);
22307
- };
22308
- return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
22309
- arr.map((elem, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
22310
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(LeafControl, { value: elem, onChange: (next) => update(idx, next) }) }),
22311
- /* @__PURE__ */ jsx(
22312
- Button,
22313
- {
22314
- variant: "ghost",
22315
- size: "sm",
22316
- icon: "trash-2",
22317
- onClick: () => remove(idx),
22318
- "aria-label": "Remove item"
22319
- }
22320
- )
22321
- ] }, idx)),
22322
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add item", onClick: add })
22323
- ] });
22324
- };
22325
- }
22326
- });
22327
- function isTraitConfigObject2(v) {
22328
- return v !== null && typeof v === "object" && !Array.isArray(v);
22329
- }
22330
- function ScalarControl({
22331
- fieldKey,
22332
- value,
22333
- onFieldChange
22334
- }) {
22335
- if (typeof value === "boolean") {
22336
- return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onFieldChange(fieldKey, c) });
22337
- }
22338
- if (typeof value === "number") {
22339
- const [draft2, setDraft2] = React74__default.useState(String(value));
22340
- React74__default.useEffect(() => setDraft2(String(value)), [value]);
22341
- const commit2 = () => {
22342
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22343
- onFieldChange(fieldKey, Number.isNaN(n) ? 0 : n);
22344
- };
22345
- return /* @__PURE__ */ jsx(
22346
- Input,
22347
- {
22348
- inputType: "number",
22349
- value: draft2,
22350
- onChange: (e) => setDraft2(e.target.value),
22351
- onBlur: commit2,
22352
- onKeyDown: (e) => {
22353
- if (e.key === "Enter") commit2();
22354
- }
22355
- }
22356
- );
22357
- }
22358
- if (isTraitConfigObject2(value)) {
22359
- const [draft2, setDraft2] = React74__default.useState(JSON.stringify(value));
22360
- React74__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22361
- const commit2 = () => {
22362
- try {
22363
- onFieldChange(fieldKey, JSON.parse(draft2));
22364
- } catch {
22365
- }
22366
- };
22367
- return /* @__PURE__ */ jsx(
22368
- Input,
22369
- {
22370
- inputType: "text",
22371
- value: draft2,
22372
- onChange: (e) => setDraft2(e.target.value),
22373
- onBlur: commit2,
22374
- onKeyDown: (e) => {
22375
- if (e.key === "Enter") commit2();
22376
- }
22377
- }
22378
- );
22379
- }
22380
- if (Array.isArray(value)) {
22381
- const [draft2, setDraft2] = React74__default.useState(JSON.stringify(value));
22382
- React74__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22383
- const commit2 = () => {
22384
- try {
22385
- onFieldChange(fieldKey, JSON.parse(draft2));
22386
- } catch {
22387
- }
22388
- };
22389
- return /* @__PURE__ */ jsx(
22390
- Input,
22391
- {
22392
- inputType: "text",
22393
- value: draft2,
22394
- onChange: (e) => setDraft2(e.target.value),
22395
- onBlur: commit2,
22396
- onKeyDown: (e) => {
22397
- if (e.key === "Enter") commit2();
22398
- }
22399
- }
22400
- );
22401
- }
22402
- const [draft, setDraft] = React74__default.useState(value === null ? "" : String(value));
22403
- React74__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22404
- const commit = () => {
22405
- onFieldChange(fieldKey, draft);
22406
- };
22407
- return /* @__PURE__ */ jsx(
22408
- Input,
22409
- {
22410
- inputType: "text",
22411
- value: draft,
22412
- onChange: (e) => setDraft(e.target.value),
22413
- onBlur: commit,
22414
- onKeyDown: (e) => {
22415
- if (e.key === "Enter") commit();
22416
- }
22417
- }
22418
- );
22419
- }
22420
- var ObjectEditor;
22421
- var init_ObjectEditor = __esm({
22422
- "components/core/molecules/ObjectEditor.tsx"() {
22423
- "use client";
22424
- init_Stack();
22425
- init_Typography();
22426
- init_Switch();
22427
- init_Input();
22428
- init_cn();
22429
- ObjectEditor = ({ value, onChange, className }) => {
22430
- const entries = Object.entries(value);
22431
- const handleFieldChange = (k, next) => {
22432
- onChange({ ...value, [k]: next });
22433
- };
22434
- if (entries.length === 0) {
22435
- return /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: "Empty object" });
22436
- }
22437
- return /* @__PURE__ */ jsx(VStack, { gap: "xs", className: cn("w-full", className), children: entries.map(([k, v]) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
22438
- /* @__PURE__ */ jsx("span", { className: "w-24 shrink-0 truncate", title: k, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: k }) }),
22439
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(ScalarControl, { fieldKey: k, value: v, onFieldChange: handleFieldChange }) })
22440
- ] }, k)) });
22441
- };
22442
- }
22443
- });
22444
- function isTraitConfigObject3(v) {
22445
- return v !== null && typeof v === "object" && !Array.isArray(v);
22446
- }
22447
- function ValueControl({
22448
- value,
22449
- onChange
22450
- }) {
22451
- if (typeof value === "boolean") {
22452
- return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onChange(c) });
22453
- }
22454
- if (typeof value === "number") {
22455
- const [draft2, setDraft2] = React74__default.useState(String(value));
22456
- React74__default.useEffect(() => setDraft2(String(value)), [value]);
22457
- const commit2 = () => {
22458
- const n = draft2.trim() === "" ? 0 : Number(draft2);
22459
- onChange(Number.isNaN(n) ? 0 : n);
22460
- };
22461
- return /* @__PURE__ */ jsx(
22462
- Input,
22463
- {
22464
- inputType: "number",
22465
- value: draft2,
22466
- onChange: (e) => setDraft2(e.target.value),
22467
- onBlur: commit2,
22468
- onKeyDown: (e) => {
22469
- if (e.key === "Enter") commit2();
22470
- }
22471
- }
22472
- );
22473
- }
22474
- if (isTraitConfigObject3(value) || Array.isArray(value)) {
22475
- const [draft2, setDraft2] = React74__default.useState(JSON.stringify(value));
22476
- React74__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
22477
- const commit2 = () => {
22478
- try {
22479
- onChange(JSON.parse(draft2));
22480
- } catch {
22481
- }
22482
- };
22483
- return /* @__PURE__ */ jsx(
22484
- Input,
22485
- {
22486
- inputType: "text",
22487
- value: draft2,
22488
- onChange: (e) => setDraft2(e.target.value),
22489
- onBlur: commit2,
22490
- onKeyDown: (e) => {
22491
- if (e.key === "Enter") commit2();
22492
- }
22493
- }
22494
- );
22495
- }
22496
- const [draft, setDraft] = React74__default.useState(value === null ? "" : String(value));
22497
- React74__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
22498
- const commit = () => {
22499
- onChange(draft);
22500
- };
22501
- return /* @__PURE__ */ jsx(
22502
- Input,
22503
- {
22504
- inputType: "text",
22505
- value: draft,
22506
- onChange: (e) => setDraft(e.target.value),
22507
- onBlur: commit,
22508
- onKeyDown: (e) => {
22509
- if (e.key === "Enter") commit();
22510
- }
22511
- }
22512
- );
22513
- }
22514
- function KeyInput({
22515
- currentKey,
22516
- onRename
22517
- }) {
22518
- const [draft, setDraft] = React74__default.useState(currentKey);
22519
- React74__default.useEffect(() => setDraft(currentKey), [currentKey]);
22520
- const commit = () => {
22521
- const trimmed = draft.trim();
22522
- if (trimmed !== "" && trimmed !== currentKey) onRename(trimmed);
22523
- else setDraft(currentKey);
22524
- };
22525
- return /* @__PURE__ */ jsx(
22526
- Input,
22527
- {
22528
- inputType: "text",
22529
- value: draft,
22530
- onChange: (e) => setDraft(e.target.value),
22531
- onBlur: commit,
22532
- onKeyDown: (e) => {
22533
- if (e.key === "Enter") commit();
22534
- },
22535
- className: "w-24 shrink-0 font-mono text-xs",
22536
- placeholder: "key"
22537
- }
22538
- );
22539
- }
22540
- var MapEditor;
22541
- var init_MapEditor = __esm({
22542
- "components/core/molecules/MapEditor.tsx"() {
22543
- "use client";
22544
- init_Stack();
22545
- init_Button();
22546
- init_Input();
22547
- init_Switch();
22548
- init_cn();
22549
- MapEditor = ({ value, onChange, className }) => {
22550
- const entries = Object.entries(value);
22551
- const updateKey = (oldKey, newKey) => {
22552
- const next = {};
22553
- for (const [k, v] of Object.entries(value)) {
22554
- next[k === oldKey ? newKey : k] = v;
22555
- }
22556
- onChange(next);
22557
- };
22558
- const updateValue = (k, next) => {
22559
- onChange({ ...value, [k]: next });
22560
- };
22561
- const remove = (k) => {
22562
- const next = { ...value };
22563
- delete next[k];
22564
- onChange(next);
22565
- };
22566
- const add = () => {
22567
- let key = "key";
22568
- let i = 1;
22569
- while (key in value) {
22570
- key = `key${i}`;
22571
- i++;
22572
- }
22573
- onChange({ ...value, [key]: "" });
22574
- };
22575
- return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
22576
- entries.map(([k, v]) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
22577
- /* @__PURE__ */ jsx(KeyInput, { currentKey: k, onRename: (newKey) => updateKey(k, newKey) }),
22578
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(ValueControl, { value: v, onChange: (next) => updateValue(k, next) }) }),
22579
- /* @__PURE__ */ jsx(
22580
- Button,
22581
- {
22582
- variant: "ghost",
22583
- size: "sm",
22584
- icon: "trash-2",
22585
- onClick: () => remove(k),
22586
- "aria-label": "Remove entry"
22587
- }
22588
- )
22589
- ] }, k)),
22590
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add entry", onClick: add })
22591
- ] });
22592
- };
22593
- }
22594
- });
22595
22179
  function kindOf(v) {
22596
22180
  if (v === null) return "null";
22597
22181
  if (isArr(v)) return "array";
@@ -22627,7 +22211,7 @@ function templateFrom(arr) {
22627
22211
  if (isArr(first)) return [];
22628
22212
  return emptyOf(kindOf(first));
22629
22213
  }
22630
- function ScalarControl2({
22214
+ function ScalarControl({
22631
22215
  value,
22632
22216
  onChange
22633
22217
  }) {
@@ -22688,7 +22272,7 @@ function ValueNode({
22688
22272
  if (kind === "object" || kind === "array") {
22689
22273
  return /* @__PURE__ */ jsx(ContainerNode, { value, onChange, depth });
22690
22274
  }
22691
- return /* @__PURE__ */ jsx(ScalarControl2, { value, onChange });
22275
+ return /* @__PURE__ */ jsx(ScalarControl, { value, onChange });
22692
22276
  }
22693
22277
  function Row({
22694
22278
  rowKey,
@@ -22703,10 +22287,10 @@ function Row({
22703
22287
  const [keyDraft, setKeyDraft] = React74__default.useState(rowKey);
22704
22288
  React74__default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
22705
22289
  const container = isObj(value) || isArr(value);
22706
- return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "group", children: [
22707
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", className: "py-0.5", children: [
22290
+ return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "group w-max min-w-full", children: [
22291
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
22708
22292
  /* @__PURE__ */ jsx(KindSelect, { kind: kindOf(value), onChange: onChangeKind }),
22709
- isArrayItem ? /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "w-7 shrink-0 font-mono", children: rowKey }) : /* @__PURE__ */ jsx("div", { className: "w-28 shrink-0", children: /* @__PURE__ */ jsx(
22293
+ isArrayItem ? /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "w-6 shrink-0 font-mono", children: rowKey }) : /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsx(
22710
22294
  Input,
22711
22295
  {
22712
22296
  inputType: "text",
@@ -22719,8 +22303,7 @@ function Row({
22719
22303
  className: "font-mono"
22720
22304
  }
22721
22305
  ) }),
22722
- !container && /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) }),
22723
- container && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
22306
+ !container && /* @__PURE__ */ jsx("div", { className: "w-48 shrink-0", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) }),
22724
22307
  /* @__PURE__ */ jsx(
22725
22308
  Button,
22726
22309
  {
@@ -22729,11 +22312,11 @@ function Row({
22729
22312
  icon: "x",
22730
22313
  onClick: onRemove,
22731
22314
  "aria-label": "Remove",
22732
- className: "opacity-0 group-hover:opacity-100 transition-opacity"
22315
+ className: "shrink-0 text-muted-foreground hover:text-error"
22733
22316
  }
22734
22317
  )
22735
22318
  ] }),
22736
- container && /* @__PURE__ */ jsx("div", { className: "pl-3", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) })
22319
+ container && /* @__PURE__ */ jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) })
22737
22320
  ] });
22738
22321
  }
22739
22322
  function ContainerNode({
@@ -22800,7 +22383,7 @@ function ContainerNode({
22800
22383
  VStack,
22801
22384
  {
22802
22385
  gap: "none",
22803
- className: cn("ml-2 pl-2 border-l-[length:var(--border-width-thin)] border-border"),
22386
+ className: cn("ml-1.5 pl-1.5 w-max min-w-full border-l-[length:var(--border-width-thin)] border-border"),
22804
22387
  children: [
22805
22388
  entries.map(([k, v], idx) => /* @__PURE__ */ jsx(
22806
22389
  Row,
@@ -22848,15 +22431,15 @@ var init_JsonTreeEditor = __esm({
22848
22431
  TYPE_LABEL = {
22849
22432
  object: "{}",
22850
22433
  array: "[]",
22851
- string: "abc",
22852
- number: "123",
22853
- boolean: "on/off",
22434
+ string: "txt",
22435
+ number: "num",
22436
+ boolean: "y/n",
22854
22437
  null: "\u2014"
22855
22438
  };
22856
22439
  KIND_OPTIONS = ["string", "number", "boolean", "object", "array"];
22857
22440
  JsonTreeEditor = ({ value, onChange, className }) => {
22858
22441
  const root = value ?? "";
22859
- return /* @__PURE__ */ jsx("div", { className: cn("w-full rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsx(ValueNode, { value: root, onChange, depth: 0 }) });
22442
+ return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsx(ValueNode, { value: root, onChange, depth: 0 }) });
22860
22443
  };
22861
22444
  }
22862
22445
  });
@@ -35581,7 +35164,7 @@ function TextLikeControl({
35581
35164
  }
35582
35165
  );
35583
35166
  }
35584
- function isTraitConfigObject4(v) {
35167
+ function isTraitConfigObject(v) {
35585
35168
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
35586
35169
  }
35587
35170
  function FieldControl({
@@ -35623,8 +35206,8 @@ function FieldControl({
35623
35206
  } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
35624
35207
  const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
35625
35208
  control = /* @__PURE__ */ jsx(JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
35626
- } else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject4(effectiveValue)) {
35627
- const obj = isTraitConfigObject4(effectiveValue) ? effectiveValue : {};
35209
+ } else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
35210
+ const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
35628
35211
  control = /* @__PURE__ */ jsx(JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
35629
35212
  } else {
35630
35213
  control = /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "muted", children: [
@@ -37548,9 +37131,6 @@ var init_GraphCanvas = __esm({
37548
37131
  var init_molecules2 = __esm({
37549
37132
  "components/core/molecules/index.ts"() {
37550
37133
  init_ErrorBoundary();
37551
- init_ArrayEditor();
37552
- init_ObjectEditor();
37553
- init_MapEditor();
37554
37134
  init_JsonTreeEditor();
37555
37135
  init_FileTree();
37556
37136
  init_FormField();
@@ -50180,4 +49760,4 @@ init_AboutPageTemplate();
50180
49760
  // components/index.ts
50181
49761
  init_cn();
50182
49762
 
50183
- export { ALL_PRESETS, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArrayEditor, 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, MapEditor, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectEditor, 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 };
49763
+ 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.28.0",
3
+ "version": "5.28.2",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -1,15 +0,0 @@
1
- import React from 'react';
2
- import type { TraitConfigValue } from '@almadar/core';
3
- export interface ArrayEditorProps {
4
- /** Current array value. */
5
- value: ReadonlyArray<TraitConfigValue>;
6
- /** Fired when the array changes. */
7
- onChange: (next: ReadonlyArray<TraitConfigValue>) => void;
8
- /** Additional CSS classes. */
9
- className?: string;
10
- }
11
- /**
12
- * ArrayEditor — edits a `ReadonlyArray<TraitConfigValue>` with add / remove per row.
13
- * Each row infers its editor from the element's runtime type.
14
- */
15
- export declare const ArrayEditor: React.FC<ArrayEditorProps>;
@@ -1,16 +0,0 @@
1
- import React from 'react';
2
- import type { TraitConfigObject } from '@almadar/core';
3
- export interface MapEditorProps {
4
- /** Current map value (object used as string-keyed map). */
5
- value: TraitConfigObject;
6
- /** Fired when an entry is added, removed, or its key/value is changed. */
7
- onChange: (next: TraitConfigObject) => void;
8
- /** Additional CSS classes. */
9
- className?: string;
10
- }
11
- /**
12
- * MapEditor — edits a `TraitConfigObject` as a dynamic key/value map.
13
- * Unlike ObjectEditor (fixed schema keys), MapEditor allows adding/removing entries
14
- * and renaming keys.
15
- */
16
- export declare const MapEditor: React.FC<MapEditorProps>;
@@ -1,15 +0,0 @@
1
- import React from 'react';
2
- import type { TraitConfigObject } from '@almadar/core';
3
- export interface ObjectEditorProps {
4
- /** Current object value. */
5
- value: TraitConfigObject;
6
- /** Fired when any field changes. */
7
- onChange: (next: TraitConfigObject) => void;
8
- /** Additional CSS classes. */
9
- className?: string;
10
- }
11
- /**
12
- * ObjectEditor — edits a `TraitConfigObject` showing one labeled row per key.
13
- * Keys are fixed (derived from the current object's shape).
14
- */
15
- export declare const ObjectEditor: React.FC<ObjectEditorProps>;