@almadar/ui 6.51.2 → 6.53.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.
Files changed (127) hide show
  1. package/dist/{EntityBindingContext-BbxrwSb9.d.ts → AwaitingSkeletonContext-Bh399p1x.d.ts} +17 -2
  2. package/dist/{Canvas3DHost-CLC_jXh_.d.ts → Canvas3DHost-B-y2TNij.d.ts} +1 -1
  3. package/dist/{FileTree-RKQqRhIM.d.ts → FileTree-DUi7e7Z8.d.ts} +5 -5
  4. package/dist/{GameAudioProvider-BgWLggIy.d.ts → GameAudioProvider-DyBvYP2c.d.ts} +1 -1
  5. package/dist/{NavStackContext-B-XLULCO.d.ts → NavStackContext-04NLdXsY.d.ts} +8 -0
  6. package/dist/Typography-JGSDH4JP.js +5 -0
  7. package/dist/{UISlotContext-DNM8iXna.d.ts → UISlotContext-CS487Uoc.d.ts} +1 -1
  8. package/dist/{UISlotRenderer-7UYHFW4S.js → UISlotRenderer-JT34I3O7.js} +9 -9
  9. package/dist/avl/index.cjs +39958 -38525
  10. package/dist/avl/index.d.ts +8 -5
  11. package/dist/avl/index.js +37 -26
  12. package/dist/{chunk-JXUYEO7U.js → chunk-2LFBQ4IS.js} +7 -1
  13. package/dist/{chunk-GIPZSCND.js → chunk-3EF5SDIJ.js} +31157 -31206
  14. package/dist/{chunk-GHXWGQTX.js → chunk-4OZDHCZV.js} +1 -1
  15. package/dist/{chunk-HQDKHLFG.js → chunk-64WACXM7.js} +15 -1
  16. package/dist/{chunk-FGHRVJCI.js → chunk-6O37FCX4.js} +13 -2
  17. package/dist/{chunk-BUEIZY54.js → chunk-7LM6I3NA.js} +8 -7
  18. package/dist/chunk-CBIJP5PL.js +284 -0
  19. package/dist/{chunk-MWPX2O4M.js → chunk-GMDMOYXD.js} +3 -16
  20. package/dist/{chunk-YKHNK5JH.js → chunk-GODZKHAL.js} +11 -4
  21. package/dist/{chunk-T7IH5ABO.js → chunk-IKULQIDX.js} +199 -88
  22. package/dist/{chunk-NTO555KF.js → chunk-JRW33U35.js} +183 -62
  23. package/dist/{chunk-OLZ3EEML.js → chunk-KQXXO42S.js} +106 -90
  24. package/dist/chunk-OKWD7LPO.js +80 -0
  25. package/dist/{chunk-YHY5K2Y7.js → chunk-PEST66PN.js} +6 -0
  26. package/dist/{chunk-L55SAFKL.js → chunk-UGHAADU5.js} +77 -1
  27. package/dist/{chunk-6CFYRP4S.js → chunk-VHTJRS2N.js} +4 -8
  28. package/dist/{chunk-R4V7IZQP.js → chunk-WPNM2KC6.js} +2 -2
  29. package/dist/{cn-CO-0rolG.d.ts → cn-ClXGlIOY.d.ts} +2 -2
  30. package/dist/components/index.cjs +46084 -44766
  31. package/dist/components/index.d.ts +645 -699
  32. package/dist/components/index.js +621 -13
  33. package/dist/context/index.cjs +20 -7
  34. package/dist/context/index.d.ts +3 -3
  35. package/dist/context/index.js +3 -3
  36. package/dist/hooks/index.cjs +126 -9
  37. package/dist/hooks/index.d.ts +32 -7
  38. package/dist/hooks/index.js +7 -7
  39. package/dist/lib/drawable/three/index.cjs +79 -2
  40. package/dist/lib/drawable/three/index.d.ts +3 -3
  41. package/dist/lib/drawable/three/index.js +7 -7
  42. package/dist/lib/index.cjs +116 -2
  43. package/dist/lib/index.d.ts +29 -6
  44. package/dist/lib/index.js +6 -5
  45. package/dist/locales/index.cjs +231 -3
  46. package/dist/locales/index.js +155 -3
  47. package/dist/{paintDispatch-CMgOyVjS.d.ts → paintDispatch-_6EhJCiL.d.ts} +6 -6
  48. package/dist/providers/index.cjs +36404 -35028
  49. package/dist/providers/index.d.ts +34 -9
  50. package/dist/providers/index.js +82 -19
  51. package/dist/renderer/index.cjs +6 -0
  52. package/dist/renderer/index.d.ts +1 -1
  53. package/dist/renderer/index.js +1 -1
  54. package/dist/runtime/index.cjs +37861 -36437
  55. package/dist/runtime/index.d.ts +6 -4
  56. package/dist/runtime/index.js +11 -11
  57. package/dist/ssr/index.cjs +584 -181
  58. package/dist/ssr/index.d.cts +36 -44
  59. package/dist/ssr/index.d.ts +36 -44
  60. package/dist/ssr/index.js +527 -124
  61. package/dist/{themeTokens-CN9WCXQc.d.ts → themeTokens-Ccu7EmGY.d.ts} +4 -2
  62. package/dist/{useUISlots-CwUWM1ra.d.ts → useUISlots-1dk2TR4j.d.ts} +1 -9
  63. package/dist/{verificationRegistry-DBHfOR9y.d.ts → verificationRegistry-CD7Xb40L.d.ts} +1 -1
  64. package/locales/ar.json +77 -1
  65. package/locales/en.json +77 -1
  66. package/locales/sl.json +77 -1
  67. package/package.json +13 -10
  68. package/tailwind-preset.cjs +37 -1
  69. package/themes/_base.css +114 -8
  70. package/themes/_contract.md +6 -0
  71. package/themes/almadar-website.css +2 -0
  72. package/themes/almadar.css +2 -0
  73. package/themes/aqua.css +5 -3
  74. package/themes/arabesque.css +9 -7
  75. package/themes/art-deco.css +5 -3
  76. package/themes/art-nouveau.css +4 -0
  77. package/themes/atelier.css +10 -8
  78. package/themes/bauhaus.css +2 -0
  79. package/themes/bloomberg-dense.css +13 -11
  80. package/themes/blueprint.css +2 -0
  81. package/themes/clay.css +2 -0
  82. package/themes/comic.css +12 -10
  83. package/themes/constructivist.css +2 -0
  84. package/themes/corporate.css +4 -2
  85. package/themes/cyberpunk.css +2 -0
  86. package/themes/frutiger-aero.css +2 -0
  87. package/themes/game-adventure.css +1 -0
  88. package/themes/game-rpg.css +1 -0
  89. package/themes/game-sci-fi.css +1 -0
  90. package/themes/game-ui-pack.css +1 -0
  91. package/themes/gazette.css +10 -8
  92. package/themes/glass.css +17 -15
  93. package/themes/gothic.css +2 -0
  94. package/themes/ink-wash.css +2 -0
  95. package/themes/kawaii.css +2 -0
  96. package/themes/kiosk.css +17 -15
  97. package/themes/linear-clean.css +12 -10
  98. package/themes/luxury.css +2 -0
  99. package/themes/mac-classic.css +2 -0
  100. package/themes/material.css +2 -0
  101. package/themes/memphis.css +2 -0
  102. package/themes/mid-century.css +2 -0
  103. package/themes/minimalist.css +2 -0
  104. package/themes/mudcloth.css +2 -0
  105. package/themes/neon.css +2 -0
  106. package/themes/neumorphic.css +2 -0
  107. package/themes/newsprint.css +2 -0
  108. package/themes/notion-editorial.css +12 -10
  109. package/themes/pixel.css +2 -0
  110. package/themes/prism.css +20 -18
  111. package/themes/retro.css +2 -0
  112. package/themes/risograph.css +2 -0
  113. package/themes/scandi.css +2 -0
  114. package/themes/sketch.css +2 -0
  115. package/themes/solarpunk.css +2 -0
  116. package/themes/steampunk.css +2 -0
  117. package/themes/swiss.css +2 -0
  118. package/themes/terminal.css +8 -6
  119. package/themes/trait-wars.css +2 -0
  120. package/themes/ukiyo-e.css +2 -0
  121. package/themes/vaporwave.css +2 -0
  122. package/themes/victorian.css +2 -0
  123. package/themes/wabi-sabi.css +2 -0
  124. package/themes/win95.css +2 -0
  125. package/themes/wireframe.css +2 -0
  126. package/themes/zine.css +2 -0
  127. package/dist/Typography-2Z3JKWHN.js +0 -5
