@almadar/ui 5.130.0 → 5.132.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.
@@ -612,6 +612,26 @@ var init_useDragReorder = __esm({
612
612
  "use client";
613
613
  }
614
614
  });
615
+ function useMediaQuery(query) {
616
+ const subscribe = React82.useCallback(
617
+ (onChange) => {
618
+ const mql = window.matchMedia(query);
619
+ mql.addEventListener("change", onChange);
620
+ return () => mql.removeEventListener("change", onChange);
621
+ },
622
+ [query]
623
+ );
624
+ return React82.useSyncExternalStore(
625
+ subscribe,
626
+ () => window.matchMedia(query).matches,
627
+ () => false
628
+ );
629
+ }
630
+ var init_useMediaQuery = __esm({
631
+ "hooks/useMediaQuery.ts"() {
632
+ "use client";
633
+ }
634
+ });
615
635
  function useInfiniteScroll(onLoadMore, options = {}) {
616
636
  const { rootMargin = "200px", hasMore = true, isLoading = false } = options;
617
637
  const observerRef = React82.useRef(null);
@@ -1651,7 +1671,7 @@ var init_Button = __esm({
1651
1671
  "cursor-pointer",
1652
1672
  "chrome-button",
1653
1673
  "transition-all duration-normal",
1654
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1674
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--focus-ring-offset)]",
1655
1675
  "disabled:opacity-50 disabled:cursor-not-allowed",
1656
1676
  variantStyles[variant],
1657
1677
  sizeStyles[size],
@@ -2372,6 +2392,8 @@ var init_Badge = __esm({
2372
2392
  };
2373
2393
  const iconPx = size === "lg" ? 20 : 16;
2374
2394
  const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx(AtlasImage, { asset: iconAsset, size: iconPx, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2395
+ const hasText = Boolean(children) || amount != null || label !== void 0 && label !== null && label !== "";
2396
+ if (!hasText && !resolvedIcon && !onRemove) return null;
2375
2397
  return /* @__PURE__ */ jsxRuntime.jsxs(
2376
2398
  "span",
2377
2399
  {
@@ -2398,7 +2420,7 @@ var init_Badge = __esm({
2398
2420
  },
2399
2421
  className: cn(
2400
2422
  "inline-flex items-center justify-center rounded-sm",
2401
- "hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring",
2423
+ "hover:bg-foreground/10 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
2402
2424
  "transition-colors",
2403
2425
  size === "sm" ? "w-4 h-4 ml-0.5" : size === "md" ? "w-5 h-5 ml-1" : "w-6 h-6 ml-1"
2404
2426
  ),
@@ -3756,7 +3778,7 @@ function NativeSelect({
3756
3778
  "block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
3757
3779
  "px-3 py-2 pr-10 text-sm text-foreground font-medium",
3758
3780
  "bg-card",
3759
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3781
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3760
3782
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3761
3783
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3762
3784
  className
@@ -3863,7 +3885,7 @@ function RichSelect({
3863
3885
  "block w-full border-[length:var(--border-width)] shadow-sm",
3864
3886
  "px-3 py-2 pr-10 text-sm text-start font-medium",
3865
3887
  "bg-card rounded-sm",
3866
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3888
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3867
3889
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3868
3890
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3869
3891
  !hasValue && "text-muted-foreground"
@@ -4786,9 +4808,9 @@ var init_Radio = __esm({
4786
4808
  "flex items-center justify-center",
4787
4809
  "border-[length:var(--border-width)] transition-all cursor-pointer",
4788
4810
  sizeClasses4[size],
4789
- hasError ? "border-error peer-focus:ring-error/20" : "border-border peer-focus:ring-ring/20",
4811
+ hasError ? "border-error peer-focus-visible:ring-error/20" : "border-border peer-focus-visible:ring-ring/20",
4790
4812
  isChecked2 ? hasError ? "border-error" : "border-primary bg-primary" : "",
4791
- "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
4813
+ "peer-focus:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2",
4792
4814
  disabled && "opacity-50 cursor-not-allowed",
4793
4815
  !disabled && "hover:border-[var(--color-border-hover)]"
4794
4816
  ),
@@ -5259,7 +5281,7 @@ var init_ThemeToggle = __esm({
5259
5281
  "inline-flex items-center justify-center gap-2",
5260
5282
  "text-foreground",
5261
5283
  "hover:bg-muted border-[length:var(--border-width)] border-transparent hover:border-border",
5262
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
5284
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5263
5285
  "transition-colors duration-fast",
5264
5286
  sizeClasses5[size],
5265
5287
  className
@@ -5694,11 +5716,13 @@ var init_TrendIndicator = __esm({
5694
5716
  size = "md",
5695
5717
  ...props
5696
5718
  }, ref) => {
5697
- const dir = resolveDirection(value, direction);
5719
+ const hasValue = typeof value === "number" && Number.isFinite(value);
5720
+ if (!hasValue && !direction) return null;
5721
+ const dir = resolveDirection(hasValue ? value : void 0, direction);
5698
5722
  const colorClass = resolveColor(dir, invert);
5699
5723
  const iconName = iconNameMap[dir];
5700
5724
  const styles = sizeStyles6[size];
5701
- const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5725
+ const formattedValue = hasValue ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5702
5726
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
5703
5727
  return /* @__PURE__ */ jsxRuntime.jsxs(
5704
5728
  "span",
@@ -11504,10 +11528,12 @@ var init_Container = __esm({
11504
11528
  };
11505
11529
  paddingStyles3 = {
11506
11530
  none: "px-0",
11507
- sm: "px-4",
11508
- md: "px-6",
11509
- lg: "px-8",
11510
- xl: "px-12"
11531
+ // Mobile-tighter, desktop-identical: fixed px-6 on a 360px phone eats ~13% of
11532
+ // the viewport, so each token steps down below the sm breakpoint.
11533
+ sm: "px-3 sm:px-4",
11534
+ md: "px-4 sm:px-6",
11535
+ lg: "px-4 sm:px-6 md:px-8",
11536
+ xl: "px-4 sm:px-8 md:px-12"
11511
11537
  };
11512
11538
  Container = ({
11513
11539
  size,
@@ -12206,7 +12232,7 @@ var init_Accordion = __esm({
12206
12232
  "bg-card",
12207
12233
  "hover:bg-muted",
12208
12234
  "transition-colors duration-fast",
12209
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-inset",
12235
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
12210
12236
  "disabled:opacity-50 disabled:cursor-not-allowed",
12211
12237
  isOpen && "bg-muted font-bold"
12212
12238
  ),
@@ -17753,26 +17779,19 @@ var init_BookViewer = __esm({
17753
17779
  function BoxPattern({
17754
17780
  p,
17755
17781
  m,
17756
- bg = "transparent",
17757
- border = false,
17758
- radius = "none",
17759
- shadow = "none",
17760
- className,
17761
- style,
17762
- children
17782
+ radius,
17783
+ isLoading: _isLoading,
17784
+ error: _error,
17785
+ entity: _entity,
17786
+ ...boxProps
17763
17787
  }) {
17764
17788
  return /* @__PURE__ */ jsxRuntime.jsx(
17765
17789
  Box,
17766
17790
  {
17767
- padding: p,
17768
- margin: m,
17769
- bg,
17770
- border,
17771
- rounded: radius,
17772
- shadow,
17773
- className,
17774
- style,
17775
- children
17791
+ padding: boxProps.padding ?? p,
17792
+ margin: boxProps.margin ?? m,
17793
+ rounded: boxProps.rounded ?? radius,
17794
+ ...boxProps
17776
17795
  }
17777
17796
  );
17778
17797
  }
@@ -18361,7 +18380,7 @@ var init_Breadcrumb = __esm({
18361
18380
  },
18362
18381
  className: cn(
18363
18382
  "flex items-center gap-1.5 transition-colors",
18364
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
18383
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
18365
18384
  isLast ? "text-foreground font-bold cursor-default" : "text-muted-foreground hover:text-foreground"
18366
18385
  ),
18367
18386
  "aria-current": isLast ? "page" : void 0,
@@ -21382,17 +21401,19 @@ var init_DashboardLayout = __esm({
21382
21401
  const [sidebarOpen, setSidebarOpen] = React82.useState(false);
21383
21402
  const [userMenuOpen, setUserMenuOpen] = React82.useState(false);
21384
21403
  const layoutRef = React82.useRef(null);
21385
- const [isMobile, setIsMobile] = React82.useState(false);
21404
+ const [layoutWidth, setLayoutWidth] = React82.useState(null);
21386
21405
  React82.useEffect(() => {
21387
21406
  const el = layoutRef.current;
21388
21407
  if (!el || typeof ResizeObserver === "undefined") return;
21389
21408
  const ro = new ResizeObserver((entries) => {
21390
21409
  const w = entries[0]?.contentRect.width ?? el.clientWidth;
21391
- setIsMobile(w < 1024);
21410
+ setLayoutWidth(w);
21392
21411
  });
21393
21412
  ro.observe(el);
21394
21413
  return () => ro.disconnect();
21395
21414
  }, []);
21415
+ const isMobile = layoutWidth !== null && layoutWidth < 768;
21416
+ const isRail = layoutWidth !== null && layoutWidth >= 768 && layoutWidth < 1024;
21396
21417
  React82.useEffect(() => {
21397
21418
  if (!isMobile && sidebarOpen) setSidebarOpen(false);
21398
21419
  }, [isMobile, sidebarOpen]);
@@ -21425,7 +21446,8 @@ var init_DashboardLayout = __esm({
21425
21446
  {
21426
21447
  as: "aside",
21427
21448
  className: cn(
21428
- "z-30 w-64 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21449
+ "z-30 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21450
+ isRail ? "w-16" : "w-64",
21429
21451
  "flex flex-col"
21430
21452
  ),
21431
21453
  style: isMobile ? {
@@ -21441,10 +21463,10 @@ var init_DashboardLayout = __esm({
21441
21463
  HStack,
21442
21464
  {
21443
21465
  align: "center",
21444
- justify: "between",
21445
- className: "h-16 px-4 border-b border-border dark:border-border",
21466
+ justify: isRail ? "center" : "between",
21467
+ className: cn("h-16 border-b border-border dark:border-border", isRail ? "px-2" : "px-4"),
21446
21468
  children: [
21447
- /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to: "/", className: "flex items-center gap-2", children: [
21469
+ /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to: "/", className: "flex items-center gap-2", title: isRail ? appName : void 0, children: [
21448
21470
  logo || /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 h-8 bg-primary rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
21449
21471
  Typography,
21450
21472
  {
@@ -21454,7 +21476,7 @@ var init_DashboardLayout = __esm({
21454
21476
  children: appName.charAt(0).toUpperCase()
21455
21477
  }
21456
21478
  ) }),
21457
- /* @__PURE__ */ jsxRuntime.jsx(
21479
+ !isRail && /* @__PURE__ */ jsxRuntime.jsx(
21458
21480
  Typography,
21459
21481
  {
21460
21482
  variant: "label",
@@ -21481,12 +21503,13 @@ var init_DashboardLayout = __esm({
21481
21503
  {
21482
21504
  as: "nav",
21483
21505
  gap: "none",
21484
- className: "flex-1 px-3 py-4 space-y-1 overflow-y-auto",
21506
+ className: cn("flex-1 py-4 space-y-1 overflow-y-auto", isRail ? "px-2" : "px-3"),
21485
21507
  children: navItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
21486
21508
  NavLink,
21487
21509
  {
21488
21510
  item,
21489
- currentPath: activePath
21511
+ currentPath: activePath,
21512
+ compact: isRail
21490
21513
  },
21491
21514
  item.href
21492
21515
  ))
@@ -21741,13 +21764,40 @@ var init_DashboardLayout = __esm({
21741
21764
  DashboardLayout.displayName = "DashboardLayout";
21742
21765
  NavLink = ({
21743
21766
  item,
21744
- currentPath
21767
+ currentPath,
21768
+ compact = false
21745
21769
  }) => {
21746
21770
  const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
21747
21771
  const iconClassName = cn(
21748
21772
  "h-5 w-5",
21749
21773
  isActive ? "text-primary-foreground" : "text-muted-foreground"
21750
21774
  );
21775
+ if (compact) {
21776
+ return /* @__PURE__ */ jsxRuntime.jsx(
21777
+ reactRouterDom.Link,
21778
+ {
21779
+ to: item.href,
21780
+ title: item.label,
21781
+ "aria-label": item.label,
21782
+ className: cn(
21783
+ "flex items-center justify-center px-2 py-2 rounded-lg transition-colors",
21784
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
21785
+ ),
21786
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { as: "span", className: "relative inline-flex", children: [
21787
+ item.icon ? typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "font-semibold", as: "span", children: item.label.charAt(0).toUpperCase() }),
21788
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(
21789
+ Badge,
21790
+ {
21791
+ variant: isActive ? "primary" : "default",
21792
+ size: "sm",
21793
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
21794
+ children: item.badge
21795
+ }
21796
+ )
21797
+ ] })
21798
+ }
21799
+ );
21800
+ }
21751
21801
  return /* @__PURE__ */ jsxRuntime.jsxs(
21752
21802
  reactRouterDom.Link,
21753
21803
  {
@@ -22813,40 +22863,55 @@ function DataGrid({
22813
22863
  {
22814
22864
  "data-entity-row": true,
22815
22865
  "data-entity-id": id,
22816
- className: cn(isSelected && "ring-2 ring-primary rounded-lg"),
22866
+ className: cn("relative group/rowactions", isSelected && "ring-2 ring-primary rounded-lg"),
22817
22867
  children: [
22818
22868
  children(itemData, index),
22819
- actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-end", children: [
22820
- (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22821
- Button,
22822
- {
22823
- variant: action.variant === "primary" ? "primary" : "ghost",
22824
- size: "sm",
22825
- onClick: handleActionClick(action, itemData),
22826
- "data-testid": `action-${action.event}`,
22827
- "data-row-id": String(itemData.id),
22828
- className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
22829
- children: [
22830
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22831
- action.label
22832
- ]
22833
- },
22834
- idx
22835
- )),
22836
- maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
22869
+ actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
22870
+ /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: [
22871
+ (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22872
+ Button,
22873
+ {
22874
+ variant: action.variant === "primary" ? "primary" : "ghost",
22875
+ size: "sm",
22876
+ onClick: handleActionClick(action, itemData),
22877
+ "data-testid": `action-${action.event}`,
22878
+ "data-row-id": String(itemData.id),
22879
+ className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
22880
+ children: [
22881
+ action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22882
+ action.label
22883
+ ]
22884
+ },
22885
+ idx
22886
+ )),
22887
+ maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
22888
+ Menu,
22889
+ {
22890
+ position: "bottom-end",
22891
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22892
+ items: actionDefs.slice(maxInlineActions).map((action) => ({
22893
+ label: action.label,
22894
+ icon: action.icon,
22895
+ event: action.event,
22896
+ onClick: () => fireAction(action, itemData)
22897
+ }))
22898
+ }
22899
+ )
22900
+ ] }),
22901
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
22837
22902
  Menu,
22838
22903
  {
22839
22904
  position: "bottom-end",
22840
22905
  trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22841
- items: actionDefs.slice(maxInlineActions).map((action) => ({
22906
+ items: actionDefs.map((action) => ({
22842
22907
  label: action.label,
22843
22908
  icon: action.icon,
22844
22909
  event: action.event,
22845
22910
  onClick: () => fireAction(action, itemData)
22846
22911
  }))
22847
22912
  }
22848
- )
22849
- ] }) })
22913
+ ) })
22914
+ ] })
22850
22915
  ]
22851
22916
  },
22852
22917
  id
@@ -22882,7 +22947,7 @@ function DataGrid({
22882
22947
  }
22883
22948
  ) });
22884
22949
  })(),
22885
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
22950
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("p-4", bodyFields.length > 0 && "pb-0"), children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
22886
22951
  selectable && /* @__PURE__ */ jsxRuntime.jsx(
22887
22952
  "input",
22888
22953
  {
@@ -22915,79 +22980,77 @@ function DataGrid({
22915
22980
  ] }, field.name);
22916
22981
  }) })
22917
22982
  ] }),
22918
- dangerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22919
- Button,
22920
- {
22921
- variant: "ghost",
22922
- size: "sm",
22923
- onClick: handleActionClick(action, itemData),
22924
- "data-testid": `action-${action.event}`,
22925
- "data-row-id": String(itemData.id),
22926
- className: "text-error hover:text-error hover:bg-error/10 px-2",
22927
- children: [
22928
- action.icon && renderIconInput(action.icon, { size: "xs" }),
22929
- action.label
22930
- ]
22931
- },
22932
- idx
22933
- )) })
22934
- ] }) }),
22935
- bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
22936
- const value = getNestedValue(itemData, field.name);
22937
- if (value === void 0 || value === null || value === "") return null;
22938
- if (field.format === "boolean") {
22939
- return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
22940
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
22941
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22942
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
22943
- ] }),
22944
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
22945
- ] }, field.name);
22946
- }
22947
- return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
22948
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
22949
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22950
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
22951
- ] }),
22952
- /* @__PURE__ */ jsxRuntime.jsx(
22953
- Typography,
22983
+ (primaryActions.length > 0 || dangerActions.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
22984
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
22985
+ Button,
22954
22986
  {
22955
- variant: field.variant === "caption" ? "caption" : "small",
22956
- className: "text-right truncate max-w-[60%]",
22957
- children: formatValue(value, field.format)
22987
+ variant: action.variant === "primary" ? "primary" : "ghost",
22988
+ size: "sm",
22989
+ onClick: handleActionClick(action, itemData),
22990
+ "data-testid": `action-${action.event}`,
22991
+ "data-row-id": String(itemData.id),
22992
+ "aria-label": action.label,
22993
+ title: action.label,
22994
+ className: cn(
22995
+ action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
22996
+ action.icon && "px-2"
22997
+ ),
22998
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
22999
+ },
23000
+ idx
23001
+ )),
23002
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23003
+ Menu,
23004
+ {
23005
+ position: "bottom-end",
23006
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23007
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23008
+ label: action.label,
23009
+ icon: action.icon,
23010
+ event: action.event,
23011
+ onClick: () => fireAction(action, itemData)
23012
+ }))
22958
23013
  }
