@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');
@@ -103,6 +104,7 @@ var LucideIcons2__namespace = /*#__PURE__*/_interopNamespace(LucideIcons2);
103
104
  var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
104
105
  var createHighlightElement__default = /*#__PURE__*/_interopDefault(createHighlightElement);
105
106
  var dark__default = /*#__PURE__*/_interopDefault(dark);
107
+ var light__default = /*#__PURE__*/_interopDefault(light);
106
108
  var langJson__default = /*#__PURE__*/_interopDefault(langJson);
107
109
  var langJavascript__default = /*#__PURE__*/_interopDefault(langJavascript);
108
110
  var langTypescript__default = /*#__PURE__*/_interopDefault(langTypescript);
@@ -335,12 +337,13 @@ var init_useEventBus = __esm({
335
337
  useEventBus_default = useEventBus;
336
338
  }
337
339
  });
338
- function resolveMarkerExpression(expression, entity, config, state) {
340
+ function resolveMarkerExpression(expression, entity, config, state, i18n) {
339
341
  const ctx = runtime.createContextFromBindings({
340
342
  entity,
341
343
  payload: {},
342
344
  state,
343
- ...config !== void 0 ? { config } : {}
345
+ ...config !== void 0 ? { config } : {},
346
+ ...i18n !== void 0 ? { locale: i18n.locale, messages: i18n.messages } : {}
344
347
  });
345
348
  return runtime.interpolateValue(expression, ctx);
346
349
  }
@@ -352,9 +355,9 @@ function isPlainObject(value) {
352
355
  if (typeof value === "function") return false;
353
356
  return true;
354
357
  }
355
- function cachedContainer(value, scopeTrait, entity, config, state) {
358
+ function cachedContainer(value, scopeTrait, entity, config, state, i18n) {
356
359
  const hit = containerResolutionCache.get(value);
357
- return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
360
+ return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.i18n === i18n && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
358
361
  }
359
362
  function isEvaluatorResolvedData(value) {
360
363
  return evaluatorResolvedData.has(value);
@@ -385,14 +388,14 @@ function subtreeHasMarker(value) {
385
388
  markerPresenceCache.set(value, found);
386
389
  return found;
387
390
  }
388
- function walkValue(value, scopeTrait, entity, config, state) {
391
+ function walkValue(value, scopeTrait, entity, config, state, i18n) {
389
392
  if (core.isRenderBindingMarker(value)) {
390
393
  const cached = markerResolutionCache.get(value);
391
- if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
394
+ if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state && cached.i18n === i18n) {
392
395
  return { resolved: cached.resolved, changed: true };
393
396
  }
394
- const resolved = resolveMarkerExpression(value.expression, entity, config, state);
395
- markerResolutionCache.set(value, { entity, config, state, resolved });
397
+ const resolved = resolveMarkerExpression(value.expression, entity, config, state, i18n);
398
+ markerResolutionCache.set(value, { entity, config, state, i18n, resolved });
396
399
  if (resolved !== null && typeof resolved === "object" && !React92__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
397
400
  resolvedMarkerFree.add(resolved);
398
401
  evaluatorResolvedData.add(resolved);
@@ -404,14 +407,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
404
407
  brandResolved(value);
405
408
  return { resolved: value, changed: false };
406
409
  }
407
- const cachedArray = cachedContainer(value, scopeTrait, entity, config, state);
410
+ const cachedArray = cachedContainer(value, scopeTrait, entity, config, state, i18n);
408
411
  if (cachedArray !== void 0) return { resolved: cachedArray, changed: true };
409
412
  const out = [];
410
413
  let changed = false;
411
414
  for (const item of value) {
412
415
  const element = item;
413
416
  const wasMarker = core.isRenderBindingMarker(element);
414
- const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
417
+ const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state, i18n);
415
418
  if (wasMarker && Array.isArray(resolved)) {
416
419
  out.push(...resolved);
417
420
  changed = true;
@@ -422,7 +425,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
422
425
  }
423
426
  brandResolved(out);
424
427
  if (!changed) return { resolved: value, changed: false };
425
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
428
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
426
429
  return { resolved: out, changed: true };
427
430
  }
428
431
  if (isPlainObject(value)) {
@@ -434,37 +437,37 @@ function walkValue(value, scopeTrait, entity, config, state) {
434
437
  if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
435
438
  return { resolved: value, changed: false };
436
439
  }
437
- const cachedObject = cachedContainer(value, scopeTrait, entity, config, state);
440
+ const cachedObject = cachedContainer(value, scopeTrait, entity, config, state, i18n);
438
441
  if (cachedObject !== void 0) return { resolved: cachedObject, changed: true };
439
442
  const out = {};
440
443
  let changed = false;
441
444
  for (const [key, item] of Object.entries(value)) {
442
- const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
445
+ const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state, i18n);
443
446
  out[key] = resolved;
444
447
  if (itemChanged) changed = true;
445
448
  }
446
449
  brandResolved(out);
447
450
  if (!changed) return { resolved: value, changed: false };
448
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
451
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
449
452
  return { resolved: out, changed: true };
450
453
  }
451
454
  return { resolved: value, changed: false };
452
455
  }
453
- function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
456
+ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state, i18n) {
454
457
  if (props === null || typeof props !== "object") return props;
455
458
  if (resolvedMarkerFree.has(props)) return props;
456
- const cached = cachedContainer(props, scopeTrait, entity, config, state);
459
+ const cached = cachedContainer(props, scopeTrait, entity, config, state, i18n);
457
460
  if (cached !== void 0) return cached;
458
461
  const out = {};
459
462
  let changed = false;
460
463
  for (const [key, value] of Object.entries(props)) {
461
- const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
464
+ const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state, i18n);
462
465
  out[key] = resolved;
463
466
  if (propChanged) changed = true;
464
467
  }
465
468
  brandResolved(out);
466
469
  if (!changed) return props;
467
- containerResolutionCache.set(props, { entity, config, state, scopeTrait, resolved: out });
470
+ containerResolutionCache.set(props, { entity, config, state, i18n, scopeTrait, resolved: out });
468
471
  return out;
469
472
  }
