@sckyzo/cosmos-react 0.4.0 → 0.5.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.
package/dist/index.js CHANGED
@@ -853,6 +853,8 @@ var Shell = ({
853
853
  onCollapsedChange,
854
854
  collapseControl = "topbar",
855
855
  container = "fluid",
856
+ variant = "attached",
857
+ sidebarGutter,
856
858
  defaultSidebarOpen = false,
857
859
  sidebarOpen: controlledOpen,
858
860
  onSidebarOpenChange,
@@ -879,10 +881,22 @@ var Shell = ({
879
881
  wasMobile.current = isMobile;
880
882
  }, [isMobile, open, setOpen]);
881
883
  const navId = useId();
884
+ const gutter = sidebarGutter ?? (variant === "floating" ? "tight" : "default");
882
885
  const shell = useMemo(
883
- () => ({ collapsed, setCollapsed, isMobile, open, setOpen, navId, collapseControl }),
884
- [collapsed, setCollapsed, isMobile, open, setOpen, navId, collapseControl]
886
+ () => ({
887
+ collapsed,
888
+ setCollapsed,
889
+ isMobile,
890
+ open,
891
+ setOpen,
892
+ navId,
893
+ collapseControl,
894
+ variant,
895
+ sidebarGutter: gutter
896
+ }),
897
+ [collapsed, setCollapsed, isMobile, open, setOpen, navId, collapseControl, variant, gutter]
885
898
  );
899
+ const floating = variant === "floating" && !isMobile;
886
900
  const layout = /* @__PURE__ */ jsxs(Fragment, { children: [
887
901
  sidebar && (isMobile ? (
888
902
  // Off screen until opened. The Drawer brings the portal, scrim, focus trap, Escape
@@ -900,24 +914,34 @@ var Shell = ({
900
914
  }
901
915
  )
902
916
  ) : /* @__PURE__ */ jsx("aside", { className: "shrink-0", children: sidebar })),
903
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
904
- topbar && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: topbar }),
905
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto lg:flex-row lg:overflow-visible", children: [
906
- /* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1 lg:overflow-auto", children }),
907
- secondary && /* @__PURE__ */ jsx(
908
- "aside",
909
- {
910
- className: clsx(
911
- "shrink-0 border-t border-[var(--color-border)] lg:overflow-auto lg:border-s lg:border-t-0",
912
- // `max-lg:` sorts after the plain width utility: full width while stacked.
913
- secondaryWidthClassName,
914
- "max-lg:w-full"
915
- ),
916
- children: secondary
917
- }
918
- )
919
- ] })
920
- ] })
917
+ /* @__PURE__ */ jsxs(
918
+ "div",
919
+ {
920
+ className: clsx(
921
+ "flex min-w-0 flex-1 flex-col",
922
+ floating && "overflow-hidden rounded-xl border border-[var(--color-border)] bg-[var(--color-bg-panel)] shadow-sm"
923
+ ),
924
+ "data-shell-panel": floating ? "" : void 0,
925
+ children: [
926
+ topbar && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: topbar }),
927
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto lg:flex-row lg:overflow-visible", children: [
928
+ /* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1 lg:overflow-auto", children }),
929
+ secondary && /* @__PURE__ */ jsx(
930
+ "aside",
931
+ {
932
+ className: clsx(
933
+ "shrink-0 border-t border-[var(--color-border)] lg:overflow-auto lg:border-s lg:border-t-0",
934
+ // `max-lg:` sorts after the plain width utility: full width while stacked.
935
+ secondaryWidthClassName,
936
+ "max-lg:w-full"
937
+ ),
938
+ children: secondary
939
+ }
940
+ )
941
+ ] })
942
+ ]
943
+ }
944
+ )
921
945
  ] });
922
946
  return /* @__PURE__ */ jsx(ShellContext.Provider, { value: sidebar ? shell : null, children: /* @__PURE__ */ jsx(
923
947
  "div",
@@ -925,12 +949,23 @@ var Shell = ({
925
949
  className: clsx(
926
950
  "flex h-screen w-screen overflow-hidden bg-[var(--color-bg-base)] text-[var(--color-text-base)]",
927
951
  container === "boxed" && "justify-center",
952
+ // Floating: 10px around and between the two cards.
953
+ floating && container === "fluid" && "gap-2.5 p-2.5",
928
954
  className
929
955
  ),
930
956
  children: container === "boxed" ? (
931
957
  // The column's hairlines only show where the page background does: the window is
932
958
  // wider than the column.
933
- /* @__PURE__ */ jsx("div", { className: "flex h-full w-full max-w-[1440px] min-w-0 border-[var(--color-border)] min-[1441px]:border-x", children: layout })
959
+ /* @__PURE__ */ jsx(
960
+ "div",
961
+ {
962
+ className: clsx(
963
+ "flex h-full w-full max-w-[1440px] min-w-0 border-[var(--color-border)] min-[1441px]:border-x",
964
+ floating && "gap-2.5 p-2.5"
965
+ ),
966
+ children: layout
967
+ }
968
+ )
934
969
  ) : layout
935
970
  }
936
971
  ) });
@@ -2092,6 +2127,8 @@ var useKeepFocus = () => {
2092
2127
  hadFocus.current = false;
2093
2128
  }, []);
2094
2129
  };
2130
+ var GUTTER = "var(--cosmos-sidebar-gutter,20px)";
2131
+ var TIGHT_GUTTER = "10px";
2095
2132
  var COMPACT_WIDTH = 88;
