@sckyzo/cosmos-react 0.4.0 → 0.4.1

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.d.cts CHANGED
@@ -5522,6 +5522,13 @@ type ColumnDef<T> = {
5522
5522
  label: ReactNode;
5523
5523
  /** Optional fixed width (CSS value, e.g. `'20%'` or `'180px'`). */
5524
5524
  width?: string;
5525
+ /**
5526
+ * The narrowest the column is drawn when `width` is a percentage or unset (a length, `'180px'`,
5527
+ * is kept as it is). Default `'8rem'`. The table is never narrower than what its columns need,
5528
+ * so on a narrow screen it scrolls sideways instead of squeezing them. Columns without a width
5529
+ * split what the others leave in equal parts: each gets at least the largest `minWidth` of them.
5530
+ */
5531
+ minWidth?: string;
5525
5532
  /** Text alignment override: `start` (the default), `end` or `center`. `end` is for numbers. */
5526
5533
  align?: 'start' | 'end' | 'center';
5527
5534
  /** Renders the cell for a row. */
package/dist/index.d.ts CHANGED
@@ -5522,6 +5522,13 @@ type ColumnDef<T> = {
5522
5522
  label: ReactNode;
5523
5523
  /** Optional fixed width (CSS value, e.g. `'20%'` or `'180px'`). */
5524
5524
  width?: string;
5525
+ /**
5526
+ * The narrowest the column is drawn when `width` is a percentage or unset (a length, `'180px'`,
5527
+ * is kept as it is). Default `'8rem'`. The table is never narrower than what its columns need,
5528
+ * so on a narrow screen it scrolls sideways instead of squeezing them. Columns without a width
5529
+ * split what the others leave in equal parts: each gets at least the largest `minWidth` of them.
5530
+ */
5531
+ minWidth?: string;
5525
5532
  /** Text alignment override: `start` (the default), `end` or `center`. `end` is for numbers. */
5526
5533
  align?: 'start' | 'end' | 'center';
5527
5534
  /** Renders the cell for a row. */
package/dist/index.js CHANGED
@@ -3198,7 +3198,7 @@ var ProfileHeader = ({
3198
3198
  ) }),
3199
3199
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 basis-60 sm:pt-3", children: [
3200
3200
  /* @__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 }) }),
3201
+ /* @__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
3202
  badges
3203
3203
  ] }),
3204
3204
  headline && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm break-words text-[var(--color-text-secondary)]", children: /* @__PURE__ */ jsx("bdi", { children: headline }) }),
