@ssa-ui-kit/core 3.16.1 → 3.16.3

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.
@@ -0,0 +1,9 @@
1
+ import { Interpolation, Theme } from '@emotion/react';
2
+ export type ClearButtonProps = {
3
+ onClick: () => void;
4
+ ariaLabel: string;
5
+ dataTestId: string;
6
+ className?: string;
7
+ css?: Interpolation<Theme>;
8
+ };
9
+ export declare const ClearButton: ({ onClick, ariaLabel, dataTestId, className, css: cssProp, }: ClearButtonProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hours and minutes columns shown beside the calendar when `showTimePicker`
3
+ * is set, matching the Figma `Day & Time Picker` pop-up.
4
+ *
5
+ * The hours and minutes columns scroll independently, so reaching a late hour
6
+ * doesn't drag the minutes list out of view. Each is centred on its own
7
+ * selected value when the popover opens.
8
+ */
9
+ export declare const DatePickerTimePanel: () => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,8 +1,10 @@
1
+ export * from './ClearButton';
1
2
  export * from './DatePickerTrigger';
2
3
  export * from './DatePickerCalendar';
3
4
  export * from './DatePickerContent';
4
5
  export * from './DatePickerMonthsSwitch';
5
6
  export * from './DatePickerHeader';
7
+ export * from './DatePickerTimePanel';
6
8
  export * from './DaysView';
7
9
  export * from './MonthsView';
8
10
  export * from './YearsView';
@@ -17,6 +17,19 @@ export declare const INVALID_DATE = "Invalid date";
17
17
  export declare const FULL_DATE_LENGTH = 10;
18
18
  export declare const FULL_MONTH_DATE_LENGTH = 7;
19
19
  export declare const FULL_YEAR_DATE_LENGTH = 4;
20
+ /**
21
+ * Time support is layered on top of a date format rather than being a separate
22
+ * set of formats, so `showTimePicker` works with any picker type without
23
+ * widening the shared `DateFormat` union (which `JsonSchemaForm` validates
24
+ * against).
25
+ */
26
+ export declare const TIME_MASK_FORMAT_SUFFIX = " HH:mm";
27
+ export declare const TIME_MASK_SUFFIX = " __:__";
28
+ export declare const TIME_LENGTH = 6;
29
+ export declare const HOURS_IN_DAY = 24;
30
+ export declare const MINUTES_IN_HOUR = 60;
31
+ /** 15-minute steps by default; pass `minuteStep={1}` for the Figma-literal list. */
32
+ export declare const DEFAULT_MINUTE_STEP = 15;
20
33
  export declare const PICKER_TYPE: {
21
34
  readonly DAYS: "days";
22
35
  readonly MONTHS: "months";
@@ -1,7 +1,7 @@
1
1
  import { DateTime } from 'luxon';
2
2
  import { DatePickerProps } from '../types';
3
- export declare const useDatePicker: ({ dateMin, dateMax, name, defaultValue, format: propFormat, maskOptions, pickerType, onOpen, onClose, onError, onChange, value: externalValue, }: DatePickerProps) => {
4
- format: import("../../JsonSchemaForm/utils").DateFormat;
3
+ export declare const useDatePicker: ({ dateMin, dateMax, name, defaultValue, format: propFormat, maskOptions, pickerType, onOpen, onClose, onError, onChange, value: externalValue, showTimePicker, }: DatePickerProps) => {
4
+ format: string;
5
5
  formatIndexes: {
6
6
  day: number;
7
7
  month: number;
@@ -13,7 +13,14 @@ export declare const useDatePicker: ({ dateMin, dateMax, name, defaultValue, for
13
13
  dateMaxDT: DateTime<true> | DateTime<false>;
14
14
  dateTime: DateTime<boolean> | undefined;
15
15
  isOpen: boolean;
16
+ isDirty: boolean;
16
17
  inputValue: any;
18
+ resetToDefault: () => void;
19
+ setTime: ({ hour, minute }: {
20
+ hour?: number;
21
+ minute?: number;
22
+ }) => void;
23
+ showTimePicker: boolean;
17
24
  calendarViewDateTime: DateTime<boolean> | undefined;
18
25
  maskInputRef: import("react").MutableRefObject<HTMLInputElement>;
19
26
  calendarType: import("../../JsonSchemaForm/utils").PickerCalendarType;
@@ -1,3 +1,51 @@
1
+ /**
2
+ * Which edge of a highlighted range a cell sits on. Drives the cell's corner
3
+ * rounding so start/end cells form a single connected pill with the range
4
+ * cells between them, matching the Figma `Range Selected Start/End` variants.
5
+ *
6
+ * - **`start`** — rounded on the left only
7
+ * - **`end`** — rounded on the right only
8
+ * - **`both`** — a standalone selection (or a one-cell range), fully rounded
9
+ */
10
+ export type RangeEdge = 'start' | 'end' | 'both';
11
+ export declare const getCellRadius: (rangeEdge: RangeEdge | undefined, isHighlighted: boolean) => "6px" | "6px 0 0 6px" | "0 6px 6px 0" | "0";
12
+ /**
13
+ * Works out which edge of a highlighted range a selected cell sits on.
14
+ *
15
+ * A range only has distinct edges when both anchors exist, so without an
16
+ * active range (or when both anchors land on the same cell) the cell is
17
+ * fully rounded. `mode` says which anchor *this* picker holds, which is what
18
+ * decides whether its own value rounds on the left or the right.
19
+ */
20
+ export declare const getRangeEdge: ({ isFirstSelected, isSecondSelected, isRangeActive, mode, }: {
21
+ isFirstSelected: boolean;
22
+ isSecondSelected: boolean;
23
+ isRangeActive: boolean;
24
+ mode?: "dateFrom" | "dateTo";
25
+ }) => RangeEdge | undefined;
26
+ /**
27
+ * Time panel shown beside the calendar. Figma lays the hours and minutes out
28
+ * as rows of two 56×40 cells with an 8px gap; two scrolling columns in one
29
+ * scroll container produce the same result while keeping the lists independent.
30
+ */
31
+ export declare const TimePanel: import("@emotion/styled").StyledComponent<{
32
+ theme?: import("@emotion/react").Theme;
33
+ as?: React.ElementType;
34
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
35
+ /**
36
+ * Each column scrolls on its own so the hours list can be moved without
37
+ * dragging the minutes along with it.
38
+ */
39
+ export declare const TimeColumn: import("@emotion/styled").StyledComponent<{
40
+ theme?: import("@emotion/react").Theme;
41
+ as?: React.ElementType;
42
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
43
+ export declare const TimeCell: import("@emotion/styled").StyledComponent<{
44
+ theme?: import("@emotion/react").Theme;
45
+ as?: React.ElementType;
46
+ } & {
47
+ isSelected: boolean;
48
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1
49
  export declare const DaysViewCell: import("@emotion/styled").StyledComponent<{
2
50
  theme?: import("@emotion/react").Theme;
3
51
  as?: React.ElementType;
@@ -13,25 +61,22 @@ export declare const DaysViewCell: import("@emotion/styled").StyledComponent<{
13
61
  } & {
14
62
  isCalendarDateNow: boolean;
15
63
  isCalendarDateSelected: boolean;
16
- isCalendarFirstDateSelected?: boolean;
17
- isCalendarSecondDateSelected?: boolean;
18
64
  isHighlighted: boolean;
65
+ rangeEdge?: RangeEdge;
19
66
  }, {}, {}>;
20
67
  export declare const YearsViewCell: import("@emotion/styled").StyledComponent<{
21
68
  theme?: import("@emotion/react").Theme;
22
69
  as?: React.ElementType;
23
70
  } & {
24
- isCalendarYear: boolean;
25
- isCalendarFirstDateSelected?: boolean;
26
- isCalendarSecondDateSelected?: boolean;
71
+ isCalendarDateSelected: boolean;
27
72
  isHighlighted: boolean;
73
+ rangeEdge?: RangeEdge;
28
74
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
29
75
  export declare const MonthsViewCell: import("@emotion/styled").StyledComponent<{
30
76
  theme?: import("@emotion/react").Theme;
31
77
  as?: React.ElementType;
32
78
  } & {
33
- isCalendarMonth: boolean;
34
- isCalendarFirstDateSelected?: boolean;
35
- isCalendarSecondDateSelected?: boolean;
79
+ isCalendarDateSelected: boolean;
36
80
  isHighlighted: boolean;
81
+ rangeEdge?: RangeEdge;
37
82
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -13,6 +13,9 @@ import type { PickerCalendarType, DateFormat } from '../JsonSchemaForm/utils/dat
13
13
  * - **`days`** — `mm/dd/yyyy` (or `dd/mm/yyyy`), day-level selection
14
14
  * - **`months`** — `mm/yyyy`, month-level selection
15
15
  * - **`years`** — `yyyy`, year-level selection
16
+ *
17
+ * With **`showTimePicker`** the granularity drops to `startOf('minute')` instead, so the
18
+ * selected hours and minutes survive on the emitted **`Date`**.
16
19
  */
17
20
  export type PickerType = (typeof PICKER_TYPE)[keyof typeof PICKER_TYPE];
18
21
  /**
@@ -22,6 +25,9 @@ export type PickerType = (typeof PICKER_TYPE)[keyof typeof PICKER_TYPE];
22
25
  * - **`mm/dd/yyyy`** | **`dd/mm/yyyy`** — day pickers
23
26
  * - **`mm/yyyy`** — month picker
24
27
  * - **`yyyy`** — year picker
28
+ *
29
+ * Always date-only: **`showTimePicker`** appends **` HH:mm`** internally rather than being
30
+ * spelled out here, so this union stays compatible with **`JsonSchemaForm`** validation.
25
31
  */
26
32
  export type DatePickerFormat = DateFormat;
27
33
  /**
@@ -127,11 +133,41 @@ export interface DatePickerProps {
127
133
  * Helper text below the field (shown with validation message when present).
128
134
  */
129
135
  helperText?: string;
136
+ /**
137
+ * Renders the field in its **success** state (green border and helper text).
138
+ * A validation error always wins, so a field with an error is never shown
139
+ * as successful.
140
+ * @default false
141
+ */
142
+ success?: boolean;
130
143
  /**
131
144
  * Whether the trailing calendar icon button is shown.
132
145
  * @default true
133
146
  */
134
147
  showCalendarIcon?: boolean;
148
+ /**
149
+ * Adds an hours/minutes panel beside the calendar and appends **`HH:mm`** to
150
+ * the field's format and mask. The emitted **`Date`** keeps its time instead
151
+ * of being floored to the start of the day.
152
+ *
153
+ * Selecting a day no longer closes the popover when this is on — otherwise
154
+ * the time panel would be unreachable. The popover closes on outside click.
155
+ * @default false
156
+ */
157
+ showTimePicker?: boolean;
158
+ /**
159
+ * Increment between selectable minutes, in minutes. Must divide 60.
160
+ * Use **`1`** to match the design's full 0–59 list.
161
+ * @default 15
162
+ */
163
+ minuteStep?: number;
164
+ /**
165
+ * Whether the trailing **clear** (×) button is shown. It appears only while
166
+ * the field differs from **`defaultValue`**, and restores that value when
167
+ * clicked — so with no **`defaultValue`** it simply empties the field.
168
+ * @default false
169
+ */
170
+ showClearButton?: boolean;
135
171
  /**
136
172
  * Last **Date** emitted from **onChange**; used with **`highlightDates`** for range styling
137
173
  * in the calendar (e.g. paired with another picker’s value).
@@ -162,6 +198,7 @@ export interface DatePickerProps {
162
198
  trigger?: {
163
199
  input?: string;
164
200
  calendarIcon?: string;
201
+ clearButton?: string;
165
202
  };
166
203
  monthsSwitch?: {
167
204
  wrapper?: string;
@@ -172,8 +209,9 @@ export interface DatePickerProps {
172
209
  label?: string;
173
210
  };
174
211
  /**
175
- * Called with the selected **`Date`** (Luxon-normalized to start of day/month/year), or
176
- * **undefined** when the field is cleared or invalid.
212
+ * Called with the selected **`Date`** (Luxon-normalized to start of day/month/year or to
213
+ * the start of the **minute** when **`showTimePicker`** is set), or **undefined** when the
214
+ * field is cleared or invalid.
177
215
  */
178
216
  onChange?: (date?: Date) => void;
179
217
  /**
@@ -214,7 +252,20 @@ export interface DatePickerProps {
214
252
  * Most consumers should use **DatePicker** only; this type documents hooks and subcomponents
215
253
  * that read context.
216
254
  */
217
- export interface DatePickerContextProps extends Omit<DatePickerProps, 'dateMin' | 'dateMax'> {
255
+ export interface DatePickerContextProps extends Omit<DatePickerProps, 'dateMin' | 'dateMax' | 'format'> {
256
+ /**
257
+ * Resolved display format. Unlike the **`format`** prop this may carry a
258
+ * **` HH:mm`** suffix when **`showTimePicker`** is set, so it is a plain
259
+ * string rather than the date-only **`DatePickerFormat`** union.
260
+ */
261
+ format: string;
262
+ /**
263
+ * Commits an hour and/or minute onto the selected date, preserving the day.
264
+ */
265
+ setTime?: (time: {
266
+ hour?: number;
267
+ minute?: number;
268
+ }) => void;
218
269
  /**
219
270
  * Ref applied to the masked **input** (merged: mask ref + forwarded ref from **DatePicker**).
220
271
  */
@@ -223,6 +274,16 @@ export interface DatePickerContextProps extends Omit<DatePickerProps, 'dateMin'
223
274
  * Whether the calendar popover is open.
224
275
  */
225
276
  isOpen: boolean;
277
+ /**
278
+ * Whether the current value differs from **`defaultValue`**. Drives the
279
+ * clear button's visibility.
280
+ */
281
+ isDirty?: boolean;
282
+ /**
283
+ * Restores **`defaultValue`** (or empties the field when there isn't one),
284
+ * clearing any validation error and emitting **`onChange`**.
285
+ */
286
+ resetToDefault?: () => void;
226
287
  /**
227
288
  * Active calendar surface: days grid, months, or years.
228
289
  */
@@ -1,3 +1,16 @@
1
+ /**
2
+ * Wraps the date grid and styles the "range you are about to pick" preview
3
+ * band that appears between a selected anchor and the currently hovered cell.
4
+ *
5
+ * The band is a translucent fill with a hairline top/bottom rule, capped with
6
+ * a rounded corner at each end — so which cell is the left cap and which is
7
+ * the right depends on the direction being previewed:
8
+ *
9
+ * - **`hover-range-from`** — hovering *before* the start anchor, so the
10
+ * hovered cell is the left cap and the selected anchor is the right.
11
+ * - **`hover-range-to`** — hovering *after* the end anchor, so the selected
12
+ * anchor is the left cap and the hovered cell is the right.
13
+ */
1
14
  export declare const DatesListWrapper: import("@emotion/styled").StyledComponent<{
2
15
  theme?: import("@emotion/react").Theme;
3
16
  as?: React.ElementType;
@@ -27,6 +27,8 @@ export declare const useDateRangePicker: ({ dateMin, dateMax, name: _name, forma
27
27
  currentIndex: number;
28
28
  currentCalendarViewDT: DateTime;
29
29
  isOpen: boolean;
30
+ isDirty: boolean;
31
+ resetToDefault: () => void;
30
32
  status?: "error" | "success" | "basic";
31
33
  inputFromRef: ReturnType<typeof useMergeRefs<HTMLInputElement | null>>;
32
34
  inputToRef: ReturnType<typeof useMergeRefs<HTMLInputElement | null>>;
@@ -16,5 +16,6 @@ export declare const useRangeSelection: ({ createNewDate, getComparisonFormat, }
16
16
  isCalendarSecondDateSelected: boolean;
17
17
  isCalendarDateSelected: boolean;
18
18
  };
19
+ isRangeActive: boolean;
19
20
  };
20
21
  export {};
@@ -1,39 +1,4 @@
1
- export declare const DaysViewCell: import("@emotion/styled").StyledComponent<{
2
- theme?: import("@emotion/react").Theme;
3
- as?: React.ElementType;
4
- } & {
5
- direction?: import("../Wrapper").WrapperDirection;
6
- alignItems?: import("../Wrapper").WrapperAlignItems;
7
- justifyContent?: import("../Wrapper").WrapperJustifyContent;
8
- fade?: boolean;
9
- fadeDelay?: number;
10
- isVisible?: boolean;
11
- } & import("../..").CommonProps & import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
12
- theme?: import("@emotion/react").Theme;
13
- } & {
14
- isCalendarDateNow: boolean;
15
- isCalendarDateSelected: boolean;
16
- isCalendarFirstDateSelected?: boolean;
17
- isCalendarSecondDateSelected?: boolean;
18
- isHighlighted: boolean;
19
- }, {}, {}>;
20
- export declare const YearsViewCell: import("@emotion/styled").StyledComponent<{
21
- theme?: import("@emotion/react").Theme;
22
- as?: React.ElementType;
23
- } & {
24
- isCalendarYear: boolean;
25
- isCalendarFirstDateSelected?: boolean;
26
- isCalendarSecondDateSelected?: boolean;
27
- isHighlighted: boolean;
28
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
29
- export declare const MonthsViewCell: import("@emotion/styled").StyledComponent<{
30
- theme?: import("@emotion/react").Theme;
31
- as?: React.ElementType;
32
- } & {
33
- isCalendarFirstDateSelected?: boolean;
34
- isCalendarSecondDateSelected?: boolean;
35
- isHighlighted: boolean;
36
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1
+ export { DaysViewCell, YearsViewCell, MonthsViewCell, getCellRadius, getRangeEdge, type RangeEdge, } from '../DatePicker/styles';
37
2
  export declare const TriggerWrapper: import("@emotion/styled").StyledComponent<{
38
3
  theme?: import("@emotion/react").Theme;
39
4
  as?: React.ElementType;
@@ -124,6 +124,14 @@ export interface DateRangePickerProps {
124
124
  * @default true
125
125
  */
126
126
  showCalendarIcon?: boolean;
127
+ /**
128
+ * Shows the trailing **clear** (×) button. It appears only while either
129
+ * field differs from **`defaultValue`**, and restores the whole range to
130
+ * that default when clicked — so with no **`defaultValue`** it empties both
131
+ * fields.
132
+ * @default false
133
+ */
134
+ showClearButton?: boolean;
127
135
  /**
128
136
  * **days** | **months** | **years** — drives default **format**, mask, and calendar chrome.
129
137
  * @default 'days'
@@ -148,6 +156,7 @@ export interface DateRangePickerProps {
148
156
  inputTo?: string;
149
157
  arrowIcon?: string;
150
158
  calendarIcon?: string;
159
+ clearButton?: string;
151
160
  };
152
161
  calendar?: string;
153
162
  label?: string;
@@ -211,6 +220,16 @@ export interface DateRangePickerContextProps extends Omit<DateRangePickerProps,
211
220
  * Whether the calendar popover is open.
212
221
  */
213
222
  isOpen: boolean;
223
+ /**
224
+ * Whether either field differs from **`defaultValue`**. Drives the clear
225
+ * button's visibility.
226
+ */
227
+ isDirty?: boolean;
228
+ /**
229
+ * Restores the whole range to **`defaultValue`** (or empties both fields
230
+ * when there isn't one) and emits **`onChange`**.
231
+ */
232
+ resetToDefault?: () => void;
214
233
  /**
215
234
  * **Luxon** date for the calendar header / navigation (current visible month or year).
216
235
  */
@@ -94,5 +94,5 @@ import { DropdownProps } from './types';
94
94
  *
95
95
  * @see https://www.w3.org/WAI/ARIA/apg/example-index/combobox/combobox-select-only.html
96
96
  */
97
- declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
97
+ declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, label, helperText, errors, success, icon, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
98
98
  export default Dropdown;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { FieldError } from 'react-hook-form';
2
3
  import { Interpolation, Theme } from '@emotion/react';
3
4
  import { DropdownOptionProps } from '../DropdownOptions';
4
5
  import { CommonProps } from '../../types/emotion';
@@ -99,6 +100,31 @@ export interface DropdownProps<P extends DropdownOptionProps> extends CommonProp
99
100
  * @default false
100
101
  */
101
102
  avatarBorder?: boolean;
103
+ /**
104
+ * Label text displayed above the dropdown
105
+ */
106
+ label?: string;
107
+ /**
108
+ * Helper text displayed below the dropdown
109
+ * Shown when no errors are present
110
+ */
111
+ helperText?: string;
112
+ /**
113
+ * React Hook Form field error object
114
+ * Used to display validation error messages
115
+ */
116
+ errors?: FieldError;
117
+ /**
118
+ * Whether to display success state styling
119
+ * When true, status is set to 'success'
120
+ * @default false
121
+ */
122
+ success?: boolean;
123
+ /**
124
+ * Leading icon shown in the toggle button when no selected item avatar is present.
125
+ * Ignored once an item with an `avatar` is selected — the avatar always takes priority.
126
+ */
127
+ icon?: IconProps['name'];
102
128
  /**
103
129
  * Props object for sub-components
104
130
  * Allows fine-grained control over component parts
@@ -3,6 +3,6 @@ import { DropdownToggleProps } from './types';
3
3
  export declare const DropdownToggleBase: import("@emotion/styled").StyledComponent<{
4
4
  theme?: Theme;
5
5
  as?: React.ElementType;
6
- } & Pick<DropdownToggleProps, "colors" | "disabled" | "isOpen" | "isMultiple" | "selectedCount">, import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
7
- declare const DropdownToggle: ({ onClick, onFocus, isOpen, isMultiple, selectedCount, disabled, children, ariaLabelledby, ariaControls, colors, className, ...restProps }: DropdownToggleProps) => import("@emotion/react/jsx-runtime").JSX.Element;
6
+ } & Pick<DropdownToggleProps, "colors" | "disabled" | "status" | "isOpen" | "isMultiple" | "selectedCount">, import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
7
+ declare const DropdownToggle: ({ onClick, onFocus, isOpen, isMultiple, selectedCount, disabled, children, ariaLabelledby, ariaControls, colors, status, className, ...restProps }: DropdownToggleProps) => import("@emotion/react/jsx-runtime").JSX.Element;
8
8
  export default DropdownToggle;
@@ -16,6 +16,7 @@ export interface DropdownToggleProps extends CommonProps, Omit<React.ButtonHTMLA
16
16
  colors?: Array<string | undefined>;
17
17
  className?: string;
18
18
  selectedCount?: number;
19
+ status?: 'basic' | 'error' | 'success';
19
20
  }
20
21
  export interface MultipleStylesProps {
21
22
  theme: Theme;
@@ -23,12 +23,22 @@ export declare const usePaginationContext: () => PaginationContextProps;
23
23
  *
24
24
  * @example
25
25
  * ```tsx
26
+ * // Uncontrolled
26
27
  * <PaginationContextProvider selectedPage={1} defaultPerPage={25}>
27
28
  * <Pagination pagesCount={10} />
28
29
  * </PaginationContextProvider>
29
30
  * ```
30
31
  *
32
+ * @example
33
+ * ```tsx
34
+ * // Controlled - parent owns page/perPage state
35
+ * const [page, setPage] = useState(1);
36
+ * <PaginationContextProvider page={page} onPageChange={setPage}>
37
+ * <Pagination pagesCount={10} />
38
+ * </PaginationContextProvider>
39
+ * ```
40
+ *
31
41
  * @see {@link Pagination} - Child component that uses this context
32
42
  * @see {@link usePaginationContext} - Hook to access context values
33
43
  */
34
- export declare const PaginationContextProvider: ({ selectedPage, defaultPerPage, children, }: PaginationContextProviderProps) => import("@emotion/react/jsx-runtime").JSX.Element;
44
+ export declare const PaginationContextProvider: ({ selectedPage, defaultPerPage, page: controlledPage, perPage: controlledPerPage, onPageChange, onPerPageChange, children, }: PaginationContextProviderProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -30,6 +30,7 @@ export interface RowsPerPageDropdownProps extends CommonProps {
30
30
  /**
31
31
  * Currently selected number of rows per page
32
32
  * Must match a value in rowsPerPageList
33
+ * @default the `perPage` value from PaginationContextProvider
33
34
  */
34
35
  selectedItem?: number;
35
36
  /**
@@ -0,0 +1 @@
1
+ export * from './useControllableState';
@@ -0,0 +1,37 @@
1
+ import { Dispatch, SetStateAction } from 'react';
2
+ interface UseControllableStateProps<T> {
3
+ /**
4
+ * Controlled value. When provided (not `undefined`), the hook always
5
+ * reflects this value and never writes to its own internal state.
6
+ */
7
+ value?: T;
8
+ /**
9
+ * Initial value used for internal state when `value` is `undefined`
10
+ * (uncontrolled mode).
11
+ */
12
+ defaultValue: T;
13
+ /**
14
+ * Called with the next value whenever the setter is invoked, whether
15
+ * controlled or uncontrolled.
16
+ */
17
+ onChange?: (value: T) => void;
18
+ /**
19
+ * Name used in the dev-mode warning when a component switches between
20
+ * controlled and uncontrolled across renders.
21
+ */
22
+ name?: string;
23
+ }
24
+ /**
25
+ * useControllableState - Backs a value that can be either controlled by a
26
+ * parent (via `value`/`onChange`) or managed internally (via `defaultValue`).
27
+ *
28
+ * Mirrors the standard React controlled/uncontrolled input pattern: passing
29
+ * `value` opts into controlled mode, where the returned value always matches
30
+ * the prop and the setter only calls `onChange` (no internal state is
31
+ * written). Omitting `value` falls back to internal state seeded from
32
+ * `defaultValue`.
33
+ *
34
+ * @internal
35
+ */
36
+ export declare const useControllableState: <T>({ value: controlledValue, defaultValue, onChange, name, }: UseControllableStateProps<T>) => [T, Dispatch<SetStateAction<T>>];
37
+ export {};
@@ -210,21 +210,59 @@ export interface PaginationContextProps {
210
210
  *
211
211
  * @example
212
212
  * ```tsx
213
+ * // Uncontrolled - provider manages its own state
213
214
  * <PaginationContextProvider selectedPage={1} defaultPerPage={25}>
214
215
  * <Pagination pagesCount={10} />
215
216
  * </PaginationContextProvider>
216
217
  * ```
218
+ *
219
+ * @example
220
+ * ```tsx
221
+ * // Controlled - parent owns page/perPage state
222
+ * const [page, setPage] = useState(1);
223
+ * <PaginationContextProvider page={page} onPageChange={setPage}>
224
+ * <Pagination pagesCount={10} />
225
+ * </PaginationContextProvider>
226
+ * ```
217
227
  */
218
228
  export interface PaginationContextProviderProps {
219
229
  /**
220
230
  * Initial selected page number (1-indexed)
231
+ * Ignored once `page` is provided (controlled mode)
221
232
  */
222
233
  selectedPage?: number;
223
234
  /**
224
235
  * Default number of items per page
236
+ * Ignored once `perPage` is provided (controlled mode)
225
237
  * @default 10
226
238
  */
227
239
  defaultPerPage?: number;
240
+ /**
241
+ * Controlled current page number (1-indexed)
242
+ * When provided, the provider stops managing page state internally and
243
+ * always reflects this value; pair with `onPageChange` to react to
244
+ * navigation.
245
+ */
246
+ page?: number;
247
+ /**
248
+ * Controlled number of items per page
249
+ * When provided, the provider stops managing perPage state internally and
250
+ * always reflects this value; pair with `onPerPageChange` to react to
251
+ * changes.
252
+ */
253
+ perPage?: number;
254
+ /**
255
+ * Called whenever the page changes (arrow clicks, page buttons, manual
256
+ * page input). Required to actually change the page when `page` is
257
+ * controlled, since the provider no longer updates its own state.
258
+ */
259
+ onPageChange?: (page: number) => void;
260
+ /**
261
+ * Called whenever perPage changes (rows per page dropdown). Required to
262
+ * actually change perPage when `perPage` is controlled, since the
263
+ * provider no longer updates its own state.
264
+ */
265
+ onPerPageChange?: (perPage: number) => void;
228
266
  /**
229
267
  * Child components that use pagination context
230
268
  * Must include Pagination component