@tailor-platform/app-shell 1.7.0 → 1.8.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.
@@ -2,9 +2,12 @@ import { AuthClient } from '@tailor-platform/auth-public-client';
2
2
  import { Autocomplete as Autocomplete_2 } from '@base-ui/react/autocomplete';
3
3
  import { AutocompleteRootProps } from '@base-ui/react/autocomplete';
4
4
  import { Avatar as Avatar_2 } from '@base-ui/react/avatar';
5
+ import { CalendarDate } from '@internationalized/date';
6
+ import { CalendarDateTime } from '@internationalized/date';
5
7
  import { ClassProp } from 'class-variance-authority/types';
6
8
  import { Combobox as Combobox_2 } from '@base-ui/react/combobox';
7
9
  import { CSSProperties } from 'react';
10
+ import { DateValue } from '@internationalized/date';
8
11
  import { Dialog as Dialog_2 } from '@base-ui/react/dialog';
9
12
  import { Drawer } from '@base-ui/react/drawer';
10
13
  import { FC } from 'react';
@@ -12,15 +15,22 @@ import { Field as Field_2 } from '@base-ui/react/field';
12
15
  import { Fieldset as Fieldset_2 } from '@base-ui/react/fieldset';
13
16
  import { Form as Form_2 } from '@base-ui/react/form';
14
17
  import { getFilter } from '@base-ui/react/internals/filter';
18
+ import { getLocalTimeZone } from '@internationalized/date';
15
19
  import { JSX } from 'react/jsx-runtime';
16
20
  import { Link } from 'react-router';
17
21
  import { LoaderFunctionArgs } from 'react-router';
18
22
  import { Menu as Menu_2 } from '@base-ui/react/menu';
23
+ import { parseAbsolute } from '@internationalized/date';
24
+ import { parseDate } from '@internationalized/date';
25
+ import { parseDateTime } from '@internationalized/date';
26
+ import { parseZonedDateTime } from '@internationalized/date';
19
27
  import * as React_2 from 'react';
20
28
  import { ReactNode } from 'react';
29
+ import { RefObject } from 'react';
21
30
  import { Select as Select_2 } from '@base-ui/react/select';
22
31
  import { StandardSchemaV1 } from '@standard-schema/spec';
23
32
  import { Tabs as Tabs_2 } from '@base-ui/react/tabs';
33
+ import { Time } from '@internationalized/date';
24
34
  import { toast } from 'sonner';
25
35
  import { Tooltip as Tooltip_2 } from '@base-ui/react/tooltip';
26
36
  import { useLocation } from 'react-router';
@@ -29,6 +39,7 @@ import { useParams } from 'react-router';
29
39
  import { useRouteError } from 'react-router';
30
40
  import { useSearchParams } from 'react-router';
31
41
  import { VariantProps } from 'class-variance-authority';
42
+ import { ZonedDateTime } from '@internationalized/date';
32
43
 
