@xsolla/xui-calendar 0.117.0-pr187.1773275482

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 ADDED
@@ -0,0 +1,218 @@
1
+ # Calendar
2
+
3
+ A cross-platform React calendar component supporting single date selection, date range selection, preset date chips, and a dual (side-by-side) calendar layout.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @xsolla/xui-calendar
9
+ # or
10
+ yarn add @xsolla/xui-calendar
11
+ ```
12
+
13
+ ## Demo
14
+
15
+ ### Single Date Selection
16
+
17
+ ```tsx
18
+ import * as React from 'react';
19
+ import { Calendar } from '@xsolla/xui-calendar';
20
+
21
+ export default function SingleDate() {
22
+ const [date, setDate] = React.useState<Date | null>(null);
23
+
24
+ return (
25
+ <Calendar
26
+ selectedDate={date}
27
+ onChange={(newDate) => setDate(newDate as Date)}
28
+ />
29
+ );
30
+ }
31
+ ```
32
+
33
+ ### Date Range Selection
34
+
35
+ ```tsx
36
+ import * as React from 'react';
37
+ import { Calendar } from '@xsolla/xui-calendar';
38
+
39
+ export default function DateRange() {
40
+ const [startDate, setStartDate] = React.useState<Date | null>(null);
41
+ const [endDate, setEndDate] = React.useState<Date | null>(null);
42
+
43
+ return (
44
+ <Calendar
45
+ selectsRange
46
+ startDate={startDate}
47
+ endDate={endDate}
48
+ onChange={(range) => {
49
+ const [start, end] = range as [Date | null, Date | null];
50
+ setStartDate(start);
51
+ setEndDate(end);
52
+ }}
53
+ />
54
+ );
55
+ }
56
+ ```
57
+
58
+ ### With Preset Chips
59
+
60
+ ```tsx
61
+ import * as React from 'react';
62
+ import { Calendar } from '@xsolla/xui-calendar';
63
+
64
+ const chips = [
65
+ { label: 'Today', value: 'today' },
66
+ { label: 'Last 7 days', value: 'last7' },
67
+ { label: 'Last 30 days', value: 'last30' },
68
+ { label: 'Last 90 days', value: 'last90' },
69
+ ];
70
+
71
+ export default function WithChips() {
72
+ const [date, setDate] = React.useState<Date | null>(null);
73
+ const [activeChip, setActiveChip] = React.useState<string | null>('last30');
74
+
75
+ return (
76
+ <Calendar
77
+ selectedDate={date}
78
+ onChange={(newDate) => setDate(newDate as Date)}
79
+ chips={chips}
80
+ activeChip={activeChip}
81
+ onChipSelect={setActiveChip}
82
+ />
83
+ );
84
+ }
85
+ ```
86
+
87
+ ### Dual Calendar (Side-by-Side)
88
+
89
+ ```tsx
90
+ import * as React from 'react';
91
+ import { DualCalendar } from '@xsolla/xui-calendar';
92
+
93
+ export default function DualRange() {
94
+ const [startDate, setStartDate] = React.useState<Date | null>(null);
95
+ const [endDate, setEndDate] = React.useState<Date | null>(null);
96
+
97
+ return (
98
+ <DualCalendar
99
+ startDate={startDate}
100
+ endDate={endDate}
101
+ onChange={(dates) => {
102
+ const [start, end] = dates;
103
+ setStartDate(start);
104
+ setEndDate(end);
105
+ }}
106
+ />
107
+ );
108
+ }
109
+ ```
110
+
111
+ ## Anatomy
112
+
113
+ ```
114
+ +---------------------------------------+
115
+ | [Custom top-content] | <- topContent slot
116
+ | [Today] [Last 7d] [Last 30d] ... | <- CalendarChips
117
+ | <- [Month ▾] [Year ▾] -> | <- CalendarHeader
118
+ | SU MO TU WE TH FR SA | <- CalendarGrid weekday row
119
+ | 29 30 31 1 2 3 4 |
120
+ | 5 6 7 8 9 10 11 |
121
+ | 12 13 14 [15] 16 17 18 | <- [15] = today/selected
122
+ | 23 20 21 22 23 24 25 |
123
+ | 26 27 28 29 30 1 2 |
124
+ | [Custom bottom-content] | <- bottomContent slot
125
+ +---------------------------------------+
126
+ ```
127
+
128
+ ## API Reference
129
+
130
+ ### Calendar
131
+
132
+ | Prop | Type | Default | Description |
133
+ | :--- | :--- | :------ | :---------- |
134
+ | selectedDate | `Date \| null` | - | Selected date for single mode. |
135
+ | startDate | `Date \| null` | - | Start date for range mode. |
136
+ | endDate | `Date \| null` | - | End date for range mode. |
137
+ | selectsRange | `boolean` | `false` | Enable date range selection. |
138
+ | onChange | `(date: Date \| [Date, Date]) => void` | - | Date change callback. |
139
+ | locale | `string` | `"enUS"` | Date-fns locale identifier. |
140
+ | firstDayOfWeek | `number` | `0` | First day of week (0=Sun, 6=Sat). |
141
+ | initialMonth | `Date` | - | Initial month to display. |
142
+ | month | `Date` | - | Controlled month to display. |
143
+ | minDate | `Date \| null` | - | Minimum selectable date. |
144
+ | maxDate | `Date \| null` | - | Maximum selectable date. |
145
+ | chips | `CalendarChipOption[]` | - | Preset date range chips. |
146
+ | activeChip | `string \| null` | - | Currently active chip value. |
147
+ | onChipSelect | `(value: string) => void` | - | Chip selection callback. |
148
+ | topContent | `({ close }) => ReactNode` | - | Custom content above chips. |
149
+ | bottomContent | `({ close }) => ReactNode` | - | Custom content below grid. |
150
+ | contextMenuMaxHeight | `number` | - | Max height for month/year dropdowns. |
151
+ | testID | `string` | - | Test identifier. |
152
+
153
+ ### DualCalendar
154
+
155
+ | Prop | Type | Default | Description |
156
+ | :--- | :--- | :------ | :---------- |
157
+ | startDate | `Date \| null` | - | Start date of selected range. |
158
+ | endDate | `Date \| null` | - | End date of selected range. |
159
+ | onChange | `(dates: [Date, Date]) => void` | - | Range change callback. |
160
+ | locale | `string` | `"enUS"` | Date-fns locale identifier. |
161
+ | firstDayOfWeek | `number` | `0` | First day of week (0=Sun, 6=Sat). |
162
+ | initialMonth | `Date` | - | Initial month for left calendar. |
163
+ | month | `Date` | - | Controlled month for left calendar. |
164
+ | minDate | `Date \| null` | - | Minimum selectable date. |
165
+ | maxDate | `Date \| null` | - | Maximum selectable date. |
166
+ | chips | `CalendarChipOption[]` | - | Shared preset date range chips. |
167
+ | activeChip | `string \| null` | - | Currently active chip value. |
168
+ | onChipSelect | `(value: string) => void` | - | Chip selection callback. |
169
+ | topContent | `({ close }) => ReactNode` | - | Custom content above chips. |
170
+ | bottomContent | `({ close }) => ReactNode` | - | Custom content below grids. |
171
+ | contextMenuMaxHeight | `number` | - | Max height for month/year dropdowns. |
172
+ | testID | `string` | - | Test identifier. |
173
+
174
+ ### CalendarChips
175
+
176
+ | Prop | Type | Default | Description |
177
+ | :--- | :--- | :------ | :---------- |
178
+ | chips | `CalendarChipOption[]` | required | Array of chip options. |
179
+ | activeChip | `string \| null` | - | Currently active chip value. |
180
+ | onChipSelect | `(value: string) => void` | - | Chip selection callback. |
181
+ | testID | `string` | - | Test identifier. |
182
+
183
+ ### CalendarChipOption
184
+
185
+ ```ts
186
+ interface CalendarChipOption {
187
+ label: string;
188
+ value: string;
189
+ }
190
+ ```
191
+
192
+ ### CalendarGrid
193
+
194
+ | Prop | Type | Default | Description |
195
+ | :--- | :--- | :------ | :---------- |
196
+ | currentMonth | `Date` | required | The month to render. |
197
+ | locale | `string` | `"enUS"` | Date-fns locale identifier. |
198
+ | firstDayOfWeek | `number` | `0` | First day of week. |
199
+ | selectsRange | `boolean` | `false` | Enable range mode. |
200
+ | minDate | `Date \| null` | - | Minimum selectable date. |
201
+ | maxDate | `Date \| null` | - | Maximum selectable date. |
202
+ | startDate | `Date \| null` | - | Range start date. |
203
+ | endDate | `Date \| null` | - | Range end date. |
204
+ | selectedDate | `Date \| null` | - | Selected date (single mode). |
205
+ | selectingRange | `Date \| null` | - | Intermediate range selection. |
206
+ | onDayPress | `(date: Date) => void` | - | Day press callback. |
207
+ | testID | `string` | - | Test identifier. |
208
+
209
+ ## Platform Support
210
+
211
+ This package works on both **web** and **React Native**. All components use cross-platform primitives (`Box`, `Text`) and avoid DOM-specific APIs.
212
+
213
+ ## Accessibility
214
+
215
+ - Navigation buttons have aria-labels ("Previous month", "Next month")
216
+ - Month and year selectors are accessible via Select component
217
+ - Day cells support keyboard navigation
218
+ - Chip selection follows radio-group pattern (single active item)
@@ -0,0 +1,211 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactNode } from 'react';
3
+ import * as locales from 'date-fns/locale';
4
+
5
+ type CalendarLocaleType = keyof typeof locales;
6
+ interface CalendarChipOption {
7
+ label: string;
8
+ value: string;
9
+ }
10
+ interface CalendarChipsProps {
11
+ /**
12
+ * Array of chip options to display.
13
+ */
14
+ chips: CalendarChipOption[];
15
+ /**
16
+ * The currently active chip value.
17
+ */
18
+ activeChip?: string | null;
19
+ /**
20
+ * Callback fired when a chip is selected.
21
+ */
22
+ onChipSelect?: (value: string) => void;
23
+ /**
24
+ * Test ID for testing frameworks
25
+ */
26
+ testID?: string;
27
+ }
28
+ interface CalendarGridProps {
29
+ currentMonth: Date;
30
+ locale?: CalendarLocaleType;
31
+ firstDayOfWeek?: number;
32
+ selectsRange?: boolean;
33
+ minDate?: Date | null;
34
+ maxDate?: Date | null;
35
+ startDate?: Date | null;
36
+ endDate?: Date | null;
37
+ selectedDate?: Date | null;
38
+ selectingRange?: Date | null;
39
+ onDayPress?: (date: Date) => void;
40
+ testID?: string;
41
+ }
42
+ interface CalendarHeaderProps {
43
+ monthDate: Date;
44
+ decreaseMonth: () => void;
45
+ increaseMonth: () => void;
46
+ changeYear: (year: number) => void;
47
+ changeMonth: (month: number) => void;
48
+ prevMonthButtonDisabled?: boolean;
49
+ nextMonthButtonDisabled?: boolean;
50
+ locale: CalendarLocaleType;
51
+ minDate?: Date | null;
52
+ maxDate?: Date | null;
53
+ contextMenuMaxHeight?: number;
54
+ }
55
+ interface CalendarProps {
56
+ locale?: CalendarLocaleType;
57
+ /**
58
+ * The day to use as first day of the week, starting from 0 (Sunday) to 6 (Saturday).
59
+ */
60
+ firstDayOfWeek?: number;
61
+ /**
62
+ * The month to display in the calendar at first render.
63
+ */
64
+ initialMonth?: Date;
65
+ /**
66
+ * The month to display in the calendar.
67
+ */
68
+ month?: Date;
69
+ /**
70
+ * Select in range mode for calendar
71
+ */
72
+ selectsRange?: boolean;
73
+ /**
74
+ * The minimum selectable date
75
+ */
76
+ minDate?: Date | null;
77
+ /**
78
+ * The maximum selectable date
79
+ */
80
+ maxDate?: Date | null;
81
+ /**
82
+ * For range mode. Start date in selected period
83
+ */
84
+ startDate?: Date | null;
85
+ /**
86
+ * For range mode. End date in selected period
87
+ */
88
+ endDate?: Date | null;
89
+ /**
90
+ * The selected date
91
+ */
92
+ selectedDate?: Date | null;
93
+ /**
94
+ * Property sets the maximum height of a context menus for selecting month and year.
95
+ */
96
+ contextMenuMaxHeight?: number;
97
+ /**
98
+ * Returns custom content to display above the calendar's date picker.
99
+ */
100
+ topContent?: (datePicker: {
101
+ close: () => void;
102
+ }) => ReactNode;
103
+ /**
104
+ * Returns custom content to display beneath the calendar's date picker.
105
+ */
106
+ bottomContent?: (datePicker: {
107
+ close: () => void;
108
+ }) => ReactNode;
109
+ /**
110
+ * Preset chip options displayed above the calendar header.
111
+ */
112
+ chips?: CalendarChipOption[];
113
+ /**
114
+ * The currently active chip value.
115
+ */
116
+ activeChip?: string | null;
117
+ /**
118
+ * Callback fired when a chip is selected.
119
+ */
120
+ onChipSelect?: (value: string) => void;
121
+ /**
122
+ * Test ID for testing frameworks
123
+ */
124
+ testID?: string;
125
+ /**
126
+ * Callback fired when the date changes
127
+ */
128
+ onChange?: (date: Date | [Date | null, Date | null]) => void;
129
+ }
130
+ interface DualCalendarProps {
131
+ locale?: CalendarLocaleType;
132
+ /**
133
+ * The day to use as first day of the week, starting from 0 (Sunday) to 6 (Saturday).
134
+ */
135
+ firstDayOfWeek?: number;
136
+ /**
137
+ * The month to display in the left calendar at first render.
138
+ */
139
+ initialMonth?: Date;
140
+ /**
141
+ * The month to display in the left calendar (controlled).
142
+ */
143
+ month?: Date;
144
+ /**
145
+ * The minimum selectable date
146
+ */
147
+ minDate?: Date | null;
148
+ /**
149
+ * The maximum selectable date
150
+ */
151
+ maxDate?: Date | null;
152
+ /**
153
+ * Start date of the selected range
154
+ */
155
+ startDate?: Date | null;
156
+ /**
157
+ * End date of the selected range
158
+ */
159
+ endDate?: Date | null;
160
+ /**
161
+ * Property sets the maximum height of a context menus for selecting month and year.
162
+ */
163
+ contextMenuMaxHeight?: number;
164
+ /**
165
+ * Returns custom content to display above the calendars.
166
+ */
167
+ topContent?: (datePicker: {
168
+ close: () => void;
169
+ }) => ReactNode;
170
+ /**
171
+ * Returns custom content to display beneath the calendars.
172
+ */
173
+ bottomContent?: (datePicker: {
174
+ close: () => void;
175
+ }) => ReactNode;
176
+ /**
177
+ * Preset chip options displayed above the calendar headers.
178
+ */
179
+ chips?: CalendarChipOption[];
180
+ /**
181
+ * The currently active chip value.
182
+ */
183
+ activeChip?: string | null;
184
+ /**
185
+ * Callback fired when a chip is selected.
186
+ */
187
+ onChipSelect?: (value: string) => void;
188
+ /**
189
+ * Test ID for testing frameworks
190
+ */
191
+ testID?: string;
192
+ /**
193
+ * Callback fired when the date range changes.
194
+ */
195
+ onChange?: (dates: [Date | null, Date | null]) => void;
196
+ }
197
+
198
+ declare const Calendar: react.ForwardRefExoticComponent<CalendarProps & react.RefAttributes<any>>;
199
+
200
+ declare const DualCalendar: react.ForwardRefExoticComponent<DualCalendarProps & react.RefAttributes<any>>;
201
+
202
+ declare const CalendarHeader: react__default.FC<CalendarHeaderProps>;
203
+
204
+ declare const CalendarGrid: react__default.FC<CalendarGridProps>;
205
+
206
+ declare const CalendarChips: react__default.FC<CalendarChipsProps>;
207
+
208
+ declare function formatDate(date: Date, formatStr: string, locale?: CalendarLocaleType): string;
209
+ declare function getMonthInLocale(month: number, locale?: CalendarLocaleType): string;
210
+
211
+ export { Calendar, type CalendarChipOption, CalendarChips, type CalendarChipsProps, CalendarGrid, type CalendarGridProps, CalendarHeader, type CalendarHeaderProps, type CalendarLocaleType, type CalendarProps, DualCalendar, type DualCalendarProps, formatDate, getMonthInLocale };
@@ -0,0 +1,211 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactNode } from 'react';
3
+ import * as locales from 'date-fns/locale';
4
+
5
+ type CalendarLocaleType = keyof typeof locales;
6
+ interface CalendarChipOption {
7
+ label: string;
8
+ value: string;
9
+ }
10
+ interface CalendarChipsProps {
11
+ /**
12
+ * Array of chip options to display.
13
+ */
14
+ chips: CalendarChipOption[];
15
+ /**
16
+ * The currently active chip value.
17
+ */
18
+ activeChip?: string | null;
19
+ /**
20
+ * Callback fired when a chip is selected.
21
+ */
22
+ onChipSelect?: (value: string) => void;
23
+ /**
24
+ * Test ID for testing frameworks
25
+ */
26
+ testID?: string;
27
+ }
28
+ interface CalendarGridProps {
29
+ currentMonth: Date;
30
+ locale?: CalendarLocaleType;
31
+ firstDayOfWeek?: number;
32
+ selectsRange?: boolean;
33
+ minDate?: Date | null;
34
+ maxDate?: Date | null;
35
+ startDate?: Date | null;
36
+ endDate?: Date | null;
37
+ selectedDate?: Date | null;
38
+ selectingRange?: Date | null;
39
+ onDayPress?: (date: Date) => void;
40
+ testID?: string;
41
+ }
42
+ interface CalendarHeaderProps {
43
+ monthDate: Date;
44
+ decreaseMonth: () => void;
45
+ increaseMonth: () => void;
46
+ changeYear: (year: number) => void;
47
+ changeMonth: (month: number) => void;
48
+ prevMonthButtonDisabled?: boolean;
49
+ nextMonthButtonDisabled?: boolean;
50
+ locale: CalendarLocaleType;
51
+ minDate?: Date | null;
52
+ maxDate?: Date | null;
53
+ contextMenuMaxHeight?: number;
54
+ }
55
+ interface CalendarProps {
56
+ locale?: CalendarLocaleType;
57
+ /**
58
+ * The day to use as first day of the week, starting from 0 (Sunday) to 6 (Saturday).
59
+ */
60
+ firstDayOfWeek?: number;
61
+ /**
62
+ * The month to display in the calendar at first render.
63
+ */
64
+ initialMonth?: Date;
65
+ /**
66
+ * The month to display in the calendar.
67
+ */
68
+ month?: Date;
69
+ /**
70
+ * Select in range mode for calendar
71
+ */
72
+ selectsRange?: boolean;
73
+ /**
74
+ * The minimum selectable date
75
+ */
76
+ minDate?: Date | null;
77
+ /**
78
+ * The maximum selectable date
79
+ */
80
+ maxDate?: Date | null;
81
+ /**
82
+ * For range mode. Start date in selected period
83
+ */
84
+ startDate?: Date | null;
85
+ /**
86
+ * For range mode. End date in selected period
87
+ */
88
+ endDate?: Date | null;
89
+ /**
90
+ * The selected date
91
+ */
92
+ selectedDate?: Date | null;
93
+ /**
94
+ * Property sets the maximum height of a context menus for selecting month and year.
95
+ */
96
+ contextMenuMaxHeight?: number;
97
+ /**
98
+ * Returns custom content to display above the calendar's date picker.
99
+ */
100
+ topContent?: (datePicker: {
101
+ close: () => void;
102
+ }) => ReactNode;
103
+ /**
104
+ * Returns custom content to display beneath the calendar's date picker.
105
+ */
106
+ bottomContent?: (datePicker: {
107
+ close: () => void;
108
+ }) => ReactNode;
109
+ /**
110
+ * Preset chip options displayed above the calendar header.
111
+ */
112
+ chips?: CalendarChipOption[];
113
+ /**
114
+ * The currently active chip value.
115
+ */
116
+ activeChip?: string | null;
117
+ /**
118
+ * Callback fired when a chip is selected.
119
+ */
120
+ onChipSelect?: (value: string) => void;
121
+ /**
122
+ * Test ID for testing frameworks
123
+ */
124
+ testID?: string;
125
+ /**
126
+ * Callback fired when the date changes
127
+ */
128
+ onChange?: (date: Date | [Date | null, Date | null]) => void;
129
+ }
130
+ interface DualCalendarProps {
131
+ locale?: CalendarLocaleType;
132
+ /**
133
+ * The day to use as first day of the week, starting from 0 (Sunday) to 6 (Saturday).
134
+ */
135
+ firstDayOfWeek?: number;
136
+ /**
137
+ * The month to display in the left calendar at first render.
138
+ */
139
+ initialMonth?: Date;
140
+ /**
141
+ * The month to display in the left calendar (controlled).
142
+ */
143
+ month?: Date;
144
+ /**
145
+ * The minimum selectable date
146
+ */
147
+ minDate?: Date | null;
148
+ /**
149
+ * The maximum selectable date
150
+ */
151
+ maxDate?: Date | null;
152
+ /**
153
+ * Start date of the selected range
154
+ */
155
+ startDate?: Date | null;
156
+ /**
157
+ * End date of the selected range
158
+ */
159
+ endDate?: Date | null;
160
+ /**
161
+ * Property sets the maximum height of a context menus for selecting month and year.
162
+ */
163
+ contextMenuMaxHeight?: number;
164
+ /**
165
+ * Returns custom content to display above the calendars.
166
+ */
167
+ topContent?: (datePicker: {
168
+ close: () => void;
169
+ }) => ReactNode;
170
+ /**
171
+ * Returns custom content to display beneath the calendars.
172
+ */
173
+ bottomContent?: (datePicker: {
174
+ close: () => void;
175
+ }) => ReactNode;
176
+ /**
177
+ * Preset chip options displayed above the calendar headers.
178
+ */
179
+ chips?: CalendarChipOption[];
180
+ /**
181
+ * The currently active chip value.
182
+ */
183
+ activeChip?: string | null;
184
+ /**
185
+ * Callback fired when a chip is selected.
186
+ */
187
+ onChipSelect?: (value: string) => void;
188
+ /**
189
+ * Test ID for testing frameworks
190
+ */
191
+ testID?: string;
192
+ /**
193
+ * Callback fired when the date range changes.
194
+ */
195
+ onChange?: (dates: [Date | null, Date | null]) => void;
196
+ }
197
+
198
+ declare const Calendar: react.ForwardRefExoticComponent<CalendarProps & react.RefAttributes<any>>;
199
+
200
+ declare const DualCalendar: react.ForwardRefExoticComponent<DualCalendarProps & react.RefAttributes<any>>;
201
+
202
+ declare const CalendarHeader: react__default.FC<CalendarHeaderProps>;
203
+
204
+ declare const CalendarGrid: react__default.FC<CalendarGridProps>;
205
+
206
+ declare const CalendarChips: react__default.FC<CalendarChipsProps>;
207
+
208
+ declare function formatDate(date: Date, formatStr: string, locale?: CalendarLocaleType): string;
209
+ declare function getMonthInLocale(month: number, locale?: CalendarLocaleType): string;
210
+
211
+ export { Calendar, type CalendarChipOption, CalendarChips, type CalendarChipsProps, CalendarGrid, type CalendarGridProps, CalendarHeader, type CalendarHeaderProps, type CalendarLocaleType, type CalendarProps, DualCalendar, type DualCalendarProps, formatDate, getMonthInLocale };