@@ -1,4 +1,4 @@
1
- import { en_default } from './chunk-L55SAFKL.js';
1
+ import { en_default } from './chunk-UGHAADU5.js';
2
2
 
3
3
  // lib/format.ts
4
4
  var { $meta: _meta, ...coreMessages } = en_default;
@@ -33,4 +33,18 @@ function cn(...inputs) {
33
33
  return twMerge(clsx(inputs));
34
34
  }
35
35
 
36
- export { cn };
36
+ // lib/domPassthrough.ts
37
+ var GLOBAL_ATTRIBUTES = /* @__PURE__ */ new Set(["role", "id", "lang", "dir", "tabIndex"]);
38
+ function domPassthrough(props) {
39
+ const out = {};
40
+ for (const [key, value] of Object.entries(props)) {
41
+ if (key.startsWith("aria-") || key.startsWith("data-") || GLOBAL_ATTRIBUTES.has(key)) {
42
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === void 0) {
43
+ out[key] = value;
44
+ }
45
+ }
46
+ }
47
+ return out;
48
+ }
49
+
50
+ export { cn, domPassthrough };
@@ -98,7 +98,10 @@ var MOTION_SHAPE_VARS = [
98
98
  { cssVar: "--motion-popover-exit-to-transform", key: "popoverExit" },
99
99
  { cssVar: "--motion-toast-enter-from-transform", key: "toastEnter" },
100
100
  { cssVar: "--motion-toast-exit-to-transform", key: "toastExit" },
101
- { cssVar: "--motion-page-enter-from-transform", key: "pageEnter" }
101
+ { cssVar: "--motion-page-enter-from-transform", key: "pageEnter" },
102
+ { cssVar: "--motion-enter-rise-from-transform", key: "enterRise" },
103
+ { cssVar: "--motion-enter-scale-from-transform", key: "enterScale" },
104
+ { cssVar: "--motion-enter-slide-from-transform", key: "enterSlide" }
102
105
  ];