22959
- )
22960
- ] }, field.name);
22961
- }) }) }),
22962
- primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-end flex-wrap", children: [
22963
- (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
22964
- Button,
22965
- {
22966
- variant: action.variant === "primary" ? "primary" : "ghost",
22967
- size: "sm",
22968
- onClick: handleActionClick(action, itemData),
22969
- "data-testid": `action-${action.event}`,
22970
- "data-row-id": String(itemData.id),
22971
- children: [
22972
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22973
- action.label
22974
- ]
22975
- },
22976
- idx
22977
- )),
22978
- maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
22979
- Menu,
22980
- {
22981
- position: "bottom-end",
22982
- trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22983
- items: primaryActions.slice(maxInlineActions).map((action) => ({
22984
- label: action.label,
22985
- icon: action.icon,
22986
- event: action.event,
22987
- onClick: () => fireAction(action, itemData)
22988
- }))
23014
+ ),
23015
+ dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
23016
+ Button,
23017
+ {
23018
+ variant: "ghost",
23019
+ size: "sm",
23020
+ onClick: handleActionClick(action, itemData),
23021
+ "data-testid": `action-${action.event}`,
23022
+ "data-row-id": String(itemData.id),
23023
+ "aria-label": action.label,
23024
+ title: action.label,
23025
+ className: "text-error hover:text-error hover:bg-error/10 px-2",
23026
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
23027
+ },
23028
+ `danger-${idx}`
23029
+ ))
23030
+ ] })
23031
+ ] }) }),
23032
+ bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
23033
+ bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
23034
+ const value = getNestedValue(itemData, field.name);
23035
+ if (value === void 0 || value === null || value === "") return null;
23036
+ return /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
23037
+ }),
23038
+ /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
23039
+ const value = getNestedValue(itemData, field.name);
23040
+ if (value === void 0 || value === null || value === "") return null;
23041
+ if (field.format === "boolean") {
23042
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23043
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23044
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) }),
23045
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
23046
+ ] }, field.name);
22989
23047
  }