@@ -3437,7 +3437,9 @@ var Button = ({
3437
3437
  type,
3438
3438
  disabled: disabled || loading,
3439
3439
  className: clsx(
3440
- "focus-visible:focus-indicator inline-flex items-center justify-center font-medium transition-colors",
3440
+ // A label on one line in a button of fixed height: a row too narrow for it wraps or
3441
+ // scrolls the buttons, not the text.
3442
+ "focus-visible:focus-indicator inline-flex items-center justify-center font-medium whitespace-nowrap transition-colors",
3441
3443
  VARIANT_CLASS[variant][intent],
3442
3444
  TEXT_CLASS[size],
3443
3445
  variant === "link" ? LINK_CLASS : [
@@ -3449,19 +3451,19 @@ var Button = ({
3449
3451
  ),
3450
3452
  ...rest,
3451
3453
  children: [
3452
- Icon2 && iconPosition === "start" && !loading && /* @__PURE__ */ jsx(Icon2, { className: ICON_SIZE[size] }),
3454
+ Icon2 && iconPosition === "start" && !loading && /* @__PURE__ */ jsx(Icon2, { className: clsx("shrink-0", ICON_SIZE[size]) }),
3453
3455
  loading && /* @__PURE__ */ jsx(
3454
3456
  "span",
3455
3457
  {
3456
3458
  "aria-hidden": true,
3457
3459
  className: clsx(
3458
- "animate-spin rounded-full border-2 border-current border-t-transparent",
3460
+ "shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent",
3459
3461
  ICON_SIZE[size]
3460
3462
  )
3461
3463
  }
3462
3464
  ),
3463
3465
  children,
3464
- Icon2 && iconPosition === "end" && !loading && /* @__PURE__ */ jsx(Icon2, { className: ICON_SIZE[size] })
3466
+ Icon2 && iconPosition === "end" && !loading && /* @__PURE__ */ jsx(Icon2, { className: clsx("shrink-0", ICON_SIZE[size]) })
3465
3467
  ]
3466
3468
  }
3467
3469
  );
@@ -4500,7 +4502,7 @@ var CheckName = ({ check, open, onToggle, outputId }) => check.output === void 0
4500
4502
  }
4501
4503
  );
4502
4504
  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" });
4505
+ var Dash = () => /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-[var(--color-text-muted)] @max-[48rem]:hidden", children: "\u2014" });
4504
4506
  var CheckRow = ({ check, open, onToggle, outputId, now }) => /* @__PURE__ */ jsxs(
4505
4507
  "li",
4506
4508
  {
@@ -4509,15 +4511,15 @@ var CheckRow = ({ check, open, onToggle, outputId, now }) => /* @__PURE__ */ jsx
4509
4511
  (check.status === "WARN" || check.status === "CRIT") && "bg-gray-50/60 dark:bg-white/[0.02]"
4510
4512
  ),
4511
4513
  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: [
4514
+ /* @__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
4515
  /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(StatusBadge, { status: check.status, label: STATUS_NAME[check.status] }) }),
4514
4516
  /* @__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, {}),
4517
+ 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
4518
  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, {})
4519
+ 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, {}),
4520
+ 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
4521
  ] }),
4520
- check.output !== void 0 && /* @__PURE__ */ jsx("div", { className: clsx(open && "mt-3 sm:ms-[7.25rem]"), children: /* @__PURE__ */ jsx(Output, { check, open, outputId }) })
4522
+ 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
4523
  ]
4522
4524
  }
4523
4525
  );
@@ -4645,7 +4647,9 @@ var HealthCheckList = ({
4645
4647
  role: ariaLabel ? "group" : void 0,
4646
4648
  "aria-label": ariaLabel,
4647
4649
  className: clsx(
4648
- variant === "list" && "overflow-hidden rounded-2xl border border-[var(--color-border)] bg-[var(--color-bg-panel)]",
4650
+ // The rows lay their columns out from the list's own width, not the screen's: in a card the
4651
+ // list is narrower than the screen, and a grid of fixed columns left the message nothing.
4652
+ variant === "list" && "@container overflow-hidden rounded-2xl border border-[var(--color-border)] bg-[var(--color-bg-panel)]",
4649
4653
  variant === "grid" && "flex flex-col gap-4",
4650
4654
  className
4651
4655
  ),
@@ -5738,9 +5742,9 @@ function StackedListItem({
5738
5742
  /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 -top-px bottom-0", "aria-hidden": true }),
5739
5743
  /* @__PURE__ */ jsx("bdi", { children: title })
5740
5744
  ] }) }) : /* @__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: [
5745
+ const titleRow = badge ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start gap-x-3 gap-y-1", children: [
5742
5746
  titleEl,
5743
- badge
5747
+ /* @__PURE__ */ jsx("span", { className: "flex-none", children: badge })
5744
5748
  ] }) : titleEl;
