@almadar/ui 6.53.0 → 6.54.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 (49) hide show
  1. package/dist/Typography-CFI7JUVE.js +5 -0
  2. package/dist/{UISlotRenderer-JT34I3O7.js → UISlotRenderer-QUEG6WFM.js} +5 -5
  3. package/dist/avl/index.cjs +578 -262
  4. package/dist/avl/index.js +28 -19
  5. package/dist/{avl-3d-context-MAt_NuU9.d.ts → avl-3d-context-BpBKZIbc.d.ts} +1 -0
  6. package/dist/{chunk-DQTV6QVS.js → chunk-4HC5HRHB.js} +53 -2
  7. package/dist/{chunk-GMDMOYXD.js → chunk-4UP6BZ4R.js} +1 -1
  8. package/dist/{chunk-CBIJP5PL.js → chunk-FJDS4SVD.js} +3 -3
  9. package/dist/{chunk-4OZDHCZV.js → chunk-MCKFWPT2.js} +1 -1
  10. package/dist/{chunk-UGHAADU5.js → chunk-N2V4LHFQ.js} +4 -1
  11. package/dist/{chunk-3EF5SDIJ.js → chunk-U2FGMHQP.js} +306 -174
  12. package/dist/{chunk-IKULQIDX.js → chunk-U3CGKPOK.js} +252 -91
  13. package/dist/{chunk-7LM6I3NA.js → chunk-Z5IYJU44.js} +1 -0
  14. package/dist/{chunk-WPNM2KC6.js → chunk-Z7JWXIRE.js} +2 -2
  15. package/dist/components/index.cjs +312 -170
  16. package/dist/components/index.d.ts +5 -1
  17. package/dist/components/index.js +11 -12
  18. package/dist/context/index.cjs +2 -0
  19. package/dist/context/index.js +2 -0
  20. package/dist/hooks/index.cjs +9 -1
  21. package/dist/hooks/index.d.ts +10 -1
  22. package/dist/hooks/index.js +3 -4
  23. package/dist/lib/drawable/three/index.cjs +5 -1
  24. package/dist/lib/drawable/three/index.d.ts +2 -2
  25. package/dist/lib/drawable/three/index.js +6 -6
  26. package/dist/lib/index.cjs +4 -1
  27. package/dist/lib/index.js +2 -2
  28. package/dist/locales/index.cjs +12 -3
  29. package/dist/locales/index.js +9 -3
  30. package/dist/providers/index.cjs +307 -170
  31. package/dist/providers/index.d.ts +1 -1
  32. package/dist/providers/index.js +5 -5
  33. package/dist/runtime/index.cjs +3850 -3523
  34. package/dist/runtime/index.d.ts +22 -4
  35. package/dist/runtime/index.js +13 -10
  36. package/dist/ssr/index.cjs +5 -2
  37. package/dist/ssr/index.js +5 -2
  38. package/locales/ar.json +4 -1
  39. package/locales/en.json +4 -1
  40. package/locales/sl.json +4 -1
  41. package/package.json +7 -6
  42. package/scripts/audit-tailwind-safelist.ts +21 -1
  43. package/tailwind-preset.cjs +15 -6
  44. package/themes/_fonts.css +6 -4
  45. package/themes/_presets.css +2 -0
  46. package/themes/almadar-heritage.css +373 -0
  47. package/themes/orb.css +373 -0
  48. package/dist/Typography-JGSDH4JP.js +0 -5
  49. package/dist/chunk-GODZKHAL.js +0 -51
@@ -17,6 +17,7 @@ var ui = require('@almadar/runtime/ui');
17
17
  var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism-light.js');
18
18
  var createHighlightElement = require('react-syntax-highlighter/dist/esm/create-element.js');
19
19
  var dark = require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus.js');
20
+ var light = require('react-syntax-highlighter/dist/esm/styles/prism/vs.js');
20
21
  var syntax = require('@almadar/syntax');
21
22
  var i18n = require('@almadar/core/i18n');
22
23
  var langJson = require('react-syntax-highlighter/dist/esm/languages/prism/json.js');
@@ -104,6 +105,7 @@ var LucideIcons2__namespace = /*#__PURE__*/_interopNamespace(LucideIcons2);
104
105
  var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
105
106
  var createHighlightElement__default = /*#__PURE__*/_interopDefault(createHighlightElement);
106
107
  var dark__default = /*#__PURE__*/_interopDefault(dark);
108
+ var light__default = /*#__PURE__*/_interopDefault(light);
107
109
  var langJson__default = /*#__PURE__*/_interopDefault(langJson);
108
110
  var langJavascript__default = /*#__PURE__*/_interopDefault(langJavascript);
109
111
  var langTypescript__default = /*#__PURE__*/_interopDefault(langTypescript);