33
44
  /**
34
45
  * A single action row in the ActionPanel (icon + label, triggered by onClick).
@@ -215,7 +226,6 @@ export declare type AIGatewayChatMessage = {
215
226
  export declare interface AIGatewayChatRequest {
216
227
  model: string;
217
228
  messages: AIGatewayChatMessage[];
218
- stream?: boolean;
219
229
  signal?: AbortSignal;
220
230
  }
221
231
 
@@ -876,6 +886,49 @@ export declare const buttonVariants: (props?: ({
876
886
  size?: "default" | "xs" | "sm" | "lg" | "icon" | null | undefined;
877
887
  } & ClassProp) | undefined) => string;
878
888
 
889
+ /**
890
+ * A standalone inline calendar — no popover, suitable for reporting filters
891
+ * or date selection within a larger layout.
892
+ *
893
+ * @example
894
+ * ```tsx
895
+ * import { Calendar } from "@tailor-platform/app-shell";
896
+ *
897
+ * <Calendar aria-label="Select date" value={value} onChange={setValue} />
898
+ * ```
899
+ */
900
+ export declare function Calendar<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, }: CalendarProps<T>): JSX.Element;
901
+
902
+ export { CalendarDate }
903
+
904
+ export { CalendarDateTime }
905
+
906
+ /**
907
+ * Public, closed-API standalone calendar — the @internationalized/date + Base UI
908
+ * implementation. Same surface as the react-aria variant; only the internals
909
+ * differ. Consumers never see Base UI or the calendar engine.
910
+ */
911
+ export declare interface CalendarProps<T extends DateValue = DateValue> {
912
+ value?: T | null;
913
+ defaultValue?: T | null;
914
+ onChange?: (value: T) => void;
915
+ minValue?: DateValue;
916
+ maxValue?: DateValue;
917
+ isDateUnavailable?: (date: DateValue) => boolean;
918
+ isDisabled?: boolean;
919
+ isReadOnly?: boolean;
920
+ focusedValue?: DateValue;
921
+ defaultFocusedValue?: DateValue;
922
+ onFocusChange?: (date: CalendarDate) => void;
923
+ firstDayOfWeek?: FirstDayOfWeek;
924
+ "aria-label"?: string;
925
+ "aria-labelledby"?: string;
926
+ timeZone?: string;
927
+ className?: string;
928
+ /** BCP-47 locale override; defaults to the AppShell formatting locale. */
929
+ locale?: string;
930
+ }
931
+
879
932
  /**
880
933
  * Internal type for tracking OAuth callback handling status.
881
934
  */
@@ -2091,6 +2144,29 @@ declare namespace DataTableToolbar {
2091
2144
  var displayName: string;
2092
2145
  }
2093
2146
 
2147
+ declare interface DateBehaviorProps<T extends DateValue> {
2148
+ value?: T | null;
2149
+ defaultValue?: T | null;
2150
+ onChange?: (value: T | null) => void;
2151
+ granularity?: Granularity;
2152
+ minValue?: DateValue;
2153
+ maxValue?: DateValue;
2154
+ isDateUnavailable?: (date: DateValue) => boolean;
2155
+ isDisabled?: boolean;
2156
+ isReadOnly?: boolean;
2157
+ isRequired?: boolean;
2158
+ isInvalid?: boolean;
2159
+ autoFocus?: boolean;
2160
+ hourCycle?: HourCycle;
2161
+ hideTimeZone?: boolean;
2162
+ placeholderValue?: DateValue;
2163
+ name?: string;
2164
+ /** Accessible name when no visible `label` is provided (e.g. a compact filter input). */
2165
+ "aria-label"?: string;
2166
+ /** BCP-47 locale override; defaults to the AppShell formatting locale. */
2167
+ locale?: string;
2168
+ }
2169
+
2094
2170
  /** Options for `type: "date"` cells. */
