@tailor-platform/app-shell 1.11.0 → 1.12.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.
@@ -21,12 +21,15 @@ import { JSX } from 'react/jsx-runtime';
21
21
  import { Link } from 'react-router';
22
22
  import { LoaderFunctionArgs } from 'react-router';
23
23
  import { Menu as Menu_2 } from '@base-ui/react/menu';
24
+ import { Navigate } from 'react-router';
24
25
  import { parseAbsolute } from '@internationalized/date';
25
26
  import { parseDate } from '@internationalized/date';
26
27
  import { parseDateTime } from '@internationalized/date';
27
28
  import { parseZonedDateTime } from '@internationalized/date';
28
29
  import * as React_2 from 'react';
30
+ import { ReactElement } from 'react';
29
31
  import { ReactNode } from 'react';
32
+ import { Ref } from 'react';
30
33
  import { RefObject } from 'react';
31
34
  import { Select as Select_2 } from '@base-ui/react/select';
32
35
  import { StandardSchemaV1 } from '@standard-schema/spec';
@@ -2210,6 +2213,14 @@ export declare interface DataTableContextValue<TRow extends Record<string, unkno
2210
2213
  clearSelection?: () => void;
2211
2214
  isAllSelected: boolean;
2212
2215
  isIndeterminate: boolean;
2216
+ /** Ids of the currently expanded rows. */
2217
+ expandedIds?: string[];
2218
+ /** Whether `row` is currently expanded. Always `false` for rows without an `id`. */
2219
+ isRowExpanded?: (row: TRow) => boolean;
2220
+ toggleRowExpansion?: (row: TRow) => void;
2221
+ collapseAllRows?: () => void;
2222
+ /** Expansion config. Its presence enables the expand column and detail rows. */
2223
+ rowExpansion?: RowExpansionOptions<TRow>;
2213
2224
  }
2214
2225
 