103
106
  var ICONOGRAPHY_VARS = [
104
107
  { cssVar: "--icon-family", key: "family" },
@@ -122,6 +125,7 @@ var GEOMETRY_VARS = [
122
125
  { cssVar: "--border-heavy", key: "borderHeavy" },
123
126
  { cssVar: "--corner-shape", key: "cornerShape" },
124
127
  { cssVar: "--corner-shape-pill", key: "cornerShapePill" },
128
+ { cssVar: "--corner-shape-interactive", key: "cornerShapeInteractive" },
125
129
  { cssVar: "--border-style", key: "borderStyle" },
126
130
  { cssVar: "--border-style-interactive", key: "borderStyleInteractive" }
127
131
  ];
@@ -260,6 +264,13 @@ function emitMotion(m, vars) {
260
264
  }
261
265
  }
262
266
  applyFlat(m.shapes, MOTION_SHAPE_VARS, vars);
267
+ if (m.entry?.default !== void 0) vars["--motion-enter-default"] = enterKeyframe(m.entry.default);
268
+ if (m.entry?.stagger !== void 0) vars["--motion-enter-stagger"] = m.entry.stagger;
269
+ if (m.busyDelay !== void 0) vars["--motion-busy-delay"] = m.busyDelay;
270
+ if (m.awaitingSkeleton !== void 0) vars["--awaiting-skeleton-display"] = m.awaitingSkeleton ? "block" : "none";
271
+ }
272
+ function enterKeyframe(enter) {
273
+ return enter === "none" ? "none" : `almadar-enter-${enter}`;
263
274
  }