5745
5749
  return /* @__PURE__ */ jsxs(
5746
5750
  "li",
@@ -7806,7 +7810,9 @@ var AvatarGroup = ({
7806
7810
  "span",
7807
7811
  {
7808
7812
  className: clsx(
7809
- "relative inline-flex shrink-0 ring-2 ring-[var(--color-bg-panel)] has-focus-visible:z-10",
7813
+ // The surface behind each avatar: a tinted fill lets the one before it, and its ring, show
7814
+ // through otherwise.
7815
+ "relative inline-flex shrink-0 bg-[var(--color-bg-panel)] ring-2 ring-[var(--color-bg-panel)] has-focus-visible:z-10",
7810
7816
  AVATAR_SHAPE_CLASS[shape],
7811
7817
  index > 0 && OVERLAP_CLASS[spacing][size],
7812
7818
  index < last && INITIALS_SHIFT_CLASS[spacing][size]
@@ -8784,7 +8790,8 @@ var STATE_CONFIG = {
8784
8790
  saving: { label: "Saving\u2026", loading: true },
8785
8791
  // The `success` intent carries the dark text on green (white on green-500 is about 2.3:1).
8786
8792
  saved: { label: "Saved", icon: Check, intent: "success" },
8787
- error: { label: "Error", intent: "danger" }
8793
+ // What to do next, not the name of the state: the save failed, the click saves again.
8794
+ error: { label: "Try again", intent: "danger" }
8788
8795
  };
8789
8796
  var StatefulSaveButton = ({
8790
8797
  state,
@@ -9134,7 +9141,9 @@ function NotificationsPanelTrigger({
9134
9141
  "aria-expanded": open,
9135
9142
  onClick: () => setOpen(!open),
9136
9143
  className: clsx(
9137
- "focus-visible:focus-indicator h-ctrl-40 w-ctrl-40 relative flex items-center justify-center rounded-lg border transition-colors",
9144
+ // The ping around the count grows to twice its size: clipped to the bell, it never widens
9145
+ // the row that holds it. The focus ring is a shadow, outside the clip.
9146
+ "focus-visible:focus-indicator h-ctrl-40 w-ctrl-40 relative flex items-center justify-center overflow-hidden rounded-lg border transition-colors",
9138
9147
  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
9148
  className
9140
9149
  ),
@@ -13719,21 +13728,30 @@ var DatePicker = (props) => {
13719
13728
  ]
13720
13729
  }
13721
13730
  ),
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"
13731
+ isRange ? (
13732
+ // Two dates side by side don't fit a phone: the end date goes under the start date.
13733
+ /* @__PURE__ */ jsxs(
13734
+ "div",
13735
+ {
13736
+ className: clsx("flex flex-wrap items-center gap-2", !fullWidth && "w-fit max-w-full"),
13737
+ children: [
13738
+ renderTrigger(
13739
+ fieldId,
13740
+ "from",
13741
+ selectedRange.from,
13742
+ props.fromPlaceholder ?? "Start date"
13743
+ ),
13744
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 dark:text-gray-400", children: "to" }),
13745
+ renderTrigger(
13746
+ void 0,
13747
+ "to",
13748
+ selectedRange.to,
13749
+ props.toPlaceholder ?? "End date"
13750
+ )
13751
+ ]
13752
+ }
13735
13753
  )
13736
- ] }) : renderTrigger(
13754
+ ) : renderTrigger(
13737
13755
  fieldId,
13738
13756
  "from",
13739
13757
  selectedSingle,
@@ -13988,7 +14006,7 @@ var OtpInput = ({
13988
14006
  if (finalValue.length === length) onComplete?.(finalValue);
13989
14007
  };
13990
14008
  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) => {
14009
+ /* @__PURE__ */ jsx("div", { dir: "ltr", className: "flex min-w-0 items-center gap-2", children: Array.from({ length }).map((_, i) => {
13992
14010
  const cellChar = value[i] ?? "";
13993
14011
  const display = mask && cellChar ? "\u2022" : cellChar;
13994
14012
  return /* @__PURE__ */ jsx(
@@ -14011,7 +14029,8 @@ var OtpInput = ({
14011
14029
  onPaste: handlePaste(i),
14012
14030
  onFocus: (e) => e.target.select(),
14013
14031
  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",
14032
+ // 2.5rem wide, narrower when the row doesn't fit (eight cells on a phone).
14033
+ "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
14034
  fieldStateClass({ invalid: error, success })
14016
14035
  )
14017
14036
  },
@@ -16053,7 +16072,8 @@ function Item4({
16053
16072
  "dd",
16054
16073
  {
16055
16074
  className: clsx(
16056
- "text-sm font-medium text-[var(--color-text-primary)]",
16075
+ // A value with no space in it (an e-mail) breaks inside the row.
16076
+ "min-w-0 text-sm font-medium break-words text-[var(--color-text-primary)]",
16057
16077
  mono && "font-mono text-xs"
16058
16078
  ),
16059
16079
  children: isolate(children)
@@ -16075,7 +16095,7 @@ function Item4({
16075
16095
  "dd",
16076
16096
  {
16077
16097
  className: clsx(
16078
- "mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300",
16098
+ "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
16099
  mono && "font-mono"
16080
16100
  ),
16081
16101
  children: isolate(children)
@@ -16172,7 +16192,7 @@ var KpiCard = ({
16172
16192
  );
16173
16193
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
16174
16194
  /* @__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 }) }),
16195
+ /* @__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
16196
  Icon2 && /* @__PURE__ */ jsx(
16177
16197
  "span",
16178
16198
  {
@@ -16195,7 +16215,9 @@ var KpiCard = ({
16195
16215
  "span",
16196
16216
  {
16197
16217
  className: clsx(
16198
- "block text-3xl font-bold tracking-tight tabular-nums",
16218
+ // A figure with no break in it (`€12,418,906.40`) wraps in a narrow card instead of
16219
+ // running out of it: cut, it would read as another number.
16220
+ "block text-3xl font-bold tracking-tight break-words tabular-nums",
16199
16221
  intent === "neutral" ? "text-gray-900 dark:text-white" : INTENT_STYLE[intent].text
16200
16222
  ),
16201
16223
  children: withExact ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -16680,7 +16702,8 @@ var MiniCalendar = ({
16680
16702
  "aria-current": isToday ? "date" : void 0,
16681
16703
  className: clsx(
16682
16704
  // 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",
16705
+ // At least 28px wide: a calendar as wide as its content had columns as narrow as the numbers.
16706
+ "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
16707
  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
16708
  ),
16686
16709
  children: [
@@ -18489,12 +18512,13 @@ var DataTableBulkActions = ({
18489
18512
  icon: item.icon,
18490
18513
  disabled: item.disabled,
18491
18514
  onClick: () => item.onClick(selectedRows),
18515
+ className: "shrink-0",
18492
18516
  children: item.label
18493
18517
  },
18494
18518
  item.key
18495
18519
  );
18496
18520
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18497
- /* @__PURE__ */ jsxs("div", { className: clsx("flex items-center gap-2", phoneIcons && "max-sm:hidden"), children: [
18521
+ /* @__PURE__ */ jsxs("div", { className: clsx("flex flex-wrap items-center gap-2", phoneIcons && "max-sm:hidden"), children: [
18498
18522
  button(first, true),
18499
18523
  rest.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
18500
18524
  /* @__PURE__ */ jsx("div", { className: "hidden items-center gap-2 @min-[1152px]:flex", children: rest.map((item) => button(item, false)) }),
@@ -18894,6 +18918,43 @@ var PageSizeSelect = ({ value, options, onChange }) => {
18894
18918
  ] });
18895
18919
  };
18896
18920
 
18921
+ // src/table/columnWidths.ts
18922
+ var DEFAULT_COLUMN_MIN_WIDTH = "8rem";
18923
+ var NUMBER = String.raw`(?:\d+(?:\.\d+)?|\.\d+)`;
18924
+ var LENGTH = new RegExp(`^${NUMBER}(?:px|rem|em|ch)$`);
18925
+ var PERCENT2 = new RegExp(`^(${NUMBER})%$`);
18926
+ var ratio = (n) => Number(n.toFixed(4));
18927
+ var tableMinWidth = (columns, fixed, takesTheRest) => {
18928
+ if (columns.length === 0) return void 0;
18929
+ const lengths = [...fixed];
18930
+ const autoMins = [];
18931
+ const percents = [];
18932
+ columns.forEach((c, i) => {
18933
+ const width = c.width?.trim() ?? "";
18934
+ const min = c.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;
18935
+ const share = PERCENT2.exec(width);
18936
+ if (i === takesTheRest) autoMins.push(LENGTH.test(width) ? width : min);
18937
+ else if (LENGTH.test(width)) lengths.push(width);
18938
+ else if (share) percents.push({ share: Number(share[1]) / 100, min });
18939
+ else autoMins.push(min);
18940
+ });
18941
+ const bounds = percents.map((p) => `calc(${p.min} / ${ratio(p.share)})`);
18942
+ const left = ratio(1 - percents.reduce((sum, p) => sum + p.share, 0));
18943
+ const widest = [...new Set(autoMins)];
18944
+ const parts = [
18945
+ ...lengths,
18946
+ ...autoMins.length > 0 ? [`${autoMins.length} * ${widest.length === 1 ? widest[0] : `max(${widest.join(", ")})`}`] : []
18947
+ ];
18948
+ if (parts.length > 0 && left > 0) {
18949
+ bounds.push(
18950
+ left === 1 ? `calc(${parts.join(" + ")})` : `calc((${parts.join(" + ")}) / ${left})`
18951
+ );
18952
+ }
18953
+ const distinct = [...new Set(bounds)];
18954
+ if (distinct.length === 0) return void 0;
18955
+ return distinct.length === 1 ? distinct[0] : `max(${distinct.join(", ")})`;
18956
+ };
18957
+
18897
18958
  // src/table/pipeline.ts
18898
18959
  var filtersToRecord = (filters) => {
18899
18960
  const out = {};
@@ -19783,12 +19844,15 @@ var DataTable = ({
19783
19844
  [filteredRows, columns, manual, sortKey, sortDir]
19784
19845
  );
19785
19846
  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;
19847
+ const tableMinimum = tableMinWidth(
19848
+ columns,
19849
+ [
19850
+ expandable && EXPAND_COLUMN_WIDTH,
19851
+ selectable && SELECT_COLUMN_WIDTH,
19852
+ actionColumn && (rowEditing ? EDIT_ACTION_COLUMN_WIDTH : ACTION_COLUMN_WIDTH)
19853
+ ].filter((w) => Boolean(w)),
19854
+ firstColumnTakesTheRest ? 0 : void 0
19855
+ );
19792
19856
  const mobileSortable = columns.some((c) => c.sortable);
19793
19857
  const hasRows = sortedRows.length > 0;
19794
19858
  const showSkeleton = loading && !hasRows;
@@ -20253,7 +20317,11 @@ var DataTable = ({
20253
20317
  /* @__PURE__ */ jsxs(
20254
20318
  "div",
20255
20319
  {
20256
- className: clsx("flex min-w-0 items-center gap-3", mobileCards && "max-sm:flex-1"),
20320
+ className: clsx(
20321
+ // The actions go to the next line when the count leaves them too little room.
20322
+ "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2",
20323
+ mobileCards && "max-sm:flex-1"
20324
+ ),
20257
20325
  children: [
20258
20326
  /* @__PURE__ */ jsx("span", { className: "text-brand-700 dark:text-brand-300 text-sm font-medium whitespace-nowrap", children: /* @__PURE__ */ jsxs("bdi", { children: [
20259
20327
  selection.size,
@@ -20268,7 +20336,7 @@ var DataTable = ({
20268
20336
  children: "Clear"
20269
20337
  }
20270
20338
  ),
20271
- (bulkActionItems || bulkActions) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 ps-1", children: [
20339
+ (bulkActionItems || bulkActions) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-auto flex-wrap items-center gap-2 ps-1", children: [
20272
20340
  bulkActionItems && /* @__PURE__ */ jsx(
20273
20341
  DataTableBulkActions,
20274
20342
  {
@@ -20405,7 +20473,7 @@ var DataTable = ({
20405
20473
  "aria-labelledby": ariaLabelledBy,
20406
20474
  "aria-busy": loading || void 0,
20407
20475
  "aria-rowcount": windowed ? pageRows.length + 1 : void 0,
20408
- style: statedMinWidth ? { minWidth: statedMinWidth } : void 0,
20476
+ style: tableMinimum ? { minWidth: tableMinimum } : void 0,
20409
20477
  className: "w-full table-fixed",
20410
20478
  children: [
20411
20479
  /* @__PURE__ */ jsxs("colgroup", { children: [
@@ -21356,7 +21424,7 @@ var SocialAuthButtons = ({
21356
21424
  onClick: () => onProviderClick(provider),
21357
21425
  disabled: isDisabled,
21358
21426
  "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",
21427
+ 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
21428
  children: [
21361
21429
  isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Icon2, {}),
21362
21430
  /* @__PURE__ */ jsx("span", { className: "truncate", children: label })