22990
- )
23048
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23049
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23050
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
23051
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
23052
+ ] }, field.name);
23053
+ }) })
22991
23054
  ] }) })
22992
23055
  ]
22993
23056
  },
@@ -23335,11 +23398,29 @@ function DataList({
23335
23398
  const wrapDnd = (node) => dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: dndId, children: node }, dndId) : node;
23336
23399
  if (hasRenderProp) {
23337
23400
  const id2 = itemData.id || String(index);
23401
+ const actions = renderItemActions(itemData);
23338
23402
  return wrapDnd(
23339
- /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23340
- /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23341
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23342
- renderItemActions(itemData)
23403
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn("relative group/rowactions", itemClickEvent && "cursor-pointer"), children: [
23404
+ children(itemData, index),
23405
+ actions && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
23406
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
23407
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
23408
+ Menu,
23409
+ {
23410
+ position: "bottom-end",
23411
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23412
+ items: (itemActions ?? []).map((action) => ({
23413
+ label: action.label,
23414
+ icon: action.icon,
23415
+ event: action.event,
23416
+ variant: action.variant === "danger" ? "danger" : "default",
23417
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23418
+ id: itemData.id,
23419
+ row: itemData
23420
+ })
23421
+ }))
23422
+ }
23423
+ ) })
23343
23424
  ] }),