264
275
  function emitIconography(i, vars) {
265
276
  applyFlat(i, ICONOGRAPHY_VARS, vars);
@@ -276,4 +287,4 @@ function resolveThemeForRuntime(theme) {
276
287
  return theme;
277
288
  }
278
289
 
279
- export { DENSITY_ELEMENT_VARS, DENSITY_SPACING_VARS, ELEVATION_VARS, GEOMETRY_VARS, ICONOGRAPHY_VARS, LEGACY_PREFIXES, MOTION_DURATION_KEYS, MOTION_EASING_KEYS, MOTION_INTENT_VARS, MOTION_SHAPE_VARS, SURFACE_VARS, TYPE_FAMILY_VARS, TYPE_HEADING_VARS, TYPE_INTENT_VARS, TYPE_SIZE_KEYS, resolveThemeForRuntime, themeTokensToCssVars };
290
+ export { DENSITY_ELEMENT_VARS, DENSITY_SPACING_VARS, ELEVATION_VARS, GEOMETRY_VARS, ICONOGRAPHY_VARS, LEGACY_PREFIXES, MOTION_DURATION_KEYS, MOTION_EASING_KEYS, MOTION_INTENT_VARS, MOTION_SHAPE_VARS, SURFACE_VARS, TYPE_FAMILY_VARS, TYPE_HEADING_VARS, TYPE_INTENT_VARS, TYPE_SIZE_KEYS, enterKeyframe, resolveThemeForRuntime, themeTokensToCssVars };
@@ -1,8 +1,7 @@
1
- import { domPassthrough } from './chunk-MWPX2O4M.js';
2
1
  import { useTapReveal } from './chunk-XJTHMW4G.js';
3
2
  import { useEventBus } from './chunk-6EV3OEBQ.js';
4
3
  import { updateAssetStatus } from './chunk-O7OLVVBR.js';
5
- import { cn } from './chunk-HQDKHLFG.js';
4
+ import { cn, domPassthrough } from './chunk-64WACXM7.js';
6
5
  import { createLogger } from '@almadar/logger';
7
6
  import React, { useCallback, createContext, useContext } from 'react';
8
7
  import { useThemeScope } from '@almadar/ui/context';
@@ -369,18 +368,20 @@ function pressableProps(onPress, options = {}) {
369
368
  }
370
369
  };
371
370
  }