2095
2171
  declare interface DateCellOptions {
2096
2172
  /**
@@ -2102,11 +2178,107 @@ declare interface DateCellOptions {
2102
2178
  locale?: string;
2103
2179
  }
2104
2180
 
2181
+ /**
2182
+ * A segmented date/time input field with no popover.
2183
+ *
2184
+ * @example
2185
+ * ```tsx
2186
+ * import { DateField } from "@tailor-platform/app-shell";
2187
+ *
2188
+ * <DateField label="Invoice date" />
2189
+ * <DateField label="Created at" granularity="minute" />
2190
+ * ```
2191
+ */
2192
+ export declare function DateField<T extends DateValue = DateValue>({ label, description, errorMessage, className, locale: localeProp, value, defaultValue, onChange, granularity, hourCycle, placeholderValue, isDisabled, isReadOnly, isInvalid, isRequired, autoFocus, name, "aria-label": ariaLabel, }: DateFieldProps<T>): JSX.Element;
2193
+
2194
+ declare interface DateFieldMetaProps {
2195
+ label?: LocalizedString;
2196
+ description?: LocalizedString;
2197
+ errorMessage?: LocalizedString;
2198
+ className?: string;
2199
+ }
2200
+
2201
+ export declare type DateFieldProps<T extends DateValue = DateValue> = DateFieldMetaProps & DateBehaviorProps<T>;
2202
+
2105
2203
  /**
2106
2204
  * Date format options
2107
2205
  */
2108
2206
  declare type DateFormat = "short" | "medium" | "long" | "relative";
2109
2207
 
2208
+ /**
2209
+ * A date/time input with a popover calendar.
2210
+ *
2211
+ * Value type is driven by `granularity`:
2212
+ * - `"day"` (default) → `CalendarDate`
2213
+ * - `"hour" | "minute" | "second"` → `CalendarDateTime` (or `ZonedDateTime` when a `timeZone` is set)
2214
+ *
2215
+ * @example
2216
+ * ```tsx
2217
+ * import { DatePicker, today, getLocalTimeZone, type CalendarDate } from "@tailor-platform/app-shell";
2218
+ *
2219
+ * const [date, setDate] = useState<CalendarDate | null>(null);
2220
+ * <DatePicker label="Ship date" value={date} onChange={setDate} />
2221
+ * ```
2222
+ */
2223
+ 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;
2224
+
2225
+ export declare type DatePickerProps<T extends DateValue = DateValue> = DateFieldProps<T> & {
2226
+ firstDayOfWeek?: FirstDayOfWeek;
2227
+ /** IANA timezone; defaults to the AppShell `timeZone`. */
2228
+ timeZone?: string;
2229
+ };
2230
+
2231
+ export { DateValue }
2232
+
2233
+ /**
2234
+ * DefaultHeader — the built-in `SidebarLayout` top bar.
2235
+ *
2236
+ * Renders the sidebar trigger and breadcrumb trail on the left, and the
2237
+ * `actions` cluster (defaulting to the appearance switcher) on the right.
2238
+ *
2239
+ * Use it via the `SidebarLayout.DefaultHeader` namespace to slightly extend the
2240
+ * built-in header without reconstructing it:
2241
+ *
2242
+ * @example
2243
+ * ```tsx
2244
+ * <SidebarLayout
2245
+ * header={
2246
+ * <SidebarLayout.DefaultHeader
2247
+ * actions={[<NotificationBell key="bell" />, <AppearanceSwitcher key="appearance" />]}
2248
+ * />
2249
+ * }
2250
+ * />
2251
+ * ```
2252
+ */
2253
+ export declare const DefaultHeader: {
2254
+ ({ actions }: DefaultHeaderProps): JSX.Element;
2255
+ displayName: string;
2256
+ };
2257
+
2258
+ export declare type DefaultHeaderProps = {
2259
+ /**
2260
+ * The right-hand cluster of the header. Rendered in a horizontal,
2261
+ * vertically-centered row with consistent spacing — you don't wrap it
2262
+ * yourself. Accepts a single node or an array of nodes.
2263
+ *
2264
+ * **`actions` replaces the entire right-hand cluster, including the
2265
+ * appearance switcher.** When omitted, it defaults to just the
2266
+ * `<AppearanceSwitcher />`. If you pass your own actions and still want the
2267
+ * switcher, include `<AppearanceSwitcher />` in the array (it is a public
2268
+ * export). Passing `actions={[]}` renders an empty right side.
2269
+ *
2270
+ * @default [<AppearanceSwitcher />]
2271
+ * @example
2272
+ * ```tsx
2273
+ * // Add a notification bell, keeping the appearance switcher:
2274
+ * <SidebarLayout.DefaultHeader
2275
+ * actions={[<NotificationBell key="bell" />, <AppearanceSwitcher key="appearance" />]}
2276
+ * />
2277
+ * ```
2278
+ */
2279
+ actions?: React.ReactNode | React.ReactNode[];
2280
+ };
2281
+
2110
2282
  /**
2111
2283
  * Default sidebar component with auto-generated navigation items.
2112
2284
  *
@@ -2914,6 +3086,14 @@ declare type FilterInputForFieldType<TFilterConfigType extends FilterConfig["typ
2914
3086
  */
2915
3087
  export declare type FilterOperator = OperatorForFilterType[FilterConfig["type"]];
2916
3088
 
3089
+ /**
3090
+ * Hand-rolled calendar-grid state — the logic react-aria's `useCalendarState`
3091
+ * would otherwise provide. We own: month/week computation (locale + first-day-
3092
+ * of-week aware), selection, roving focus, and full APG keyboard navigation
3093
+ * (arrows, Home/End, PageUp/Down, Shift+PageUp/Down).
3094
+ */
3095
+ declare type FirstDayOfWeek = "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
3096
+
2917
3097
  /** The table footer section (`<tfoot>`). */
2918
3098
  declare function Footer({ className, ...props }: React_2.ComponentProps<"tfoot">): JSX.Element;
2919
3099
 
@@ -3025,6 +3205,20 @@ export declare type FormProps<FormValues extends Record<string, any> = Record<st
3025
3205
 
3026
3206
  declare type FormSubmitEventDetails = NonNullable<React_2.ComponentProps<typeof Form_2>["onFormSubmit"]> extends (values: any, details: infer D) => any ? D : never;
3027
3207
 
3208
+ export { getLocalTimeZone }
3209
+
3210
+ /**
3211
+ * Hand-rolled segmented-date-field state.
3212
+ *
3213
+ * This is the logic react-aria's `useDateFieldState` would otherwise provide.
3214
+ * We own it here: locale-driven segment ordering (via `DateFormatter`), per-
3215
+ * segment spinbutton semantics (increment/decrement with context-aware limits),
3216
+ * numeric type-to-fill with auto-advance, and value-type discrimination by
3217
+ * `granularity`. No `Date` ever escapes — `onChange` emits `@internationalized/date`
3218
+ * values (or `null`).
3219
+ */
3220
+ declare type Granularity = "day" | "hour" | "minute" | "second";
3221
+
3028
3222
  export declare const Grid: React_2.ForwardRefExoticComponent<Omit<GridProps, "ref"> & React_2.RefAttributes<HTMLDivElement>> & {
3029
3223
  Item: React_2.ForwardRefExoticComponent<Omit<GridItemProps, "ref"> & React_2.RefAttributes<HTMLDivElement>>;
3030
3224
  };
@@ -3237,6 +3431,8 @@ declare type HeadProps = React_2.ComponentProps<"th"> & {
3237
3431
  */
3238
3432
  export declare const hidden: () => GuardResult;
3239
3433
 
3434
+ declare type HourCycle = 12 | 24;
3435
+
3240
3436
  export declare type I18nLabels<Def extends Record<string, LabelValue> = Record<string, LabelValue>, L extends string = never> = {
3241
3437
  en: Def;
3242
3438
  } & {
@@ -3388,7 +3584,7 @@ declare type LabelValue = string | ((props: any) => string);
3388
3584
  * </Layout>
3389
3585
  * ```
3390
3586
  */
3391
- export declare function Layout({ columns, className, style, gap, title, actions, children }: LayoutProps): JSX.Element;
3587
+ export declare function Layout({ columns, className, style, gap, title, actions, fill, children, }: LayoutProps): JSX.Element;
3392
3588
 
3393
3589
  export declare namespace Layout {
3394
3590
  var Column: React_2.ForwardRefExoticComponent<ColumnProps & React_2.RefAttributes<HTMLDivElement>>;
@@ -3439,6 +3635,24 @@ export declare interface LayoutProps {
3439
3635
  * @deprecated Use `<Layout.Header actions={...}>` instead.
3440
3636
  */
3441
3637
  actions?: ReactNode[];
3638
+ /**
3639
+ * Fill the available height instead of growing with content.
3640
+ *
3641
+ * When set, the layout stretches to the height of its container
3642
+ * (`flex-1 min-h-0`) and bounds its column row (`minmax(0, 1fr)`), so
3643
+ * children such as `DataTable` can scroll internally while the
3644
+ * `Layout.Header` stays pinned. Without it, the layout grows naturally
3645
+ * and the surrounding content area scrolls.
3646
+ *
3647
+ * Intended for single-row (one `Layout.Column` per breakpoint row) pages;
3648
+ * on stacked mobile layouts with multiple columns the content area
3649
+ * scrolls as usual.
3650
+ *
3651
+ * A `fill` layout also renders a `data-layout-fill` attribute on its root,
3652
+ * which the AppShell content area targets via `:has([data-layout-fill])` to
3653
+ * disable its own scrolling (the fill layout bounds everything internally).
3654
+ */
3655
+ fill?: boolean;
3442
3656
  /** Child elements - Layout.Header and/or Layout.Column components */
3443
3657
  children: ReactNode;
3444
3658
  }
@@ -3740,6 +3954,12 @@ declare namespace Panel {
3740
3954
  var displayName: string;
3741
3955
  }
3742
3956
 
3957
+ export { parseAbsolute }
3958
+
3959
+ export { parseDate }
3960
+
3961
+ export { parseDateTime }
3962
+
3743
3963
  /** The row data passed to `onValidate`, after transforms have been applied. */
3744
3964
  export declare type ParsedRow = {
3745
3965
  /** 0-based row index, stable across edits. */
@@ -3748,6 +3968,8 @@ export declare type ParsedRow = {
3748
3968
  data: Record<string, unknown>;
3749
3969
  };
3750
3970
 
3971
+ export { parseZonedDateTime }
3972
+
3751
3973
  /**
3752
3974
  * Allow access to the route. Continue to next guard or render component.
3753
3975
  *
@@ -3916,7 +4138,7 @@ declare namespace Root_10 {
3916
4138
  * </Tabs.Root>
3917
4139
  * ```
3918
4140
  */
3919
- declare function Root_11({ className, children, variant, ...props }: RootProps_3): JSX.Element;
4141
+ declare function Root_11({ className, children, variant, size, ...props }: RootProps_3): JSX.Element;
3920
4142
 
3921
4143
  declare namespace Root_11 {
3922
4144
  var displayName: string;
@@ -4116,6 +4338,10 @@ declare type RootConfiguration = {
4116
4338
  basePath?: string;
4117
4339
  errorBoundary: ErrorBoundaryComponent;
4118
4340
  locale: string;
4341
+ /** Full BCP-47 tag (e.g. "en-GB") for Intl / date formatting. Falls back to `locale`. */
4342
+ resolvedLocale?: string;
4343
+ /** IANA timezone (e.g. "America/Los_Angeles"). Used by date/time components. */
4344
+ timeZone?: string;
4119
4345
  };
4120
4346
 
4121
4347
  declare type RootProps = React_2.ComponentProps<"div"> & VariantProps<typeof alertVariants> & {
@@ -4133,6 +4359,12 @@ declare type RootProps_3 = Pick<React_2.ComponentProps<typeof Tabs_2.Root>, "def
4133
4359
  children: React_2.ReactNode;
4134
4360
  className?: string;
4135
4361
  variant?: TabsVariant;
4362
+ /**
4363
+ * Minimum size of the tabs, mirroring Button's height tiers. Only affects the
4364
+ * `capsule` variant, keeping its track aligned with a sibling Button and its
4365
+ * icon-only tabs square.
4366
+ */
4367
+ size?: TabsSize;
4136
4368
  };
4137
4369
 
4138
4370
  /**
@@ -4470,6 +4702,13 @@ declare type SharedAppShellProps = React.PropsWithChildren<{
4470
4702
  * No browser locale information avilable, "en" used as default.
4471
4703
  */
4472
4704
  locale?: string;
4705
+ /**
4706
+ * IANA timezone (e.g. "America/Los_Angeles") used by date/time components
4707
+ * as the default for resolving "today" and for `ZonedDateTime` values.
4708
+ *
4709
+ * If not provided, date/time components fall back to the user's local timezone.
4710
+ */
4711
+ timeZone?: string;
4473
4712
  /**
4474
4713
  * Global error boundary component applied to all routes.
4475
4714
  *
@@ -4728,7 +4967,15 @@ declare type SidebarItemRenderProps = {
4728
4967
  isActive: boolean;
4729
4968
  };
4730
4969
 
4731
- export declare const SidebarLayout: (props: SidebarLayoutProps) => JSX.Element;
4970
+ export declare function SidebarLayout(props: SidebarLayoutProps): JSX.Element;
4971
+
4972
+ export declare namespace SidebarLayout {
4973
+ var DefaultSidebar: (props: DefaultSidebarProps) => JSX.Element;
4974
+ var DefaultHeader: {
4975
+ ({ actions }: DefaultHeaderProps): JSX.Element;
4976
+ displayName: string;
4977
+ };
4978
+ }
4732
4979
 
4733
4980
  export declare type SidebarLayoutProps = {
4734
4981
  /**
@@ -4751,15 +4998,39 @@ export declare type SidebarLayoutProps = {
4751
4998
  Outlet: () => React.ReactNode;
4752
4999
  }) => React.ReactNode;
4753
5000
  /**
4754
- * Custom sidebar content.
5001
+ * Custom sidebar content. Replaces the whole sidebar region.
4755
5002
  *
4756
- * @default DefaultSidebar
5003
+ * @default <SidebarLayout.DefaultSidebar />
4757
5004
  * @example
4758
5005
  * ```tsx
4759
5006
  * <SidebarLayout sidebar={<MyCustomSidebar />} />
4760
5007
  * ```
4761
5008
  */
4762
5009
  sidebar?: React.ReactNode;
5010
+ /**
5011
+ * Custom header content. Replaces the whole top-bar region.
5012
+ *
5013
+ * Omit it for the built-in header. To slightly extend the built-in header
5014
+ * (e.g. add a notification bell), pass `<SidebarLayout.DefaultHeader />` with
5015
+ * its `actions` slot rather than reconstructing the header from scratch.
5016
+ *
5017
+ * @default <SidebarLayout.DefaultHeader />
5018
+ * @example
5019
+ * ```tsx
5020
+ * // Extend the built-in header:
5021
+ * <SidebarLayout
5022
+ * header={
5023
+ * <SidebarLayout.DefaultHeader
5024
+ * actions={[<NotificationBell key="bell" />, <AppearanceSwitcher key="appearance" />]}
5025
+ * />
5026
+ * }
5027
+ * />
5028
+ *
5029
+ * // Or replace it entirely:
5030
+ * <SidebarLayout header={<MyCustomHeader />} />
5031
+ * ```
5032
+ */
5033
+ header?: React.ReactNode;
4763
5034
  /**
4764
5035
  * Whether the sidebar is open by default on desktop.
4765
5036
  *
@@ -4914,8 +5185,24 @@ export declare const Tabs: {
4914
5185
  Panel: typeof Panel;
4915
5186
  };
4916
5187
 
5188
+ declare type TabsSize = "xs" | "sm" | "default" | "lg";
5189
+
4917
5190
  declare type TabsVariant = "default" | "line" | "capsule";
4918
5191
 
5192
+ export { Time }
5193
+
5194
+ /**
5195
+ * Resolved timezone object with helpers bound to the configured timezone.
5196
+ */
5197
+ export declare interface TimeZone {
5198
+ /** Raw IANA timezone string (e.g. "America/Los_Angeles"). */
5199
+ value: string;
5200
+ /** Today's date in this timezone. */
5201
+ today: () => CalendarDate;
5202
+ /** Current instant in this timezone. */
5203
+ now: () => ZonedDateTime;
5204
+ }
5205
+
4919
5206
  declare function Title({ className, ...props }: React_2.ComponentProps<"div">): JSX.Element;
4920
5207
 
4921
5208
  declare namespace Title {
@@ -5018,7 +5305,6 @@ declare type TypedPaths<TRoutes extends Record<string, Record<string, string>>>
5018
5305
  export declare function useAIChat(config: {
5019
5306
  client: AIGatewayClient;
5020
5307
  model: string;
5021
- stream?: boolean;
5022
5308
  }): {
5023
5309
  messages: AIChatMessage[];
5024
5310
  status: AIChatStatus;
@@ -5056,6 +5342,41 @@ export declare const useAppShellConfig: () => AppShellConfigContextType;
5056
5342
  */
5057
5343
  export declare const useAppShellData: () => AppShellDataContextType;
5058
5344
 
5345
+ /**
5346
+ * Ref to the AppShell **content scroll container** — the element that owns
5347
+ * vertical scrolling for page content.
5348
+ *
5349
+ * The shell is viewport-bounded (`h-svh`), so the document itself no longer
5350
+ * scrolls; the content area does. Use this wherever you would previously have
5351
+ * reached for `window`/document scroll — reading `scrollTop`, calling
5352
+ * `scrollTo`, attaching a `scroll` listener, or passing `root` to an
5353
+ * `IntersectionObserver`:
5354
+ *
5355
+ * ```tsx
5356
+ * const scrollRef = useAppShellScrollContainer();
5357
+ * useEffect(() => {
5358
+ * const el = scrollRef.current;
5359
+ * if (!el) return;
5360
+ * const onScroll = () =>
5361
+ * setProgress(el.scrollTop / (el.scrollHeight - el.clientHeight));
5362
+ * el.addEventListener("scroll", onScroll, { passive: true });
5363
+ * return () => el.removeEventListener("scroll", onScroll);
5364
+ * }, [scrollRef]);
5365
+ * ```
5366
+ *
5367
+ * The element mounts with the layout, above your page, so read `ref.current`
5368
+ * inside an effect (it is populated by the time effects run), not during
5369
+ * render.
5370
+ *
5371
+ * Notes:
5372
+ * - On a `<Layout fill>` page this element does not scroll — its children
5373
+ * (e.g. a `DataTable`) manage their own scrolling.
5374
+ * - Outside a `SidebarLayout` the returned ref's `current` is always `null`.
5375
+ * - The same element carries a `data-appshell-scroll-container` attribute for
5376
+ * non-React access (CSS, tests, `document.querySelector`).
5377
+ */
5378
+ export declare function useAppShellScrollContainer(): RefObject<HTMLElement | null>;
5379
+
5059
5380
  /**
5060
5381
  * Hook that encapsulates the async select pattern — fetching on open,
5061
5382
  * request cancellation via `AbortController`, and loading/error state.
@@ -5829,6 +6150,17 @@ export { useParams }
5829
6150
  */
5830
6151
  export declare function useRegisterCommandPaletteActions(group: string, actions: CommandPaletteAction[]): void;
5831
6152
 
6153
+ /**
6154
+ * Returns the full BCP-47 locale (e.g. "en-GB") for Intl / date formatting.
6155
+ * Also returns the language code (e.g. "en") used for label resolution.
6156
+ *
6157
+ * Falls back to browser detection when used outside an AppShell.
6158
+ */
6159
+ export declare const useResolvedLocale: () => {
6160
+ locale: string;
6161
+ language: string;
6162
+ };
6163
+
5832
6164
  export { useRouteError }
5833
6165
 
5834
6166
  export { useSearchParams }
@@ -5856,6 +6188,12 @@ export declare const useTheme: () => {
5856
6188
  setTheme: (colorTheme: ColorTheme) => void;
5857
6189
  };
5858
6190
 
6191
+ /**
6192
+ * Returns the configured timezone with bound `today()` and `now()` helpers.
6193
+ * Falls back to the user's local timezone when not configured.
6194
+ */
6195
+ export declare const useTimeZone: () => TimeZone;
6196
+
5859
6197
  export declare const useToast: () => typeof toast;
5860
6198
 
5861
6199
  /**
@@ -6019,4 +6357,6 @@ export declare function withURLCollectionState(options: UseCollectionOptions & {
6019
6357
  tableMetadata?: never;
6020
6358
  }, [searchParams, setSearchParams]: SearchParamsBinding): UseCollectionOptions;
6021
6359
 
6360
+ export { ZonedDateTime }
6361
+
6022
6362
  export { }