@@ -2201,7 +2203,7 @@ var init_Button = __esm({
2201
2203
  const testId = dataTestId ?? (action ? `action-${action}` : void 0);
2202
2204
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2203
2205
  busy && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "almadar-busy-indicator absolute inset-0 flex items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Loader2, { className: "h-icon-default w-icon-default animate-spin" }) }),
2204
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex items-center justify-center gap-2", busy && "almadar-busy-content"), children: [
2206
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex flex-1 min-w-0 items-center [justify-content:inherit] gap-2", busy && "almadar-busy-content"), children: [
2205
2207
  resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
2206
2208
  (Array.isArray(children) ? children.length > 0 : Boolean(children)) ? children : label ? /* @__PURE__ */ jsxRuntime.jsx("span", { ...{ [INLINE_TEXT_ATTR]: "label" }, children: label }) : label,
2207
2209
  resolvedRightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
@@ -2562,6 +2564,7 @@ var init_en = __esm({
2562
2564
  "status.draft": "Draft",
2563
2565
  "status.archived": "Archived",
2564
2566
  "error.generic": "Something went wrong",
2567
+ "error.traitMountFailed": "{{trait}} failed to start",
2565
2568
  "error.retry": "Try again",
2566
2569
  "error.notFound": "Not found",
2567
2570
  "error.loadFailed": "Failed to load: {{message}}",
@@ -3730,7 +3733,9 @@ var init_en = __esm({
3730
3733
  "agentActivity.llmToolCalls": "Tool calls",
3731
3734
  "agentActivity.showRawLlm": "Raw LLM",
3732
3735
  "agentActivity.earlierConversations": "Earlier conversations ({{count}})",
3733
- "agentActivity.earlierActivity": "Earlier activity"
3736
+ "agentActivity.earlierActivity": "Earlier activity",
3737
+ "tabs.scrollStart": "Scroll tabs back",
3738
+ "tabs.scrollEnd": "Scroll tabs forward"
3734
3739
  };
3735
3740
  }
3736
3741
  });
@@ -8725,12 +8730,13 @@ var init_Skeleton = __esm({
8725
8730
  Skeleton.displayName = "Skeleton";
8726
8731
  }
8727
8732
  });
8728
- function resolveMarkerExpression(expression, entity, config, state) {
8733
+ function resolveMarkerExpression(expression, entity, config, state, i18n) {
8729
8734
  const ctx = runtime.createContextFromBindings({
8730
8735
  entity,
8731
8736
  payload: {},
8732
8737
  state,
8733
- ...config !== void 0 ? { config } : {}
8738
+ ...config !== void 0 ? { config } : {},
8739
+ ...i18n !== void 0 ? { locale: i18n.locale, messages: i18n.messages } : {}
8734
8740
  });
8735
8741
  return runtime.interpolateValue(expression, ctx);
8736
8742
  }
@@ -8742,9 +8748,9 @@ function isPlainObject(value) {
8742
8748
  if (typeof value === "function") return false;
8743
8749
  return true;
8744
8750
  }
8745
- function cachedContainer(value, scopeTrait, entity, config, state) {
8751
+ function cachedContainer(value, scopeTrait, entity, config, state, i18n) {
8746
8752
  const hit = containerResolutionCache.get(value);
8747
- return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
8753
+ return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.i18n === i18n && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
8748
8754
  }
8749
8755
  function isEvaluatorResolvedData(value) {
8750
8756
  return evaluatorResolvedData.has(value);
@@ -8775,14 +8781,14 @@ function subtreeHasMarker(value) {
8775
8781
  markerPresenceCache.set(value, found);
8776
8782
  return found;
8777
8783
  }
8778
- function walkValue(value, scopeTrait, entity, config, state) {
8784
+ function walkValue(value, scopeTrait, entity, config, state, i18n) {
8779
8785
  if (core.isRenderBindingMarker(value)) {
8780
8786
  const cached = markerResolutionCache.get(value);
8781
- if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
8787
+ if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state && cached.i18n === i18n) {
8782
8788
  return { resolved: cached.resolved, changed: true };
8783
8789
  }
8784
- const resolved = resolveMarkerExpression(value.expression, entity, config, state);
8785
- markerResolutionCache.set(value, { entity, config, state, resolved });
8790
+ const resolved = resolveMarkerExpression(value.expression, entity, config, state, i18n);
8791
+ markerResolutionCache.set(value, { entity, config, state, i18n, resolved });
8786
8792
  if (resolved !== null && typeof resolved === "object" && !React82__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
8787
8793
  resolvedMarkerFree.add(resolved);
8788
8794
  evaluatorResolvedData.add(resolved);
@@ -8794,14 +8800,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
8794
8800
  brandResolved(value);
8795
8801
  return { resolved: value, changed: false };
8796
8802
  }
8797
- const cachedArray = cachedContainer(value, scopeTrait, entity, config, state);
8803
+ const cachedArray = cachedContainer(value, scopeTrait, entity, config, state, i18n);
8798
8804
  if (cachedArray !== void 0) return { resolved: cachedArray, changed: true };
8799
8805
  const out = [];
8800
8806
  let changed = false;
8801
8807
  for (const item of value) {
8802
8808
  const element = item;
8803
8809
  const wasMarker = core.isRenderBindingMarker(element);
8804
- const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
8810
+ const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state, i18n);
8805
8811
  if (wasMarker && Array.isArray(resolved)) {
8806
8812
  out.push(...resolved);
8807
8813
  changed = true;
@@ -8812,7 +8818,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
8812
8818
  }
8813
8819
  brandResolved(out);
8814
8820
  if (!changed) return { resolved: value, changed: false };
8815
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
8821
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
8816
8822
  return { resolved: out, changed: true };
8817
8823
  }
8818
8824
  if (isPlainObject(value)) {
@@ -8824,37 +8830,37 @@ function walkValue(value, scopeTrait, entity, config, state) {
8824
8830
  if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
8825
8831
  return { resolved: value, changed: false };
8826
8832
  }
8827
- const cachedObject = cachedContainer(value, scopeTrait, entity, config, state);
8833
+ const cachedObject = cachedContainer(value, scopeTrait, entity, config, state, i18n);
8828
8834
  if (cachedObject !== void 0) return { resolved: cachedObject, changed: true };
8829
8835
  const out = {};
8830
8836
  let changed = false;
8831
8837
  for (const [key, item] of Object.entries(value)) {
8832
- const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
8838
+ const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state, i18n);
8833
8839
  out[key] = resolved;
8834
8840
  if (itemChanged) changed = true;
8835
8841
  }
8836
8842
  brandResolved(out);
8837
8843
  if (!changed) return { resolved: value, changed: false };
8838
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
8844
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
8839
8845
  return { resolved: out, changed: true };
8840
8846
  }
8841
8847
  return { resolved: value, changed: false };
8842
8848
  }
8843
- function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
8849
+ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state, i18n) {
8844
8850
  if (props === null || typeof props !== "object") return props;
8845
8851
  if (resolvedMarkerFree.has(props)) return props;
8846
- const cached = cachedContainer(props, scopeTrait, entity, config, state);
8852
+ const cached = cachedContainer(props, scopeTrait, entity, config, state, i18n);
8847
8853
  if (cached !== void 0) return cached;
8848
8854
  const out = {};
8849
8855
  let changed = false;
8850
8856
  for (const [key, value] of Object.entries(props)) {
8851
- const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
8857
+ const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state, i18n);
8852
8858
  out[key] = resolved;
8853
8859
  if (propChanged) changed = true;
8854
8860
  }
8855
8861
  brandResolved(out);
8856
8862
  if (!changed) return props;
8857
- containerResolutionCache.set(props, { entity, config, state, scopeTrait, resolved: out });
8863
+ containerResolutionCache.set(props, { entity, config, state, i18n, scopeTrait, resolved: out });
8858
8864
  return out;
8859
8865
  }
8860
8866
  var markerPresenceCache, markerResolutionCache, containerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
@@ -10805,6 +10811,7 @@ var init_Tabs = __esm({
10805
10811
  init_Badge();
10806
10812
  init_Typography();
10807
10813
  init_Box();
10814
+ init_Button();
10808
10815
  init_cn();
10809
10816
  init_useEventBus();
10810
10817
  init_domPassthrough();
@@ -10836,6 +10843,28 @@ var init_Tabs = __esm({
10836
10843
  const uid = React82.useId();
10837
10844
  const tabId = (id) => `${uid}-tab-${id}`;
10838
10845
  const panelId = (id) => `${uid}-panel-${id}`;
10846
+ const laneRef = React82.useRef(null);
10847
+ const [hidden, setHidden] = React82.useState({ start: false, end: false });
10848
+ const measure = React82.useCallback(() => {
10849
+ const lane = laneRef.current;
10850
+ if (!lane || orientation !== "horizontal") return;
10851
+ const max = lane.scrollWidth - lane.clientWidth;
10852
+ const start = max > 1 && lane.scrollLeft > 1;
10853
+ const end = max > 1 && lane.scrollLeft < max - 1;
10854
+ setHidden((prev) => prev.start === start && prev.end === end ? prev : { start, end });
10855
+ }, [orientation]);
10856
+ React82.useLayoutEffect(() => {
10857
+ measure();
10858
+ const lane = laneRef.current;
10859
+ if (!lane || typeof ResizeObserver === "undefined") return void 0;
10860
+ const observer2 = new ResizeObserver(measure);
10861
+ observer2.observe(lane);
10862
+ return () => observer2.disconnect();
10863
+ }, [measure, rawItems.length]);
10864
+ const scrollLane = (direction) => {
10865
+ const lane = laneRef.current;
10866
+ if (lane) lane.scrollBy({ left: direction * lane.clientWidth * 0.8, behavior: "smooth" });
10867
+ };
10839
10868
  const handleTabChange = (tabId2, tabEvent) => {
10840
10869
  if (controlledActiveTab === void 0) {
10841
10870
  setInternalActiveTab(tabId2);
@@ -10892,62 +10921,97 @@ var init_Tabs = __esm({
10892
10921
  "data-[active=true]:border-primary"
10893
10922
  ].join(" ")
10894
10923
  };
10895
- return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
10896
- /* @__PURE__ */ jsxRuntime.jsx(
10897
- exports.Box,
10898
- {
10899
- role: "tablist",
10900
- "aria-orientation": orientation,
10901
- className: cn(
10902
- "flex",
10903
- // Horizontal tab strip becomes a horizontally-scrollable lane
10904
- // below its container width — phones with many tabs scroll
10905
- // instead of clipping. `snap-x` snaps to each tab; the
10906
- // scrollbar is hidden for a cleaner affordance (the swipe
10907
- // gesture is the discoverability cue).
10908
- orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
10909
- variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
10910
- variant === "underline" && orientation === "vertical" && "border-b-0"
10911
- ),
10912
- children: safeItems.map((item, index) => {
10913
- const isActive = item.id === activeTab;
10914
- const isDisabled = item.disabled;
10915
- return /* @__PURE__ */ jsxRuntime.jsxs(
10916
- exports.Box,
10917
- {
10918
- as: "button",
10919
- ref: (el) => {
10920
- tabRefs.current[item.id] = el;
10921
- },
10922
- id: tabId(item.id),
10923
- role: "tab",
10924
- "aria-selected": isActive,
10925
- "aria-controls": isActive ? panelId(item.id) : void 0,
10926
- "aria-disabled": isDisabled,
10927
- tabIndex: isActive ? 0 : -1,
10928
- onClick: () => !isDisabled && handleTabChange(item.id, item.event),
10929
- onKeyDown: (e) => handleKeyDown(e, index),
10930
- "data-active": isActive,
10931
- "data-testid": `tab-${item.id}`,
10932
- className: cn(
10933
- "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
10934
- orientation === "horizontal" && "snap-start shrink-0",
10935
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
10936
- isDisabled && "opacity-50 cursor-not-allowed",
10937
- variantClasses2[variant],
10938
- isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
10939
- ),
10940
- children: [
10941
- item.iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm" })),
10942
- /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
10943
- item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: item.badge })
10944
- ]
10924
+ const tablist = /* @__PURE__ */ jsxRuntime.jsx(
10925
+ exports.Box,
10926
+ {
10927
+ ref: laneRef,
10928
+ role: "tablist",
10929
+ "aria-orientation": orientation,
10930
+ onScroll: measure,
10931
+ "data-scroll-affordance": hidden.start || hidden.end ? "true" : void 0,
10932
+ className: cn(
10933
+ "flex",
10934
+ // Horizontal tab strip becomes a horizontally-scrollable lane
10935
+ // below its container width — phones with many tabs scroll
10936
+ // instead of clipping. `snap-x` snaps to each tab; the
10937
+ // scrollbar is hidden — the edge chevrons are the affordance.
10938
+ orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
10939
+ variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
10940
+ variant === "underline" && orientation === "vertical" && "border-b-0"
10941
+ ),
10942
+ children: safeItems.map((item, index) => {
10943
+ const isActive = item.id === activeTab;
10944
+ const isDisabled = item.disabled;
10945
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10946
+ exports.Box,
10947
+ {
10948
+ as: "button",
10949
+ ref: (el) => {
10950
+ tabRefs.current[item.id] = el;
10945
10951
  },
10946
- item.id
10947
- );
10948
- })
10949
- }
10950
- ),
10952
+ id: tabId(item.id),
10953
+ role: "tab",
10954
+ "aria-selected": isActive,
10955
+ "aria-controls": isActive ? panelId(item.id) : void 0,
10956
+ "aria-disabled": isDisabled,
10957
+ tabIndex: isActive ? 0 : -1,
10958
+ onClick: () => !isDisabled && handleTabChange(item.id, item.event),
10959
+ onKeyDown: (e) => handleKeyDown(e, index),
10960
+ "data-active": isActive,
10961
+ "data-testid": `tab-${item.id}`,
10962
+ className: cn(
10963
+ "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
10964
+ orientation === "horizontal" && "snap-start shrink-0",
10965
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
10966
+ isDisabled && "opacity-50 cursor-not-allowed",
10967
+ variantClasses2[variant],
10968
+ isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
10969
+ ),
10970
+ children: [
10971
+ item.iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm" })),
10972
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
10973
+ item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: item.badge })
10974
+ ]
10975
+ },
10976
+ item.id
10977
+ );
10978
+ })
10979
+ }
10980
+ );
10981
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
10982
+ orientation === "horizontal" ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "relative", children: [
10983
+ tablist,
10984
+ hidden.start && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10985
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "pointer-events-none absolute inset-y-0 start-0 w-10 bg-gradient-to-r from-[var(--color-background)] to-transparent rtl:bg-gradient-to-l" }),
10986
+ /* @__PURE__ */ jsxRuntime.jsx(
10987
+ exports.Button,
10988
+ {
10989
+ variant: "ghost",
10990
+ size: "sm",
10991
+ leftIcon: "chevron-left",
10992
+ "aria-label": t("tabs.scrollStart"),
10993
+ "data-testid": "tabs-scroll-start",
10994
+ className: "absolute start-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
10995
+ onClick: () => scrollLane(-1)
10996
+ }
10997
+ )
10998
+ ] }),
10999
+ hidden.end && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11000
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "pointer-events-none absolute inset-y-0 end-0 w-10 bg-gradient-to-l from-[var(--color-background)] to-transparent rtl:bg-gradient-to-r" }),
11001
+ /* @__PURE__ */ jsxRuntime.jsx(
11002
+ exports.Button,
11003
+ {
11004
+ variant: "ghost",
11005
+ size: "sm",
11006
+ leftIcon: "chevron-right",
11007
+ "aria-label": t("tabs.scrollEnd"),
11008
+ "data-testid": "tabs-scroll-end",
11009
+ className: "absolute end-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
11010
+ onClick: () => scrollLane(1)
11011
+ }
11012
+ )
11013
+ ] })
11014
+ ] }) : tablist,
10951
11015
  activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsxRuntime.jsx(
10952
11016
  exports.Box,
10953
11017
  {
@@ -12161,6 +12225,35 @@ function withTokenTypes(node) {
12161
12225
  function renderWithTokenTypes({ rows: rows2, stylesheet, useInlineStyles }) {
12162
12226
  return rows2.map((node, i) => createHighlightElement__default.default({ node: withTokenTypes(node), stylesheet, useInlineStyles, key: `code-segment-${i}` }));
12163
12227
  }
12228
+ function island(value, style) {
12229
+ return { type: "element", tagName: "span", properties: { className: [], "data-bidi-island": "", style }, children: [{ type: "text", value }] };
12230
+ }
12231
+ function splitLtrWords(value) {
12232
+ const out = [];
12233
+ let last = 0;
12234
+ for (const match of value.matchAll(LTR_WORD)) {
12235
+ const start = match.index ?? 0;
12236
+ if (start > last) out.push({ type: "text", value: value.slice(last, start) });
12237
+ out.push(island(match[0], LTR_ISLAND_STYLE));
12238
+ last = start + match[0].length;
12239
+ }
12240
+ if (last < value.length) out.push({ type: "text", value: value.slice(last) });
12241
+ return out;
12242
+ }
12243
+ function withBidiIslands(node) {
12244
+ if (node.type === "text") return splitLtrWords(String(node.value ?? ""));
12245
+ if (node.type !== "element") return [node];
12246
+ const classes = node.properties?.className;
12247
+ if (Array.isArray(classes) && classes.includes("string")) {
12248
+ return [{ ...node, properties: { ...node.properties, className: classes, "data-bidi-island": "", style: STRING_ISLAND_STYLE } }];
12249
+ }
12250
+ return [{ ...node, ...node.children ? { children: node.children.flatMap(withBidiIslands) } : {} }];
12251
+ }
12252
+ function renderRtlCode({ rows: rows2, stylesheet, useInlineStyles }) {
12253
+ return rows2.map(
12254
+ (node, i) => withBidiIslands(node).map((n, j) => createHighlightElement__default.default({ node: n, stylesheet, useInlineStyles, key: `code-rtl-${i}-${j}` }))
12255
+ );
12256
+ }
12164
12257
  function tokenClassAt(layer, offset) {
12165
12258
  const walker = document.createTreeWalker(layer, NodeFilter.SHOW_TEXT);
12166
12259
  let pos = 0;
@@ -12217,10 +12310,9 @@ function useLanguageReady(language) {
12217
12310
  }, [language]);
12218
12311
  return ready;
12219
12312
  }
12220
- function resolveHighlightStyle(lang) {
12221
- if (lang === "orb") return orbStyle;
12222
- if (lang === "lolo") return loloStyle;
12223
- return dark__default.default;
12313
+ function resolveHighlightStyle(lang, scheme) {
12314
+ if (lang === "orb" || lang === "lolo") return HIGHLIGHT_STYLES[scheme][lang];
12315
+ return SCHEME_BASE[scheme];
12224
12316
  }
12225
12317
  function plainCodeColorOf(style) {
12226
12318
  return style['code[class*="language-"]']?.color ?? "#d4d4d4";
@@ -12255,7 +12347,7 @@ function translateProgram(source, language, lang) {
12255
12347
  }
12256
12348
  return source;
12257
12349
  }
12258
- var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, MONO_EDITOR_FONT, GHOST_COLOR, GUTTER_COLOR, caretOf, DIAGNOSTIC_ERROR_COLOR, DIAGNOSTIC_WARNING_COLOR, EDITOR_LINE_PX, log3, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE; exports.CodeBlock = void 0;
12350
+ var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, loloStyleOverrides, SCHEME_BASE, HIGHLIGHT_STYLES, MONO_EDITOR_FONT, GHOST_COLOR, GUTTER_COLOR, caretOf, LTR_WORD, LTR_ISLAND_STYLE, STRING_ISLAND_STYLE, DIAGNOSTIC_ERROR_COLOR, DIAGNOSTIC_WARNING_COLOR, EDITOR_LINE_PX, log3, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE, VIEWER_LINE_NUMBER_STYLE_RTL; exports.CodeBlock = void 0;
12259
12351
  var init_CodeBlock = __esm({
12260
12352
  "components/core/molecules/markdown/CodeBlock.tsx"() {
12261
12353
  init_cn();
@@ -12360,52 +12452,64 @@ var init_CodeBlock = __esm({
12360
12452
  SyntaxHighlighter__default.default.registerLanguage("lolo", syntax.loloLanguage);
12361
12453
  dynamicallyLoaded = /* @__PURE__ */ new Set();
12362
12454
  codeLanguageLoader = null;
12363
- orbStyleOverrides = {
12364
- "orb-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
12365
- "orb-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
12366
- "orb-event": { color: syntax.ORB_COLORS.dark.event },
12367
- "orb-slot": { color: syntax.ORB_COLORS.dark.uiSlot },
12368
- "orb-structural": { color: syntax.ORB_COLORS.dark.structural },
12369
- "orb-field-type": { color: syntax.ORB_COLORS.dark.fieldType },
12370
- "orb-persistence": { color: syntax.ORB_COLORS.dark.persistence },
12371
- "orb-pattern": { color: syntax.ORB_COLORS.dark.pattern },
12372
- "orb-behavior": { color: syntax.ORB_COLORS.dark.behavior },
12373
- "orb-unknown-op": { color: syntax.ORB_COLORS.dark.error, textDecoration: "wavy underline" },
12374
- "orb-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
12375
- "orb-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
12376
- "orb-op-logic": { color: syntax.ORB_COLORS.dark.logic },
12377
- "orb-op-string": { color: syntax.ORB_COLORS.dark.string },
12378
- "orb-op-collection": { color: syntax.ORB_COLORS.dark.collection },
12379
- "orb-op-time": { color: syntax.ORB_COLORS.dark.time },
12380
- "orb-op-control": { color: syntax.ORB_COLORS.dark.control },
12381
- "orb-op-async": { color: syntax.ORB_COLORS.dark.async }
12382
- };
12383
- orbStyle = { ...dark__default.default, ...orbStyleOverrides };
12384
- loloStyleOverrides = {
12385
- "lolo-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
12386
- "lolo-event": { color: syntax.ORB_COLORS.dark.event },
12387
- "lolo-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
12388
- "keyword": { color: syntax.ORB_COLORS.dark.loloKeyword },
12389
- "lolo-constructor": { color: syntax.ORB_COLORS.dark.loloConstructor },
12390
- "lolo-arrow": { color: syntax.ORB_COLORS.dark.loloArrow },
12391
- "lolo-reference": { color: syntax.ORB_COLORS.dark.loloReference },
12392
- "lolo-type": { color: syntax.ORB_COLORS.dark.fieldType },
12393
- "lolo-persistence": { color: syntax.ORB_COLORS.dark.persistence },
12394
- "lolo-unknown-op": { color: syntax.ORB_COLORS.dark.error },
12395
- "lolo-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
12396
- "lolo-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
12397
- "lolo-op-logic": { color: syntax.ORB_COLORS.dark.logic },
12398
- "lolo-op-string": { color: syntax.ORB_COLORS.dark.string },
12399
- "lolo-op-collection": { color: syntax.ORB_COLORS.dark.collection },
12400
- "lolo-op-time": { color: syntax.ORB_COLORS.dark.time },
12401
- "lolo-op-control": { color: syntax.ORB_COLORS.dark.control },
12402
- "lolo-op-async": { color: syntax.ORB_COLORS.dark.async }
12403
- };
12404
- loloStyle = { ...dark__default.default, ...loloStyleOverrides };
12455
+ orbStyleOverrides = (c) => ({
12456
+ "orb-binding": { color: c.binding, fontWeight: "bold" },
12457
+ "orb-effect": { color: c.effect, fontWeight: "bold" },
12458
+ "orb-event": { color: c.event },
12459
+ "orb-slot": { color: c.uiSlot },
12460
+ "orb-structural": { color: c.structural },
12461
+ "orb-field-type": { color: c.fieldType },
12462
+ "orb-persistence": { color: c.persistence },
12463
+ "orb-pattern": { color: c.pattern },
12464
+ "orb-behavior": { color: c.behavior },
12465
+ "orb-unknown-op": { color: c.error, textDecoration: "wavy underline" },
12466
+ "orb-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
12467
+ "orb-op-comparison": { color: c.comparison },
12468
+ "orb-op-logic": { color: c.logic },
12469
+ "orb-op-string": { color: c.string },
12470
+ "orb-op-collection": { color: c.collection },
12471
+ "orb-op-time": { color: c.time },
12472
+ "orb-op-control": { color: c.control },
12473
+ "orb-op-async": { color: c.async }
12474
+ });
12475
+ loloStyleOverrides = (c) => ({
12476
+ "lolo-binding": { color: c.binding, fontWeight: "bold" },
12477
+ "lolo-event": { color: c.event },
12478
+ "lolo-effect": { color: c.effect, fontWeight: "bold" },
12479
+ "keyword": { color: c.loloKeyword },
12480
+ "lolo-constructor": { color: c.loloConstructor },
12481
+ "lolo-arrow": { color: c.loloArrow },
12482
+ "lolo-reference": { color: c.loloReference },
12483
+ "lolo-type": { color: c.fieldType },
12484
+ "lolo-persistence": { color: c.persistence },
12485
+ "lolo-unknown-op": { color: c.error },
12486
+ "lolo-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
12487
+ "lolo-op-comparison": { color: c.comparison },
12488
+ "lolo-op-logic": { color: c.logic },
12489
+ "lolo-op-string": { color: c.string },
12490
+ "lolo-op-collection": { color: c.collection },
12491
+ "lolo-op-time": { color: c.time },
12492
+ "lolo-op-control": { color: c.control },
12493
+ "lolo-op-async": { color: c.async }
12494
+ });
12495
+ SCHEME_BASE = { dark: dark__default.default, light: light__default.default };
12496
+ HIGHLIGHT_STYLES = {
12497
+ dark: {
12498
+ orb: { ...dark__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.dark) },
12499
+ lolo: { ...dark__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.dark) }
12500
+ },
12501
+ light: {
12502
+ orb: { ...light__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.light) },
12503
+ lolo: { ...light__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.light) }
12504
+ }
12505
+ };
12405
12506
  MONO_EDITOR_FONT = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
12406
12507
  GHOST_COLOR = "#7f848e";
12407
12508
  GUTTER_COLOR = "#858585";
12408
12509
  caretOf = (ta) => ta.selectionDirection === "backward" ? ta.selectionStart : ta.selectionEnd;
12510
+ LTR_WORD = /[A-Za-z0-9_$@?][A-Za-z0-9_$@?.!-]*/g;
12511
+ LTR_ISLAND_STYLE = { unicodeBidi: "isolate", direction: "ltr" };
12512
+ STRING_ISLAND_STYLE = { unicodeBidi: "plaintext" };
12409
12513
  DIAGNOSTIC_ERROR_COLOR = "#f14c4c";
12410
12514
  DIAGNOSTIC_WARNING_COLOR = "#cca700";
12411
12515
  EDITOR_LINE_PX = 19.5;
@@ -12505,7 +12609,7 @@ var init_CodeBlock = __esm({
12505
12609
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
12506
12610
  HIDDEN_LINE_NUMBERS = { display: "none" };
12507
12611
  HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
12508
- MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
12612
+ MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", "IBM Plex Sans Arabic", "Noto Sans Arabic", monospace';
12509
12613
  VIEWER_LINE_NUMBER_STYLE = {
12510
12614
  minWidth: "2.5em",
12511
12615
  paddingRight: "1rem",
@@ -12514,6 +12618,15 @@ var init_CodeBlock = __esm({
12514
12618
  opacity: 0.5,
12515
12619
  fontVariantNumeric: "tabular-nums"
12516
12620
  };
12621
+ VIEWER_LINE_NUMBER_STYLE_RTL = {
12622
+ minWidth: "2.5em",
12623
+ paddingRight: 0,
12624
+ paddingLeft: "1rem",
12625
+ textAlign: "left",
12626
+ userSelect: "none",
12627
+ opacity: 0.5,
12628
+ fontVariantNumeric: "tabular-nums"
12629
+ };
12517
12630
  exports.CodeBlock = React82__namespace.default.memo(
12518
12631
  ({
12519
12632
  code: rawCode,
@@ -12593,8 +12706,12 @@ var init_CodeBlock = __esm({
12593
12706
  }) => {
12594
12707
  const englishCode = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
12595
12708
  const naturalTabs = !editable && naturalLanguages && naturalLanguages.length > 1 ? naturalLanguages : void 0;
12596
- const [naturalLanguage, setNaturalLanguage] = React82.useState(() => naturalTabs?.[0] ?? "en");
12709
+ const { locale: pageLocale } = hooks.useTranslate();
12710
+ const [naturalLanguage, setNaturalLanguage] = React82.useState(
12711
+ () => naturalTabs?.find((lang) => lang === pageLocale) ?? naturalTabs?.[0] ?? "en"
12712
+ );
12597
12713
  const activeNaturalLanguage = naturalTabs?.includes(naturalLanguage) === true ? naturalLanguage : naturalTabs?.[0] ?? "en";
12714
+ const codeDir = naturalTabs && i18n.coreTables[activeNaturalLanguage].meta.rtl ? "rtl" : "ltr";
12598
12715
  const translationCache = React82.useMemo(() => /* @__PURE__ */ new Map(), [englishCode, files]);
12599
12716
  const translateFor = React82.useCallback(
12600
12717
  (source, sourceLanguage, cacheKey) => {
@@ -12633,11 +12750,12 @@ var init_CodeBlock = __esm({
12633
12750
  )
12634
12751
  }
12635
12752
  ) : null;
12636
- const activeStyle = resolveHighlightStyle(language);
12753
+ const activeStyle = resolveHighlightStyle(language, "dark");
12637
12754
  const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
12638
12755
  const plainCodeColor = plainCodeColorOf(activeStyle);
12639
12756
  const eventBus = useEventBus();
12640
12757
  const { t } = hooks.useTranslate();
12758
+ const { resolvedMode } = context.useTheme();
12641
12759
  const scrollRef = React82.useRef(null);
12642
12760
  const codeRef = React82.useRef(null);
12643
12761
  const savedScrollLeftRef = React82.useRef(0);
@@ -12648,7 +12766,7 @@ var init_CodeBlock = __esm({
12648
12766
  const activeLanguage = activeFile?.language ?? language;
12649
12767
  const activeCode = activeFile ? translateFor(activeFile.code, activeLanguage, `file-${activeFileIndex}`) : code;
12650
12768
  const languageReady = useLanguageReady(activeLanguage);
12651
- const viewerStyle = resolveHighlightStyle(activeLanguage);
12769
+ const viewerStyle = resolveHighlightStyle(activeLanguage, resolvedMode);
12652
12770
  const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
12653
12771
  const diffLines = React82.useMemo(() => {
12654
12772
  if (propDiff && propDiff.length > 0) return propDiff;
@@ -12986,8 +13104,9 @@ var init_CodeBlock = __esm({
12986
13104
  wrapLines: true,
12987
13105
  wrapLongLines: wrap,
12988
13106
  showLineNumbers,
12989
- lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
13107
+ lineNumberStyle: codeDir === "rtl" ? VIEWER_LINE_NUMBER_STYLE_RTL : VIEWER_LINE_NUMBER_STYLE,
12990
13108
  lineProps: viewerLineProps,
13109
+ renderer: codeDir === "rtl" ? renderRtlCode : void 0,
12991
13110
  customStyle: {
12992
13111
  backgroundColor: "transparent",
12993
13112
  borderRadius: 0,
@@ -12997,13 +13116,15 @@ var init_CodeBlock = __esm({
12997
13116
  wordBreak: wrap ? "break-all" : "normal",
12998
13117
  fontFamily: MONO_FONT_FAMILY,
12999
13118
  fontSize: "12px",
13000
- lineHeight: "1.6"
13119
+ lineHeight: "1.6",
13120
+ direction: codeDir,
13121
+ textAlign: "start"
13001
13122
  },
13002
- codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
13123
+ codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6", direction: codeDir, textAlign: "start" } },
13003
13124
  children: activeCode
13004
13125
  }
13005
13126
  ),
13006
- [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
13127
+ [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady, codeDir]
13007
13128
  );
13008
13129
  const diffOverCapacity = React82.useMemo(
13009
13130
  () => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
@@ -13273,33 +13394,35 @@ var init_CodeBlock = __esm({
13273
13394
  ]
13274
13395
  }
13275
13396
  ),
13276
- /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, dir: "ltr", children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
13397
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, dir: codeDir, children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
13277
13398
  ] }) });
13278
13399
  }
13279
- const hasHeader = showLanguageBadge || effectiveCopy;
13400
+ const hasHeader = showLanguageBadge;
13401
+ const copyButton = effectiveCopy ? /* @__PURE__ */ jsxRuntime.jsx(
13402
+ exports.Button,
13403
+ {
13404
+ variant: "ghost",
13405
+ size: "sm",
13406
+ onClick: handleCopy,
13407
+ className: `opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground${hasHeader ? "" : " absolute top-2 end-2 z-10"}`,
13408
+ "aria-label": t("common.copy"),
13409
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "copy", className: "w-4 h-4" })
13410
+ }
13411
+ ) : null;
13280
13412
  return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { ...domPassthrough(a11yRest), className: `relative group not-prose ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
13281
- hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
13413
+ hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(
13282
13414
  exports.HStack,
13283
13415
  {
13284
13416
  justify: "between",
13285
13417
  align: "center",
13286
13418
  className: "px-3 py-2 bg-[var(--color-card)] rounded-t-container border-b border-border",
13419
+ "data-testid": "code-block-header",
13287
13420
  children: [
13288
- showLanguageBadge && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: language }),
13289
- effectiveCopy && /* @__PURE__ */ jsxRuntime.jsx(
13290
- exports.Button,
13291
- {
13292
- variant: "ghost",
13293
- size: "sm",
13294
- onClick: handleCopy,
13295
- className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
13296
- "aria-label": t("common.copy"),
13297
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "copy", className: "w-4 h-4" })
13298
- }
13299
- )
13421
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: language }),
13422
+ copyButton
13300
13423
  ]
13301
13424
  }
13302
- ),
13425
+ ) : copyButton,
13303
13426
  naturalTabStrip,
13304
13427
  editable ? (
13305
13428
  /* GAP-77 / GAP-82 / GAP-83: editable mode = transparent textarea on
@@ -28765,7 +28888,7 @@ function DataList({
28765
28888
  return f3.variant === "badge" ? (
28766
28889
  // `format` applies here too — a boolean field badged
28767
28890
  // without it renders the raw "false" instead of "No".
28768
- /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: formatValue2(v, f3.format, fmt, relationsData?.[f3.name]) }, f3.name)
28891
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: valueLabelFor(formatValue2(v, f3.format, fmt, relationsData?.[f3.name]), f3.labels) }, f3.name)
28769
28892
  ) : /* @__PURE__ */ jsxRuntime.jsx(
28770
28893
  exports.Typography,
28771
28894
  {
@@ -28928,7 +29051,7 @@ function DataList({
28928
29051
  if (val === void 0 || val === null || val === "") return null;
28929
29052
  return /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
28930
29053
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
28931
- /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: formatValue2(val, field.format, fmt, relationsData?.[field.name]) })
29054
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: valueLabelFor(formatValue2(val, field.format, fmt, relationsData?.[field.name]), field.labels) })
28932
29055
  ] }, field.name);
28933
29056
  })
28934
29057
  ] }),
@@ -29477,7 +29600,7 @@ var init_MapView = __esm({
29477
29600
  shadowSize: [41, 41]
29478
29601
  });
29479
29602
  L.Marker.prototype.options.icon = defaultIcon;
29480
- const { useEffect: useEffect77, useRef: useRef81, useCallback: useCallback106, useState: useState112 } = React82__namespace.default;
29603
+ const { useEffect: useEffect77, useRef: useRef81, useCallback: useCallback107, useState: useState112 } = React82__namespace.default;
29481
29604
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
29482
29605
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
29483
29606
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -29526,7 +29649,7 @@ var init_MapView = __esm({
29526
29649
  const contentSurface = providers.useContentSurface(surface);
29527
29650
  const eventBus = useEventBus2();
29528
29651
  const [clickedPosition, setClickedPosition] = useState112(null);
29529
- const handleMapClick = useCallback106((lat, lng) => {
29652
+ const handleMapClick = useCallback107((lat, lng) => {
29530
29653
  if (showClickedPin) {
29531
29654
  setClickedPosition({ lat, lng });
29532
29655
  }
@@ -29535,7 +29658,7 @@ var init_MapView = __esm({
29535
29658
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
29536
29659
  }
29537
29660
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
29538
- const handleMarkerClick = useCallback106((marker) => {
29661
+ const handleMarkerClick = useCallback107((marker) => {
29539
29662
  onMarkerClick?.(marker);
29540
29663
  if (markerClickEvent) {
29541
29664
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -32167,7 +32290,7 @@ var init_DocSidebar = __esm({
32167
32290
  className: cn(
32168
32291
  "h-auto w-full justify-start rounded-interactive px-3 py-1.5 text-sm font-normal",
32169
32292
  depth > 0 && "ml-2",
32170
- item.active ? "bg-primary/8 text-foreground font-semibold" : "text-muted-foreground"
32293
+ item.active ? "bg-primary/[0.08] text-foreground font-semibold" : "text-muted-foreground"
32171
32294
  ),
32172
32295
  children: label
32173
32296
  }
@@ -40755,11 +40878,23 @@ var init_Header = __esm({
40755
40878
  variant = "mobile",
40756
40879
  look = "compact-bar",
40757
40880
  onLogoClick,
40881
+ brandHref,
40758
40882
  className,
40759
40883
  ...rest
40760
40884
  }) => {
40761
40885
  const { t } = hooks.useTranslate();
40762
40886
  const resolvedSearchPlaceholder = searchPlaceholder ?? t("common.search");
40887
+ const brandContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
40888
+ logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(exports.Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
40889
+ brandName && /* @__PURE__ */ jsxRuntime.jsx(
40890
+ exports.Typography,
40891
+ {
40892
+ variant: "h5",
40893
+ className: "text-lg text-foreground",
40894
+ children: brandName
40895
+ }
40896
+ )
40897
+ ] });
40763
40898
  const userInitials = userAvatar?.initials || userName?.[0]?.toUpperCase() || "U";
40764
40899
  return /* @__PURE__ */ jsxRuntime.jsxs(
40765
40900
  exports.Box,
@@ -40786,7 +40921,16 @@ var init_Header = __esm({
40786
40921
  children: isMenuOpen ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.X, { size: 24 }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Menu, { size: 24 })
40787
40922
  }
40788
40923
  ),
40789
- /* @__PURE__ */ jsxRuntime.jsxs(
40924
+ brandHref ? /* @__PURE__ */ jsxRuntime.jsx(
40925
+ exports.Button,
40926
+ {
40927
+ variant: "ghost",
40928
+ href: brandHref,
40929
+ "aria-label": brandName,
40930
+ className: "gap-2 px-0 hover:bg-transparent",
40931
+ children: brandContent
40932
+ }
40933
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
40790
40934
  exports.HStack,
40791
40935
  {
40792
40936
  gap: "none",
@@ -40797,17 +40941,7 @@ var init_Header = __esm({
40797
40941
  ),
40798
40942
  ...pressableProps(onLogoClick),
40799
40943
  "aria-label": onLogoClick ? brandName : void 0,
40800
- children: [
40801
- logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(exports.Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
40802
- brandName && /* @__PURE__ */ jsxRuntime.jsx(
40803
- exports.Typography,
40804
- {
40805
- variant: "h5",
40806
- className: "text-lg text-foreground",
40807
- children: brandName
40808
- }
40809
- )
40810
- ]
40944
+ children: brandContent
40811
40945
  }
40812
40946
  )
40813
40947
  ] }),
@@ -51467,8 +51601,8 @@ var init_VersionDiff = __esm({
51467
51601
  }
51468
51602
  ),
51469
51603
  /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "overflow-auto bg-muted/20", style: { maxHeight: 600 }, children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "py-8", "data-testid": "version-diff-empty", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", color: "muted", align: "center", children: t("versionDiff.noChanges") }) }) : activeView === "side-by-side" ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "grid grid-cols-1 md:grid-cols-2", children: [
51470
- /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "border-b md:border-b-0 md:border-r border-border", "data-testid": "version-diff-before", children: renderColumn("before") }),
51471
- /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { "data-testid": "version-diff-after", children: renderColumn("after") })
51604
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "min-w-0 overflow-x-auto border-b md:border-b-0 md:border-r border-border", "data-testid": "version-diff-before", children: renderColumn("before") }),
51605
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "min-w-0 overflow-x-auto", "data-testid": "version-diff-after", children: renderColumn("after") })
51472
51606
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "none", className: "font-mono text-xs", children: shown.map((row, idx) => {
51473
51607
  if (row.kind === "header") return renderHeader(row.header, `i-h-${idx}`);
51474
51608
  if (row.kind === "gap") return renderGap(row, `i-g-${row.id}`);
@@ -52619,6 +52753,7 @@ function UISlotComponentInner({
52619
52753
  const awaiting = isPortalSlot(slot) ? void 0 : awaitingSkeleton ?? runtimeAwaiting;
52620
52754
  const regionClassName = fallback !== void 0 ? cn("contents", className) : className;
52621
52755
  const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
52756
+ const i18n = hooks.useRenderI18n();
52622
52757
  const content = React82.useMemo(() => {
52623
52758
  if (!rawContent) return rawContent;
52624
52759
  const resolvedProps = resolveRenderBindingMarkers(
@@ -52626,10 +52761,11 @@ function UISlotComponentInner({
52626
52761
  rawContent.sourceTrait,
52627
52762
  binding.entity,
52628
52763
  binding.config,
52629
- binding.state
52764
+ binding.state,
52765
+ i18n
52630
52766
  );
52631
52767
  return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
52632
- }, [rawContent, binding.entity, binding.config, binding.state]);
52768
+ }, [rawContent, binding.entity, binding.config, binding.state, i18n]);
52633
52769
  const animatedPortal = isAnimatedPortalSlot(slot);
52634
52770
  const holdForPending = useScopeHasPending(React82.useContext(PendingScopeContext));
52635
52771
  const runtimePresence = useSlotPresence(portal && animatedPortal ? content ?? null : null, holdForPending);
@@ -53267,9 +53403,10 @@ function SlotContentRenderer({
53267
53403
  const ambientScope = providers.useTraitScope();
53268
53404
  const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
53269
53405
  const binding = providers.useEntityBindingSnapshot(bindingTrait);
53406
+ const i18n = hooks.useRenderI18n();
53270
53407
  const liveProps = React82.useMemo(
53271
- () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
53272
- [content.props, bindingTrait, binding.entity, binding.config, binding.state]
53408
+ () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n),
53409
+ [content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n]
53273
53410
  );
53274
53411
  const propsObj = typeof liveProps === "string" ? {} : liveProps;
53275
53412
  const entityProp = propsObj.entity;
@@ -56934,6 +57071,10 @@ function I18nProvider({ value, children, documentRoot }) {
56934
57071
  function useTranslate156() {
56935
57072
  return React82.useContext(I18nContext);
56936
57073
  }
57074
+ function useRenderI18n2() {
57075
+ const { locale, messages } = React82.useContext(I18nContext);
57076
+ return React82.useMemo(() => messages !== void 0 ? { locale, messages } : void 0, [locale, messages]);
57077
+ }
56937
57078
  function useFormatContext12() {
56938
57079
  const { t, locale, currency } = React82.useContext(I18nContext);
56939
57080
  return React82.useMemo(
@@ -57305,6 +57446,7 @@ exports.usePresence = usePresence;
57305
57446
  exports.usePreview = usePreview;
57306
57447
  exports.usePullToRefresh = usePullToRefresh;
57307
57448
  exports.useQuerySingleton = useQuerySingleton;
57449
+ exports.useRenderI18n = useRenderI18n2;
57308
57450
  exports.useRenderInterpolation = useRenderInterpolation;
57309
57451
  exports.useSharedEntitySnapshot = useSharedEntitySnapshot;
57310
57452
  exports.useSharedEntityStore = useSharedEntityStore;