372
- function rowActivationProps(onActivate) {
373
- if (!onActivate) return {};
371
+ function rowOpenControlProps(enabled) {
372
+ if (!enabled) return {};
374
373
  return {
374
+ role: "button",
375
375
  tabIndex: 0,
376
- onClick: onActivate,
377
376
  onKeyDown: (e) => {
378
- if (e.target !== e.currentTarget || e.key !== "Enter") return;
377
+ if (e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " ") return;
379
378
  e.preventDefault();
380
379
  clickElement(e.currentTarget);
381
380
  }
382
381
  };
383
382
  }
383
+ var STRETCHED_CONTROL = "after:absolute after:inset-0 after:content-[''] after:rounded-[inherit] focus-visible:outline-none focus-visible:after:ring-2 focus-visible:after:ring-primary focus-visible:after:ring-inset";
384
+ var STRETCHED_ABOVE = "relative z-[1]";
384
385
 
385
386
  // components/core/atoms/Box.tsx
386
387
  var paddingStyles = {
@@ -1998,4 +1999,4 @@ function rotatePoint(p, center, radians) {
1998
1999
  return { x: center.x + dx * cos - dy * sin, y: center.y + dx * sin + dy * cos };
1999
2000
  }
2000
2001
 
2001
- export { AVL_FONT, AVL_INK, AVL_STROKE, Box, CONFETTI_BURST_KEYFRAMES, CONNECTION_COLORS, DrawFxLayer, DrawGroup, DrawMesh, DrawShape, DrawSkinnedMesh, DrawableRegistryContext, EFFECT_CATEGORY_COLORS, HStack, OPERATOR_CATEGORY_COLORS, SPRITE_FALLBACK_FILL, SPRITE_FALLBACK_STROKE, STATE_COLORS, Stack, THEME_SERIES, VStack, applyMeshAnimation, applyShapeAnimation, asEffectOperator, atlasFailed, atlasUrlOf, avlBlend, avlSeries, avlTint, blit, buildHitIndex, clampSegments, collectDrawnItems, createConfettiParticles, effectCategoryOf, effectZoneOf, expandFxLayer, fxHash01, getAtlas, getImageStatus, getOrLoadImage, getStateRole, hitTestSprites, isAnimatedGroup, isAnimatedMesh, isAnimatedShape, isAtlasAsset, isSpriteSheetAtlas, isValidScenePos, paintShape, paintSkinnedMesh, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, polyhedronBounds, pressableProps, resolveAssetSource, resolveThemeColor, rowActivationProps, spriteAssetState, spriteRect, subRectFor, traitEventWires, traitLevelFromTrait, traitTransitionRenderUi, withPreviewPosition };
2002
+ export { AVL_FONT, AVL_INK, AVL_STROKE, Box, CONFETTI_BURST_KEYFRAMES, CONNECTION_COLORS, DrawFxLayer, DrawGroup, DrawMesh, DrawShape, DrawSkinnedMesh, DrawableRegistryContext, EFFECT_CATEGORY_COLORS, HStack, OPERATOR_CATEGORY_COLORS, SPRITE_FALLBACK_FILL, SPRITE_FALLBACK_STROKE, STATE_COLORS, STRETCHED_ABOVE, STRETCHED_CONTROL, Stack, THEME_SERIES, VStack, applyMeshAnimation, applyShapeAnimation, asEffectOperator, atlasFailed, atlasUrlOf, avlBlend, avlSeries, avlTint, blit, buildHitIndex, clampSegments, collectDrawnItems, createConfettiParticles, effectCategoryOf, effectZoneOf, expandFxLayer, fxHash01, getAtlas, getImageStatus, getOrLoadImage, getStateRole, hitTestSprites, isAnimatedGroup, isAnimatedMesh, isAnimatedShape, isAtlasAsset, isSpriteSheetAtlas, isValidScenePos, paintShape, paintSkinnedMesh, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, polyhedronBounds, pressableProps, resolveAssetSource, resolveThemeColor, rowOpenControlProps, spriteAssetState, spriteRect, subRectFor, traitEventWires, traitLevelFromTrait, traitTransitionRenderUi, withPreviewPosition };
@@ -0,0 +1,284 @@
1
+ import { Icon, Button, Switch, Input } from './chunk-3EF5SDIJ.js';
2
+ import { VStack, HStack } from './chunk-7LM6I3NA.js';
3
+ import { Typography } from './chunk-GMDMOYXD.js';
4
+ import { cn } from './chunk-64WACXM7.js';
5
+ import React from 'react';
6
+ import { useTranslate } from '@almadar/ui/hooks';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ var isObj = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
10
+ var isArr = (v) => Array.isArray(v);
11
+ function kindOf(v) {
12
+ if (v === null) return "null";
13
+ if (isArr(v)) return "array";
14
+ if (isObj(v)) return "object";
15
+ if (typeof v === "number") return "number";
16
+ if (typeof v === "boolean") return "boolean";
17
+ return "string";
18
+ }
19
+ var TYPE_LABEL_KEY = {
20
+ string: "jsonTree.type.text",
21
+ number: "jsonTree.type.number",
22
+ boolean: "jsonTree.type.boolean"
23
+ };
24
+ var TYPE_LABEL_SYMBOL = {
25
+ object: "{}",
26
+ array: "[]",
27
+ null: "\u2014"
28
+ };
29
+ function typeLabel(kind, t) {
30
+ if (kind === "object" || kind === "array" || kind === "null") return TYPE_LABEL_SYMBOL[kind];
31
+ return t(TYPE_LABEL_KEY[kind] ?? "");
32
+ }
33
+ var KIND_OPTIONS = ["string", "number", "boolean", "object", "array"];
34
+ function emptyOf(kind) {
35
+ switch (kind) {
36
+ case "object":
37
+ return {};
38
+ case "array":
39
+ return [];
40
+ case "number":
41
+ return 0;
42
+ case "boolean":
43
+ return false;
44
+ case "null":
45
+ return null;
46
+ default:
47
+ return "";
48
+ }
49
+ }
50
+ function templateFrom(arr) {
51
+ if (arr.length === 0) return "";
52
+ const first = arr[0];
53
+ if (isObj(first)) {
54
+ const blank = {};
55
+ for (const k of Object.keys(first)) blank[k] = isObj(first[k]) ? {} : isArr(first[k]) ? [] : first[k];
56
+ return blank;
57
+ }
58
+ if (isArr(first)) return [];
59
+ return emptyOf(kindOf(first));
60
+ }
61
+ function ScalarControl({
62
+ value,
63
+ onChange
64
+ }) {
65
+ if (typeof value === "boolean") {
66
+ return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onChange(c) });
67
+ }
68
+ const numeric = typeof value === "number";
69
+ const initial = value === null ? "" : String(value);
70
+ const [draft, setDraft] = React.useState(initial);
71
+ React.useEffect(() => setDraft(initial), [initial]);
72
+ const commit = () => {
73
+ if (numeric) {
74
+ const n = draft.trim() === "" ? 0 : Number(draft);
75
+ onChange(Number.isNaN(n) ? 0 : n);
76
+ } else {
77
+ onChange(draft);
78
+ }
79
+ };
80
+ return /* @__PURE__ */ jsx(
81
+ Input,
82
+ {
83
+ inputType: numeric ? "number" : "text",
84
+ value: draft,
85
+ placeholder: value === null ? "null" : void 0,
86
+ onChange: (e) => setDraft(e.target.value),
87
+ onBlur: commit,
88
+ onKeyDown: (e) => {
89
+ if (e.key === "Enter") commit();
90
+ }
91
+ }
92
+ );
93
+ }
94
+ function KindSelect({
95
+ kind,
96
+ onChange
97
+ }) {
98
+ const { t } = useTranslate();
99
+ return /* @__PURE__ */ jsx(
100
+ "select",
101
+ {
102
+ value: kind === "null" ? "string" : kind,
103
+ onChange: (e) => onChange(e.target.value),
104
+ "aria-label": t("jsonTree.valueType"),
105
+ className: cn(
106
+ "h-6 rounded-interactive bg-muted text-muted-foreground text-[10px] font-mono px-1",
107
+ "border-[length:var(--border-width-thin)] border-border",
108
+ "hover:bg-card focus:outline-none focus:ring-1 focus:ring-ring"
109
+ ),
110
+ children: KIND_OPTIONS.map((k) => /* @__PURE__ */ jsx("option", { value: k, children: typeLabel(k, t) }, k))
111
+ }
112
+ );
113
+ }
114
+ function ValueNode({
115
+ value,
116
+ onChange,
117
+ depth,
118
+ readonly
119
+ }) {
120
+ const kind = kindOf(value);
121
+ if (kind === "object" || kind === "array") {
122
+ return /* @__PURE__ */ jsx(ContainerNode, { value, onChange, depth, readonly });
123
+ }
124
+ if (readonly) {
125
+ return /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-mono text-foreground", children: value === null ? "null" : String(value) });
126
+ }
127
+ return /* @__PURE__ */ jsx(ScalarControl, { value, onChange });
128
+ }
129
+ function Row({
130
+ rowKey,
131
+ isArrayItem,
132
+ value,
133
+ depth,
134
+ onValue,
135
+ onRenameKey,
136
+ onChangeKind,
137
+ onRemove,
138
+ readonly
139
+ }) {
140
+ const { t } = useTranslate();
141
+ const [keyDraft, setKeyDraft] = React.useState(rowKey);
142
+ React.useEffect(() => setKeyDraft(rowKey), [rowKey]);
143
+ const container = isObj(value) || isArr(value);
144
+ return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "group w-max min-w-full", children: [
145
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
146
+ readonly ? /* @__PURE__ */ jsx("span", { className: cn(
147
+ "h-6 rounded-interactive bg-muted text-muted-foreground text-[10px] font-mono px-1 flex items-center",
148
+ "border-[length:var(--border-width-thin)] border-border"
149
+ ), children: typeLabel(kindOf(value), t) }) : /* @__PURE__ */ jsx(KindSelect, { kind: kindOf(value), onChange: onChangeKind }),
150
+ isArrayItem ? /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "w-6 shrink-0 font-mono", children: rowKey }) : readonly ? /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "w-20 shrink-0 font-mono truncate", children: rowKey }) : /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsx(
151
+ Input,
152
+ {
153
+ inputType: "text",
154
+ value: keyDraft,
155
+ onChange: (e) => setKeyDraft(e.target.value),
156
+ onBlur: () => keyDraft !== rowKey && onRenameKey(keyDraft),
157
+ onKeyDown: (e) => {
158
+ if (e.key === "Enter" && keyDraft !== rowKey) onRenameKey(keyDraft);
159
+ },
160
+ className: "font-mono"
161
+ }
162
+ ) }),
163
+ !container && /* @__PURE__ */ jsx("div", { className: "w-48 shrink-0", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1, readonly }) }),
164
+ !readonly && /* @__PURE__ */ jsx(
165
+ Button,
166
+ {
167
+ variant: "ghost",
168
+ size: "sm",
169
+ icon: "x",
170
+ onClick: onRemove,
171
+ "aria-label": t("common.remove"),
172
+ className: "shrink-0 text-muted-foreground hover:text-error"
173
+ }
174
+ )
175
+ ] }),
176
+ container && /* @__PURE__ */ jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsx(ValueNode, { value, onChange: onValue, depth: depth + 1, readonly }) })
177
+ ] });
178
+ }
179
+ function ContainerNode({
180
+ value,
181
+ onChange,
182
+ depth,
183
+ readonly
184
+ }) {
185
+ const { t } = useTranslate();
186
+ const [open, setOpen] = React.useState(depth < 2);
187
+ const array = isArr(value);
188
+ const entries = array ? value.map((v, i) => [String(i), v]) : Object.entries(value);
189
+ const setObjValue = (key, next) => {
190
+ onChange({ ...value, [key]: next });
191
+ };
192
+ const renameKey = (oldKey, newKey) => {
193
+ if (!newKey || newKey === oldKey) return;
194
+ const out = {};
195
+ for (const [k, v] of Object.entries(value)) out[k === oldKey ? newKey : k] = v;
196
+ onChange(out);
197
+ };
198
+ const removeObjKey = (key) => {
199
+ const out = {};
200
+ for (const [k, v] of Object.entries(value)) if (k !== key) out[k] = v;
201
+ onChange(out);
202
+ };
203
+ const changeObjKind = (key, k) => setObjValue(key, emptyOf(k));
204
+ const setArrValue = (idx, next) => {
205
+ const copy = [...value];
206
+ copy[idx] = next;
207
+ onChange(copy);
208
+ };
209
+ const removeArrIdx = (idx) => onChange(value.filter((_, i) => i !== idx));
210
+ const changeArrKind = (idx, k) => setArrValue(idx, emptyOf(k));
211
+ const add = () => {
212
+ if (array) {
213
+ onChange([...value, templateFrom(value)]);
214
+ } else {
215
+ const obj = value;
216
+ let key = "key";
217
+ let n = 1;
218
+ while (key in obj) {
219
+ key = `key${n}`;
220
+ n += 1;
221
+ }
222
+ onChange({ ...obj, [key]: "" });
223
+ }
224
+ };
225
+ const summaryKey = array ? entries.length === 1 ? "jsonTree.itemCountOne" : "jsonTree.itemCountOther" : entries.length === 1 ? "jsonTree.fieldCountOne" : "jsonTree.fieldCountOther";
226
+ const summary = t(summaryKey, { count: entries.length });
227
+ return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "w-full", children: [
228
+ /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: /* @__PURE__ */ jsxs(
229
+ "button",
230
+ {
231
+ type: "button",
232
+ onClick: () => setOpen((o) => !o),
233
+ className: "flex items-center gap-1 text-muted-foreground hover:text-foreground",
234
+ "aria-label": open ? t("jsonTree.collapse") : t("jsonTree.expand"),
235
+ children: [
236
+ /* @__PURE__ */ jsx(Icon, { name: open ? "chevron-down" : "chevron-right", size: "sm" }),
237
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-xs", children: array ? "[ ]" : "{ }" }),
238
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: summary })
239
+ ]
240
+ }
241
+ ) }),
242
+ open && /* @__PURE__ */ jsxs(
243
+ VStack,
244
+ {
245
+ gap: "none",
246
+ className: cn("ml-1.5 pl-1.5 w-max min-w-full border-l-[length:var(--border-width-thin)] border-border"),
247
+ children: [
248
+ entries.map(([k, v], idx) => /* @__PURE__ */ jsx(
249
+ Row,
250
+ {
251
+ rowKey: k,
252
+ isArrayItem: array,
253
+ value: v,
254
+ depth,
255
+ onValue: (next) => array ? setArrValue(idx, next) : setObjValue(k, next),
256
+ onRenameKey: (nk) => renameKey(k, nk),
257
+ onChangeKind: (kind) => array ? changeArrKind(idx, kind) : changeObjKind(k, kind),
258
+ onRemove: () => array ? removeArrIdx(idx) : removeObjKey(k),
259
+ readonly
260
+ },
261
+ array ? idx : k
262
+ )),
263
+ !readonly && /* @__PURE__ */ jsx(
264
+ Button,
265
+ {
266
+ variant: "ghost",
267
+ size: "sm",
268
+ icon: "plus",
269
+ label: array ? t("jsonTree.addItem") : t("jsonTree.addField"),
270
+ onClick: add,
271
+ className: "self-start text-muted-foreground"
272
+ }
273
+ )
274
+ ]
275
+ }
276
+ )
277
+ ] });
278
+ }
279
+ var JsonTreeEditor = ({ value, onChange, className, readonly }) => {
280
+ const root = value ?? "";
281
+ return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto rounded-container bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsx(ValueNode, { value: root, onChange, depth: 0, readonly }) });
282
+ };
283
+
284
+ export { JsonTreeEditor };
@@ -1,23 +1,10 @@
1
- import { cn } from './chunk-HQDKHLFG.js';
2
- import { formatValue } from './chunk-GHXWGQTX.js';
1
+ import { cn, domPassthrough } from './chunk-64WACXM7.js';
2
+ import { formatValue } from './chunk-4OZDHCZV.js';
3
3
  import React from 'react';