2096
2133
  var SidebarContext = createContext({
2097
2134
  collapsed: false,
@@ -2110,32 +2147,41 @@ var useSidebarCollapsed = (override) => {
2110
2147
  };
2111
2148
  var SidebarDepthContext = createContext(0);
2112
2149
  var ROW_INSET = {
2113
- wide: { margin: "mx-5", width: "w-[calc(100%-2.5rem)]", px: 20 },
2114
- tight: { margin: "mx-2", width: "w-[calc(100%-1rem)]", px: 8 },
2115
- none: { margin: "mx-0", width: "w-full", px: 0 }
2150
+ wide: {
2151
+ margin: "mx-[var(--cosmos-sidebar-gutter,20px)]",
2152
+ width: "w-[calc(100%-2*var(--cosmos-sidebar-gutter,20px))]",
2153
+ px: GUTTER
2154
+ },
2155
+ tight: { margin: "mx-2", width: "w-[calc(100%-1rem)]", px: "8px" },
2156
+ none: { margin: "mx-0", width: "w-full", px: "0px" }
2116
2157
  };
2158
+ var ROW_PADDING = 12;
2159
+ var ICON = 16;
2160
+ var TOP_LABEL = ROW_PADDING + ICON + 12;
2117
2161
  var LEVEL = [
2118
- { text: "text-sm", py: "py-row-10" },
2119
2162
  { text: "text-sm", py: "py-row-6" },
2120
- { text: "text-xs", py: "py-row-6" },
2121
- { text: "text-xs", py: "py-row-5" }
2163
+ { text: "text-sm", py: "py-row-4" },
2164
+ { text: "text-xs", py: "py-row-5" },
2165
+ { text: "text-xs", py: "py-row-4" }
2122
2166
  ];
2123
2167
  var level = (depth) => LEVEL[Math.min(depth, LEVEL.length - 1)];
2124
2168
  var NESTED_PADDING = 10;
2125
2169
  var useNestedGeometry = (inset) => {
2126
2170
  const { labelOrigin } = useContext(SidebarContext);
2127
- const origin = labelOrigin ?? ROW_INSET[inset].px + 44;
2128
- const labelX = (depth) => origin + 16 * (depth - 1);
2171
+ const margin = ROW_INSET[inset].px;
2172
+ const at = (px2) => labelOrigin === void 0 ? `calc(${margin} + ${px2}px)` : `${labelOrigin + px2 - TOP_LABEL}px`;
2173
+ const labelX = (depth) => TOP_LABEL + 16 * (depth - 1);
2129
2174
  return {
2130
2175
  /** Margin (and, for a `<button>`, width) that puts a nested row's pill at its own indent. */
2131
2176
  rowStyle: (depth, button) => {
2132
- const left = labelX(depth) - NESTED_PADDING;
2133
- return button ? { marginInlineStart: left, width: `calc(100% - ${left + ROW_INSET[inset].px}px)` } : { marginInlineStart: left };
2177
+ const left = at(labelX(depth) - NESTED_PADDING);
2178
+ return button ? { marginInlineStart: left, width: `calc(100% - ${left} - ${margin})` } : { marginInlineStart: left };
2134
2179
  },
2135
2180
  /** The guide line under a row's children: under a top-level icon, or 4 px before the label. */
2136
- guideStart: (depth) => depth === 0 ? ROW_INSET[inset].px + 22 : labelX(depth) - 4
2181
+ guideStart: (depth) => depth === 0 ? at(ROW_PADDING + ICON / 2) : at(labelX(depth) - 4)
2137
2182
  };
2138
2183
  };
2184
+ var RAIL_ROW = "mx-auto mb-1 size-ctrl-36 justify-center text-sm";
2139
2185
  var ACTIVE_ROW = {
2140
2186
  tint: "bg-brand-500/10 text-brand-600 dark:text-brand-400",
2141
2187
  solid: "bg-brand-500 text-white"
@@ -2177,7 +2223,7 @@ var CompactLabel = ({
2177
2223
  var CompactTip = ({ label, children }) => /* @__PURE__ */ jsx(Tooltip, { content: label, position: "end", block: true, children });
2178
2224
  var FOOTER_DIVIDER = {
2179
2225
  full: "border-t border-[var(--color-border)]",
2180
- inset: "relative before:absolute before:inset-x-5 before:top-0 before:h-px before:bg-[var(--color-border)]",
2226
+ inset: "relative before:absolute before:inset-x-[var(--cosmos-sidebar-gutter,20px)] before:top-0 before:h-px before:bg-[var(--color-border)]",
2181
2227
  none: ""
2182
2228
  };
2183
2229
  var SidebarRoot = ({
@@ -2192,6 +2238,8 @@ var SidebarRoot = ({
2192
2238
  footer,
2193
2239
  footerDivider = "full",
2194
2240
  activeStyle = "tint",
2241
+ gutter: gutterProp,
2242
+ edgeToggle: edgeToggleProp,
2195
2243
  onCollapsedChange,
2196
2244
  className
2197
2245
  }) => {
@@ -2205,6 +2253,10 @@ var SidebarRoot = ({
2205
2253
  const inDrawer = shell?.isMobile === true;
2206
2254
  const compact = variant === "compact" && !inDrawer;
2207
2255
  const collapsed = inDrawer || compact ? false : shell ? shell.collapsed : ownCollapsed;
2256
+ const floating = shell?.variant === "floating" && !inDrawer;
2257
+ const gutter = gutterProp ?? shell?.sidebarGutter ?? "default";
2258
+ const edgeToggle = (edgeToggleProp ?? floating) && !inDrawer && !compact;
2259
+ const toggleCollapsed = () => shell ? shell.setCollapsed(!shell.collapsed) : setOwnCollapsed(!ownCollapsed);
2208
2260
  const ownNavId = useId();
2209
2261
  const navId = shell ? shell.navId : ownNavId;
2210
2262
  const showToggle = !inDrawer && !compact && (onCollapsedChange !== void 0 || shell?.collapseControl === "sidebar");
@@ -2232,11 +2284,15 @@ var SidebarRoot = ({
2232
2284
  ref: navRef,
2233
2285
  id: navId,
2234
2286
  "aria-label": "Main navigation",
2235
- style: inDrawer ? void 0 : { width: compact ? COMPACT_WIDTH : rail ? collapsedWidth : fit.width },
2287
+ style: {
2288
+ ...inDrawer ? {} : { width: compact ? COMPACT_WIDTH : rail ? collapsedWidth : fit.width },
2289
+ ...gutter === "tight" ? { "--cosmos-sidebar-gutter": TIGHT_GUTTER } : {}
2290
+ },
2236
2291
  className: clsx(
2237
- "flex h-full flex-col overflow-hidden bg-[var(--color-bg-panel)]",
2238
- // The drawer panel draws the edge and the shadow, and sets the width.
2239
- inDrawer ? "w-full" : "border-e border-[var(--color-border)]",
2292
+ "relative flex h-full flex-col overflow-hidden bg-[var(--color-bg-panel)]",
2293
+ // The drawer panel draws the edge and the shadow, and sets the width. Floating, the
2294
+ // sidebar is a card of its own.
2295
+ inDrawer ? "w-full" : floating ? "rounded-xl border border-[var(--color-border)] shadow-sm" : "border-e border-[var(--color-border)]",
2240
2296
  // Not before the first frames: the width measured at mount shows at once.
2241
2297
  fit.animated && clsx(
2242
2298
  overlay ? "transition-[width,box-shadow]" : "transition-[width]",
@@ -2250,14 +2306,33 @@ var SidebarRoot = ({
2250
2306
  ...hover.props,
2251
2307
  children: [
2252
2308
  /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-x-hidden overflow-y-auto", children }),
2309
+ edgeToggle && // Mouse only: hidden from assistive technology and out of the tab order, since the
2310
+ // toggles already do the job by keyboard. The line shows under the pointer.
2311
+ /* @__PURE__ */ jsx(
2312
+ "button",
2313
+ {
2314
+ type: "button",
2315
+ tabIndex: -1,
2316
+ "aria-hidden": true,
2317
+ "data-sidebar-edge": "",
2318
+ onClick: toggleCollapsed,
2319
+ title: collapsed ? "Expand sidebar" : "Collapse sidebar",
2320
+ className: clsx(
2321
+ "group/edge absolute inset-y-0 end-0 z-10 w-2",
2322
+ collapsed ? "cursor-e-resize rtl:cursor-w-resize" : "cursor-w-resize rtl:cursor-e-resize"
2323
+ ),
2324
+ children: /* @__PURE__ */ jsx("span", { className: "group-hover/edge:bg-brand-500 absolute inset-y-3 end-0 w-0.5 rounded-full bg-transparent transition-colors" })
2325
+ }
2326
+ ),
2253
2327
  footer && /* @__PURE__ */ jsx(
2254
2328
  "div",
2255
2329
  {
2256
2330
  className: clsx(
2257
2331
  "shrink-0 overflow-hidden",
2258
- compact ? "p-2" : "p-3",
2332
+ compact ? "p-2" : rail ? "p-3" : "py-3",
2259
2333
  FOOTER_DIVIDER[footerDivider]
2260
2334
  ),
2335
+ style: compact || rail ? void 0 : { paddingInline: `max(0px, calc(${GUTTER} - 8px))` },
2261
2336
  children: /* @__PURE__ */ jsx(
2262
2337
  SidebarContext.Provider,
2263
2338
  {
@@ -2344,9 +2419,10 @@ var SidebarBrand = ({
2344
2419
  const baseClass = clsx(
2345
2420
  "focus-visible:focus-indicator flex h-[72px] items-center focus-visible:ring-inset",
2346
2421
  // The logo alone has the row to itself: centred, with no gap for the hidden title.
2347
- compact ? "justify-center" : "gap-3 px-5",
2422
+ compact ? "justify-center" : collapsed ? "gap-3 px-5" : "gap-3",
2348
2423
  inDrawer ? "min-w-0 flex-1" : clsx("shrink-0", divider && "border-b border-[var(--color-border)]")
2349
2424
  );
2425
+ const brandStyle = compact || collapsed ? void 0 : { paddingInline: `calc(${GUTTER} + 2px) ${GUTTER}` };
2350
2426
  const marker = inDrawer || !divider ? void 0 : "";
2351
2427
  let brand;
2352
2428
  if (href) {
@@ -2356,7 +2432,9 @@ var SidebarBrand = ({
2356
2432
  ref,
2357
2433
  href,
2358
2434
  className: baseClass,
2435
+ style: brandStyle,
2359
2436
  "data-sidebar-brand": marker,
2437
+ "data-sidebar-head": "",
2360
2438
  children: inner
2361
2439
  }
2362
2440
  );
@@ -2368,12 +2446,24 @@ var SidebarBrand = ({
2368
2446
  type: "button",
2369
2447
  onClick,
2370
2448
  className: clsx(baseClass, "w-full text-start"),
2449
+ style: brandStyle,
2371
2450
  "data-sidebar-brand": marker,
2451
+ "data-sidebar-head": "",
2372
2452
  children: inner
2373
2453
  }
2374
2454
  );
2375
2455
  } else {
2376
- brand = /* @__PURE__ */ jsx("div", { ref, className: baseClass, "data-sidebar-brand": marker, children: inner });
2456
+ brand = /* @__PURE__ */ jsx(
2457
+ "div",
2458
+ {
2459
+ ref,
2460
+ className: baseClass,
2461
+ style: brandStyle,
2462
+ "data-sidebar-brand": marker,
2463
+ "data-sidebar-head": "",
2464
+ children: inner
2465
+ }
2466
+ );
2377
2467
  }
2378
2468
  if (!inDrawer || !shell) return brand;
2379
2469
  return /* @__PURE__ */ jsxs(
@@ -2384,6 +2474,7 @@ var SidebarBrand = ({
2384
2474
  divider && "border-b border-[var(--color-border)]"
2385
2475
  ),
2386
2476
  "data-sidebar-brand": divider ? "" : void 0,
2477
+ "data-sidebar-head": "",
2387
2478
  children: [
2388
2479
  brand,
2389
2480
  /* @__PURE__ */ jsx(
@@ -2429,22 +2520,22 @@ var SidebarItem = ({
2429
2520
  const nested = !collapsed && depth > 0;
2430
2521
  const baseClass = clsx(
2431
2522
  "group focus-visible:focus-indicator flex items-center rounded-lg font-medium transition-colors",
2432
- compact ? "text-2xs relative flex-col gap-1 py-2 text-center" : clsx(
2433
- "gap-3",
2434
- nested ? "px-2.5" : collapsed ? "justify-center px-2" : "px-3",
2523
+ compact ? clsx("text-2xs relative flex-col gap-1 py-2 text-center", ROW_INSET[inset].margin) : collapsed ? RAIL_ROW : clsx(
2524
+ "mb-1 gap-3",
2525
+ nested ? "px-2.5" : "px-3",
2435
2526
  level(nested ? depth : 0).py,
2436
- level(nested ? depth : 0).text
2527
+ level(nested ? depth : 0).text,
2528
+ ROW_INSET[inset].margin
2437
2529
  ),
2438
- ROW_INSET[inset].margin,
2439
2530
  active ? ACTIVE_ROW[ctx.activeStyle] : IDLE_ROW
2440
2531
  );
2441
2532
  const style = nested ? geometry.rowStyle(depth, !href) : void 0;
2442
2533
  const content = compact ? /* @__PURE__ */ jsxs(Fragment, { children: [
2443
- /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
2534
+ /* @__PURE__ */ jsx(Icon2, { className: "size-5 shrink-0" }),
2444
2535
  /* @__PURE__ */ jsx(CompactLabel, { label, labelRef: setCompactLabel }),
2445
2536
  badge && /* @__PURE__ */ jsx("span", { className: "inset-e-1 absolute top-1", children: badge })
2446
2537
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2447
- !nested && /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
2538
+ !nested && /* @__PURE__ */ jsx(Icon2, { className: "size-4 shrink-0" }),
2448
2539
  !collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
2449
2540
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", ...fitLabel(labelId), children: label }),
2450
2541
  badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: badge })
@@ -2474,7 +2565,7 @@ var SidebarItem = ({
2474
2565
  closeDrawer?.();
2475
2566
  },
2476
2567
  "aria-label": name,
2477
- className: clsx(baseClass, ROW_INSET[inset].width, !compact && "text-start"),
2568
+ className: clsx(baseClass, !collapsed && ROW_INSET[inset].width, !compact && "text-start"),
2478
2569
  style,
2479
2570
  "aria-current": active ? "page" : void 0,
2480
2571
  "data-sidebar-item": "",
@@ -2537,13 +2628,13 @@ var SidebarSubMenu = ({
2537
2628
  "aria-label": compact ? void 0 : label,
2538
2629
  className: clsx(
2539
2630
  "group focus-visible:focus-indicator flex items-center rounded-lg font-medium transition-colors",
2540
- compact ? "text-2xs py-row-8 flex-col gap-1 text-center" : "py-row-10 justify-center px-2 text-sm",
2541
- ROW_INSET[inset].margin,
2542
- ROW_INSET[inset].width,
2631
+ compact ? "text-2xs py-row-8 flex-col gap-1 text-center" : RAIL_ROW,
2632
+ compact && ROW_INSET[inset].margin,
2633
+ compact && ROW_INSET[inset].width,
2543
2634
  active ? ACTIVE_ROW[ctx.activeStyle] : IDLE_ROW
2544
2635
  ),
2545
2636
  children: [
2546
- /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
2637
+ /* @__PURE__ */ jsx(Icon2, { className: clsx("shrink-0", compact ? "size-5" : "size-4") }),
2547
2638
  compact && /* @__PURE__ */ jsx(CompactLabel, { label, labelRef: setCompactLabel })
2548
2639
  ]
2549
2640
  }
@@ -2559,10 +2650,10 @@ var SidebarSubMenu = ({
2559
2650
  inDrawer: false,
2560
2651
  inset: "tight",
2561
2652
  activeStyle: ctx.activeStyle,
2562
- labelOrigin: ROW_INSET.tight.px + NESTED_PADDING
2653
+ labelOrigin: 8 + NESTED_PADDING
2563
2654
  },
2564
2655
  children: /* @__PURE__ */ jsxs(SidebarDepthContext.Provider, { value: 1, children: [
2565
- /* @__PURE__ */ jsx("p", { className: "px-3 pt-1 pb-2 text-xs font-semibold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
2656
+ /* @__PURE__ */ jsx("p", { className: "px-3 pt-1 pb-1.5 text-xs font-medium text-[var(--color-text-muted)]", children: label }),
2566
2657
  /* @__PURE__ */ jsx(
2567
2658
  "div",
2568
2659
  {
@@ -2585,14 +2676,14 @@ var SidebarSubMenu = ({
2585
2676
  const padding = nested ? "px-2.5" : "px-3";
2586
2677
  const tone = active ? ACTIVE_ROW[ctx.activeStyle] : inTrail ? TRAIL_ROW : nested && !ownPage ? GROUPING_ROW : IDLE_ROW;
2587
2678
  const row = clsx(
2588
- "group flex items-center rounded-lg font-medium transition-colors",
2679
+ "group mb-1 flex items-center rounded-lg font-medium transition-colors",
2589
2680
  text,
2590
2681
  ROW_INSET[inset].margin,
2591
2682
  tone
2592
2683
  );
2593
2684
  const toggle = () => setOpen((v) => !v);
2594
2685
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
2595
- !nested && /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
2686
+ !nested && /* @__PURE__ */ jsx(Icon2, { className: "size-4 shrink-0" }),
2596
2687
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", ...fitLabel(labelId), children: label }),
2597
2688
  badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: badge })
2598
2689
  ] });
@@ -2715,14 +2806,18 @@ var SidebarGroup = ({
2715
2806
  if (collapsed) {
2716
2807
  return /* @__PURE__ */ jsx("div", { className: "my-1", children });
2717
2808
  }
2718
- return /* @__PURE__ */ jsxs("div", { className: "my-1", children: [
2809
+ return /* @__PURE__ */ jsxs("div", { className: "pt-[18px] [[data-sidebar-head]+&]:pt-1", children: [
2719
2810
  /* @__PURE__ */ jsxs(
2720
2811
  "button",
2721
2812
  {
2722
2813
  type: "button",
2723
2814
  onClick: () => setOpen((v) => !v),
2724
2815
  "aria-expanded": open,
2725
- className: "text-2xs focus-visible:focus-indicator py-row-6 mx-2 flex w-[calc(100%-1rem)] items-center gap-2 rounded-lg px-3 font-semibold tracking-wider text-[var(--color-text-muted)] uppercase hover:text-[var(--color-text-secondary)]",
2816
+ className: clsx(
2817
+ "focus-visible:focus-indicator py-row-4 flex items-center gap-2 rounded-lg px-3 text-xs font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]",
2818
+ ROW_INSET.wide.margin,
2819
+ ROW_INSET.wide.width
2820
+ ),
2726
2821
  children: [
2727
2822
  open ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 rtl:-scale-x-100" }),
2728
2823
  label
@@ -2735,10 +2830,8 @@ var SidebarGroup = ({
2735
2830
  var SectionTitle = ({ label, className }) => /* @__PURE__ */ jsx(
2736
2831
  "p",
2737
2832
  {
2738
- className: clsx(
2739
- "text-2xs px-5 font-semibold tracking-wider text-[var(--color-text-muted)] uppercase",
2740
- className
2741
- ),
2833
+ className: clsx("text-xs font-medium text-[var(--color-text-muted)]", className),
2834
+ style: { paddingInline: `calc(${GUTTER} + ${ROW_PADDING}px) ${GUTTER}` },
2742
2835
  children: label
2743
2836
  }
2744
2837
  );
@@ -2756,14 +2849,29 @@ var SidebarSection = ({
2756
2849
  /* @__PURE__ */ jsx("div", { children })
2757
2850
  ] });
2758
2851
  }
2759
- return /* @__PURE__ */ jsxs("div", { className: collapsed ? void 0 : "mt-4", children: [
2760
- collapsed ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-2 text-[var(--color-text-muted)]", "aria-hidden": true, children: /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: [
2761
- /* @__PURE__ */ jsx("circle", { cx: "6", cy: "12", r: "1.75" }),
2762
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.75" }),
2763
- /* @__PURE__ */ jsx("circle", { cx: "18", cy: "12", r: "1.75" })
2764
- ] }) }) : label && /* @__PURE__ */ jsx(SectionTitle, { label, className: "mb-1.5" }),
2765
- /* @__PURE__ */ jsx("div", { children })
2766
- ] });
2852
+ const titled = Boolean(label);
2853
+ return /* @__PURE__ */ jsxs(
2854
+ "div",
2855
+ {
2856
+ className: collapsed && titled ? "[[data-sidebar-head]+&]:-mt-3.5" : "pt-[18px] [[data-sidebar-head]+&]:pt-1",
2857
+ children: [
2858
+ collapsed ? titled && /* @__PURE__ */ jsx(
2859
+ "div",
2860
+ {
2861
+ "data-sidebar-mark": "",
2862
+ className: "flex justify-center py-2 text-[var(--color-text-muted)] [[data-sidebar-head]+div>&]:invisible",
2863
+ "aria-hidden": true,
2864
+ children: /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: [
2865
+ /* @__PURE__ */ jsx("circle", { cx: "6", cy: "12", r: "1.75" }),
2866
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.75" }),
2867
+ /* @__PURE__ */ jsx("circle", { cx: "18", cy: "12", r: "1.75" })
2868
+ ] })
2869
+ }
2870
+ ) : label && /* @__PURE__ */ jsx(SectionTitle, { label, className: "mb-1.5" }),
2871
+ /* @__PURE__ */ jsx("div", { children })
2872
+ ]
2873
+ }
2874
+ );
2767
2875
  };
2768
2876
  var Sidebar = SidebarRoot;
2769
2877
  Sidebar.Brand = SidebarBrand;
@@ -3198,7 +3306,7 @@ var ProfileHeader = ({
3198
3306
  ) }),
3199
3307
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 basis-60 sm:pt-3", children: [
3200
3308
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
3201
- /* @__PURE__ */ jsx(Heading2, { className: "text-xl font-bold break-words text-[var(--color-text-primary)]", children: /* @__PURE__ */ jsx("bdi", { children: name }) }),
3309
+ /* @__PURE__ */ jsx(Heading2, { className: "min-w-0 text-xl font-bold break-words text-[var(--color-text-primary)]", children: /* @__PURE__ */ jsx("bdi", { children: name }) }),
3202
3310
  badges
3203
3311
  ] }),
3204
3312
  headline && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm break-words text-[var(--color-text-secondary)]", children: /* @__PURE__ */ jsx("bdi", { children: headline }) }),
@@ -3437,7 +3545,9 @@ var Button = ({
3437
3545
  type,
3438
3546
  disabled: disabled || loading,
3439
3547
  className: clsx(
3440
- "focus-visible:focus-indicator inline-flex items-center justify-center font-medium transition-colors",
3548
+ // A label on one line in a button of fixed height: a row too narrow for it wraps or
3549
+ // scrolls the buttons, not the text.
3550
+ "focus-visible:focus-indicator inline-flex items-center justify-center font-medium whitespace-nowrap transition-colors",
3441
3551
  VARIANT_CLASS[variant][intent],
3442
3552
  TEXT_CLASS[size],
3443
3553
  variant === "link" ? LINK_CLASS : [
@@ -3449,19 +3559,19 @@ var Button = ({
3449
3559
  ),
3450
3560
  ...rest,
3451
3561
  children: [
3452
- Icon2 && iconPosition === "start" && !loading && /* @__PURE__ */ jsx(Icon2, { className: ICON_SIZE[size] }),
3562
+ Icon2 && iconPosition === "start" && !loading && /* @__PURE__ */ jsx(Icon2, { className: clsx("shrink-0", ICON_SIZE[size]) }),
3453
3563
  loading && /* @__PURE__ */ jsx(
3454
3564
  "span",
3455
3565
  {
3456
3566
  "aria-hidden": true,
3457
3567
  className: clsx(
3458
- "animate-spin rounded-full border-2 border-current border-t-transparent",
3568
+ "shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent",
3459
3569
  ICON_SIZE[size]
3460
3570
  )
3461
3571
  }
3462
3572
  ),
3463
3573
  children,
3464
- Icon2 && iconPosition === "end" && !loading && /* @__PURE__ */ jsx(Icon2, { className: ICON_SIZE[size] })
3574
+ Icon2 && iconPosition === "end" && !loading && /* @__PURE__ */ jsx(Icon2, { className: clsx("shrink-0", ICON_SIZE[size]) })
3465
3575
  ]
3466
3576
  }
3467
3577
  );
@@ -4040,7 +4150,7 @@ var DEFAULT_SUMMARY_LABELS = {
4040
4150
  UNKNOWN: "Status unknown",
4041
4151
  INFO: "Operational, with notices"
4042
4152
  };
4043
- var ICON = {
4153
+ var ICON2 = {
4044
4154
  OK: CheckCircle,
4045
4155
  WARN: AlertTriangle,
4046
4156
  CRIT: XCircle,
@@ -4126,7 +4236,7 @@ var HealthSummary = ({
4126
4236
  }
4127
4237
  );
4128
4238
  }
4129
- const Icon2 = ICON[shown];
4239
+ const Icon2 = ICON2[shown];
4130
4240
  return /* @__PURE__ */ jsxs(
4131
4241
  "div",
4132
4242
  {
@@ -4500,7 +4610,7 @@ var CheckName = ({ check, open, onToggle, outputId }) => check.output === void 0
4500
4610
  }
4501
4611
  );
4502
4612
  var Output = ({ check, open, outputId }) => check.output === void 0 ? null : /* @__PURE__ */ jsx("div", { id: outputId, hidden: !open, className: "min-w-0", children: open && /* @__PURE__ */ jsx(CodeBlock, { code: check.output }) });
4503
- var Dash = () => /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-[var(--color-text-muted)] max-sm:hidden", children: "\u2014" });
4613
+ var Dash = () => /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-[var(--color-text-muted)] @max-[48rem]:hidden", children: "\u2014" });
4504
4614
  var CheckRow = ({ check, open, onToggle, outputId, now }) => /* @__PURE__ */ jsxs(
4505
4615
  "li",
4506
4616
  {
@@ -4509,15 +4619,15 @@ var CheckRow = ({ check, open, onToggle, outputId, now }) => /* @__PURE__ */ jsx
4509
4619
  (check.status === "WARN" || check.status === "CRIT") && "bg-gray-50/60 dark:bg-white/[0.02]"
4510
4620
  ),
4511
4621
  children: [
4512
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 sm:grid sm:grid-cols-[6.5rem_minmax(0,10rem)_minmax(0,12rem)_minmax(0,1fr)_5rem_6rem] sm:items-center sm:gap-3", children: [
4622
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 @min-[48rem]:grid @min-[48rem]:grid-cols-[6.5rem_minmax(6rem,10rem)_minmax(0,12rem)_minmax(12rem,1fr)_5rem_7rem] @min-[48rem]:items-center @min-[48rem]:gap-3", children: [
4513
4623
  /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(StatusBadge, { status: check.status, label: STATUS_NAME[check.status] }) }),
4514
4624
  /* @__PURE__ */ jsx(CheckName, { check, open, onToggle, outputId }),
4515
- check.target ? /* @__PURE__ */ jsx("span", { className: "font-mono text-xs break-all text-[var(--color-text-secondary)] sm:truncate", children: /* @__PURE__ */ jsx("bdi", { children: check.target }) }) : /* @__PURE__ */ jsx(Dash, {}),
4625
+ check.target ? /* @__PURE__ */ jsx("span", { className: "font-mono text-xs break-all text-[var(--color-text-secondary)] @min-[48rem]:truncate", children: /* @__PURE__ */ jsx("bdi", { children: check.target }) }) : /* @__PURE__ */ jsx(Dash, {}),
4516
4626
  check.message ? /* @__PURE__ */ jsx("span", { className: "min-w-0 break-words", children: /* @__PURE__ */ jsx("bdi", { children: check.message }) }) : /* @__PURE__ */ jsx(Dash, {}),
4517
- check.latency !== void 0 ? /* @__PURE__ */ jsx("span", { className: "tabular-nums sm:text-end", children: /* @__PURE__ */ jsx("bdi", { children: formatLatency(check.latency) }) }) : /* @__PURE__ */ jsx(Dash, {}),
4518
- check.checkedAt !== void 0 ? /* @__PURE__ */ jsx("span", { className: "text-[var(--color-text-secondary)] tabular-nums sm:text-end", children: /* @__PURE__ */ jsx(RelativeTime, { value: check.checkedAt, now }) }) : /* @__PURE__ */ jsx(Dash, {})
4627
+ check.latency !== void 0 ? /* @__PURE__ */ jsx("span", { className: "tabular-nums @min-[48rem]:text-end", children: /* @__PURE__ */ jsx("bdi", { children: formatLatency(check.latency) }) }) : /* @__PURE__ */ jsx(Dash, {}),
4628
+ check.checkedAt !== void 0 ? /* @__PURE__ */ jsx("span", { className: "text-[var(--color-text-secondary)] tabular-nums @min-[48rem]:text-end", children: /* @__PURE__ */ jsx(RelativeTime, { value: check.checkedAt, now }) }) : /* @__PURE__ */ jsx(Dash, {})
4519
4629
  ] }),
4520
- check.output !== void 0 && /* @__PURE__ */ jsx("div", { className: clsx(open && "mt-3 sm:ms-[7.25rem]"), children: /* @__PURE__ */ jsx(Output, { check, open, outputId }) })
4630
+ check.output !== void 0 && /* @__PURE__ */ jsx("div", { className: clsx(open && "mt-3 @min-[48rem]:ms-[7.25rem]"), children: /* @__PURE__ */ jsx(Output, { check, open, outputId }) })
4521
4631
  ]
4522
4632
  }
4523
4633
  );
@@ -4645,7 +4755,9 @@ var HealthCheckList = ({
4645
4755
  role: ariaLabel ? "group" : void 0,
4646
4756
  "aria-label": ariaLabel,
4647
4757
  className: clsx(
4648
- variant === "list" && "overflow-hidden rounded-2xl border border-[var(--color-border)] bg-[var(--color-bg-panel)]",
4758
+ // The rows lay their columns out from the list's own width, not the screen's: in a card the
4759
+ // list is narrower than the screen, and a grid of fixed columns left the message nothing.
4760
+ variant === "list" && "@container overflow-hidden rounded-2xl border border-[var(--color-border)] bg-[var(--color-bg-panel)]",
4649
4761
  variant === "grid" && "flex flex-col gap-4",
4650
4762
  className
4651
4763
  ),
@@ -5738,9 +5850,9 @@ function StackedListItem({
5738
5850
  /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 -top-px bottom-0", "aria-hidden": true }),
5739
5851
  /* @__PURE__ */ jsx("bdi", { children: title })
5740
5852
  ] }) }) : /* @__PURE__ */ jsx("p", { className: "text-sm/6 font-semibold text-gray-900 dark:text-white", children: /* @__PURE__ */ jsx("bdi", { children: title }) });
5741
- const titleRow = badge ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-x-3", children: [
5853
+ const titleRow = badge ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start gap-x-3 gap-y-1", children: [
5742
5854
  titleEl,
5743
- badge
5855
+ /* @__PURE__ */ jsx("span", { className: "flex-none", children: badge })
5744
5856
  ] }) : titleEl;
5745
5857
  return /* @__PURE__ */ jsxs(
5746
5858
  "li",
@@ -7806,7 +7918,9 @@ var AvatarGroup = ({
7806
7918
  "span",
7807
7919
  {
7808
7920
  className: clsx(
7809
- "relative inline-flex shrink-0 ring-2 ring-[var(--color-bg-panel)] has-focus-visible:z-10",
7921
+ // The surface behind each avatar: a tinted fill lets the one before it, and its ring, show
7922
+ // through otherwise.
7923
+ "relative inline-flex shrink-0 bg-[var(--color-bg-panel)] ring-2 ring-[var(--color-bg-panel)] has-focus-visible:z-10",
7810
7924
  AVATAR_SHAPE_CLASS[shape],
7811
7925
  index > 0 && OVERLAP_CLASS[spacing][size],
7812
7926
  index < last && INITIALS_SHIFT_CLASS[spacing][size]
@@ -8784,7 +8898,8 @@ var STATE_CONFIG = {
8784
8898
  saving: { label: "Saving\u2026", loading: true },
8785
8899
  // The `success` intent carries the dark text on green (white on green-500 is about 2.3:1).
8786
8900
  saved: { label: "Saved", icon: Check, intent: "success" },
8787
- error: { label: "Error", intent: "danger" }
8901
+ // What to do next, not the name of the state: the save failed, the click saves again.
8902
+ error: { label: "Try again", intent: "danger" }
8788
8903
  };
8789
8904
  var StatefulSaveButton = ({
8790
8905
  state,
@@ -9134,7 +9249,9 @@ function NotificationsPanelTrigger({
9134
9249
  "aria-expanded": open,
9135
9250
  onClick: () => setOpen(!open),
9136
9251
  className: clsx(
9137
- "focus-visible:focus-indicator h-ctrl-40 w-ctrl-40 relative flex items-center justify-center rounded-lg border transition-colors",
9252
+ // The ping around the count grows to twice its size: clipped to the bell, it never widens
9253
+ // the row that holds it. The focus ring is a shadow, outside the clip.
9254
+ "focus-visible:focus-indicator h-ctrl-40 w-ctrl-40 relative flex items-center justify-center overflow-hidden rounded-lg border transition-colors",
9138
9255
  muted ? "border-gray-200 text-gray-400 dark:border-gray-700 dark:text-gray-600" : "border-gray-200 text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-white",
9139
9256
  className
9140
9257
  ),
@@ -13719,21 +13836,30 @@ var DatePicker = (props) => {
13719
13836
  ]
13720
13837
  }
13721
13838
  ),
13722
- isRange ? /* @__PURE__ */ jsxs("div", { className: clsx("flex items-center gap-2", !fullWidth && "w-fit"), children: [
13723
- renderTrigger(
13724
- fieldId,
13725
- "from",
13726
- selectedRange.from,
13727
- props.fromPlaceholder ?? "Start date"
13728
- ),
13729
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 dark:text-gray-400", children: "to" }),
13730
- renderTrigger(
13731
- void 0,
13732
- "to",
13733
- selectedRange.to,
13734
- props.toPlaceholder ?? "End date"
13839
+ isRange ? (
13840
+ // Two dates side by side don't fit a phone: the end date goes under the start date.
13841
+ /* @__PURE__ */ jsxs(
13842
+ "div",
13843
+ {
13844
+ className: clsx("flex flex-wrap items-center gap-2", !fullWidth && "w-fit max-w-full"),
13845
+ children: [
13846
+ renderTrigger(
13847
+ fieldId,
13848
+ "from",
13849
+ selectedRange.from,
13850
+ props.fromPlaceholder ?? "Start date"
13851
+ ),
13852
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 dark:text-gray-400", children: "to" }),
13853
+ renderTrigger(
13854
+ void 0,
13855
+ "to",
13856
+ selectedRange.to,
13857
+ props.toPlaceholder ?? "End date"
13858
+ )
13859
+ ]
13860
+ }
13735
13861
  )
13736
- ] }) : renderTrigger(
13862
+ ) : renderTrigger(
13737
13863
  fieldId,
13738
13864
  "from",
13739
13865
  selectedSingle,
@@ -13988,7 +14114,7 @@ var OtpInput = ({
13988
14114
  if (finalValue.length === length) onComplete?.(finalValue);
13989
14115
  };
13990
14116
  return /* @__PURE__ */ jsxs("div", { className: clsx("flex items-center gap-2", className), role: "group", "aria-label": ariaLabel, children: [
13991
- /* @__PURE__ */ jsx("div", { dir: "ltr", className: "flex items-center gap-2", children: Array.from({ length }).map((_, i) => {
14117
+ /* @__PURE__ */ jsx("div", { dir: "ltr", className: "flex min-w-0 items-center gap-2", children: Array.from({ length }).map((_, i) => {
13992
14118
  const cellChar = value[i] ?? "";
13993
14119
  const display = mask && cellChar ? "\u2022" : cellChar;
13994
14120
  return /* @__PURE__ */ jsx(
@@ -14011,7 +14137,8 @@ var OtpInput = ({
14011
14137
  onPaste: handlePaste(i),
14012
14138
  onFocus: (e) => e.target.select(),
14013
14139
  className: clsx(
14014
- "h-ctrl-48 w-10 rounded-lg border bg-white text-center text-lg font-semibold text-gray-900 tabular-nums transition-colors disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white",
14140
+ // 2.5rem wide, narrower when the row doesn't fit (eight cells on a phone).
14141
+ "h-ctrl-48 w-10 min-w-0 rounded-lg border bg-white text-center text-lg font-semibold text-gray-900 tabular-nums transition-colors disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white",
14015
14142
  fieldStateClass({ invalid: error, success })
14016
14143
  )
14017
14144
  },
@@ -16053,7 +16180,8 @@ function Item4({
16053
16180
  "dd",
16054
16181
  {
16055
16182
  className: clsx(
16056
- "text-sm font-medium text-[var(--color-text-primary)]",
16183
+ // A value with no space in it (an e-mail) breaks inside the row.
16184
+ "min-w-0 text-sm font-medium break-words text-[var(--color-text-primary)]",
16057
16185
  mono && "font-mono text-xs"
16058
16186
  ),
16059
16187
  children: isolate(children)
@@ -16075,7 +16203,7 @@ function Item4({
16075
16203
  "dd",
16076
16204
  {
16077
16205
  className: clsx(
16078
- "mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300",
16206
+ "mt-1 min-w-0 text-sm/6 break-words text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300",
16079
16207
  mono && "font-mono"
16080
16208
  ),
16081
16209
  children: isolate(children)
@@ -16172,7 +16300,7 @@ var KpiCard = ({
16172
16300
  );
16173
16301
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
16174
16302
  /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-between gap-3", children: [
16175
- /* @__PURE__ */ jsx("span", { className: "min-w-0 text-xs font-medium tracking-wider text-gray-500 uppercase dark:text-gray-400", children: /* @__PURE__ */ jsx("bdi", { children: label }) }),
16303
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 text-xs font-medium tracking-wider break-words hyphens-auto text-gray-500 uppercase dark:text-gray-400", children: /* @__PURE__ */ jsx("bdi", { children: label }) }),
16176
16304
  Icon2 && /* @__PURE__ */ jsx(
16177
16305
  "span",
16178
16306
  {
@@ -16195,7 +16323,9 @@ var KpiCard = ({
16195
16323
  "span",
16196
16324
  {
16197
16325
  className: clsx(
16198
- "block text-3xl font-bold tracking-tight tabular-nums",
16326
+ // A figure with no break in it (`€12,418,906.40`) wraps in a narrow card instead of
16327
+ // running out of it: cut, it would read as another number.
16328
+ "block text-3xl font-bold tracking-tight break-words tabular-nums",
16199
16329
  intent === "neutral" ? "text-gray-900 dark:text-white" : INTENT_STYLE[intent].text
16200
16330
  ),
16201
16331
  children: withExact ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -16680,7 +16810,8 @@ var MiniCalendar = ({
16680
16810
  "aria-current": isToday ? "date" : void 0,
16681
16811
  className: clsx(
16682
16812
  // The number sits above the middle of the cell (`pb-1.5`) to leave room for the event dot under it.
16683
- "h-ctrl-36 relative flex items-center justify-center rounded-md border pb-1.5 text-xs font-medium transition-colors focus-visible:ring-inset",
16813
+ // At least 28px wide: a calendar as wide as its content had columns as narrow as the numbers.
16814
+ "h-ctrl-36 min-w-ctrl-28 relative flex items-center justify-center rounded-md border pb-1.5 text-xs font-medium transition-colors focus-visible:ring-inset",
16684
16815
  isSelected ? "bg-brand-500 hover:bg-brand-600 focus-visible:focus-indicator-on-accent border-transparent text-white" : isToday ? "border-brand-500 text-brand-600 hover:bg-brand-50 focus-visible:focus-indicator dark:text-brand-400 dark:hover:bg-white/5" : "focus-visible:focus-indicator border-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-white/5"
16685
16816
  ),
16686
16817
  children: [
@@ -18489,12 +18620,13 @@ var DataTableBulkActions = ({
18489
18620
  icon: item.icon,
18490
18621
  disabled: item.disabled,
18491
18622
  onClick: () => item.onClick(selectedRows),
18623
+ className: "shrink-0",
18492
18624
  children: item.label
18493
18625
  },
18494
18626
  item.key
18495
18627
  );
18496
18628
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18497
- /* @__PURE__ */ jsxs("div", { className: clsx("flex items-center gap-2", phoneIcons && "max-sm:hidden"), children: [
18629
+ /* @__PURE__ */ jsxs("div", { className: clsx("flex flex-wrap items-center gap-2", phoneIcons && "max-sm:hidden"), children: [
18498
18630
  button(first, true),
18499
18631
  rest.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
18500
18632
  /* @__PURE__ */ jsx("div", { className: "hidden items-center gap-2 @min-[1152px]:flex", children: rest.map((item) => button(item, false)) }),
@@ -18894,6 +19026,43 @@ var PageSizeSelect = ({ value, options, onChange }) => {
18894
19026
  ] });
18895
19027
  };
18896
19028
 
19029
+ // src/table/columnWidths.ts
19030
+ var DEFAULT_COLUMN_MIN_WIDTH = "8rem";
19031
+ var NUMBER = String.raw`(?:\d+(?:\.\d+)?|\.\d+)`;
19032
+ var LENGTH = new RegExp(`^${NUMBER}(?:px|rem|em|ch)$`);
19033
+ var PERCENT2 = new RegExp(`^(${NUMBER})%$`);
19034
+ var ratio = (n) => Number(n.toFixed(4));
19035
+ var tableMinWidth = (columns, fixed, takesTheRest) => {
19036
+ if (columns.length === 0) return void 0;
19037
+ const lengths = [...fixed];
19038
+ const autoMins = [];
19039
+ const percents = [];
19040
+ columns.forEach((c, i) => {
19041
+ const width = c.width?.trim() ?? "";
19042
+ const min = c.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;
19043
+ const share = PERCENT2.exec(width);
19044
+ if (i === takesTheRest) autoMins.push(LENGTH.test(width) ? width : min);
19045
+ else if (LENGTH.test(width)) lengths.push(width);
19046
+ else if (share) percents.push({ share: Number(share[1]) / 100, min });
19047
+ else autoMins.push(min);
19048
+ });
19049
+ const bounds = percents.map((p) => `calc(${p.min} / ${ratio(p.share)})`);
19050
+ const left = ratio(1 - percents.reduce((sum, p) => sum + p.share, 0));
19051
+ const widest = [...new Set(autoMins)];
19052
+ const parts = [
19053
+ ...lengths,
19054
+ ...autoMins.length > 0 ? [`${autoMins.length} * ${widest.length === 1 ? widest[0] : `max(${widest.join(", ")})`}`] : []
19055
+ ];
19056
+ if (parts.length > 0 && left > 0) {
19057
+ bounds.push(
19058
+ left === 1 ? `calc(${parts.join(" + ")})` : `calc((${parts.join(" + ")}) / ${left})`
19059
+ );
19060
+ }
19061
+ const distinct = [...new Set(bounds)];
19062
+ if (distinct.length === 0) return void 0;
19063
+ return distinct.length === 1 ? distinct[0] : `max(${distinct.join(", ")})`;
19064
+ };
19065
+
18897
19066
  // src/table/pipeline.ts
18898
19067
  var filtersToRecord = (filters) => {
18899
19068
  const out = {};
@@ -19783,12 +19952,15 @@ var DataTable = ({
19783
19952
  [filteredRows, columns, manual, sortKey, sortDir]
19784
19953
  );
19785
19954
  const firstColumnTakesTheRest = (selectable || actionColumn) && columns.length > 0 && columns.every((c) => c.width);
19786
- const statedMinWidth = firstColumnTakesTheRest ? `calc(${[
19787
- expandable && EXPAND_COLUMN_WIDTH,
19788
- selectable && SELECT_COLUMN_WIDTH,
19789
- ...columns.map((c) => c.width),
19790
- actionColumn && (rowEditing ? EDIT_ACTION_COLUMN_WIDTH : ACTION_COLUMN_WIDTH)
19791
- ].filter(Boolean).join(" + ")})` : void 0;
19955
+ const tableMinimum = tableMinWidth(
19956
+ columns,
19957
+ [
19958
+ expandable && EXPAND_COLUMN_WIDTH,
19959
+ selectable && SELECT_COLUMN_WIDTH,
19960
+ actionColumn && (rowEditing ? EDIT_ACTION_COLUMN_WIDTH : ACTION_COLUMN_WIDTH)
19961
+ ].filter((w) => Boolean(w)),
19962
+ firstColumnTakesTheRest ? 0 : void 0
19963
+ );
19792
19964
  const mobileSortable = columns.some((c) => c.sortable);
19793
19965
  const hasRows = sortedRows.length > 0;
19794
19966
  const showSkeleton = loading && !hasRows;
@@ -20253,7 +20425,11 @@ var DataTable = ({
20253
20425
  /* @__PURE__ */ jsxs(
20254
20426
  "div",
20255
20427
  {
20256
- className: clsx("flex min-w-0 items-center gap-3", mobileCards && "max-sm:flex-1"),
20428
+ className: clsx(
20429
+ // The actions go to the next line when the count leaves them too little room.
20430
+ "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2",
20431
+ mobileCards && "max-sm:flex-1"
20432
+ ),
20257
20433
  children: [
20258
20434
  /* @__PURE__ */ jsx("span", { className: "text-brand-700 dark:text-brand-300 text-sm font-medium whitespace-nowrap", children: /* @__PURE__ */ jsxs("bdi", { children: [
20259
20435
  selection.size,
@@ -20268,7 +20444,7 @@ var DataTable = ({
20268
20444
  children: "Clear"
20269
20445
  }
20270
20446
  ),
20271
- (bulkActionItems || bulkActions) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 ps-1", children: [
20447
+ (bulkActionItems || bulkActions) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-auto flex-wrap items-center gap-2 ps-1", children: [
20272
20448
  bulkActionItems && /* @__PURE__ */ jsx(
20273
20449
  DataTableBulkActions,
20274
20450
  {
@@ -20405,7 +20581,7 @@ var DataTable = ({
20405
20581
  "aria-labelledby": ariaLabelledBy,
20406
20582
  "aria-busy": loading || void 0,
20407
20583
  "aria-rowcount": windowed ? pageRows.length + 1 : void 0,
20408
- style: statedMinWidth ? { minWidth: statedMinWidth } : void 0,
20584
+ style: tableMinimum ? { minWidth: tableMinimum } : void 0,
20409
20585
  className: "w-full table-fixed",
20410
20586
  children: [
20411
20587
  /* @__PURE__ */ jsxs("colgroup", { children: [
@@ -21356,7 +21532,7 @@ var SocialAuthButtons = ({
21356
21532
  onClick: () => onProviderClick(provider),
21357
21533
  disabled: isDisabled,
21358
21534
  "aria-label": label,
21359
- className: "focus-visible:focus-indicator h-ctrl-40 flex items-center justify-center gap-2 rounded-lg border border-gray-200 bg-white text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700",
21535
+ className: "focus-visible:focus-indicator h-ctrl-40 flex items-center justify-center gap-2 rounded-lg border border-gray-200 bg-white text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 [&>svg]:shrink-0",
21360
21536
  children: [
21361
21537
  isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Icon2, {}),
21362
21538
  /* @__PURE__ */ jsx("span", { className: "truncate", children: label })