@almadar/ui 5.154.0 → 5.156.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.
@@ -8496,6 +8496,11 @@ var init_ComponentPatterns = __esm({
8496
8496
  AlertPattern.displayName = "AlertPattern";
8497
8497
  }
8498
8498
  });
8499
+ function themeBodyFont(el) {
8500
+ if (typeof getComputedStyle !== "function") return "system-ui, sans-serif";
8501
+ const v = getComputedStyle(el).getPropertyValue("--font-family-body").trim();
8502
+ return v || "system-ui, sans-serif";
8503
+ }
8499
8504
  function resolveColor2(color, ctx, fallback) {
8500
8505
  if (!color) return fallback;
8501
8506
  if (color.startsWith("var(")) {
@@ -8695,7 +8700,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
8695
8700
  case "text": {
8696
8701
  if (shape.x == null || shape.y == null || !shape.text) break;
8697
8702
  ctx.fillStyle = stroke;
8698
- ctx.font = `${shape.fontSize ?? 14}px system-ui, sans-serif`;
8703
+ ctx.font = `${shape.fontSize ?? 14}px ${themeBodyFont(ctx.canvas)}`;
8699
8704
  ctx.textAlign = shape.align ?? "left";
8700
8705
  ctx.textBaseline = "middle";
8701
8706
  ctx.fillText(shape.text, shape.x, shape.y);
@@ -16567,7 +16572,22 @@ function eventStartDate(event, startField) {
16567
16572
  const raw = getNestedValue(event, startField);
16568
16573
  return new Date(raw ?? "");
16569
16574
  }
16570
- function generateDefaultTimeSlots(events2, startField) {
16575
+ function eventEndDate(event, endField) {
16576
+ const raw = getNestedValue(event, endField);
16577
+ if (raw === void 0 || raw === null || raw === "") return null;
16578
+ const end = new Date(raw);
16579
+ return Number.isNaN(end.getTime()) ? null : end;
16580
+ }
16581
+ function eventContinuesInSlot(event, day, slotTime, startField, endField) {
16582
+ const eventStart = eventStartDate(event, startField);
16583
+ const eventEnd = eventEndDate(event, endField);
16584
+ if (eventEnd === null || Number.isNaN(eventStart.getTime())) return false;
16585
+ const [slotHour] = slotTime.split(":").map(Number);
16586
+ const slotStart = new Date(day);
16587
+ slotStart.setHours(slotHour, 0, 0, 0);
16588
+ return slotStart.getTime() > eventStart.getTime() && slotStart.getTime() < eventEnd.getTime();
16589
+ }
16590
+ function generateDefaultTimeSlots(events2, startField, endField) {
16571
16591
  let first = DEFAULT_FIRST_HOUR;
16572
16592
  let last = DEFAULT_LAST_HOUR;
16573
16593
  for (const ev of events2) {
@@ -16576,6 +16596,11 @@ function generateDefaultTimeSlots(events2, startField) {
16576
16596
  const hour = start.getHours();
16577
16597
  if (hour < first) first = hour;
16578
16598
  if (hour > last) last = hour;
16599
+ const end = eventEndDate(ev, endField);
16600
+ if (end && end.toDateString() === start.toDateString()) {
16601
+ const endHour = end.getMinutes() === 0 && end.getSeconds() === 0 ? end.getHours() - 1 : end.getHours();
16602
+ if (endHour > last) last = endHour;
16603
+ }
16579
16604
  }
16580
16605
  const slots = [];
16581
16606
  for (let hour = first; hour <= last; hour++) {
@@ -16604,6 +16629,7 @@ function CalendarGrid({
16604
16629
  dayWindow = "auto",
16605
16630
  titleField = "title",
16606
16631
  startField = "startTime",
16632
+ endField = "endTime",
16607
16633
  colorField = "color",
16608
16634
  children,
16609
16635
  renderItem
@@ -16621,8 +16647,8 @@ function CalendarGrid({
16621
16647
  [resolvedWeekStart]
16622
16648
  );
16623
16649
  const resolvedTimeSlots = React77.useMemo(
16624
- () => timeSlots ?? generateDefaultTimeSlots(evs, startField),
16625
- [timeSlots, evs, startField]
16650
+ () => timeSlots ?? generateDefaultTimeSlots(evs, startField, endField),
16651
+ [timeSlots, evs, startField, endField]
16626
16652
  );
16627
16653
  const visibleCount = useDayWindow(dayWindow);
16628
16654
  const [dayOffset, setDayOffset] = React77.useState(0);
@@ -16782,12 +16808,15 @@ function CalendarGrid({
16782
16808
  const slotEvents = evs.filter(
16783
16809
  (ev) => eventInSlot(ev, day, time, startField)
16784
16810
  );
16811
+ const continuingEvents = evs.filter(
16812
+ (ev) => eventContinuesInSlot(ev, day, time, startField, endField)
16813
+ );
16785
16814
  const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
16786
16815
  return /* @__PURE__ */ jsxRuntime.jsx(
16787
16816
  TimeSlotCell,
16788
16817
  {
16789
16818
  time,
16790
- isOccupied: slotEvents.length > 0,
16819
+ isOccupied: slotEvents.length > 0 || continuingEvents.length > 0,
16791
16820
  onClick: () => handleSlotClick(day, time),
16792
16821
  className: cn(
16793
16822
  "border-l border-border",
@@ -16798,7 +16827,25 @@ function CalendarGrid({
16798
16827
  onPointerUp: clearLongPress,
16799
16828
  onPointerCancel: clearLongPress
16800
16829
  } : {},
16801
- children: /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "xs", children: slotEvents.map(renderEvent) })
16830
+ children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
16831
+ slotEvents.map(renderEvent),
16832
+ continuingEvents.map((event) => {
16833
+ const color = getNestedValue(event, colorField);
16834
+ return /* @__PURE__ */ jsxRuntime.jsx(
16835
+ exports.Box,
16836
+ {
16837
+ rounded: "sm",
16838
+ border: true,
16839
+ className: cn(
16840
+ "cursor-pointer h-2",
16841
+ color ? cn(color, "opacity-50") : "bg-primary/10 border-primary/20"
16842
+ ),
16843
+ onClick: (e) => handleEventClick(event, e)
16844
+ },
16845
+ `${event.id}-cont`
16846
+ );
16847
+ })
16848
+ ] })
16802
16849
  },
16803
16850
  `${day.toISOString()}-${time}`
16804
16851
  );
@@ -22005,10 +22052,21 @@ function ControlGrid({
22005
22052
  directionAssets,
22006
22053
  size = "md",
22007
22054
  disabled,
22055
+ visibility = "auto",
22008
22056
  className
22009
22057
  }) {
22010
22058
  const eventBus = useEventBus();
22011
22059
  const [active, setActive] = React77__namespace.useState(/* @__PURE__ */ new Set());
22060
+ const [coarse, setCoarse] = React77__namespace.useState(
22061
+ () => typeof window !== "undefined" && window.matchMedia("(pointer: coarse)").matches
22062
+ );
22063
+ React77__namespace.useEffect(() => {
22064
+ if (visibility !== "auto" || typeof window === "undefined") return;
22065
+ const mq = window.matchMedia("(pointer: coarse)");
22066
+ const onChange = (e) => setCoarse(e.matches);
22067
+ mq.addEventListener("change", onChange);
22068
+ return () => mq.removeEventListener("change", onChange);
22069
+ }, [visibility]);
22012
22070
  const handlePress = React77__namespace.useCallback(
22013
22071
  (id) => {
22014
22072
  setActive((prev) => new Set(prev).add(id));
@@ -22041,6 +22099,7 @@ function ControlGrid({
22041
22099
  },
22042
22100
  [kind, actionEvent, directionEvent, directionReleaseEvents, eventBus, onAction, onDirection]
22043
22101
  );
22102
+ if (visibility === "auto" && !coarse) return null;
22044
22103
  if (kind === "dpad") {
22045
22104
  const ds = dpadSizeMap[size];
22046
22105
  const dir = (d) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -29556,7 +29615,7 @@ function StatBadge({
29556
29615
  assetUrl,
29557
29616
  iconUrl,
29558
29617
  label,
29559
- value = 0,
29618
+ value,
29560
29619
  max,
29561
29620
  format = "number",
29562
29621
  icon,
@@ -29567,6 +29626,7 @@ function StatBadge({
29567
29626
  source: _source,
29568
29627
  field: _field
29569
29628
  }) {
29629
+ const hasValue = value !== void 0 && value !== null;
29570
29630
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
29571
29631
  const resolvedAsset = iconUrl ?? assetUrl;
29572
29632
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -29580,8 +29640,8 @@ function StatBadge({
29580
29640
  ),
29581
29641
  children: [
29582
29642
  resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: resolvedAsset, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, className: "w-4 h-4" }) }) : null,
29583
- /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
29584
- format === "hearts" && max && /* @__PURE__ */ jsxRuntime.jsx(
29643
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground font-medium text-xs", children: label }),
29644
+ hasValue && format === "hearts" && max && /* @__PURE__ */ jsxRuntime.jsx(
29585
29645
  HealthBar,
29586
29646
  {
29587
29647
  current: numValue,
@@ -29590,7 +29650,7 @@ function StatBadge({
29590
29650
  size: size === "lg" ? "md" : "sm"
29591
29651
  }
29592
29652
  ),
29593
- format === "bar" && max && /* @__PURE__ */ jsxRuntime.jsx(
29653
+ hasValue && format === "bar" && max && /* @__PURE__ */ jsxRuntime.jsx(
29594
29654
  HealthBar,
29595
29655
  {
29596
29656
  current: numValue,
@@ -29599,14 +29659,15 @@ function StatBadge({
29599
29659
  size: size === "lg" ? "md" : "sm"
29600
29660
  }
29601
29661
  ),
29602
- format === "number" && /* @__PURE__ */ jsxRuntime.jsx(
29662
+ hasValue && format === "number" && /* @__PURE__ */ jsxRuntime.jsx(
29603
29663
  ScoreDisplay,
29604
29664
  {
29605
29665
  value: numValue,
29606
- size: size === "lg" ? "md" : "sm"
29666
+ size: size === "lg" ? "md" : "sm",
29667
+ className: "font-display"
29607
29668
  }
29608
29669
  ),
29609
- format === "text" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "font-bold text-foreground", children: value })
29670
+ hasValue && format === "text" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "font-bold text-foreground", children: value })
29610
29671
  ]
29611
29672
  }
29612
29673
  );
@@ -29622,6 +29683,7 @@ var init_StatBadge = __esm({
29622
29683
  init_HealthBar();
29623
29684
  init_ScoreDisplay();
29624
29685
  sizeMap7 = {
29686
+ xs: "text-xs px-1.5 py-0.5",
29625
29687
  sm: "text-xs px-2 py-1",
29626
29688
  md: "text-sm px-3 py-1.5",
29627
29689
  lg: "text-base px-4 py-2"
@@ -29664,6 +29726,7 @@ function GameHud({
29664
29726
  items,
29665
29727
  elements,
29666
29728
  size = "md",
29729
+ variant = "floating",
29667
29730
  className,
29668
29731
  transparent = true
29669
29732
  }) {
@@ -29678,7 +29741,7 @@ function GameHud({
29678
29741
  /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { position: "absolute", className: "top-4 right-4 flex flex-col gap-2 items-end pointer-events-auto", children: rightStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
29679
29742
  ] });
29680
29743
  }
29681
- if (position === "top" || position === "bottom") {
29744
+ if ((position === "top" || position === "bottom") && variant === "bar") {
29682
29745
  const mid = Math.ceil(stats.length / 2);
29683
29746
  const leftStats = stats.slice(0, mid);
29684
29747
  const rightStats = stats.slice(mid);
@@ -31335,7 +31398,7 @@ var init_physicsPresets = __esm({
31335
31398
  ];
31336
31399
  }
31337
31400
  });
31338
- var FONT_BASE, GAME_FONTS, FONT_FACES; exports.GameShell = void 0;
31401
+ var GAME_FONTS; exports.GameShell = void 0;
31339
31402
  var init_GameShell = __esm({
31340
31403
  "components/game/templates/GameShell.tsx"() {
31341
31404
  init_cn();
@@ -31343,7 +31406,6 @@ var init_GameShell = __esm({
31343
31406
  init_Card();
31344
31407
  init_Typography();
31345
31408
  init_AtlasImage();
31346
- FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
31347
31409
  GAME_FONTS = {
31348
31410
  future: "Kenney Future",
31349
31411
  "future-narrow": "Kenney Future Narrow",
@@ -31351,14 +31413,6 @@ var init_GameShell = __esm({
31351
31413
  blocks: "Kenney Blocks",
31352
31414
  mini: "Kenney Mini"
31353
31415
  };
31354
- FONT_FACES = `
31355
- @font-face { font-family: 'Kenney Future'; src: url('${FONT_BASE}/Kenney%20Future.ttf') format('truetype'); font-display: swap; }
31356
- @font-face { font-family: 'Kenney Future Narrow'; src: url('${FONT_BASE}/Kenney%20Future%20Narrow.ttf') format('truetype'); font-display: swap; }
31357
- @font-face { font-family: 'Kenney Pixel'; src: url('${FONT_BASE}/Kenney%20Pixel.ttf') format('truetype'); font-display: swap; }
31358
- @font-face { font-family: 'Kenney Blocks'; src: url('${FONT_BASE}/Kenney%20Blocks.ttf') format('truetype'); font-display: swap; }
31359
- @font-face { font-family: 'Kenney Mini'; src: url('${FONT_BASE}/Kenney%20Mini.ttf') format('truetype'); font-display: swap; }
31360
- .game-shell, .game-shell * { font-family: inherit; }
31361
- `;
31362
31416
  exports.GameShell = ({
31363
31417
  appName = "Game",
31364
31418
  hud,
@@ -31385,10 +31439,12 @@ var init_GameShell = __esm({
31385
31439
  overflow: "hidden",
31386
31440
  background: "var(--color-background, #0a0a0f)",
31387
31441
  color: "var(--color-foreground, #e0e0e0)",
31388
- fontFamily: `'${font}', system-ui, sans-serif`
31442
+ // The fontFamily knob is a scoped override of the theme contract's
31443
+ // display slot: titles/numerics take the game face, body text keeps
31444
+ // the active theme's --font-family-body.
31445
+ "--font-family-display": `'${font}', ui-sans-serif, system-ui, sans-serif`
31389
31446
  },
31390
31447
  children: [
31391
- /* @__PURE__ */ jsxRuntime.jsx("style", { children: FONT_FACES }),
31392
31448
  backgroundAsset && /* @__PURE__ */ jsxRuntime.jsx(
31393
31449
  AtlasPanel,
31394
31450
  {
@@ -31426,6 +31482,7 @@ var init_GameShell = __esm({
31426
31482
  exports.Typography,
31427
31483
  {
31428
31484
  as: "span",
31485
+ className: "font-display",
31429
31486
  style: {
31430
31487
  fontWeight: 700,
31431
31488
  fontSize: "1.05rem",
@@ -33091,13 +33148,13 @@ var init_MapView = __esm({
33091
33148
  shadowSize: [41, 41]
33092
33149
  });
33093
33150
  L.Marker.prototype.options.icon = defaultIcon;
33094
- const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback108, useState: useState104 } = React77__namespace.default;
33151
+ const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback108, useState: useState104 } = React77__namespace.default;
33095
33152
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
33096
33153
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
33097
33154
  function MapUpdater({ centerLat, centerLng, zoom }) {
33098
33155
  const map = useMap();
33099
33156
  const prevRef = useRef65({ centerLat, centerLng, zoom });
33100
- useEffect67(() => {
33157
+ useEffect69(() => {
33101
33158
  const prev = prevRef.current;
33102
33159
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
33103
33160
  map.setView([centerLat, centerLng], zoom);
@@ -33108,7 +33165,7 @@ var init_MapView = __esm({
33108
33165
  }
33109
33166
  function MapClickHandler({ onMapClick }) {
33110
33167
  const map = useMap();
33111
- useEffect67(() => {
33168
+ useEffect69(() => {
33112
33169
  if (!onMapClick) return;
33113
33170
  const handler = (e) => {
33114
33171
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -33637,14 +33694,34 @@ var init_UploadDropZone = __esm({
33637
33694
  if (valid.length > 0) {
33638
33695
  onFiles?.(valid);
33639
33696
  if (action) {
33640
- eventBus.emit(`UI:${action}`, {
33641
- ...actionPayload,
33642
- files: valid.map((f3) => ({ name: f3.name, size: f3.size, type: f3.type }))
33697
+ void Promise.all(
33698
+ valid.map(
33699
+ (f3) => new Promise(
33700
+ (resolvePayload, rejectPayload) => {
33701
+ const reader = new FileReader();
33702
+ reader.onload = () => resolvePayload({
33703
+ name: f3.name,
33704
+ size: f3.size,
33705
+ type: f3.type,
33706
+ content: String(reader.result ?? "")
33707
+ });
33708
+ reader.onerror = () => rejectPayload(reader.error);
33709
+ reader.readAsDataURL(f3);
33710
+ }
33711
+ )
33712
+ )
33713
+ ).then((payloadFiles) => {
33714
+ eventBus.emit(`UI:${action}`, {
33715
+ ...actionPayload,
33716
+ files: payloadFiles
33717
+ });
33718
+ }).catch(() => {
33719
+ setError(t("Could not read the selected file"));
33643
33720
  });
33644
33721
  }
33645
33722
  }
33646
33723
  },
33647
- [validateFiles, onFiles, action, actionPayload, eventBus]
33724
+ [validateFiles, onFiles, action, actionPayload, eventBus, t]
33648
33725
  );
33649
33726
  const handleDragOver = (e) => {
33650
33727
  e.preventDefault();
@@ -43386,22 +43463,6 @@ var init_DataTable = __esm({
43386
43463
  DataTable.displayName = "DataTable";
43387
43464
  }
43388
43465
  });
43389
- function getFieldIcon(fieldName) {
43390
- const name = fieldName.toLowerCase();
43391
- if (name.includes("date") || name.includes("time")) return LucideIcons2.Calendar;
43392
- if (name.includes("status")) return LucideIcons2.Tag;
43393
- if (name.includes("priority")) return LucideIcons2.AlertCircle;
43394
- if (name.includes("progress") || name.includes("percent")) return LucideIcons2.TrendingUp;
43395
- if (name.includes("assignee") || name.includes("owner") || name.includes("user") || name.includes("member"))
43396
- return LucideIcons2.User;
43397
- if (name.includes("due")) return LucideIcons2.Clock;
43398
- if (name.includes("complete")) return LucideIcons2.CheckCircle2;
43399
- if (name.includes("budget") || name.includes("cost") || name.includes("price"))
43400
- return LucideIcons2.DollarSign;
43401
- if (name.includes("description") || name.includes("note") || name.includes("comment"))
43402
- return LucideIcons2.FileText;
43403
- return LucideIcons2.Package;
43404
- }
43405
43466
  function getBadgeVariant(fieldName, value) {
43406
43467
  const name = fieldName.toLowerCase();
43407
43468
  const val = String(value).toLowerCase();
@@ -43451,6 +43512,18 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
43451
43512
  }
43452
43513
  ) });
43453
43514
  }
43515
+ if (fieldType === "url" && /^https?:\/\//i.test(str2)) {
43516
+ return /* @__PURE__ */ jsxRuntime.jsx(
43517
+ "a",
43518
+ {
43519
+ href: str2,
43520
+ target: "_blank",
43521
+ rel: "noreferrer",
43522
+ className: "text-primary hover:underline break-all",
43523
+ children: str2
43524
+ }
43525
+ );
43526
+ }
43454
43527
  return str2;
43455
43528
  }
43456
43529
  case "markdown":
@@ -43549,6 +43622,23 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
43549
43622
  }
43550
43623
  return str2;
43551
43624
  }
43625
+ case "boolean": {
43626
+ if (typeof value === "boolean") return value ? "Yes" : "No";
43627
+ if (str2 === "true") return "Yes";
43628
+ if (str2 === "false") return "No";
43629
+ return str2;
43630
+ }
43631
+ case "array": {
43632
+ if (Array.isArray(value) && value.length > 0) {
43633
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "xs", wrap: true, children: value.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", children: String(item) }, i)) });
43634
+ }
43635
+ if (Array.isArray(value)) return "\u2014";
43636
+ return str2;
43637
+ }
43638
+ case "email":
43639
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href: `mailto:${str2}`, className: "text-primary hover:underline break-all", children: str2 });
43640
+ case "phone":
43641
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href: `tel:${str2}`, className: "text-primary hover:underline", children: str2 });
43552
43642
  default:
43553
43643
  if (meta?.values && meta.values.length > 0 && meta.values.includes(str2)) {
43554
43644
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: getBadgeVariant(fieldName, str2), children: humanizeEnumValue(str2) });
@@ -43621,10 +43711,11 @@ var init_DetailPanel = __esm({
43621
43711
  avatar,
43622
43712
  sections: propSections,
43623
43713
  actions,
43624
- maxInlineActions,
43714
+ maxInlineActions = 2,
43625
43715
  backAction,
43626
43716
  footer,
43627
43717
  slideOver = false,
43718
+ showActions = true,
43628
43719
  className,
43629
43720
  entity,
43630
43721
  fields: propFields,
@@ -43672,9 +43763,6 @@ var init_DetailPanel = __esm({
43672
43763
  },
43673
43764
  [eventBus]
43674
43765
  );
43675
- const handleClose = React77.useCallback(() => {
43676
- eventBus.emit("UI:CLOSE", {});
43677
- }, [eventBus]);
43678
43766
  const entityRecord = Array.isArray(entity) ? entity[0] : entity;
43679
43767
  const data = entityRecord ?? initialData;
43680
43768
  let title = propTitle;
@@ -43688,8 +43776,7 @@ var init_DetailPanel = __esm({
43688
43776
  const value = getNestedValue(normalizedData, field);
43689
43777
  return {
43690
43778
  label: labelFor(field),
43691
- value: formatFieldValue2(value, field),
43692
- icon: getFieldIcon(field)
43779
+ value: formatFieldValue2(value, field)
43693
43780
  };
43694
43781
  }
43695
43782
  return field;
@@ -43723,15 +43810,14 @@ var init_DetailPanel = __esm({
43723
43810
  (f3) => (!titleDerivedFromPrimary || f3 !== primaryField) && !statusFields.includes(f3) && !progressFields.includes(f3) && !metricFields.includes(f3) && !dateFields.includes(f3) && !descriptionFields.includes(f3)
43724
43811
  );
43725
43812
  sections = [];
43726
- if (statusFields.length > 0 || otherFields.length > 0) {
43813
+ if (otherFields.length > 0) {
43727
43814
  const overviewFields = [];
43728
- [...statusFields, ...otherFields].forEach((field) => {
43815
+ otherFields.forEach((field) => {
43729
43816
  const value = getNestedValue(normalizedData, field);
43730
43817
  if (value !== void 0 && value !== null) {
43731
43818
  overviewFields.push({
43732
43819
  label: labelFor(field),
43733
- value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field)),
43734
- icon: getFieldIcon(field)
43820
+ value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field))
43735
43821
  });
43736
43822
  }
43737
43823
  });
@@ -43746,8 +43832,7 @@ var init_DetailPanel = __esm({
43746
43832
  if (value !== void 0 && value !== null) {
43747
43833
  metricsFields.push({
43748
43834
  label: labelFor(field),
43749
- value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field)),
43750
- icon: getFieldIcon(field)
43835
+ value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field))
43751
43836
  });
43752
43837
  }
43753
43838
  });
@@ -43762,8 +43847,7 @@ var init_DetailPanel = __esm({
43762
43847
  if (value !== void 0 && value !== null) {
43763
43848
  timelineFields.push({
43764
43849
  label: labelFor(field),
43765
- value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field)),
43766
- icon: getFieldIcon(field)
43850
+ value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field))
43767
43851
  });
43768
43852
  }
43769
43853
  });
@@ -43778,8 +43862,7 @@ var init_DetailPanel = __esm({
43778
43862
  if (value !== void 0 && value !== null) {
43779
43863
  descFields.push({
43780
43864
  label: labelFor(field),
43781
- value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field)),
43782
- icon: getFieldIcon(field)
43865
+ value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field))
43783
43866
  });
43784
43867
  }
43785
43868
  });
@@ -43788,6 +43871,15 @@ var init_DetailPanel = __esm({
43788
43871
  }
43789
43872
  }
43790
43873
  }
43874
+ const renderSlot = providers.useRenderSlot();
43875
+ const navStack = providers.useNavStack();
43876
+ const { setCurrentLabel } = navStack;
43877
+ const resolvedTitle = normalizedData ? title : void 0;
43878
+ React77.useEffect(() => {
43879
+ if (renderSlot === "main" && !slideOver && resolvedTitle) {
43880
+ setCurrentLabel(resolvedTitle);
43881
+ }
43882
+ }, [renderSlot, slideOver, resolvedTitle, setCurrentLabel]);
43791
43883
  if (isLoading) {
43792
43884
  return /* @__PURE__ */ jsxRuntime.jsx(
43793
43885
  exports.LoadingState,
@@ -43826,8 +43918,7 @@ var init_DetailPanel = __esm({
43826
43918
  const value = normalizedData ? getNestedValue(normalizedData, field) : void 0;
43827
43919
  allFields.push({
43828
43920
  label: labelFor(field),
43829
- value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field)),
43830
- icon: getFieldIcon(field)
43921
+ value: renderRichFieldValue(value, field, fieldTypeMap[field], metaFor(field))
43831
43922
  });
43832
43923
  } else {
43833
43924
  allFields.push(field);
@@ -43839,24 +43930,50 @@ var init_DetailPanel = __esm({
43839
43930
  (a) => a.event === "CLOSE" || a.event === "CANCEL" || a.label?.toLowerCase() === "close"
43840
43931
  );
43841
43932
  const otherActions = actions?.filter((a) => a !== closeAction) ?? [];
43842
- const effectiveCloseAction = closeAction ?? { event: void 0};
43843
- const content = /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { variant: "elevated", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "md", className: "p-6", children: [
43844
- /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "center", gap: "xs", children: [
43845
- /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { align: "center", gap: "xs", children: backAction && /* @__PURE__ */ jsxRuntime.jsx(
43846
- exports.Button,
43933
+ const statusBadges = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
43934
+ normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
43935
+ (f3) => f3.toLowerCase().includes("status") || f3.toLowerCase().includes("priority")
43936
+ ).map((field) => {
43937
+ const value = getNestedValue(normalizedData, field);
43938
+ if (!value) return null;
43939
+ return /* @__PURE__ */ jsxRuntime.jsx(
43940
+ exports.Badge,
43847
43941
  {
43848
- variant: backAction.variant || "ghost",
43849
- size: "sm",
43850
- action: backAction.navigatesTo ? void 0 : backAction.event,
43851
- actionPayload: { row: normalizedData },
43852
- onClick: backAction.navigatesTo ? () => handleActionClick(backAction, normalizedData) : void 0,
43853
- icon: backAction.icon ?? LucideIcons2.ArrowLeft,
43854
- "data-testid": backAction.event ? `action-${backAction.event}` : "action-back",
43855
- children: backAction.label
43856
- }
43857
- ) }),
43858
- /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "end", align: "center", gap: "xs", children: [
43859
- (maxInlineActions != null ? otherActions.slice(0, maxInlineActions) : otherActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
43942
+ variant: getBadgeVariant(field, String(value)),
43943
+ children: humanizeEnumValue(String(value))
43944
+ },
43945
+ field
43946
+ );
43947
+ }),
43948
+ status && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: status.variant ?? "default", children: status.label })
43949
+ ] });
43950
+ const content = /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { variant: "elevated", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "md", className: "p-6", children: [
43951
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "start", gap: "md", children: [
43952
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
43953
+ backAction && /* @__PURE__ */ jsxRuntime.jsx(
43954
+ exports.Button,
43955
+ {
43956
+ variant: backAction.variant || "ghost",
43957
+ size: "sm",
43958
+ action: backAction.navigatesTo ? void 0 : backAction.event,
43959
+ actionPayload: { row: normalizedData },
43960
+ onClick: backAction.navigatesTo ? () => handleActionClick(backAction, normalizedData) : void 0,
43961
+ icon: backAction.icon ?? LucideIcons2.ArrowLeft,
43962
+ "data-testid": backAction.event ? `action-${backAction.event}` : "action-back",
43963
+ children: backAction.label
43964
+ }
43965
+ ),
43966
+ avatar,
43967
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "min-w-0", children: [
43968
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { align: "center", gap: "sm", wrap: true, children: [
43969
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h2", weight: "bold", children: title || "Details" }),
43970
+ statusBadges
43971
+ ] }),
43972
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: subtitle })
43973
+ ] })
43974
+ ] }),
43975
+ showActions && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "end", align: "center", gap: "xs", className: "shrink-0", children: [
43976
+ otherActions.slice(0, maxInlineActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
43860
43977
  exports.Button,
43861
43978
  {
43862
43979
  variant: action.variant || "secondary",
@@ -43871,7 +43988,7 @@ var init_DetailPanel = __esm({
43871
43988
  },
43872
43989
  idx
43873
43990
  )),
43874
- maxInlineActions != null && otherActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
43991
+ otherActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
43875
43992
  exports.Menu,
43876
43993
  {
43877
43994
  position: "bottom-end",
@@ -43887,40 +44004,20 @@ var init_DetailPanel = __esm({
43887
44004
  }))
43888
44005
  }
43889
44006
  ),
43890
- /* @__PURE__ */ jsxRuntime.jsx(
44007
+ closeAction && /* @__PURE__ */ jsxRuntime.jsx(
43891
44008
  exports.Button,
43892
44009
  {
43893
44010
  variant: "ghost",
43894
44011
  size: "sm",
43895
- action: effectiveCloseAction.event,
44012
+ action: closeAction.event,
43896
44013
  actionPayload: { row: normalizedData },
43897
- onClick: effectiveCloseAction.event ? void 0 : handleClose,
44014
+ onClick: closeAction.event ? void 0 : () => handleActionClick(closeAction, normalizedData),
43898
44015
  icon: LucideIcons2.X,
43899
- "data-testid": effectiveCloseAction.event ? `action-${effectiveCloseAction.event}` : "action-close"
44016
+ "data-testid": closeAction.event ? `action-${closeAction.event}` : "action-close"
43900
44017
  }
43901
44018
  )
43902
44019
  ] })
43903
44020
  ] }),
43904
- avatar,
43905
- /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h2", weight: "bold", children: title || "Details" }),
43906
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: subtitle }),
43907
- /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", wrap: true, children: [
43908
- normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
43909
- (f3) => f3.toLowerCase().includes("status") || f3.toLowerCase().includes("priority")
43910
- ).map((field) => {
43911
- const value = getNestedValue(normalizedData, field);
43912
- if (!value) return null;
43913
- return /* @__PURE__ */ jsxRuntime.jsx(
43914
- exports.Badge,
43915
- {
43916
- variant: getBadgeVariant(field, String(value)),
43917
- children: String(value)
43918
- },
43919
- field
43920
- );
43921
- }),
43922
- status && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: status.variant ?? "default", children: status.label })
43923
- ] }),
43924
44021
  normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
43925
44022
  (f3) => f3.toLowerCase().includes("progress") || f3.toLowerCase().includes("percent")
43926
44023
  ).map((field) => {
@@ -43953,9 +44050,10 @@ var init_DetailPanel = __esm({
43953
44050
  /* @__PURE__ */ jsxRuntime.jsx(
43954
44051
  exports.Typography,
43955
44052
  {
43956
- variant: "small",
43957
- color: "secondary",
44053
+ variant: "caption",
44054
+ color: "muted",
43958
44055
  weight: "medium",
44056
+ className: "uppercase tracking-wider",
43959
44057
  children: field.label
43960
44058
  }
43961
44059
  ),
@@ -44024,7 +44122,7 @@ var init_DrawerSlot = __esm({
44024
44122
  position,
44025
44123
  width: size,
44026
44124
  className,
44027
- children
44125
+ children: /* @__PURE__ */ jsxRuntime.jsx(providers.RenderSlotProvider, { slot: "drawer", children })
44028
44126
  }
44029
44127
  );
44030
44128
  };
@@ -46071,7 +46169,7 @@ var init_ModalSlot = __esm({
46071
46169
  title,
46072
46170
  size,
46073
46171
  className,
46074
- children
46172
+ children: /* @__PURE__ */ jsxRuntime.jsx(providers.RenderSlotProvider, { slot: "modal", children })
46075
46173
  }
46076
46174
  );
46077
46175
  };
@@ -50474,7 +50572,10 @@ function MaybeTraitScope({
50474
50572
  }
50475
50573
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
50476
50574
  }
50477
- function UISlotComponent({
50575
+ function UISlotComponent(props) {
50576
+ return /* @__PURE__ */ jsxRuntime.jsx(providers.RenderSlotProvider, { slot: props.slot, children: /* @__PURE__ */ jsxRuntime.jsx(UISlotComponentInner, { ...props }) });
50577
+ }
50578
+ function UISlotComponentInner({
50478
50579
  slot,
50479
50580
  portal = false,
50480
50581
  position,