4
4
  import { useFormatContext } from '@almadar/ui/hooks';
5
5
 
6
6
  // lib/inlineText.ts
7
7
  var INLINE_TEXT_ATTR = "data-inline-text";
8
-
9
- // lib/domPassthrough.ts
10
- function domPassthrough(props) {
11
- const out = {};
12
- for (const [key, value] of Object.entries(props)) {
13
- if (key.startsWith("aria-") || key.startsWith("data-") || key === "role" || key === "id") {
14
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === void 0) {
15
- out[key] = value;
16
- }
17
- }
18
- }
19
- return out;
20
- }
21
8
  var variantStyles = {
22
9
  h1: "text-4xl heading-voice text-foreground",
23
10
  h2: "text-3xl heading-voice text-foreground",
@@ -150,4 +137,4 @@ var Typography = ({
150
137
  };
151
138
  Typography.displayName = "Typography";
152
139
 
153
- export { INLINE_TEXT_ATTR, Typography, domPassthrough };
140
+ export { INLINE_TEXT_ATTR, Typography };
@@ -1,6 +1,6 @@
1
- import { DEFAULT_CURRENCY } from './chunk-GHXWGQTX.js';
2
- import { en_default } from './chunk-L55SAFKL.js';
3
- import { createContext, useContext, useMemo } from 'react';
1
+ import { DEFAULT_CURRENCY } from './chunk-4OZDHCZV.js';
2
+ import { en_default } from './chunk-UGHAADU5.js';
3
+ import React, { createContext, useEffect, useContext, useMemo } from 'react';
4
4
 
5
5
  var { $meta: _meta, ...coreMessages } = en_default;
6
6
  var coreLocale = coreMessages;
@@ -18,7 +18,14 @@ var I18nContext = createContext({
18
18
  }
19
19
  });
20
20
  I18nContext.displayName = "I18nContext";
21
- var I18nProvider = I18nContext.Provider;
21
+ function I18nProvider({ value, children, documentRoot }) {
22
+ useEffect(() => {
23
+ if (!documentRoot) return;
24
+ document.documentElement.lang = value.locale;
25
+ document.documentElement.dir = value.direction;
26
+ }, [documentRoot, value.locale, value.direction]);
27
+ return React.createElement(I18nContext.Provider, { value }, children);
28
+ }
22
29
  function useTranslate() {
23
30
  return useContext(I18nContext);
24
31
  }