@xsolla/xui-date-picker 0.184.0 → 0.185.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/README.md +31 -2
- package/native/index.d.mts +146 -2
- package/native/index.d.ts +146 -2
- package/native/index.js +731 -55
- package/native/index.js.map +1 -1
- package/native/index.mjs +727 -55
- package/native/index.mjs.map +1 -1
- package/package.json +5 -5
- package/web/index.d.mts +146 -2
- package/web/index.d.ts +146 -2
- package/web/index.js +731 -55
- package/web/index.js.map +1 -1
- package/web/index.mjs +727 -55
- package/web/index.mjs.map +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
} from '@xsolla/xui-date-picker';
|
|
59
59
|
import type {
|
|
60
60
|
DatePickerProps,
|
|
61
|
+
DatePickerPlacement,
|
|
61
62
|
DateRangeType,
|
|
62
63
|
CalendarProps,
|
|
63
64
|
DualCalendarProps,
|
|
@@ -99,7 +100,8 @@ const [date, setDate] = useState<Date | null>(null);
|
|
|
99
100
|
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Input size. |
|
|
100
101
|
| `disabled` | `boolean` | `false` | Disable the input. |
|
|
101
102
|
| `backgroundColor` | `string` | — | Custom background colour for the input. |
|
|
102
|
-
| `dropdownPosition` | `'left' \| 'right'` | `'left'` |
|
|
103
|
+
| `dropdownPosition` | `'left' \| 'right'` | `'left'` | **Deprecated** — use the alignment suffix on `placement` (`dropdownPosition="right"` → `placement="bottom-end"`). Still honoured as a fallback when `placement` has no suffix. |
|
|
104
|
+
| `placement` | `DatePickerPlacement` | auto | Where the calendar opens, as `{side}[-alignment]` — same `{side}-{start\|center\|end}` convention as `ContextMenuPlacement`. A bare side aligns to `start`. When omitted, the calendar measures viewport space on open and auto-flips, preferring `bottom` → `top` → `left` → `right`, also flipping the cross-axis edge to stay on screen. When set, it always opens at that placement. Web only. |
|
|
103
105
|
| `locale` | `CalendarLocaleType` | `'enUS'` | `date-fns` locale identifier. |
|
|
104
106
|
| `firstDayOfWeek` | `number` | — | First day of the week (0 = Sunday … 6 = Saturday). |
|
|
105
107
|
| `initialMonth` | `Date` | — | Month shown on first render. |
|
|
@@ -150,6 +152,10 @@ Re-exported from `@xsolla/xui-calendar`. Preset chips bar (e.g. "Last 7 days", "
|
|
|
150
152
|
|
|
151
153
|
```ts
|
|
152
154
|
type DateRangeType = [Date | null, Date | null];
|
|
155
|
+
|
|
156
|
+
type DatePickerSide = 'top' | 'bottom' | 'left' | 'right';
|
|
157
|
+
type DatePickerAlignment = 'start' | 'center' | 'end';
|
|
158
|
+
type DatePickerPlacement = DatePickerSide | `${DatePickerSide}-${DatePickerAlignment}`;
|
|
153
159
|
```
|
|
154
160
|
|
|
155
161
|
## Examples
|
|
@@ -180,7 +186,7 @@ const [end, setEnd] = useState<Date | null>(null);
|
|
|
180
186
|
|
|
181
187
|
<DatePicker
|
|
182
188
|
variant="dual"
|
|
183
|
-
|
|
189
|
+
placement="bottom-end"
|
|
184
190
|
startDate={start}
|
|
185
191
|
endDate={end}
|
|
186
192
|
onChange={(range) => {
|
|
@@ -191,6 +197,29 @@ const [end, setEnd] = useState<Date | null>(null);
|
|
|
191
197
|
/>;
|
|
192
198
|
```
|
|
193
199
|
|
|
200
|
+
### Placement and autoflip
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
const [date, setDate] = useState<Date | null>(null);
|
|
204
|
+
|
|
205
|
+
// Default: the calendar auto-flips based on available viewport space.
|
|
206
|
+
<DatePicker selectedDate={date} onChange={(d) => setDate(d as Date | null)} />;
|
|
207
|
+
|
|
208
|
+
// Force a side with `placement`.
|
|
209
|
+
<DatePicker
|
|
210
|
+
placement="top"
|
|
211
|
+
selectedDate={date}
|
|
212
|
+
onChange={(d) => setDate(d as Date | null)}
|
|
213
|
+
/>;
|
|
214
|
+
|
|
215
|
+
// Force a side and alignment (here: opens upward, right-aligned).
|
|
216
|
+
<DatePicker
|
|
217
|
+
placement="top-end"
|
|
218
|
+
selectedDate={date}
|
|
219
|
+
onChange={(d) => setDate(d as Date | null)}
|
|
220
|
+
/>;
|
|
221
|
+
```
|
|
222
|
+
|
|
194
223
|
### Preset chips
|
|
195
224
|
|
|
196
225
|
```tsx
|
package/native/index.d.mts
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { CalendarProps, CalendarLocaleType } from '@xsolla/xui-calendar';
|
|
2
2
|
export { Calendar, CalendarChipOption, CalendarChips, CalendarChipsProps, CalendarGrid, CalendarGridProps, CalendarHeader, CalendarHeaderProps, CalendarLocaleType, CalendarProps, DualCalendar, DualCalendarProps } from '@xsolla/xui-calendar';
|
|
3
3
|
import * as react from 'react';
|
|
4
|
+
import { ReactNode, FocusEvent, MouseEvent, KeyboardEvent, ClipboardEvent } from 'react';
|
|
4
5
|
import { ThemeMode, ProductContext } from '@xsolla/xui-core';
|
|
5
6
|
|
|
6
7
|
type DateRangeType = [Date | null, Date | null];
|
|
7
8
|
type DatePickerDropdownPosition = "left" | "right";
|
|
9
|
+
/** Side the calendar opens toward, relative to the input. */
|
|
10
|
+
type DatePickerSide = "top" | "bottom" | "left" | "right";
|
|
11
|
+
/** Alignment along the chosen side. `start`/`end` map to the leading/trailing edge. */
|
|
12
|
+
type DatePickerAlignment = "start" | "center" | "end";
|
|
13
|
+
/**
|
|
14
|
+
* Where the calendar opens, following the Floating UI / `ContextMenuPlacement`
|
|
15
|
+
* convention: a {@link DatePickerSide} optionally suffixed with an alignment
|
|
16
|
+
* (`-start` | `-center` | `-end`). A bare side aligns to `start` (top/bottom:
|
|
17
|
+
* left edge; left/right: top edge). For `top`/`bottom` the suffix sets the
|
|
18
|
+
* horizontal edge; for `left`/`right` it sets the vertical edge.
|
|
19
|
+
*/
|
|
20
|
+
type DatePickerPlacement = DatePickerSide | `${DatePickerSide}-${DatePickerAlignment}`;
|
|
8
21
|
interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
9
22
|
/**
|
|
10
23
|
* Calendar variant: "single" shows a single month, "dual" shows two months side-by-side.
|
|
@@ -19,6 +32,12 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
19
32
|
* Placeholder text for the input
|
|
20
33
|
*/
|
|
21
34
|
placeholder?: string;
|
|
35
|
+
/**
|
|
36
|
+
* date-fns format string used to both render and parse the field's text value
|
|
37
|
+
* (e.g. `"dd/MM/yyyy"`). Applies to each date in a range. Defaults to
|
|
38
|
+
* `"MM/dd/yyyy"`.
|
|
39
|
+
*/
|
|
40
|
+
dateFormat?: string;
|
|
22
41
|
/**
|
|
23
42
|
* Size of the input
|
|
24
43
|
*/
|
|
@@ -32,9 +51,64 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
32
51
|
*/
|
|
33
52
|
backgroundColor?: string;
|
|
34
53
|
/**
|
|
35
|
-
*
|
|
54
|
+
* Trailing icon shown inside the field. Defaults to a calendar icon
|
|
55
|
+
* (`icon_calendar--line`). Pass `null` to hide it.
|
|
56
|
+
*/
|
|
57
|
+
iconRight?: ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Optional leading icon shown inside the field.
|
|
60
|
+
*/
|
|
61
|
+
iconLeft?: ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* Highlights the field as invalid (error state).
|
|
64
|
+
*/
|
|
65
|
+
error?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Error message shown below the field. Also puts the field in the error state.
|
|
68
|
+
*/
|
|
69
|
+
errorMessage?: string;
|
|
70
|
+
/**
|
|
71
|
+
* When a chip is selected, show its label in the field (e.g. "Last 30 days").
|
|
72
|
+
* Set to `false` to show the resolved date/range instead. Defaults to `true`.
|
|
73
|
+
*/
|
|
74
|
+
showChipLabel?: boolean;
|
|
75
|
+
/** Renders the field read-only: it can open the calendar but not be edited. */
|
|
76
|
+
readOnly?: boolean;
|
|
77
|
+
/** Called on field focus (invoked before the picker's own focus handling). */
|
|
78
|
+
onFocus?: (e: FocusEvent<HTMLInputElement>) => void;
|
|
79
|
+
/** Called on field blur (invoked before the picker's own blur handling). */
|
|
80
|
+
onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
|
|
81
|
+
/** Called on field click (invoked before the picker's own click handling). */
|
|
82
|
+
onClick?: (e: MouseEvent<HTMLInputElement>) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Called on field keydown before the picker's own handling; call
|
|
85
|
+
* `e.preventDefault()` to suppress the built-in segment editing for that key.
|
|
86
|
+
*/
|
|
87
|
+
onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Called on field paste before the picker's own handling; call
|
|
90
|
+
* `e.preventDefault()` to suppress the built-in parse.
|
|
91
|
+
*/
|
|
92
|
+
onPaste?: (e: ClipboardEvent<HTMLInputElement>) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Horizontal alignment of the calendar for `top`/`bottom` placements. Retained
|
|
95
|
+
* as a fallback: applied only when `placement` has no alignment suffix, so
|
|
96
|
+
* existing usage keeps working.
|
|
97
|
+
*
|
|
98
|
+
* @deprecated Use the `placement` alignment suffix instead (e.g. `bottom-end`).
|
|
36
99
|
*/
|
|
37
100
|
dropdownPosition?: DatePickerDropdownPosition;
|
|
101
|
+
/**
|
|
102
|
+
* Where the calendar opens, e.g. `"bottom"`, `"bottom-start"`, `"top-end"`,
|
|
103
|
+
* `"right"`. Follows the same `{side}[-alignment]` convention as
|
|
104
|
+
* `ContextMenuPlacement`. A bare side aligns to `start`; add `-start`,
|
|
105
|
+
* `-center`, or `-end` to align along that side. When omitted, the calendar
|
|
106
|
+
* measures the available viewport space when it opens and automatically flips
|
|
107
|
+
* to the best direction (prefers `"bottom"`, then `"top"`, then `"left"`,
|
|
108
|
+
* then `"right"`), also flipping the horizontal edge so it stays on screen.
|
|
109
|
+
* When set, the calendar always opens at that placement. Web only.
|
|
110
|
+
*/
|
|
111
|
+
placement?: DatePickerPlacement;
|
|
38
112
|
/** Test ID for testing frameworks */
|
|
39
113
|
testID?: string;
|
|
40
114
|
/** Theme mode for the calendar overlay. Defaults to themeMode when not set. */
|
|
@@ -46,5 +120,75 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
46
120
|
declare const DatePicker: react.ForwardRefExoticComponent<DatePickerProps & react.RefAttributes<any>>;
|
|
47
121
|
|
|
48
122
|
declare function formatDate(date: Date, formatStr: string, locale?: CalendarLocaleType): string;
|
|
123
|
+
type DateSegmentType = "day" | "month" | "year";
|
|
124
|
+
/** A date broken into editable parts; `null` means "not yet filled". */
|
|
125
|
+
interface DateParts {
|
|
126
|
+
day: number | null;
|
|
127
|
+
month: number | null;
|
|
128
|
+
year: number | null;
|
|
129
|
+
}
|
|
130
|
+
/** A rendered segment's character span within the field text. */
|
|
131
|
+
interface SegmentRange {
|
|
132
|
+
type: DateSegmentType;
|
|
133
|
+
start: number;
|
|
134
|
+
end: number;
|
|
135
|
+
filled: boolean;
|
|
136
|
+
}
|
|
137
|
+
type FormatToken = {
|
|
138
|
+
kind: "segment";
|
|
139
|
+
type: DateSegmentType;
|
|
140
|
+
} | {
|
|
141
|
+
kind: "literal";
|
|
142
|
+
text: string;
|
|
143
|
+
};
|
|
144
|
+
/** Split a date format into ordered segment tokens and literal separators. */
|
|
145
|
+
declare function parseDateFormat(format: string): FormatToken[];
|
|
146
|
+
declare function datePartsFromDate(date: Date | null | undefined): DateParts;
|
|
147
|
+
/** Assemble a `Date`, or null if any part is missing or the date is invalid. */
|
|
148
|
+
declare function datePartsToDate(parts: DateParts): Date | null;
|
|
149
|
+
declare function isDatePartsComplete(parts: DateParts): boolean;
|
|
150
|
+
/** Clamp a raw numeric segment value into its valid range. */
|
|
151
|
+
declare function clampDatePart(type: DateSegmentType, value: number, parts: DateParts): number;
|
|
152
|
+
/** Step a numeric segment value, wrapping within its range (day/month) or ±1 (year). */
|
|
153
|
+
declare function stepDatePart(type: DateSegmentType, current: number, delta: number, parts: DateParts): number;
|
|
154
|
+
/**
|
|
155
|
+
* Render `parts` into field text using `format`, returning each segment's char
|
|
156
|
+
* range. Filled parts are zero-padded; unfilled parts show a token placeholder
|
|
157
|
+
* (`dd`/`mm`/`yyyy`). `active`, when set, renders the raw in-progress buffer for
|
|
158
|
+
* the segment currently being typed.
|
|
159
|
+
*/
|
|
160
|
+
declare function buildSegmentedValue(format: string, parts: DateParts, active?: {
|
|
161
|
+
type: DateSegmentType;
|
|
162
|
+
buffer: string;
|
|
163
|
+
}): {
|
|
164
|
+
text: string;
|
|
165
|
+
ranges: SegmentRange[];
|
|
166
|
+
};
|
|
167
|
+
/** Whether a first digit rules out a valid second digit (for early auto-commit). */
|
|
168
|
+
declare function isSegmentComplete(type: DateSegmentType, buffer: string): boolean;
|
|
169
|
+
interface DateSegment {
|
|
170
|
+
type: DateSegmentType;
|
|
171
|
+
/** Inclusive character index of the segment's first digit in `value`. */
|
|
172
|
+
start: number;
|
|
173
|
+
/** Exclusive character index one past the segment's last digit. */
|
|
174
|
+
end: number;
|
|
175
|
+
}
|
|
176
|
+
/** Number of days in the given month (0-indexed) of the given year. */
|
|
177
|
+
declare function daysInMonth(year: number, monthIndex: number): number;
|
|
178
|
+
/**
|
|
179
|
+
* Locate the day/month/year segments within a formatted date `value` by walking
|
|
180
|
+
* the `format` string in parallel: `d`/`M`/`y` token runs consume the matching
|
|
181
|
+
* digit run in `value`, other characters are treated as literal separators.
|
|
182
|
+
* Works for any token order (e.g. `MM/dd/yyyy`, `dd/MM/yyyy`, `yyyy-MM-dd`) and
|
|
183
|
+
* both fixed- and variable-width tokens. Returns segments in display order.
|
|
184
|
+
*/
|
|
185
|
+
declare function getDateSegments(format: string, value: string): DateSegment[];
|
|
186
|
+
/**
|
|
187
|
+
* Step a single date segment by `delta`, isolated to that field (no carry):
|
|
188
|
+
* day wraps within the current month, month wraps within the year (day clamped
|
|
189
|
+
* to the new month's length), year increments freely. Mirrors the segment wrap
|
|
190
|
+
* behaviour of the InputTime segments.
|
|
191
|
+
*/
|
|
192
|
+
declare function stepDateSegment(date: Date, type: DateSegmentType, delta: number): Date;
|
|
49
193
|
|
|
50
|
-
export { DatePicker, type DatePickerDropdownPosition, type DatePickerProps, type DateRangeType, formatDate };
|
|
194
|
+
export { type DateParts, DatePicker, type DatePickerAlignment, type DatePickerDropdownPosition, type DatePickerPlacement, type DatePickerProps, type DatePickerSide, type DateRangeType, type DateSegment, type DateSegmentType, type SegmentRange, buildSegmentedValue, clampDatePart, datePartsFromDate, datePartsToDate, daysInMonth, formatDate, getDateSegments, isDatePartsComplete, isSegmentComplete, parseDateFormat, stepDatePart, stepDateSegment };
|
package/native/index.d.ts
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { CalendarProps, CalendarLocaleType } from '@xsolla/xui-calendar';
|
|
2
2
|
export { Calendar, CalendarChipOption, CalendarChips, CalendarChipsProps, CalendarGrid, CalendarGridProps, CalendarHeader, CalendarHeaderProps, CalendarLocaleType, CalendarProps, DualCalendar, DualCalendarProps } from '@xsolla/xui-calendar';
|
|
3
3
|
import * as react from 'react';
|
|
4
|
+
import { ReactNode, FocusEvent, MouseEvent, KeyboardEvent, ClipboardEvent } from 'react';
|
|
4
5
|
import { ThemeMode, ProductContext } from '@xsolla/xui-core';
|
|
5
6
|
|
|
6
7
|
type DateRangeType = [Date | null, Date | null];
|
|
7
8
|
type DatePickerDropdownPosition = "left" | "right";
|
|
9
|
+
/** Side the calendar opens toward, relative to the input. */
|
|
10
|
+
type DatePickerSide = "top" | "bottom" | "left" | "right";
|
|
11
|
+
/** Alignment along the chosen side. `start`/`end` map to the leading/trailing edge. */
|
|
12
|
+
type DatePickerAlignment = "start" | "center" | "end";
|
|
13
|
+
/**
|
|
14
|
+
* Where the calendar opens, following the Floating UI / `ContextMenuPlacement`
|
|
15
|
+
* convention: a {@link DatePickerSide} optionally suffixed with an alignment
|
|
16
|
+
* (`-start` | `-center` | `-end`). A bare side aligns to `start` (top/bottom:
|
|
17
|
+
* left edge; left/right: top edge). For `top`/`bottom` the suffix sets the
|
|
18
|
+
* horizontal edge; for `left`/`right` it sets the vertical edge.
|
|
19
|
+
*/
|
|
20
|
+
type DatePickerPlacement = DatePickerSide | `${DatePickerSide}-${DatePickerAlignment}`;
|
|
8
21
|
interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
9
22
|
/**
|
|
10
23
|
* Calendar variant: "single" shows a single month, "dual" shows two months side-by-side.
|
|
@@ -19,6 +32,12 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
19
32
|
* Placeholder text for the input
|
|
20
33
|
*/
|
|
21
34
|
placeholder?: string;
|
|
35
|
+
/**
|
|
36
|
+
* date-fns format string used to both render and parse the field's text value
|
|
37
|
+
* (e.g. `"dd/MM/yyyy"`). Applies to each date in a range. Defaults to
|
|
38
|
+
* `"MM/dd/yyyy"`.
|
|
39
|
+
*/
|
|
40
|
+
dateFormat?: string;
|
|
22
41
|
/**
|
|
23
42
|
* Size of the input
|
|
24
43
|
*/
|
|
@@ -32,9 +51,64 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
32
51
|
*/
|
|
33
52
|
backgroundColor?: string;
|
|
34
53
|
/**
|
|
35
|
-
*
|
|
54
|
+
* Trailing icon shown inside the field. Defaults to a calendar icon
|
|
55
|
+
* (`icon_calendar--line`). Pass `null` to hide it.
|
|
56
|
+
*/
|
|
57
|
+
iconRight?: ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Optional leading icon shown inside the field.
|
|
60
|
+
*/
|
|
61
|
+
iconLeft?: ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* Highlights the field as invalid (error state).
|
|
64
|
+
*/
|
|
65
|
+
error?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Error message shown below the field. Also puts the field in the error state.
|
|
68
|
+
*/
|
|
69
|
+
errorMessage?: string;
|
|
70
|
+
/**
|
|
71
|
+
* When a chip is selected, show its label in the field (e.g. "Last 30 days").
|
|
72
|
+
* Set to `false` to show the resolved date/range instead. Defaults to `true`.
|
|
73
|
+
*/
|
|
74
|
+
showChipLabel?: boolean;
|
|
75
|
+
/** Renders the field read-only: it can open the calendar but not be edited. */
|
|
76
|
+
readOnly?: boolean;
|
|
77
|
+
/** Called on field focus (invoked before the picker's own focus handling). */
|
|
78
|
+
onFocus?: (e: FocusEvent<HTMLInputElement>) => void;
|
|
79
|
+
/** Called on field blur (invoked before the picker's own blur handling). */
|
|
80
|
+
onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
|
|
81
|
+
/** Called on field click (invoked before the picker's own click handling). */
|
|
82
|
+
onClick?: (e: MouseEvent<HTMLInputElement>) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Called on field keydown before the picker's own handling; call
|
|
85
|
+
* `e.preventDefault()` to suppress the built-in segment editing for that key.
|
|
86
|
+
*/
|
|
87
|
+
onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Called on field paste before the picker's own handling; call
|
|
90
|
+
* `e.preventDefault()` to suppress the built-in parse.
|
|
91
|
+
*/
|
|
92
|
+
onPaste?: (e: ClipboardEvent<HTMLInputElement>) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Horizontal alignment of the calendar for `top`/`bottom` placements. Retained
|
|
95
|
+
* as a fallback: applied only when `placement` has no alignment suffix, so
|
|
96
|
+
* existing usage keeps working.
|
|
97
|
+
*
|
|
98
|
+
* @deprecated Use the `placement` alignment suffix instead (e.g. `bottom-end`).
|
|
36
99
|
*/
|
|
37
100
|
dropdownPosition?: DatePickerDropdownPosition;
|
|
101
|
+
/**
|
|
102
|
+
* Where the calendar opens, e.g. `"bottom"`, `"bottom-start"`, `"top-end"`,
|
|
103
|
+
* `"right"`. Follows the same `{side}[-alignment]` convention as
|
|
104
|
+
* `ContextMenuPlacement`. A bare side aligns to `start`; add `-start`,
|
|
105
|
+
* `-center`, or `-end` to align along that side. When omitted, the calendar
|
|
106
|
+
* measures the available viewport space when it opens and automatically flips
|
|
107
|
+
* to the best direction (prefers `"bottom"`, then `"top"`, then `"left"`,
|
|
108
|
+
* then `"right"`), also flipping the horizontal edge so it stays on screen.
|
|
109
|
+
* When set, the calendar always opens at that placement. Web only.
|
|
110
|
+
*/
|
|
111
|
+
placement?: DatePickerPlacement;
|
|
38
112
|
/** Test ID for testing frameworks */
|
|
39
113
|
testID?: string;
|
|
40
114
|
/** Theme mode for the calendar overlay. Defaults to themeMode when not set. */
|
|
@@ -46,5 +120,75 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
|
|
|
46
120
|
declare const DatePicker: react.ForwardRefExoticComponent<DatePickerProps & react.RefAttributes<any>>;
|
|
47
121
|
|
|
48
122
|
declare function formatDate(date: Date, formatStr: string, locale?: CalendarLocaleType): string;
|
|
123
|
+
type DateSegmentType = "day" | "month" | "year";
|
|
124
|
+
/** A date broken into editable parts; `null` means "not yet filled". */
|
|
125
|
+
interface DateParts {
|
|
126
|
+
day: number | null;
|
|
127
|
+
month: number | null;
|
|
128
|
+
year: number | null;
|
|
129
|
+
}
|
|
130
|
+
/** A rendered segment's character span within the field text. */
|
|
131
|
+
interface SegmentRange {
|
|
132
|
+
type: DateSegmentType;
|
|
133
|
+
start: number;
|
|
134
|
+
end: number;
|
|
135
|
+
filled: boolean;
|
|
136
|
+
}
|
|
137
|
+
type FormatToken = {
|
|
138
|
+
kind: "segment";
|
|
139
|
+
type: DateSegmentType;
|
|
140
|
+
} | {
|
|
141
|
+
kind: "literal";
|
|
142
|
+
text: string;
|
|
143
|
+
};
|
|
144
|
+
/** Split a date format into ordered segment tokens and literal separators. */
|
|
145
|
+
declare function parseDateFormat(format: string): FormatToken[];
|
|
146
|
+
declare function datePartsFromDate(date: Date | null | undefined): DateParts;
|
|
147
|
+
/** Assemble a `Date`, or null if any part is missing or the date is invalid. */
|
|
148
|
+
declare function datePartsToDate(parts: DateParts): Date | null;
|
|
149
|
+
declare function isDatePartsComplete(parts: DateParts): boolean;
|
|
150
|
+
/** Clamp a raw numeric segment value into its valid range. */
|
|
151
|
+
declare function clampDatePart(type: DateSegmentType, value: number, parts: DateParts): number;
|
|
152
|
+
/** Step a numeric segment value, wrapping within its range (day/month) or ±1 (year). */
|
|
153
|
+
declare function stepDatePart(type: DateSegmentType, current: number, delta: number, parts: DateParts): number;
|
|
154
|
+
/**
|
|
155
|
+
* Render `parts` into field text using `format`, returning each segment's char
|
|
156
|
+
* range. Filled parts are zero-padded; unfilled parts show a token placeholder
|
|
157
|
+
* (`dd`/`mm`/`yyyy`). `active`, when set, renders the raw in-progress buffer for
|
|
158
|
+
* the segment currently being typed.
|
|
159
|
+
*/
|
|
160
|
+
declare function buildSegmentedValue(format: string, parts: DateParts, active?: {
|
|
161
|
+
type: DateSegmentType;
|
|
162
|
+
buffer: string;
|
|
163
|
+
}): {
|
|
164
|
+
text: string;
|
|
165
|
+
ranges: SegmentRange[];
|
|
166
|
+
};
|
|
167
|
+
/** Whether a first digit rules out a valid second digit (for early auto-commit). */
|
|
168
|
+
declare function isSegmentComplete(type: DateSegmentType, buffer: string): boolean;
|
|
169
|
+
interface DateSegment {
|
|
170
|
+
type: DateSegmentType;
|
|
171
|
+
/** Inclusive character index of the segment's first digit in `value`. */
|
|
172
|
+
start: number;
|
|
173
|
+
/** Exclusive character index one past the segment's last digit. */
|
|
174
|
+
end: number;
|
|
175
|
+
}
|
|
176
|
+
/** Number of days in the given month (0-indexed) of the given year. */
|
|
177
|
+
declare function daysInMonth(year: number, monthIndex: number): number;
|
|
178
|
+
/**
|
|
179
|
+
* Locate the day/month/year segments within a formatted date `value` by walking
|
|
180
|
+
* the `format` string in parallel: `d`/`M`/`y` token runs consume the matching
|
|
181
|
+
* digit run in `value`, other characters are treated as literal separators.
|
|
182
|
+
* Works for any token order (e.g. `MM/dd/yyyy`, `dd/MM/yyyy`, `yyyy-MM-dd`) and
|
|
183
|
+
* both fixed- and variable-width tokens. Returns segments in display order.
|
|
184
|
+
*/
|
|
185
|
+
declare function getDateSegments(format: string, value: string): DateSegment[];
|
|
186
|
+
/**
|
|
187
|
+
* Step a single date segment by `delta`, isolated to that field (no carry):
|
|
188
|
+
* day wraps within the current month, month wraps within the year (day clamped
|
|
189
|
+
* to the new month's length), year increments freely. Mirrors the segment wrap
|
|
190
|
+
* behaviour of the InputTime segments.
|
|
191
|
+
*/
|
|
192
|
+
declare function stepDateSegment(date: Date, type: DateSegmentType, delta: number): Date;
|
|
49
193
|
|
|
50
|
-
export { DatePicker, type DatePickerDropdownPosition, type DatePickerProps, type DateRangeType, formatDate };
|
|
194
|
+
export { type DateParts, DatePicker, type DatePickerAlignment, type DatePickerDropdownPosition, type DatePickerPlacement, type DatePickerProps, type DatePickerSide, type DateRangeType, type DateSegment, type DateSegmentType, type SegmentRange, buildSegmentedValue, clampDatePart, datePartsFromDate, datePartsToDate, daysInMonth, formatDate, getDateSegments, isDatePartsComplete, isSegmentComplete, parseDateFormat, stepDatePart, stepDateSegment };
|