470
473
  var markerPresenceCache, markerResolutionCache, containerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
@@ -1656,7 +1659,7 @@ var init_Button = __esm({
1656
1659
  const testId = dataTestId ?? (action ? `action-${action}` : void 0);
1657
1660
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1658
1661
  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" }) }),
1659
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex items-center justify-center gap-2", busy && "almadar-busy-content"), children: [
1662
+ /* @__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: [
1660
1663
  resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
1661
1664
  (Array.isArray(children) ? children.length > 0 : Boolean(children)) ? children : label ? /* @__PURE__ */ jsxRuntime.jsx("span", { ...{ [INLINE_TEXT_ATTR]: "label" }, children: label }) : label,
1662
1665
  resolvedRightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
@@ -1805,6 +1808,7 @@ var init_en = __esm({
1805
1808
  "status.draft": "Draft",
1806
1809
  "status.archived": "Archived",
1807
1810
  "error.generic": "Something went wrong",
1811
+ "error.traitMountFailed": "{{trait}} failed to start",
1808
1812
  "error.retry": "Try again",
1809
1813
  "error.notFound": "Not found",
1810
1814
  "error.loadFailed": "Failed to load: {{message}}",
@@ -2973,7 +2977,9 @@ var init_en = __esm({
2973
2977
  "agentActivity.llmToolCalls": "Tool calls",
2974
2978
  "agentActivity.showRawLlm": "Raw LLM",
2975
2979
  "agentActivity.earlierConversations": "Earlier conversations ({{count}})",
2976
- "agentActivity.earlierActivity": "Earlier activity"
2980
+ "agentActivity.earlierActivity": "Earlier activity",
2981
+ "tabs.scrollStart": "Scroll tabs back",
2982
+ "tabs.scrollEnd": "Scroll tabs forward"
2977
2983
  };
2978
2984
  }
2979
2985
  });
@@ -17807,6 +17813,7 @@ var init_Tabs = __esm({
17807
17813
  init_Badge();
17808
17814
  init_Typography();
17809
17815
  init_Box();
17816
+ init_Button();
17810
17817
  init_cn();
17811
17818
  init_useEventBus();
17812
17819
  init_domPassthrough();
@@ -17838,6 +17845,28 @@ var init_Tabs = __esm({
17838
17845
  const uid = React92.useId();
17839
17846
  const tabId = (id) => `${uid}-tab-${id}`;
17840
17847
  const panelId = (id) => `${uid}-panel-${id}`;
17848
+ const laneRef = React92.useRef(null);
17849
+ const [hidden, setHidden] = React92.useState({ start: false, end: false });
17850
+ const measure = React92.useCallback(() => {
17851
+ const lane = laneRef.current;
17852
+ if (!lane || orientation !== "horizontal") return;
17853
+ const max = lane.scrollWidth - lane.clientWidth;
17854
+ const start = max > 1 && lane.scrollLeft > 1;
17855
+ const end = max > 1 && lane.scrollLeft < max - 1;
17856
+ setHidden((prev) => prev.start === start && prev.end === end ? prev : { start, end });
17857
+ }, [orientation]);
17858
+ React92.useLayoutEffect(() => {
17859
+ measure();
17860
+ const lane = laneRef.current;
17861
+ if (!lane || typeof ResizeObserver === "undefined") return void 0;
17862
+ const observer2 = new ResizeObserver(measure);
17863
+ observer2.observe(lane);
17864
+ return () => observer2.disconnect();
17865
+ }, [measure, rawItems.length]);
17866
+ const scrollLane = (direction) => {
17867
+ const lane = laneRef.current;
17868
+ if (lane) lane.scrollBy({ left: direction * lane.clientWidth * 0.8, behavior: "smooth" });
17869
+ };
17841
17870
  const handleTabChange = (tabId2, tabEvent) => {
17842
17871
  if (controlledActiveTab === void 0) {
17843
17872
  setInternalActiveTab(tabId2);
@@ -17894,62 +17923,97 @@ var init_Tabs = __esm({
17894
17923
  "data-[active=true]:border-primary"
17895
17924
  ].join(" ")
17896
17925
  };
17897
- return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
17898
- /* @__PURE__ */ jsxRuntime.jsx(
17899
- Box,
17900
- {
17901
- role: "tablist",
17902
- "aria-orientation": orientation,
17903
- className: cn(
17904
- "flex",
17905
- // Horizontal tab strip becomes a horizontally-scrollable lane
17906
- // below its container width — phones with many tabs scroll
17907
- // instead of clipping. `snap-x` snaps to each tab; the
17908
- // scrollbar is hidden for a cleaner affordance (the swipe
17909
- // gesture is the discoverability cue).
17910
- 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",
17911
- variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
17912
- variant === "underline" && orientation === "vertical" && "border-b-0"
17913
- ),
17914
- children: safeItems.map((item, index) => {
17915
- const isActive = item.id === activeTab;
17916
- const isDisabled = item.disabled;
17917
- return /* @__PURE__ */ jsxRuntime.jsxs(
17918
- Box,
17919
- {
17920
- as: "button",
17921
- ref: (el) => {
17922
- tabRefs.current[item.id] = el;
17923
- },
17924
- id: tabId(item.id),
17925
- role: "tab",
17926
- "aria-selected": isActive,
17927
- "aria-controls": isActive ? panelId(item.id) : void 0,
17928
- "aria-disabled": isDisabled,
17929
- tabIndex: isActive ? 0 : -1,
17930
- onClick: () => !isDisabled && handleTabChange(item.id, item.event),
17931
- onKeyDown: (e) => handleKeyDown(e, index),
17932
- "data-active": isActive,
17933
- "data-testid": `tab-${item.id}`,
17934
- className: cn(
17935
- "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
17936
- orientation === "horizontal" && "snap-start shrink-0",
17937
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
17938
- isDisabled && "opacity-50 cursor-not-allowed",
17939
- variantClasses2[variant],
17940
- isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
17941
- ),
17942
- children: [
17943
- 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(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm" })),
17944
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
17945
- item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge })
17946
- ]
17926
+ const tablist = /* @__PURE__ */ jsxRuntime.jsx(
17927
+ Box,
17928
+ {
17929
+ ref: laneRef,
17930
+ role: "tablist",
17931
+ "aria-orientation": orientation,
17932
+ onScroll: measure,
17933
+ "data-scroll-affordance": hidden.start || hidden.end ? "true" : void 0,
17934
+ className: cn(
17935
+ "flex",
17936
+ // Horizontal tab strip becomes a horizontally-scrollable lane
17937
+ // below its container width — phones with many tabs scroll
17938
+ // instead of clipping. `snap-x` snaps to each tab; the
17939
+ // scrollbar is hidden — the edge chevrons are the affordance.
17940
+ 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",
17941
+ variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
17942
+ variant === "underline" && orientation === "vertical" && "border-b-0"
17943
+ ),
17944
+ children: safeItems.map((item, index) => {
17945
+ const isActive = item.id === activeTab;
17946
+ const isDisabled = item.disabled;
17947
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17948
+ Box,
17949
+ {
17950
+ as: "button",
17951
+ ref: (el) => {
17952
+ tabRefs.current[item.id] = el;
17947
17953
  },
17948
- item.id
17949
- );
17950
- })
17951
- }
17952
- ),
17954
+ id: tabId(item.id),
17955
+ role: "tab",
17956
+ "aria-selected": isActive,
17957
+ "aria-controls": isActive ? panelId(item.id) : void 0,
17958
+ "aria-disabled": isDisabled,
17959
+ tabIndex: isActive ? 0 : -1,
17960
+ onClick: () => !isDisabled && handleTabChange(item.id, item.event),
17961
+ onKeyDown: (e) => handleKeyDown(e, index),
17962
+ "data-active": isActive,
17963
+ "data-testid": `tab-${item.id}`,
17964
+ className: cn(
17965
+ "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
17966
+ orientation === "horizontal" && "snap-start shrink-0",
17967
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
17968
+ isDisabled && "opacity-50 cursor-not-allowed",
17969
+ variantClasses2[variant],
17970
+ isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
17971
+ ),
17972
+ children: [
17973
+ 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(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm" })),
17974
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
17975
+ item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge })
17976
+ ]
17977
+ },
17978
+ item.id
17979
+ );
17980
+ })
17981
+ }
17982
+ );
17983
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
17984
+ orientation === "horizontal" ? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
17985
+ tablist,
17986
+ hidden.start && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17987
+ /* @__PURE__ */ jsxRuntime.jsx(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" }),
17988
+ /* @__PURE__ */ jsxRuntime.jsx(
17989
+ Button,
17990
+ {
17991
+ variant: "ghost",
17992
+ size: "sm",
17993
+ leftIcon: "chevron-left",
17994
+ "aria-label": t("tabs.scrollStart"),
17995
+ "data-testid": "tabs-scroll-start",
17996
+ className: "absolute start-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
17997
+ onClick: () => scrollLane(-1)
17998
+ }
17999
+ )
18000
+ ] }),
18001
+ hidden.end && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18002
+ /* @__PURE__ */ jsxRuntime.jsx(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" }),
18003
+ /* @__PURE__ */ jsxRuntime.jsx(
18004
+ Button,
18005
+ {
18006
+ variant: "ghost",
18007
+ size: "sm",
18008
+ leftIcon: "chevron-right",
18009
+ "aria-label": t("tabs.scrollEnd"),
18010
+ "data-testid": "tabs-scroll-end",
18011
+ className: "absolute end-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
18012
+ onClick: () => scrollLane(1)
18013
+ }
18014
+ )
18015
+ ] })
18016
+ ] }) : tablist,
17953
18017
  activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsxRuntime.jsx(
17954
18018
  Box,
17955
18019
  {
@@ -19160,6 +19224,35 @@ function withTokenTypes(node) {
19160
19224
  function renderWithTokenTypes({ rows, stylesheet, useInlineStyles }) {
19161
19225
  return rows.map((node, i) => createHighlightElement__default.default({ node: withTokenTypes(node), stylesheet, useInlineStyles, key: `code-segment-${i}` }));
19162
19226
  }
19227
+ function island(value, style) {
19228
+ return { type: "element", tagName: "span", properties: { className: [], "data-bidi-island": "", style }, children: [{ type: "text", value }] };
19229
+ }
19230
+ function splitLtrWords(value) {
19231
+ const out = [];
19232
+ let last = 0;
19233
+ for (const match of value.matchAll(LTR_WORD)) {
19234
+ const start = match.index ?? 0;
19235
+ if (start > last) out.push({ type: "text", value: value.slice(last, start) });
19236
+ out.push(island(match[0], LTR_ISLAND_STYLE));
19237
+ last = start + match[0].length;
19238
+ }
19239
+ if (last < value.length) out.push({ type: "text", value: value.slice(last) });
19240
+ return out;
19241
+ }
19242
+ function withBidiIslands(node) {
19243
+ if (node.type === "text") return splitLtrWords(String(node.value ?? ""));
19244
+ if (node.type !== "element") return [node];
19245
+ const classes = node.properties?.className;
19246
+ if (Array.isArray(classes) && classes.includes("string")) {
19247
+ return [{ ...node, properties: { ...node.properties, className: classes, "data-bidi-island": "", style: STRING_ISLAND_STYLE } }];
19248
+ }
19249
+ return [{ ...node, ...node.children ? { children: node.children.flatMap(withBidiIslands) } : {} }];
19250
+ }
19251
+ function renderRtlCode({ rows, stylesheet, useInlineStyles }) {
19252
+ return rows.map(
19253
+ (node, i) => withBidiIslands(node).map((n, j) => createHighlightElement__default.default({ node: n, stylesheet, useInlineStyles, key: `code-rtl-${i}-${j}` }))
19254
+ );
19255
+ }
19163
19256
  function tokenClassAt(layer, offset) {
19164
19257
  const walker = document.createTreeWalker(layer, NodeFilter.SHOW_TEXT);
19165
19258
  let pos = 0;
@@ -19216,10 +19309,9 @@ function useLanguageReady(language) {
19216
19309
  }, [language]);
19217
19310
  return ready;
19218
19311
  }
19219
- function resolveHighlightStyle(lang) {
19220
- if (lang === "orb") return orbStyle;
19221
- if (lang === "lolo") return loloStyle;
19222
- return dark__default.default;
19312
+ function resolveHighlightStyle(lang, scheme) {
19313
+ if (lang === "orb" || lang === "lolo") return HIGHLIGHT_STYLES[scheme][lang];
19314
+ return SCHEME_BASE[scheme];
19223
19315
  }
19224
19316
  function plainCodeColorOf(style) {
19225
19317
  return style['code[class*="language-"]']?.color ?? "#d4d4d4";
@@ -19254,7 +19346,7 @@ function translateProgram(source, language, lang) {
19254
19346
  }
19255
19347
  return source;
19256
19348
  }
19257
- var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, MONO_EDITOR_FONT, GHOST_COLOR, GUTTER_COLOR, caretOf, DIAGNOSTIC_ERROR_COLOR, DIAGNOSTIC_WARNING_COLOR, EDITOR_LINE_PX, log8, 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, CodeBlock;
19349
+ 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, log8, 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, CodeBlock;
19258
19350
  var init_CodeBlock = __esm({
19259
19351
  "components/core/molecules/markdown/CodeBlock.tsx"() {
19260
19352
  init_cn();
@@ -19357,52 +19449,64 @@ var init_CodeBlock = __esm({
19357
19449
  SyntaxHighlighter__default.default.registerLanguage("lolo", syntax.loloLanguage);
19358
19450
  dynamicallyLoaded = /* @__PURE__ */ new Set();
19359
19451
  codeLanguageLoader = null;
19360
- orbStyleOverrides = {
19361
- "orb-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
19362
- "orb-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
19363
- "orb-event": { color: syntax.ORB_COLORS.dark.event },
19364
- "orb-slot": { color: syntax.ORB_COLORS.dark.uiSlot },
19365
- "orb-structural": { color: syntax.ORB_COLORS.dark.structural },
19366
- "orb-field-type": { color: syntax.ORB_COLORS.dark.fieldType },
19367
- "orb-persistence": { color: syntax.ORB_COLORS.dark.persistence },
19368
- "orb-pattern": { color: syntax.ORB_COLORS.dark.pattern },
19369
- "orb-behavior": { color: syntax.ORB_COLORS.dark.behavior },
19370
- "orb-unknown-op": { color: syntax.ORB_COLORS.dark.error, textDecoration: "wavy underline" },
19371
- "orb-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
19372
- "orb-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
19373
- "orb-op-logic": { color: syntax.ORB_COLORS.dark.logic },
19374
- "orb-op-string": { color: syntax.ORB_COLORS.dark.string },
19375
- "orb-op-collection": { color: syntax.ORB_COLORS.dark.collection },
19376
- "orb-op-time": { color: syntax.ORB_COLORS.dark.time },
19377
- "orb-op-control": { color: syntax.ORB_COLORS.dark.control },
19378
- "orb-op-async": { color: syntax.ORB_COLORS.dark.async }
19379
- };
19380
- orbStyle = { ...dark__default.default, ...orbStyleOverrides };
19381
- loloStyleOverrides = {
19382
- "lolo-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
19383
- "lolo-event": { color: syntax.ORB_COLORS.dark.event },
19384
- "lolo-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
19385
- "keyword": { color: syntax.ORB_COLORS.dark.loloKeyword },
19386
- "lolo-constructor": { color: syntax.ORB_COLORS.dark.loloConstructor },
19387
- "lolo-arrow": { color: syntax.ORB_COLORS.dark.loloArrow },
19388
- "lolo-reference": { color: syntax.ORB_COLORS.dark.loloReference },
19389
- "lolo-type": { color: syntax.ORB_COLORS.dark.fieldType },
19390
- "lolo-persistence": { color: syntax.ORB_COLORS.dark.persistence },
19391
- "lolo-unknown-op": { color: syntax.ORB_COLORS.dark.error },
19392
- "lolo-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
19393
- "lolo-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
19394
- "lolo-op-logic": { color: syntax.ORB_COLORS.dark.logic },
19395
- "lolo-op-string": { color: syntax.ORB_COLORS.dark.string },
19396
- "lolo-op-collection": { color: syntax.ORB_COLORS.dark.collection },
19397
- "lolo-op-time": { color: syntax.ORB_COLORS.dark.time },
19398
- "lolo-op-control": { color: syntax.ORB_COLORS.dark.control },
19399
- "lolo-op-async": { color: syntax.ORB_COLORS.dark.async }
19400
- };
19401
- loloStyle = { ...dark__default.default, ...loloStyleOverrides };
19452
+ orbStyleOverrides = (c) => ({
19453
+ "orb-binding": { color: c.binding, fontWeight: "bold" },
19454
+ "orb-effect": { color: c.effect, fontWeight: "bold" },
19455
+ "orb-event": { color: c.event },
19456
+ "orb-slot": { color: c.uiSlot },
19457
+ "orb-structural": { color: c.structural },
19458
+ "orb-field-type": { color: c.fieldType },
19459
+ "orb-persistence": { color: c.persistence },
19460
+ "orb-pattern": { color: c.pattern },
19461
+ "orb-behavior": { color: c.behavior },
19462
+ "orb-unknown-op": { color: c.error, textDecoration: "wavy underline" },
19463
+ "orb-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
19464
+ "orb-op-comparison": { color: c.comparison },
19465
+ "orb-op-logic": { color: c.logic },
19466
+ "orb-op-string": { color: c.string },
19467
+ "orb-op-collection": { color: c.collection },
19468
+ "orb-op-time": { color: c.time },
19469
+ "orb-op-control": { color: c.control },
19470
+ "orb-op-async": { color: c.async }
19471
+ });
19472
+ loloStyleOverrides = (c) => ({
19473
+ "lolo-binding": { color: c.binding, fontWeight: "bold" },
19474
+ "lolo-event": { color: c.event },
19475
+ "lolo-effect": { color: c.effect, fontWeight: "bold" },
19476
+ "keyword": { color: c.loloKeyword },
19477
+ "lolo-constructor": { color: c.loloConstructor },
19478
+ "lolo-arrow": { color: c.loloArrow },
19479
+ "lolo-reference": { color: c.loloReference },
19480
+ "lolo-type": { color: c.fieldType },
19481
+ "lolo-persistence": { color: c.persistence },
19482
+ "lolo-unknown-op": { color: c.error },
19483
+ "lolo-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
19484
+ "lolo-op-comparison": { color: c.comparison },
19485
+ "lolo-op-logic": { color: c.logic },
19486
+ "lolo-op-string": { color: c.string },
19487
+ "lolo-op-collection": { color: c.collection },
19488
+ "lolo-op-time": { color: c.time },
19489
+ "lolo-op-control": { color: c.control },
19490
+ "lolo-op-async": { color: c.async }
19491
+ });
19492
+ SCHEME_BASE = { dark: dark__default.default, light: light__default.default };
19493
+ HIGHLIGHT_STYLES = {
19494
+ dark: {
19495
+ orb: { ...dark__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.dark) },
19496
+ lolo: { ...dark__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.dark) }
19497
+ },
19498
+ light: {
19499
+ orb: { ...light__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.light) },
19500
+ lolo: { ...light__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.light) }
19501
+ }
19502
+ };
19402
19503
  MONO_EDITOR_FONT = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
19403
19504
  GHOST_COLOR = "#7f848e";
19404
19505
  GUTTER_COLOR = "#858585";
19405
19506
  caretOf = (ta) => ta.selectionDirection === "backward" ? ta.selectionStart : ta.selectionEnd;
19507
+ LTR_WORD = /[A-Za-z0-9_$@?][A-Za-z0-9_$@?.!-]*/g;
19508
+ LTR_ISLAND_STYLE = { unicodeBidi: "isolate", direction: "ltr" };
19509
+ STRING_ISLAND_STYLE = { unicodeBidi: "plaintext" };
19406
19510
  DIAGNOSTIC_ERROR_COLOR = "#f14c4c";
19407
19511
  DIAGNOSTIC_WARNING_COLOR = "#cca700";
19408
19512
  EDITOR_LINE_PX = 19.5;
@@ -19502,7 +19606,7 @@ var init_CodeBlock = __esm({
19502
19606
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
19503
19607
  HIDDEN_LINE_NUMBERS = { display: "none" };
19504
19608
  HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
19505
- MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
19609
+ MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", "IBM Plex Sans Arabic", "Noto Sans Arabic", monospace';
19506
19610
  VIEWER_LINE_NUMBER_STYLE = {
19507
19611
  minWidth: "2.5em",
19508
19612
  paddingRight: "1rem",
@@ -19511,6 +19615,15 @@ var init_CodeBlock = __esm({
19511
19615
  opacity: 0.5,
19512
19616
  fontVariantNumeric: "tabular-nums"
19513
19617
  };
19618
+ VIEWER_LINE_NUMBER_STYLE_RTL = {
19619
+ minWidth: "2.5em",
19620
+ paddingRight: 0,
19621
+ paddingLeft: "1rem",
19622
+ textAlign: "left",
19623
+ userSelect: "none",
19624
+ opacity: 0.5,
19625
+ fontVariantNumeric: "tabular-nums"
19626
+ };
19514
19627
  CodeBlock = React92__namespace.default.memo(
19515
19628
  ({
19516
19629
  code: rawCode,
@@ -19590,8 +19703,12 @@ var init_CodeBlock = __esm({
19590
19703
  }) => {
19591
19704
  const englishCode = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
19592
19705
  const naturalTabs = !editable && naturalLanguages && naturalLanguages.length > 1 ? naturalLanguages : void 0;
19593
- const [naturalLanguage, setNaturalLanguage] = React92.useState(() => naturalTabs?.[0] ?? "en");
19706
+ const { locale: pageLocale } = hooks.useTranslate();
19707
+ const [naturalLanguage, setNaturalLanguage] = React92.useState(
19708
+ () => naturalTabs?.find((lang) => lang === pageLocale) ?? naturalTabs?.[0] ?? "en"
19709
+ );
19594
19710
  const activeNaturalLanguage = naturalTabs?.includes(naturalLanguage) === true ? naturalLanguage : naturalTabs?.[0] ?? "en";
19711
+ const codeDir = naturalTabs && i18n.coreTables[activeNaturalLanguage].meta.rtl ? "rtl" : "ltr";
19595
19712
  const translationCache = React92.useMemo(() => /* @__PURE__ */ new Map(), [englishCode, files]);
19596
19713
  const translateFor = React92.useCallback(
19597
19714
  (source, sourceLanguage, cacheKey) => {
@@ -19630,11 +19747,12 @@ var init_CodeBlock = __esm({
19630
19747
  )
19631
19748
  }
19632
19749
  ) : null;
19633
- const activeStyle = resolveHighlightStyle(language);
19750
+ const activeStyle = resolveHighlightStyle(language, "dark");
19634
19751
  const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
19635
19752
  const plainCodeColor = plainCodeColorOf(activeStyle);
19636
19753
  const eventBus = useEventBus();
19637
19754
  const { t } = hooks.useTranslate();
19755
+ const { resolvedMode } = context.useTheme();
19638
19756
  const scrollRef = React92.useRef(null);
19639
19757
  const codeRef = React92.useRef(null);
19640
19758
  const savedScrollLeftRef = React92.useRef(0);
@@ -19645,7 +19763,7 @@ var init_CodeBlock = __esm({
19645
19763
  const activeLanguage = activeFile?.language ?? language;
19646
19764
  const activeCode = activeFile ? translateFor(activeFile.code, activeLanguage, `file-${activeFileIndex}`) : code;
19647
19765
  const languageReady = useLanguageReady(activeLanguage);
19648
- const viewerStyle = resolveHighlightStyle(activeLanguage);
19766
+ const viewerStyle = resolveHighlightStyle(activeLanguage, resolvedMode);
19649
19767
  const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
19650
19768
  const diffLines = React92.useMemo(() => {
19651
19769
  if (propDiff && propDiff.length > 0) return propDiff;
@@ -19983,8 +20101,9 @@ var init_CodeBlock = __esm({
19983
20101
  wrapLines: true,
19984
20102
  wrapLongLines: wrap,
19985
20103
  showLineNumbers,
19986
- lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
20104
+ lineNumberStyle: codeDir === "rtl" ? VIEWER_LINE_NUMBER_STYLE_RTL : VIEWER_LINE_NUMBER_STYLE,
19987
20105
  lineProps: viewerLineProps,
20106
+ renderer: codeDir === "rtl" ? renderRtlCode : void 0,
19988
20107
  customStyle: {
19989
20108
  backgroundColor: "transparent",
19990
20109
  borderRadius: 0,
@@ -19994,13 +20113,15 @@ var init_CodeBlock = __esm({
19994
20113
  wordBreak: wrap ? "break-all" : "normal",
19995
20114
  fontFamily: MONO_FONT_FAMILY,
19996
20115
  fontSize: "12px",
19997
- lineHeight: "1.6"
20116
+ lineHeight: "1.6",
20117
+ direction: codeDir,
20118
+ textAlign: "start"
19998
20119
  },
19999
- codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
20120
+ codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6", direction: codeDir, textAlign: "start" } },
20000
20121
  children: activeCode
20001
20122
  }
20002
20123
  ),
20003
- [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
20124
+ [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady, codeDir]
20004
20125
  );
20005
20126
  const diffOverCapacity = React92.useMemo(
20006
20127
  () => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
@@ -20270,33 +20391,35 @@ var init_CodeBlock = __esm({
20270
20391
  ]
20271
20392
  }
20272
20393
  ),
20273
- /* @__PURE__ */ jsxRuntime.jsx(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 }) })
20394
+ /* @__PURE__ */ jsxRuntime.jsx(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 }) })
20274
20395
  ] }) });
20275
20396
  }
20276
- const hasHeader = showLanguageBadge || effectiveCopy;
20397
+ const hasHeader = showLanguageBadge;
20398
+ const copyButton = effectiveCopy ? /* @__PURE__ */ jsxRuntime.jsx(
20399
+ Button,
20400
+ {
20401
+ variant: "ghost",
20402
+ size: "sm",
20403
+ onClick: handleCopy,
20404
+ 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"}`,
20405
+ "aria-label": t("common.copy"),
20406
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "copy", className: "w-4 h-4" })
20407
+ }
20408
+ ) : null;
20277
20409
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(a11yRest), className: `relative group not-prose ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
20278
- hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
20410
+ hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(
20279
20411
  HStack,
20280
20412
  {
20281
20413
  justify: "between",
20282
20414
  align: "center",
20283
20415
  className: "px-3 py-2 bg-[var(--color-card)] rounded-t-container border-b border-border",
20416
+ "data-testid": "code-block-header",
20284
20417
  children: [
20285
- showLanguageBadge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: language }),
20286
- effectiveCopy && /* @__PURE__ */ jsxRuntime.jsx(
20287
- Button,
20288
- {
20289
- variant: "ghost",
20290
- size: "sm",
20291
- onClick: handleCopy,
20292
- className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
20293
- "aria-label": t("common.copy"),
20294
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "copy", className: "w-4 h-4" })
20295
- }
20296
- )
20418
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: language }),
20419
+ copyButton
20297
20420
  ]
20298
20421
  }
20299
- ),
20422
+ ) : copyButton,
20300
20423
  naturalTabStrip,
20301
20424
  editable ? (
20302
20425
  /* GAP-77 / GAP-82 / GAP-83: editable mode = transparent textarea on
@@ -31026,7 +31149,7 @@ function DataList({
31026
31149
  return f3.variant === "badge" ? (
31027
31150
  // `format` applies here too — a boolean field badged
31028
31151
  // without it renders the raw "false" instead of "No".
31029
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: formatValue2(v, f3.format, fmt, relationsData?.[f3.name]) }, f3.name)
31152
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: valueLabelFor(formatValue2(v, f3.format, fmt, relationsData?.[f3.name]), f3.labels) }, f3.name)
31030
31153
  ) : /* @__PURE__ */ jsxRuntime.jsx(
31031
31154
  Typography,
31032
31155
  {
@@ -31189,7 +31312,7 @@ function DataList({
31189
31312
  if (val === void 0 || val === null || val === "") return null;
31190
31313
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
31191
31314
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
31192
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: formatValue2(val, field.format, fmt, relationsData?.[field.name]) })
31315
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: valueLabelFor(formatValue2(val, field.format, fmt, relationsData?.[field.name]), field.labels) })
31193
31316
  ] }, field.name);
31194
31317
  })
31195
31318
  ] }),
@@ -31738,7 +31861,7 @@ var init_MapView = __esm({
31738
31861
  shadowSize: [41, 41]
31739
31862
  });
31740
31863
  L.Marker.prototype.options.icon = defaultIcon;
31741
- const { useEffect: useEffect77, useRef: useRef79, useCallback: useCallback100, useState: useState107 } = React92__namespace.default;
31864
+ const { useEffect: useEffect77, useRef: useRef79, useCallback: useCallback101, useState: useState107 } = React92__namespace.default;
31742
31865
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
31743
31866
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
31744
31867
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -31787,7 +31910,7 @@ var init_MapView = __esm({
31787
31910
  const contentSurface = providers.useContentSurface(surface);
31788
31911
  const eventBus = useEventBus2();
31789
31912
  const [clickedPosition, setClickedPosition] = useState107(null);
31790
- const handleMapClick = useCallback100((lat, lng) => {
31913
+ const handleMapClick = useCallback101((lat, lng) => {
31791
31914
  if (showClickedPin) {
31792
31915
  setClickedPosition({ lat, lng });
31793
31916
  }
@@ -31796,7 +31919,7 @@ var init_MapView = __esm({
31796
31919
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
31797
31920
  }
31798
31921
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
31799
- const handleMarkerClick = useCallback100((marker) => {
31922
+ const handleMarkerClick = useCallback101((marker) => {
31800
31923
  onMarkerClick?.(marker);
31801
31924
  if (markerClickEvent) {
31802
31925
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -34373,7 +34496,7 @@ var init_DocSidebar = __esm({
34373
34496
  className: cn(
34374
34497
  "h-auto w-full justify-start rounded-interactive px-3 py-1.5 text-sm font-normal",
34375
34498
  depth > 0 && "ml-2",
34376
- item.active ? "bg-primary/8 text-foreground font-semibold" : "text-muted-foreground"
34499
+ item.active ? "bg-primary/[0.08] text-foreground font-semibold" : "text-muted-foreground"
34377
34500
  ),
34378
34501
  children: label
34379
34502
  }
@@ -41915,11 +42038,23 @@ var init_Header = __esm({
41915
42038
  variant = "mobile",
41916
42039
  look = "compact-bar",
41917
42040
  onLogoClick,
42041
+ brandHref,
41918
42042
  className,
41919
42043
  ...rest
41920
42044
  }) => {
41921
42045
  const { t } = hooks.useTranslate();
41922
42046
  const resolvedSearchPlaceholder = searchPlaceholder ?? t("common.search");
42047
+ const brandContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
42048
+ logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
42049
+ brandName && /* @__PURE__ */ jsxRuntime.jsx(
42050
+ Typography,
42051
+ {
42052
+ variant: "h5",
42053
+ className: "text-lg text-foreground",
42054
+ children: brandName
42055
+ }
42056
+ )
42057
+ ] });
41923
42058
  const userInitials = userAvatar?.initials || userName?.[0]?.toUpperCase() || "U";
41924
42059
  return /* @__PURE__ */ jsxRuntime.jsxs(
41925
42060
  Box,
@@ -41946,7 +42081,16 @@ var init_Header = __esm({
41946
42081
  children: isMenuOpen ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.X, { size: 24 }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Menu, { size: 24 })
41947
42082
  }
41948
42083
  ),
41949
- /* @__PURE__ */ jsxRuntime.jsxs(
42084
+ brandHref ? /* @__PURE__ */ jsxRuntime.jsx(
42085
+ Button,
42086
+ {
42087
+ variant: "ghost",
42088
+ href: brandHref,
42089
+ "aria-label": brandName,
42090
+ className: "gap-2 px-0 hover:bg-transparent",
42091
+ children: brandContent
42092
+ }
42093
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
41950
42094
  HStack,
41951
42095
  {
41952
42096
  gap: "none",
@@ -41957,17 +42101,7 @@ var init_Header = __esm({
41957
42101
  ),
41958
42102
  ...pressableProps(onLogoClick),
41959
42103
  "aria-label": onLogoClick ? brandName : void 0,
41960
- children: [
41961
- logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
41962
- brandName && /* @__PURE__ */ jsxRuntime.jsx(
41963
- Typography,
41964
- {
41965
- variant: "h5",
41966
- className: "text-lg text-foreground",
41967
- children: brandName
41968
- }
41969
- )
41970
- ]
42104
+ children: brandContent
41971
42105
  }
41972
42106
  )
41973
42107
  ] }),
@@ -51883,8 +52017,8 @@ var init_VersionDiff = __esm({
51883
52017
  }
51884
52018
  ),
51885
52019
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight: 600 }, children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "py-8", "data-testid": "version-diff-empty", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", color: "muted", align: "center", children: t("versionDiff.noChanges") }) }) : activeView === "side-by-side" ? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "grid grid-cols-1 md:grid-cols-2", children: [
51886
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "border-b md:border-b-0 md:border-r border-border", "data-testid": "version-diff-before", children: renderColumn("before") }),
51887
- /* @__PURE__ */ jsxRuntime.jsx(Box, { "data-testid": "version-diff-after", children: renderColumn("after") })
52020
+ /* @__PURE__ */ jsxRuntime.jsx(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") }),
52021
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "min-w-0 overflow-x-auto", "data-testid": "version-diff-after", children: renderColumn("after") })
51888
52022
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "font-mono text-xs", children: shown.map((row, idx) => {
51889
52023
  if (row.kind === "header") return renderHeader(row.header, `i-h-${idx}`);
51890
52024
  if (row.kind === "gap") return renderGap(row, `i-g-${row.id}`);
@@ -53035,6 +53169,7 @@ function UISlotComponentInner({
53035
53169
  const awaiting = isPortalSlot(slot) ? void 0 : awaitingSkeleton ?? runtimeAwaiting;
53036
53170
  const regionClassName = fallback !== void 0 ? cn("contents", className) : className;
53037
53171
  const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
53172
+ const i18n = hooks.useRenderI18n();
53038
53173
  const content = React92.useMemo(() => {
53039
53174
  if (!rawContent) return rawContent;
53040
53175
  const resolvedProps = resolveRenderBindingMarkers(
@@ -53042,10 +53177,11 @@ function UISlotComponentInner({
53042
53177
  rawContent.sourceTrait,
53043
53178
  binding.entity,
53044
53179
  binding.config,
53045
- binding.state
53180
+ binding.state,
53181
+ i18n
53046
53182
  );
53047
53183
  return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
53048
- }, [rawContent, binding.entity, binding.config, binding.state]);
53184
+ }, [rawContent, binding.entity, binding.config, binding.state, i18n]);
53049
53185
  const animatedPortal = isAnimatedPortalSlot(slot);
53050
53186
  const holdForPending = useScopeHasPending(React92.useContext(PendingScopeContext));
53051
53187
  const runtimePresence = useSlotPresence(portal && animatedPortal ? content ?? null : null, holdForPending);
@@ -53683,9 +53819,10 @@ function SlotContentRenderer({
53683
53819
  const ambientScope = providers.useTraitScope();
53684
53820
  const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
53685
53821
  const binding = providers.useEntityBindingSnapshot(bindingTrait);
53822
+ const i18n = hooks.useRenderI18n();
53686
53823
  const liveProps = React92.useMemo(
53687
- () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
53688
- [content.props, bindingTrait, binding.entity, binding.config, binding.state]
53824
+ () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n),
53825
+ [content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n]
53689
53826
  );
53690
53827
  const propsObj = typeof liveProps === "string" ? {} : liveProps;
53691
53828
  const entityProp = propsObj.entity;