23344
23425
  isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
23345
23426
  ] }, id2)
@@ -23379,7 +23460,7 @@ function DataList({
23379
23460
  ] }, field.name);
23380
23461
  })
23381
23462
  ] }),
23382
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
23463
+ bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: cn("flex-wrap", isCompact ? "mt-0.5" : "mt-1.5"), children: bodyFields.map((field) => {
23383
23464
  const value = getNestedValue(itemData, field.name);
23384
23465
  if (value === void 0 || value === null || value === "") return null;
23385
23466
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
@@ -23729,10 +23810,7 @@ var init_FileTree = __esm({
23729
23810
  className,
23730
23811
  indent = 16
23731
23812
  }) => {
23732
- const { t } = hooks.useTranslate();
23733
- if (tree.length === 0) {
23734
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `p-4 ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "muted", children: t("fileTree.noFiles") }) });
23735
- }
23813
+ if (tree.length === 0) return null;
23736
23814
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
23737
23815
  TreeNodeItem,
23738
23816
  {
@@ -26914,7 +26992,7 @@ var init_MapView = __esm({
26914
26992
  shadowSize: [41, 41]
26915
26993
  });
26916
26994
  L.Marker.prototype.options.icon = defaultIcon;
26917
- const { useEffect: useEffect59, useRef: useRef60, useCallback: useCallback87, useState: useState89 } = React82__namespace.default;
26995
+ const { useEffect: useEffect59, useRef: useRef60, useCallback: useCallback88, useState: useState89 } = React82__namespace.default;
26918
26996
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
26919
26997
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
26920
26998
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -26960,7 +27038,7 @@ var init_MapView = __esm({
26960
27038
  }) {
26961
27039
  const eventBus = useEventBus2();
26962
27040
  const [clickedPosition, setClickedPosition] = useState89(null);
26963
- const handleMapClick = useCallback87((lat, lng) => {
27041
+ const handleMapClick = useCallback88((lat, lng) => {
26964
27042
  if (showClickedPin) {
26965
27043
  setClickedPosition({ lat, lng });
26966
27044
  }
@@ -26969,7 +27047,7 @@ var init_MapView = __esm({
26969
27047
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
26970
27048
  }
26971
27049
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
26972
- const handleMarkerClick = useCallback87((marker) => {
27050
+ const handleMarkerClick = useCallback88((marker) => {
26973
27051
  onMarkerClick?.(marker);
26974
27052
  if (markerClickEvent) {
26975
27053
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -27171,7 +27249,7 @@ var init_NumberStepper = __esm({
27171
27249
  "active:bg-muted",
27172
27250
  "transition-colors duration-instant",
27173
27251
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27174
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27252
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27175
27253
  styles.button
27176
27254
  ),
27177
27255
  "aria-label": t("aria.decrease"),
@@ -27212,7 +27290,7 @@ var init_NumberStepper = __esm({
27212
27290
  "active:bg-muted",
27213
27291
  "transition-colors duration-instant",
27214
27292
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27215
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27293
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27216
27294
  styles.button
27217
27295
  ),
27218
27296
  "aria-label": t("aria.increase"),
@@ -27668,7 +27746,7 @@ var init_Lightbox = __esm({
27668
27746
  "p-2 rounded-full",
27669
27747
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27670
27748
  "hover:bg-opacity-70 transition-opacity",
27671
- "focus:outline-none focus:ring-2 focus:ring-ring"
27749
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27672
27750
  ),
27673
27751
  "aria-label": t("aria.closeModal"),
27674
27752
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "w-6 h-6" })
@@ -27687,7 +27765,7 @@ var init_Lightbox = __esm({
27687
27765
  "p-2 rounded-full",
27688
27766
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27689
27767
  "hover:bg-opacity-70 transition-opacity",
27690
- "focus:outline-none focus:ring-2 focus:ring-ring"
27768
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27691
27769
  ),
27692
27770
  "aria-label": t("aria.previousImage"),
27693
27771
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-left", className: "w-8 h-8" })
@@ -27724,7 +27802,7 @@ var init_Lightbox = __esm({
27724
27802
  "p-2 rounded-full",
27725
27803
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27726
27804
  "hover:bg-opacity-70 transition-opacity",
27727
- "focus:outline-none focus:ring-2 focus:ring-ring"
27805
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27728
27806
  ),
27729
27807
  "aria-label": t("aria.nextImage"),
27730
27808
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-right", className: "w-8 h-8" })
@@ -27851,6 +27929,7 @@ function TableView({
27851
27929
  const hasMore = pageSize > 0 && visibleCount < ordered.length;
27852
27930
  const hasRenderProp = typeof children === "function";
27853
27931
  const idField = dndItemIdField ?? "id";
27932
+ const isCoarsePointer = useMediaQuery("(pointer: coarse)");
27854
27933
  const selected = selectedIds ? new Set(selectedIds) : localSelected;
27855
27934
  const emitSelection = (next) => {
27856
27935
  if (!selectedIds) setLocalSelected(next);
@@ -27883,6 +27962,17 @@ function TableView({
27883
27962
  };
27884
27963
  eventBus.emit(`UI:${action.event}`, payload);
27885
27964
  };
27965
+ const colFloors = React82__namespace.default.useMemo(
27966
+ () => colDefs.map((col) => {
27967
+ const longest = data.reduce((widest, row) => {
27968
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
27969
+ return Math.max(widest, cell.length);
27970
+ }, columnLabel(col).length);
27971
+ const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
27972
+ return Math.min(longest + chrome, MAX_MEASURED_COL_CH);
27973
+ }),
27974
+ [colDefs, data]
27975
+ );
27886
27976
  if (isLoading) {
27887
27977
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
27888
27978
  }
@@ -27895,19 +27985,10 @@ function TableView({
27895
27985
  }
27896
27986
  const lk = LOOKS[look];
27897
27987
  const hasActions = Boolean(itemActions && itemActions.length > 0);
27898
- const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
27899
- const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
27988
+ const effectiveMaxInline = isCoarsePointer ? 0 : maxInlineActions;
27989
+ const inlineActionCount = hasActions ? effectiveMaxInline != null ? Math.min(itemActions.length, effectiveMaxInline) : itemActions.length : 0;
27990
+ const hasOverflowActions = hasActions && effectiveMaxInline != null && itemActions.length > effectiveMaxInline;
27900
27991
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
27901
- const colFloors = React82__namespace.default.useMemo(
27902
- () => colDefs.map((col) => {
27903
- const longest = data.reduce((widest, row) => {
27904
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
27905
- return Math.max(widest, cell.length);
27906
- }, columnLabel(col).length);
27907
- return Math.min(longest, MAX_MEASURED_COL_CH);
27908
- }),
27909
- [colDefs, data]
27910
- );
27911
27992
  const gridTemplateColumns = [
27912
27993
  selectable ? "auto" : null,
27913
27994
  ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
@@ -27994,9 +28075,9 @@ function TableView({
27994
28075
  col.className
27995
28076
  );
27996
28077
  if (col.format === "badge" && raw != null && raw !== "") {
27997
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28078
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: String(raw) }) }, col.key);
27998
28079
  }
27999
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28080
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
28000
28081
  }),
28001
28082
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
28002
28083
  HStack,
@@ -28010,15 +28091,15 @@ function TableView({
28010
28091
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
28011
28092
  ),
28012
28093
  children: [
28013
- (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28094
+ (effectiveMaxInline != null ? itemActions.slice(0, effectiveMaxInline) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28014
28095
  Button,
28015
28096
  {
28016
- variant: action.variant ?? "ghost",
28097
+ variant: action.variant === "primary" ? "primary" : "ghost",
28017
28098
  size: "sm",
28018
28099
  onClick: handleActionClick(action, row),
28019
28100
  "data-testid": `action-${action.event}`,
28020
28101
  "data-row-id": String(row.id),
28021
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
28102
+ className: cn(action.variant === "danger" && "text-error hover:text-error hover:bg-error/10"),
28022
28103
  children: [
28023
28104
  action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
28024
28105
  action.label
@@ -28026,12 +28107,12 @@ function TableView({
28026
28107
  },
28027
28108
  i
28028
28109
  )),
28029
- maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
28110
+ effectiveMaxInline != null && itemActions.length > effectiveMaxInline && /* @__PURE__ */ jsxRuntime.jsx(
28030
28111
  Menu,
28031
28112
  {
28032
28113
  position: "bottom-end",
28033
28114
  trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
28034
- items: itemActions.slice(maxInlineActions).map((action) => ({
28115
+ items: itemActions.slice(effectiveMaxInline).map((action) => ({
28035
28116
  label: action.label,
28036
28117
  icon: action.icon,
28037
28118
  event: action.event,
@@ -28077,13 +28158,14 @@ function TableView({
28077
28158
  }
28078
28159
  );
28079
28160
  }
28080
- var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
28161
+ var MAX_MEASURED_COL_CH, BADGE_CHROME_CH, alignClass, weightClass, LOOKS;
28081
28162
  var init_TableView = __esm({
28082
28163
  "components/core/molecules/TableView.tsx"() {
28083
28164
  "use client";
28084
28165
  init_cn();
28085
28166
  init_getNestedValue();
28086
28167
  init_useEventBus();
28168
+ init_useMediaQuery();
28087
28169
  init_Box();
28088
28170
  init_Stack();
28089
28171
  init_Typography();
@@ -28096,6 +28178,7 @@ var init_TableView = __esm({
28096
28178
  init_useDataDnd();
28097
28179
  logger.createLogger("almadar:ui:table-view");
28098
28180
  MAX_MEASURED_COL_CH = 32;
28181
+ BADGE_CHROME_CH = 4;
28099
28182
  alignClass = {
28100
28183
  left: "justify-start text-left",
28101
28184
  center: "justify-center text-center",
@@ -28107,7 +28190,7 @@ var init_TableView = __esm({
28107
28190
  semibold: "font-semibold"
28108
28191
  };
28109
28192
  LOOKS = {
28110
- dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
28193
+ dense: { rowPad: "px-card-md py-2", headPad: "px-card-md py-2", striped: false, divider: true },
28111
28194
  spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
28112
28195
  striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
28113
28196
  borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
@@ -30193,7 +30276,7 @@ var init_VoteStack = __esm({
30193
30276
  "active:bg-muted",
30194
30277
  "transition-colors duration-instant",
30195
30278
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30196
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30279
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30197
30280
  styles.button
30198
30281
  ),
30199
30282
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-up", className: styles.icon })
@@ -30230,7 +30313,7 @@ var init_VoteStack = __esm({
30230
30313
  "active:bg-muted",
30231
30314
  "transition-colors duration-instant",
30232
30315
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30233
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30316
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30234
30317
  styles.button
30235
30318
  ),
30236
30319
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: styles.icon })
@@ -30751,7 +30834,7 @@ var init_QrScanner = __esm({
30751
30834
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30752
30835
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
30753
30836
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30754
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30837
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30755
30838
  ),
30756
30839
  "aria-label": isPaused ? t("qrScanner.resumeScanning") : t("qrScanner.pauseScanning"),
30757
30840
  children: isPaused ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "play", className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "pause", className: "h-4 w-4" })
@@ -30766,7 +30849,7 @@ var init_QrScanner = __esm({
30766
30849
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30767
30850
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
30768
30851
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30769
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30852
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30770
30853
  ),
30771
30854
  "aria-label": currentFacing === "environment" ? t("qrScanner.switchToFrontCamera") : t("qrScanner.switchToRearCamera"),
30772
30855
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "refresh-cw", className: "h-4 w-4" })
@@ -30781,7 +30864,7 @@ var init_QrScanner = __esm({
30781
30864
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30782
30865
  "rounded-full bg-black bg-opacity-60 px-3 py-2 text-xs text-white",
30783
30866
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30784
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30867
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30785
30868
  ),
30786
30869
  "aria-label": t("aria.mockScanDev"),
30787
30870
  children: t("qrScanner.mockScan")
@@ -39026,27 +39109,24 @@ var init_MasterDetailLayout = __esm({
39026
39109
  masterClassName,
39027
39110
  detailClassName
39028
39111
  }) => {
39029
- masterWidth.endsWith("%") ? parseInt(masterWidth, 10) : 30;
39030
39112
  return /* @__PURE__ */ jsxRuntime.jsxs(
39031
39113
  "div",
39032
39114
  {
39033
- className: cn("flex h-full w-full", className),
39034
- style: {
39035
- display: "grid",
39036
- gridTemplateColumns: masterWidth.endsWith("%") ? `${masterWidth} 1fr` : `${masterWidth} 1fr`
39037
- },
39115
+ className: cn("w-full h-full md:grid md:grid-cols-[var(--master-detail-cols)]", className),
39116
+ style: { "--master-detail-cols": `${masterWidth} 1fr` },
39038
39117
  children: [
39039
39118
  /* @__PURE__ */ jsxRuntime.jsx(
39040
39119
  "div",
39041
39120
  {
39042
39121
  className: cn(
39043
- "border-r-2 border-border overflow-auto",
39122
+ "border-r border-border overflow-auto",
39123
+ hasSelection && "hidden md:block",
39044
39124
  masterClassName
39045
39125
  ),
39046
39126
  children: master
39047
39127
  }
39048
39128
  ),
39049
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-auto", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsxRuntime.jsx(DefaultEmptyDetail, {}) })
39129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-auto", !hasSelection && "hidden md:block", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsxRuntime.jsx(DefaultEmptyDetail, {}) })
39050
39130
  ]
39051
39131
  }
39052
39132
  );
@@ -42618,7 +42698,7 @@ var init_TabbedContainer = __esm({
42618
42698
  onClick: () => !isDisabled && handleTabChange(tab.id),
42619
42699
  className: cn(
42620
42700
  "flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors",
42621
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
42701
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
42622
42702
  "disabled:opacity-50 disabled:cursor-not-allowed",
42623
42703
  isActive ? "bg-primary text-primary-foreground" : "bg-card text-foreground hover:bg-muted",
42624
42704
  isVertical ? "justify-start" : "justify-center"