2215
2226
  /**
@@ -2309,10 +2320,30 @@ declare namespace DataTableToolbar {
2309
2320
  var displayName: string;
2310
2321
  }
2311
2322
 
2312
- declare interface DateBehaviorProps<T extends DateValue> {
2323
+ /** Options for `type: "date"` cells. */
2324
+ declare interface DateCellOptions {
2325
+ /**
2326
+ * Format style. `"short"` → `Apr 9, 2026`; `"long"` → `April 9, 2026`;
2327
+ * `"datetime"` → `Apr 9, 2026, 3:45 PM`. Default: `"short"`.
2328
+ */
2329
+ dateFormat?: "short" | "long" | "datetime";
2330
+ /** BCP 47 locale tag. Defaults to the runtime locale. */
2331
+ locale?: string;
2332
+ }
2333
+
2334
+ /**
2335
+ * Public date controls.
2336
+ *
2337
+ * These are standalone composite widgets built on plain accessible markup and a
2338
+ * proxy input for form value / native validity. Inside `Field.Root`, they also
2339
+ * register with Base UI's label, description, and validation plumbing. All of
2340
+ * that coupling lives in `useDateFieldFieldBridge` (see `./use-date-field-bridge`).
2341
+ */
2342
+ declare interface DateControlProps<T extends DateValue> {
2313
2343
  value?: T | null;
2314
2344
  defaultValue?: T | null;
2315
2345
  onChange?: (value: T | null) => void;
2346
+ onBlur?: () => void;
2316
2347
  granularity?: Granularity;
2317
2348
  minValue?: DateValue;
2318
2349
  maxValue?: DateValue;
@@ -2323,52 +2354,32 @@ declare interface DateBehaviorProps<T extends DateValue> {
2323
2354
  isInvalid?: boolean;
2324
2355
  autoFocus?: boolean;
2325
2356
  hourCycle?: HourCycle;
2326
- hideTimeZone?: boolean;
2327
2357
  placeholderValue?: DateValue;
2328
- /**
2329
- * First day of the week (0 = Sunday … 6 = Saturday); defaults to the locale.
2330
- * Only affects the `w`/`k` (start/end of week) keyboard shortcuts here.
2331
- */
2332
2358
  firstDayOfWeek?: FirstDayOfWeek;
2333
2359
  name?: string;
2334
- /** Accessible name when no visible `label` is provided (e.g. a compact filter input). */
2360
+ className?: string;
2361
+ id?: string;
2362
+ /** Accessible name when there is no visible label. */
2335
2363
  "aria-label"?: string;
2364
+ /** ID of the element(s) that label the control. */
2365
+ "aria-labelledby"?: string;
2366
+ /** ID of the element(s) that describe the control. */
2367
+ "aria-describedby"?: string;
2336
2368
  /** BCP-47 locale override; defaults to the AppShell formatting locale. */
2337
2369
  locale?: string;
2338
2370
  }
2339
2371
 
2340
- /** Options for `type: "date"` cells. */
2341
- declare interface DateCellOptions {
2342
- /**
2343
- * Format style. `"short"` → `Apr 9, 2026`; `"long"` → `April 9, 2026`;
2344
- * `"datetime"` → `Apr 9, 2026, 3:45 PM`. Default: `"short"`.
2345
- */
2346
- dateFormat?: "short" | "long" | "datetime";
2347
- /** BCP 47 locale tag. Defaults to the runtime locale. */
2348
- locale?: string;
2349
- }
2350
-
2351
2372
  /**
2352
2373
  * A segmented date/time input field with no popover.
2353
2374
  *
2354
- * @example
2355
- * ```tsx
2356
- * import { DateField } from "@tailor-platform/app-shell";
2357
- *
2358
- * <DateField label="Invoice date" />
2359
- * <DateField label="Created at" granularity="minute" />
2360
- * ```
2375
+ * Compose with `Field.Root` for label / description / error presentation, or
2376
+ * provide standalone ARIA wiring yourself.
2361
2377
  */
2362
- export declare function DateField<T extends DateValue = DateValue>({ label, description, errorMessage, className, locale: localeProp, value, defaultValue, onChange, granularity, hourCycle, placeholderValue, minValue, maxValue, isDateUnavailable, isDisabled, isReadOnly, isInvalid, isRequired, autoFocus, firstDayOfWeek, name, "aria-label": ariaLabel, }: DateFieldProps<T>): JSX.Element;
2363
-
2364
- declare interface DateFieldMetaProps {
2365
- label?: LocalizedString;
2366
- description?: LocalizedString;
2367
- errorMessage?: LocalizedString;
2368
- className?: string;
2369
- }
2378
+ export declare const DateField: <T extends DateValue = DateValue>(props: DateFieldProps<T> & {
2379
+ ref?: Ref<HTMLInputElement>;
2380
+ }) => ReactElement;
2370
2381
 
2371
- export declare type DateFieldProps<T extends DateValue = DateValue> = DateFieldMetaProps & DateBehaviorProps<T>;
2382
+ export declare type DateFieldProps<T extends DateValue = DateValue> = DateControlProps<T>;
2372
2383
 
2373
2384
  /**
2374
2385
  * Date format options
@@ -2378,21 +2389,92 @@ declare type DateFormat = "short" | "medium" | "long" | "relative";
2378
2389
  /**
2379
2390
  * A date/time input with a popover calendar.
2380
2391
  *
2381
- * Value type is driven by `granularity`:
2382
- * - `"day"` (default) → `CalendarDate`
2383
- * - `"hour" | "minute" | "second"` → `CalendarDateTime` (or `ZonedDateTime` when a `timeZone` is set)
2384
- *
2385
- * @example
2386
- * ```tsx
2387
- * import { DatePicker, today, getLocalTimeZone, type CalendarDate } from "@tailor-platform/app-shell";
2392
+ * Compose with `Field.Root` for label / description / error presentation, or
2393
+ * provide standalone ARIA wiring yourself.
2394
+ */
2395
+ export declare const DatePicker: <T extends DateValue = DateValue>(props: DatePickerProps<T> & {
2396
+ ref?: Ref<HTMLInputElement>;
2397
+ }) => ReactElement;
2398
+
2399
+ export declare type DatePickerProps<T extends DateValue = DateValue> = DateControlProps<T> & {
2400
+ /** IANA timezone; defaults to the AppShell `timeZone`. */
2401
+ timeZone?: string;
2402
+ };
2403
+
2404
+ /**
2405
+ * Range calendar state — the logic react-aria's `useRangeCalendarState` would
2406
+ * otherwise provide, on top of the shared `useCalendarGridState` engine.
2388
2407
  *
2389
- * const [date, setDate] = useState<CalendarDate | null>(null);
2390
- * <DatePicker label="Ship date" value={date} onChange={setDate} />
2391
- * ```
2408
+ * Selection is the react-aria two-click model: the first confirmed day sets an
2409
+ * *anchor*; while the anchor is set the highlighted range live-extends to the
2410
+ * focused day (keyboard nav and pointer hover both move it); the second
2411
+ * confirmed day commits `{ start, end }` in one `onChange`. Picking a day
2412
+ * before the anchor swaps the endpoints, so a committed range is always
2413
+ * ordered — a reversed range can only be produced by typing into the field.
2392
2414
  */
2393
- export declare function DatePicker<T extends DateValue = DateValue>({ label, description, errorMessage, className, locale: localeProp, timeZone: timeZoneProp, value, defaultValue, onChange, granularity, hourCycle, placeholderValue, minValue, maxValue, isDateUnavailable, isDisabled, isReadOnly, isInvalid, isRequired, autoFocus, firstDayOfWeek, name, "aria-label": ariaLabel, }: DatePickerProps<T>): JSX.Element;
2415
+ /** An inclusive date range. `start` and `end` may be the same day. */
2416
+ export declare interface DateRange<T extends DateValue = DateValue> {
2417
+ start: T;
2418
+ end: T;
2419
+ }
2394
2420
 
2395
- export declare type DatePickerProps<T extends DateValue = DateValue> = DateFieldProps<T> & {
2421
+ export declare const DateRangePicker: <T extends DateValue = DateValue>(props: DateRangePickerProps<T> & {
2422
+ ref?: Ref<HTMLInputElement>;
2423
+ }) => ReactElement;
2424
+
2425
+ /**
2426
+ * Public date-range control — the @internationalized/date + Base UI
2427
+ * implementation, mirroring react-aria's `DateRangePicker` interaction spec.
2428
+ *
2429
+ * Like `DateField`/`DatePicker`, it is a standalone composite widget that also
2430
+ * composes inside `Field.Root` (label / description / error / form validation).
2431
+ * A single combined proxy input is registered as the one Field control (its
2432
+ * value is empty until BOTH ends are complete, so `required` blocks a partial
2433
+ * range); two optional plain hidden inputs (`startName` / `endName`) provide
2434
+ * classic form-POST parity. A range typed in reverse is flagged invalid rather
2435
+ * than swapped — only the calendar normalizes endpoint order.
2436
+ */
2437
+ export declare type DateRangePickerProps<T extends DateValue = DateValue> = {
2438
+ value?: DateRange<T> | null;
2439
+ defaultValue?: DateRange<T> | null;
2440
+ /**
2441
+ * Fired with a complete `{ start, end }` range, or `null` when the range is
2442
+ * cleared or becomes incomplete. Never fired for half-typed intermediates.
2443
+ */
2444
+ onChange?: (value: DateRange<T> | null) => void;
2445
+ onBlur?: () => void;
2446
+ granularity?: Granularity;
2447
+ minValue?: DateValue;
2448
+ maxValue?: DateValue;
2449
+ isDateUnavailable?: (date: DateValue) => boolean;
2450
+ isDisabled?: boolean;
2451
+ isReadOnly?: boolean;
2452
+ isRequired?: boolean;
2453
+ isInvalid?: boolean;
2454
+ autoFocus?: boolean;
2455
+ hourCycle?: HourCycle;
2456
+ placeholderValue?: DateValue;
2457
+ firstDayOfWeek?: FirstDayOfWeek;
2458
+ /**
2459
+ * Name for the combined hidden proxy input — a single `name=start/end` field
2460
+ * for native form POST, mirroring `DateField` / `DatePicker`. Inside
2461
+ * `Field.Root`, the Field's `name` takes precedence. For two separate fields,
2462
+ * use `startName` / `endName` instead.
2463
+ */
2464
+ name?: string;
2465
+ /** Names for the two plain hidden start/end inputs (classic form POST). */
2466
+ startName?: string;
2467
+ endName?: string;
2468
+ className?: string;
2469
+ id?: string;
2470
+ /** Accessible name when there is no visible label. */
2471
+ "aria-label"?: string;
2472
+ /** ID of the element(s) that label the control. */
2473
+ "aria-labelledby"?: string;
2474
+ /** ID of the element(s) that describe the control. */
2475
+ "aria-describedby"?: string;
2476
+ /** BCP-47 locale override; defaults to the AppShell formatting locale. */
2477
+ locale?: string;
2396
2478
  /** IANA timezone; defaults to the AppShell `timeZone`. */
2397
2479
  timeZone?: string;
2398
2480
  };
@@ -2743,6 +2825,8 @@ declare namespace Description_4 {
2743
2825
  * Renders structured key-value information with automatic layout.
2744
2826
  * Use { type: "divider" } in the fields array to add dividers between sections.
2745
2827
  *
2828
+ * Pass `render` on a field to draw it yourself when no built-in `type` fits.
2829
+ *
2746
2830
  * @example
2747
2831
  * ```tsx
2748
2832
  * <DescriptionCard
@@ -2753,22 +2837,26 @@ declare namespace Description_4 {
2753
2837
  * { key: "orderNumber", label: "Order #", meta: { copyable: true } },
2754
2838
  * { type: "divider" },
2755
2839
  * { key: "total", label: "Total", type: "money" },
2840
+ * { key: "deliveryBreakdown", label: "Delivery", render: (d) => <PieChart data={d.deliveryBreakdown} /> },
2756
2841
  * ]}
2757
2842
  * />
2758
2843
  * ```
2759
2844
  */
2760
- export declare function DescriptionCard({ data, title, fields, columns, className, style, headerAction, }: DescriptionCardProps): JSX.Element;
2845
+ export declare function DescriptionCard<TData extends object = Record<string, unknown>>({ data, title, fields, columns, className, style, headerAction, }: DescriptionCardProps<TData>): JSX.Element;
2761
2846
 
2762
2847
  /**
2763
2848
  * Props for the DescriptionCard component
2849
+ *
2850
+ * `TData` is inferred from `data`; constrained to `object` rather than
2851
+ * `Record<string, unknown>` so interfaces are accepted.
2764
2852
  */
2765
- export declare interface DescriptionCardProps {
2853
+ export declare interface DescriptionCardProps<TData extends object = Record<string, unknown>> {
2766
2854
  /** Raw backend data object */
2767
- data: Record<string, unknown>;
2855
+ data: TData;
2768
2856
  /** Card title */
2769
2857
  title: string;
2770
2858
  /** Ordered list of field definitions (use { type: "divider" } for dividers) */
2771
- fields: FieldConfig[];
2859
+ fields: FieldConfig<TData>[];
2772
2860
  /** Number of columns on desktop (3 or 4) */
2773
2861
  columns?: Columns;
2774
2862
  /** Additional CSS classes */
@@ -3030,12 +3118,12 @@ export declare const Field: {
3030
3118
  /**
3031
3119
  * A field configuration - either a divider or a field definition
3032
3120
  */
3033
- declare type FieldConfig = FieldDivider | FieldDefinition;
3121
+ declare type FieldConfig<TData extends object = Record<string, unknown>> = FieldDivider | FieldDefinition<TData>;
3034
3122
 
3035
3123
  /**
3036
3124
  * Field definition - renders a key-value pair
3037
3125
  */
3038
- declare interface FieldDefinition {
3126
+ declare interface FieldDefinition<TData extends object = Record<string, unknown>> {
3039
3127
  /** Field type determines rendering (defaults to "text") */
3040
3128
  type?: FieldType_2;
3041
3129
  /** Path to the value in the data object (supports dot notation) */
@@ -3046,6 +3134,12 @@ declare interface FieldDefinition {
3046
3134
  meta?: FieldMeta;
3047
3135
  /** Behavior when value is empty (defaults to "dash") */
3048
3136
  emptyBehavior?: EmptyBehavior;
3137
+ /**
3138
+ * Draws the field from `data` instead of using `type`. Wins over `type` and
3139
+ * replaces the built-in output, so `meta` is not applied. Still runs when the
3140
+ * value at `key` is empty; `emptyBehavior: "hide"` is checked first.
3141
+ */
3142
+ render?: FieldRender<TData>;
3049
3143
  }
3050
3144
 
3051
3145
  /**
@@ -3108,6 +3202,9 @@ export declare interface FieldMetadata {
3108
3202
  };
3109
3203
  }
3110
3204
 
3205
+ /** Renders a field from the whole `data` object, like `render` on DataTable's `Column`. */
3206
+ declare type FieldRender<TData extends object = Record<string, unknown>> = (data: TData) => ReactNode;
3207
+
3111
3208
  declare type FieldRootProps = Pick<React_2.ComponentProps<typeof Field_2.Root>, "name" | "disabled" | "validate" | "validationMode" | "validationDebounceTime" | "className" | "style"> & {
3112
3209
  children: React_2.ReactNode;
3113
3210
  /** Whether the field has been blurred. Maps to Base UI's `touched`. */
@@ -4031,6 +4128,8 @@ declare interface MoneyCellOptions<TRow extends Record<string, unknown>> {
4031
4128
  locale?: string;
4032
4129
  }
4033
4130
 
4131
+ export { Navigate }
4132
+
4034
4133
  /**
4035
4134
  * Extract the node type from a cursor connection result.
4036
4135
  */
@@ -4225,6 +4324,48 @@ declare namespace RadioItemIndicator {
4225
4324
  var displayName: string;
4226
4325
  }
4227
4326
 
4327
+ /**
4328
+ * A standalone inline range calendar. The first click sets one end of the
4329
+ * range, the highlight follows the pointer (or arrow keys), and the second
4330
+ * click completes it — picking a day before the first swaps the endpoints.
4331
+ *
4332
+ * @example
4333
+ * ```tsx
4334
+ * import { RangeCalendar, type DateRange } from "@tailor-platform/app-shell";
4335
+ *
4336
+ * const [range, setRange] = useState<DateRange | null>(null);
4337
+ * <RangeCalendar aria-label="Stay dates" value={range} onChange={setRange} />
4338
+ * ```
4339
+ */
4340
+ export declare function RangeCalendar<T extends DateValue = DateValue>({ value, defaultValue, onChange, minValue, maxValue, isDateUnavailable, isDisabled, isReadOnly, focusedValue, defaultFocusedValue, onFocusChange, firstDayOfWeek, timeZone: timeZoneProp, locale: localeProp, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: RangeCalendarProps<T>): JSX.Element;
4341
+
4342
+ /**
4343
+ * Public, closed-API standalone range calendar — the @internationalized/date +
4344
+ * Base UI implementation. Same surface as the react-aria variant; only the
4345
+ * internals differ. Consumers never see Base UI or the calendar engine.
4346
+ */
4347
+ export declare interface RangeCalendarProps<T extends DateValue = DateValue> {
4348
+ value?: DateRange<T> | null;
4349
+ defaultValue?: DateRange<T> | null;
4350
+ /** Fired once per selection, when the second date completes the range. */
4351
+ onChange?: (value: DateRange<T>) => void;
4352
+ minValue?: DateValue;
4353
+ maxValue?: DateValue;
4354
+ isDateUnavailable?: (date: DateValue) => boolean;
4355
+ isDisabled?: boolean;
4356
+ isReadOnly?: boolean;
4357
+ focusedValue?: DateValue;
4358
+ defaultFocusedValue?: DateValue;
4359
+ onFocusChange?: (date: CalendarDate) => void;
4360
+ firstDayOfWeek?: FirstDayOfWeek;
4361
+ "aria-label"?: string;
4362
+ "aria-labelledby"?: string;
4363
+ timeZone?: string;
4364
+ className?: string;
4365
+ /** BCP-47 locale override; defaults to the AppShell formatting locale. */
4366
+ locale?: string;
4367
+ }
4368
+
4228
4369
  /**
4229
4370
  * Redirect to another path.
4230
4371
  *
@@ -4642,6 +4783,54 @@ export declare interface RowAction<TRow extends Record<string, unknown>> {
4642
4783
  onClick: (row: TRow) => void;
4643
4784
  }
4644
4785
 
4786
+ /**
4787
+ * Expandable-row configuration for `useDataTable`.
4788
+ *
4789
+ * The union is what makes an invalid setup unrepresentable: pass `expandedIds`
4790
+ * and you must pass `onChange` with it (controlled), or pass neither and let
4791
+ * the hook own the state. `onChange` alone is still allowed — in uncontrolled
4792
+ * mode it is a notification.
4793
+ */
4794
+ declare type RowExpansionOptions<TRow extends Record<string, unknown>> = {
4795
+ /** Renders the detail panel for an expanded row. */
4796
+ render: (row: TRow) => ReactNode;
4797
+ /**
4798
+ * Decides whether a row can be expanded. Rows returning `false` render an
4799
+ * empty cell in place of the chevron. Defaults to `true` for rows with an
4800
+ * `id`. Gates the panel in both directions: an id in `expandedIds` never
4801
+ * opens a panel for a row this rejects.
4802
+ */
4803
+ canExpand?: (row: TRow) => boolean;
4804
+ /**
4805
+ * The row's record identity — a **bare identifier** such as `"INV-1001"`, not
4806
+ * a sentence. The built-in i18n labels compose it into the accessible names of
4807
+ * the chevron ("Expand row INV-1001") and the panel ("INV-1001 details").
4808
+ * Without it, the generic "Expand row" / "Row details" fallbacks are used.
4809
+ */
4810
+ getLabel?: (row: TRow) => string;
4811
+ } & ({
4812
+ /**
4813
+ * Ids of the expanded rows. Passing this switches expansion to
4814
+ * **controlled** mode: internal state is never written and you update this
4815
+ * array from `onChange`.
4816
+ *
4817
+ * **Batching caveat:** each toggle derives the next array from this
4818
+ * value, so two toggles dispatched before your state commits share a base
4819
+ * and the first is lost. Relevant behind an async store (a debounced URL
4820
+ * sync, `startTransition`) or when looping the toggle over many rows.
4821
+ */
4822
+ expandedIds: string[];
4823
+ /** Called with the full array of expanded ids. Fires once per toggle. */
4824
+ onChange: (ids: string[]) => void;
4825
+ } | {
4826
+ expandedIds?: never;
4827
+ /**
4828
+ * Optional notification in uncontrolled mode, called with the full array
4829
+ * of expanded ids. Fires once per toggle, including under StrictMode.
4830
+ */
4831
+ onChange?: (ids: string[]) => void;
4832
+ });
4833
+
4645
4834
  /**
4646
4835
  * Setter shape compatible with `useSearchParams()`.
4647
4836
  */
@@ -6615,6 +6804,22 @@ export declare type UseDataTableOptions<TRow extends Record<string, unknown>, TF
6615
6804
  * the rows on the **current page**, not all pages.
6616
6805
  */
6617
6806
  onSelectionChange?: (ids: string[]) => void;
6807
+ /**
6808
+ * Expandable detail rows. Providing this enables the whole feature: a chevron
6809
+ * column is added at the left edge (auto-pinned left, after the selection
6810
+ * column) and `render`'s output appears in a full-width row beneath its parent.
6811
+ *
6812
+ * Grouped rather than flat so the parts can't be configured in a broken
6813
+ * combination — a label or predicate without a renderer, or `expandedIds`
6814
+ * without `onChange`, are all compile errors.
6815
+ *
6816
+ * **Requirement:** Each row must have a string or number `id` field.
6817
+ * Expansion is keyed by `id`, so rows without one render no chevron.
6818
+ *
6819
+ * **Note:** Expansion is **not** cleared on page change — ids of rows no
6820
+ * longer on the page simply do not render. Call `collapseAllRows()` to reset.
6821
+ */
6822
+ rowExpansion?: RowExpansionOptions<TRow>;
6618
6823
  /**
6619
6824
  * Sort behaviour configuration.
6620
6825
  *
@@ -6699,6 +6904,16 @@ export declare interface UseDataTableReturn<TRow extends Record<string, unknown>
6699
6904
  clearSelection?: () => void;
6700
6905
  isAllSelected: boolean;
6701
6906
  isIndeterminate: boolean;
6907
+ /** Ids of the currently expanded rows. */
6908
+ expandedIds: string[];
6909
+ /** Whether `row` is currently expanded. Always `false` for rows without an `id`. */
6910
+ isRowExpanded: (row: TRow) => boolean;
6911
+ /** Toggle `row`'s detail panel. Undefined when `rowExpansion` is not provided. */
6912
+ toggleRowExpansion?: (row: TRow) => void;
6913
+ /** Collapse every expanded row. Undefined when `rowExpansion` is not provided. */
6914
+ collapseAllRows?: () => void;
6915
+ /** Expansion config (passthrough for `DataTable.Root`). */
6916
+ rowExpansion?: RowExpansionOptions<TRow>;
6702
6917
  }
6703
6918
 
6704
6919
  /**