@carbon/react 1.113.0 → 1.114.0-rc.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.
- package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +901 -901
- package/es/components/DatePicker/DatePicker.d.ts +10 -0
- package/es/components/DatePicker/DatePicker.js +6 -5
- package/es/components/DatePicker/next/components/Calendar.d.ts +40 -0
- package/es/components/DatePicker/next/components/Calendar.js +181 -0
- package/es/components/DatePicker/next/components/DatePicker.d.ts +86 -0
- package/es/components/DatePicker/next/components/DatePicker.js +147 -0
- package/es/components/DatePicker/next/components/DatePickerInput.d.ts +143 -0
- package/es/components/DatePicker/next/components/DatePickerInput.js +124 -0
- package/es/components/DatePicker/next/components/DatePickerSkeleton.d.ts +22 -0
- package/es/components/DatePicker/next/components/DatePickerSkeleton.js +32 -0
- package/es/components/DatePicker/next/hooks/useDatePicker.d.ts +144 -0
- package/es/components/DatePicker/next/hooks/useDatePicker.js +286 -0
- package/es/components/DatePicker/next/index.d.ts +12 -0
- package/es/components/DatePicker/next/index.js +19 -0
- package/es/index.d.ts +1 -0
- package/es/index.js +2 -1
- package/es/internal/checkForOverflow.d.ts +5 -0
- package/es/internal/useFocus.d.ts +23 -0
- package/es/internal/usePrefersReducedMotion.d.ts +11 -0
- package/es/internal/useSidePanelPresence.d.ts +21 -0
- package/lib/components/DatePicker/DatePicker.d.ts +10 -0
- package/lib/components/DatePicker/DatePicker.js +6 -5
- package/lib/components/DatePicker/next/components/Calendar.d.ts +40 -0
- package/lib/components/DatePicker/next/components/Calendar.js +184 -0
- package/lib/components/DatePicker/next/components/DatePicker.d.ts +86 -0
- package/lib/components/DatePicker/next/components/DatePicker.js +150 -0
- package/lib/components/DatePicker/next/components/DatePickerInput.d.ts +143 -0
- package/lib/components/DatePicker/next/components/DatePickerInput.js +127 -0
- package/lib/components/DatePicker/next/components/DatePickerSkeleton.d.ts +22 -0
- package/lib/components/DatePicker/next/components/DatePickerSkeleton.js +41 -0
- package/lib/components/DatePicker/next/hooks/useDatePicker.d.ts +144 -0
- package/lib/components/DatePicker/next/hooks/useDatePicker.js +286 -0
- package/lib/components/DatePicker/next/index.d.ts +12 -0
- package/lib/components/DatePicker/next/index.js +27 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +29 -22
- package/lib/internal/checkForOverflow.d.ts +5 -0
- package/lib/internal/useFocus.d.ts +23 -0
- package/lib/internal/usePrefersReducedMotion.d.ts +11 -0
- package/lib/internal/useSidePanelPresence.d.ts +21 -0
- package/package.json +11 -11
- package/scss/components/action-set/_action-set.scss +9 -0
- package/scss/components/action-set/_index.scss +9 -0
- package/scss/components/resizer/_index.scss +9 -0
- package/scss/components/resizer/_resizer.scss +9 -0
- package/scss/components/side-panel/_index.scss +9 -0
- package/scss/components/side-panel/_side-panel.scss +9 -0
- package/scss/components/truncated-text/_index.scss +9 -0
- package/scss/components/truncated-text/_truncated-text.scss +9 -0
- package/telemetry.yml +41 -1
|
@@ -19,6 +19,8 @@ export interface DatePickerProps {
|
|
|
19
19
|
allowInput?: boolean;
|
|
20
20
|
/**
|
|
21
21
|
* The DOM element the flatpickr should be inserted into `<body>` by default.
|
|
22
|
+
*
|
|
23
|
+
* @deprecated This prop will be removed in the next major release, please see `preview__DatePicker` which does not flatpickr.
|
|
22
24
|
*/
|
|
23
25
|
appendTo?: HTMLElement;
|
|
24
26
|
/**
|
|
@@ -47,14 +49,20 @@ export interface DatePickerProps {
|
|
|
47
49
|
datePickerType?: DatePickerTypes;
|
|
48
50
|
/**
|
|
49
51
|
* The flatpickr `disable` option that allows a user to disable certain dates.
|
|
52
|
+
*
|
|
53
|
+
* @deprecated This prop will be removed in the next major release, please see `preview__DatePicker` which does not flatpickr
|
|
50
54
|
*/
|
|
51
55
|
disable?: DateLimit<DateOption>[];
|
|
52
56
|
/**
|
|
53
57
|
* The flatpickr `enable` option that allows a user to enable certain dates.
|
|
58
|
+
*
|
|
59
|
+
* @deprecated This prop will be removed in the next major release, please see `preview__DatePicker` which does not flatpickr
|
|
54
60
|
*/
|
|
55
61
|
enable?: DateLimit<DateOption>[];
|
|
56
62
|
/**
|
|
57
63
|
* The flatpickr `inline` option.
|
|
64
|
+
*
|
|
65
|
+
* @deprecated This prop will be removed in the next major release, please see `preview__DatePicker` which does not flatpickr
|
|
58
66
|
*/
|
|
59
67
|
inline?: boolean;
|
|
60
68
|
/**
|
|
@@ -91,6 +99,8 @@ export interface DatePickerProps {
|
|
|
91
99
|
onOpen?: flatpickr.Options.Hook;
|
|
92
100
|
/**
|
|
93
101
|
* flatpickr prop passthrough. Controls how dates are parsed.
|
|
102
|
+
*
|
|
103
|
+
* @deprecated This prop will be removed in the next major release, please see `preview__DatePicker` which does not flatpickr
|
|
94
104
|
*/
|
|
95
105
|
parseDate?: (date: string) => Date | false;
|
|
96
106
|
/**
|
|
@@ -40,6 +40,7 @@ function initializeWeekdayShorthand() {
|
|
|
40
40
|
}
|
|
41
41
|
const forEach = Array.prototype.forEach;
|
|
42
42
|
const defaultAriaDateFormat = "l, F j, Y";
|
|
43
|
+
const flatpickrDeprecation = (prop) => `The \`${prop}\` prop is deprecated and will be removed in the next major release. Please use the new \`preview__DatePicker\` component which doesn't use it — if that blocks you, tell us why: https://github.com/carbon-design-system/carbon/issues.`;
|
|
43
44
|
/**
|
|
44
45
|
* @param {number} monthNumber The month number.
|
|
45
46
|
* @param {boolean} shorthand `true` to use shorthand month.
|
|
@@ -455,7 +456,7 @@ DatePicker.propTypes = {
|
|
|
455
456
|
/**
|
|
456
457
|
* The DOM element the Flatpicker should be inserted into. `<body>` by default.
|
|
457
458
|
*/
|
|
458
|
-
appendTo: PropTypes.object,
|
|
459
|
+
appendTo: deprecate(PropTypes.object, flatpickrDeprecation("appendTo")),
|
|
459
460
|
/**
|
|
460
461
|
* The child nodes.
|
|
461
462
|
*/
|
|
@@ -487,15 +488,15 @@ DatePicker.propTypes = {
|
|
|
487
488
|
/**
|
|
488
489
|
* The flatpickr `disable` option that allows a user to disable certain dates.
|
|
489
490
|
*/
|
|
490
|
-
disable: PropTypes.array,
|
|
491
|
+
disable: deprecate(PropTypes.array, flatpickrDeprecation("disable")),
|
|
491
492
|
/**
|
|
492
493
|
* The flatpickr `enable` option that allows a user to enable certain dates.
|
|
493
494
|
*/
|
|
494
|
-
enable: PropTypes.array,
|
|
495
|
+
enable: deprecate(PropTypes.array, flatpickrDeprecation("enable")),
|
|
495
496
|
/**
|
|
496
497
|
* The flatpickr `inline` option.
|
|
497
498
|
*/
|
|
498
|
-
inline: PropTypes.bool,
|
|
499
|
+
inline: deprecate(PropTypes.bool, flatpickrDeprecation("inline")),
|
|
499
500
|
/**
|
|
500
501
|
* Specify whether or not the control is invalid (Fluid only)
|
|
501
502
|
*/
|
|
@@ -534,7 +535,7 @@ DatePicker.propTypes = {
|
|
|
534
535
|
/**
|
|
535
536
|
* flatpickr prop passthrough. Controls how dates are parsed.
|
|
536
537
|
*/
|
|
537
|
-
parseDate: PropTypes.func,
|
|
538
|
+
parseDate: deprecate(PropTypes.func, flatpickrDeprecation("parseDate")),
|
|
538
539
|
/**
|
|
539
540
|
* whether the DatePicker is to be readOnly
|
|
540
541
|
* if boolean applies to all inputs
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { DatePickerContext } from '@carbon/utilities/date-picker';
|
|
8
|
+
/**
|
|
9
|
+
* Calendar component props
|
|
10
|
+
*/
|
|
11
|
+
export interface CalendarProps {
|
|
12
|
+
/**
|
|
13
|
+
* State machine context
|
|
14
|
+
*/
|
|
15
|
+
context: DatePickerContext;
|
|
16
|
+
/**
|
|
17
|
+
* Date selection handler
|
|
18
|
+
*/
|
|
19
|
+
onDateSelect: (date: Temporal.PlainDate) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Navigation handler
|
|
22
|
+
*/
|
|
23
|
+
onNavigate: (eventType: string) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Additional CSS class names
|
|
26
|
+
*/
|
|
27
|
+
className?: string;
|
|
28
|
+
/**
|
|
29
|
+
* BCP 47 locale tag used to localize month and weekday labels
|
|
30
|
+
*/
|
|
31
|
+
locale?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calendar component
|
|
35
|
+
* Renders a calendar grid for date selection
|
|
36
|
+
*/
|
|
37
|
+
export declare function Calendar({ context, onDateSelect, onNavigate, className, locale, }: CalendarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
38
|
+
export declare namespace Calendar {
|
|
39
|
+
var displayName: string;
|
|
40
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { usePrefix } from "../../../../internal/usePrefix.js";
|
|
9
|
+
import { useCallback, useMemo, useState } from "react";
|
|
10
|
+
import cx from "classnames";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { generateCalendarGrid, getFullDateLabel, getMonthYearLabel, getWeekdayLabels } from "@carbon/utilities/date-picker";
|
|
13
|
+
//#region src/components/DatePicker/next/components/Calendar.tsx
|
|
14
|
+
/**
|
|
15
|
+
* Copyright IBM Corp. 2026
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
18
|
+
* LICENSE file in the root directory of this source tree.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Calendar component
|
|
22
|
+
* Renders a calendar grid for date selection
|
|
23
|
+
*/
|
|
24
|
+
function Calendar({ context, onDateSelect, onNavigate, className, locale = "en" }) {
|
|
25
|
+
const prefix = usePrefix();
|
|
26
|
+
const { viewDate, startDate, endDate, minDate, maxDate, focusedDate, mode } = context;
|
|
27
|
+
const [hoveredDate, setHoveredDate] = useState(null);
|
|
28
|
+
const calendarGrid = useMemo(() => {
|
|
29
|
+
if (!viewDate) return [];
|
|
30
|
+
return generateCalendarGrid(viewDate, minDate, maxDate);
|
|
31
|
+
}, [
|
|
32
|
+
viewDate,
|
|
33
|
+
minDate,
|
|
34
|
+
maxDate
|
|
35
|
+
]);
|
|
36
|
+
const handlePrevMonth = useCallback(() => {
|
|
37
|
+
onNavigate("PREV_MONTH");
|
|
38
|
+
}, [onNavigate]);
|
|
39
|
+
const handleNextMonth = useCallback(() => {
|
|
40
|
+
onNavigate("NEXT_MONTH");
|
|
41
|
+
}, [onNavigate]);
|
|
42
|
+
const handleDateClick = useCallback((date, isDisabled) => {
|
|
43
|
+
if (!isDisabled) onDateSelect(date);
|
|
44
|
+
}, [onDateSelect]);
|
|
45
|
+
const isDateSelected = useCallback((date) => {
|
|
46
|
+
if (!startDate) return false;
|
|
47
|
+
if (Temporal.PlainDate.compare(date, startDate) === 0) return true;
|
|
48
|
+
if (endDate && Temporal.PlainDate.compare(date, endDate) === 0) return true;
|
|
49
|
+
return false;
|
|
50
|
+
}, [startDate, endDate]);
|
|
51
|
+
const isDateInRange = useCallback((date) => {
|
|
52
|
+
if (mode !== "range" || !startDate) return false;
|
|
53
|
+
if (endDate) return Temporal.PlainDate.compare(date, startDate) > 0 && Temporal.PlainDate.compare(date, endDate) < 0;
|
|
54
|
+
const previewDate = hoveredDate || focusedDate;
|
|
55
|
+
if (previewDate) {
|
|
56
|
+
if (minDate && Temporal.PlainDate.compare(previewDate, minDate) < 0 || maxDate && Temporal.PlainDate.compare(previewDate, maxDate) > 0) return false;
|
|
57
|
+
const earlierDate = Temporal.PlainDate.compare(startDate, previewDate) < 0 ? startDate : previewDate;
|
|
58
|
+
const laterDate = Temporal.PlainDate.compare(startDate, previewDate) < 0 ? previewDate : startDate;
|
|
59
|
+
return Temporal.PlainDate.compare(date, earlierDate) > 0 && Temporal.PlainDate.compare(date, laterDate) < 0;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}, [
|
|
63
|
+
mode,
|
|
64
|
+
startDate,
|
|
65
|
+
endDate,
|
|
66
|
+
hoveredDate,
|
|
67
|
+
focusedDate,
|
|
68
|
+
minDate,
|
|
69
|
+
maxDate
|
|
70
|
+
]);
|
|
71
|
+
const isDateFocused = useCallback((date) => {
|
|
72
|
+
if (!focusedDate) return false;
|
|
73
|
+
return Temporal.PlainDate.compare(date, focusedDate) === 0;
|
|
74
|
+
}, [focusedDate]);
|
|
75
|
+
if (!viewDate) return null;
|
|
76
|
+
const calendarClasses = cx(`${prefix}--date-picker__calendar`, className);
|
|
77
|
+
const monthYear = getMonthYearLabel(viewDate, locale);
|
|
78
|
+
const weekdayLabels = getWeekdayLabels(locale);
|
|
79
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
80
|
+
className: calendarClasses,
|
|
81
|
+
role: "grid",
|
|
82
|
+
"aria-label": "Calendar",
|
|
83
|
+
tabIndex: 0,
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ jsxs("div", {
|
|
86
|
+
className: `${prefix}--date-picker__month`,
|
|
87
|
+
children: [
|
|
88
|
+
/* @__PURE__ */ jsx("button", {
|
|
89
|
+
type: "button",
|
|
90
|
+
className: `${prefix}--date-picker__month-nav`,
|
|
91
|
+
onClick: handlePrevMonth,
|
|
92
|
+
"aria-label": "Previous month",
|
|
93
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
94
|
+
focusable: "false",
|
|
95
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
96
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
97
|
+
fill: "currentColor",
|
|
98
|
+
width: "16",
|
|
99
|
+
height: "16",
|
|
100
|
+
viewBox: "0 0 16 16",
|
|
101
|
+
"aria-hidden": "true",
|
|
102
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
103
|
+
d: "M11 8l-5 5-.7-.7L9.6 8 5.3 3.7 6 3z",
|
|
104
|
+
transform: "rotate(180 8 8)"
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
}),
|
|
108
|
+
/* @__PURE__ */ jsx("div", {
|
|
109
|
+
className: `${prefix}--date-picker__current-month`,
|
|
110
|
+
children: monthYear
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ jsx("button", {
|
|
113
|
+
type: "button",
|
|
114
|
+
className: `${prefix}--date-picker__month-nav`,
|
|
115
|
+
onClick: handleNextMonth,
|
|
116
|
+
"aria-label": "Next month",
|
|
117
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
118
|
+
focusable: "false",
|
|
119
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
120
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
121
|
+
fill: "currentColor",
|
|
122
|
+
width: "16",
|
|
123
|
+
height: "16",
|
|
124
|
+
viewBox: "0 0 16 16",
|
|
125
|
+
"aria-hidden": "true",
|
|
126
|
+
children: /* @__PURE__ */ jsx("path", { d: "M11 8l-5 5-.7-.7L9.6 8 5.3 3.7 6 3z" })
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
]
|
|
130
|
+
}),
|
|
131
|
+
/* @__PURE__ */ jsx("div", {
|
|
132
|
+
className: `${prefix}--date-picker__weekdays`,
|
|
133
|
+
children: weekdayLabels.map((day, index) => /* @__PURE__ */ jsx("div", {
|
|
134
|
+
className: `${prefix}--date-picker__weekday`,
|
|
135
|
+
title: day,
|
|
136
|
+
children: day
|
|
137
|
+
}, index))
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ jsx("div", {
|
|
140
|
+
className: `${prefix}--date-picker__days`,
|
|
141
|
+
children: calendarGrid.flat().map((dayCell, index) => {
|
|
142
|
+
const { date, isCurrentMonth, isDisabled, isToday } = dayCell;
|
|
143
|
+
const selected = isDateSelected(date);
|
|
144
|
+
const inRange = isDateInRange(date);
|
|
145
|
+
const focused = isDateFocused(date);
|
|
146
|
+
return /* @__PURE__ */ jsx("button", {
|
|
147
|
+
type: "button",
|
|
148
|
+
className: cx(`${prefix}--date-picker__day`, {
|
|
149
|
+
today: isToday,
|
|
150
|
+
selected,
|
|
151
|
+
inRange,
|
|
152
|
+
prevMonthDay: !isCurrentMonth && date.month < viewDate.month,
|
|
153
|
+
nextMonthDay: !isCurrentMonth && date.month > viewDate.month,
|
|
154
|
+
disabled: isDisabled,
|
|
155
|
+
focused
|
|
156
|
+
}),
|
|
157
|
+
onMouseDown: (event) => {
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
},
|
|
160
|
+
onMouseEnter: () => {
|
|
161
|
+
if (mode === "range" && startDate && !endDate) setHoveredDate(date);
|
|
162
|
+
},
|
|
163
|
+
onMouseLeave: () => {
|
|
164
|
+
setHoveredDate(null);
|
|
165
|
+
},
|
|
166
|
+
onClick: () => handleDateClick(date, isDisabled),
|
|
167
|
+
disabled: isDisabled,
|
|
168
|
+
"aria-label": getFullDateLabel(date, locale),
|
|
169
|
+
"aria-pressed": selected || void 0,
|
|
170
|
+
"aria-current": isToday ? "date" : void 0,
|
|
171
|
+
tabIndex: focused ? 0 : -1,
|
|
172
|
+
children: date.day
|
|
173
|
+
}, index);
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
Calendar.displayName = "Calendar";
|
|
180
|
+
//#endregion
|
|
181
|
+
export { Calendar };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
/**
|
|
9
|
+
* DatePicker component props
|
|
10
|
+
* Maintains 100% backwards compatibility with Carbon React v11 API
|
|
11
|
+
*/
|
|
12
|
+
export interface DatePickerProps {
|
|
13
|
+
/**
|
|
14
|
+
* The type of date picker
|
|
15
|
+
*/
|
|
16
|
+
datePickerType?: 'simple' | 'single' | 'range';
|
|
17
|
+
/**
|
|
18
|
+
* The date format string
|
|
19
|
+
*/
|
|
20
|
+
dateFormat?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Minimum selectable date (mm/dd/yyyy format)
|
|
23
|
+
*/
|
|
24
|
+
minDate?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum selectable date (mm/dd/yyyy format)
|
|
27
|
+
*/
|
|
28
|
+
maxDate?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Locale for date formatting
|
|
31
|
+
*/
|
|
32
|
+
locale?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the picker is read-only
|
|
35
|
+
*/
|
|
36
|
+
readOnly?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether to use the light variant
|
|
39
|
+
*/
|
|
40
|
+
light?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to use the short variant
|
|
43
|
+
*/
|
|
44
|
+
short?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether to allow manual input
|
|
47
|
+
*/
|
|
48
|
+
allowInput?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to close calendar on date selection
|
|
51
|
+
*/
|
|
52
|
+
closeOnSelect?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Change handler - receives array of Date objects
|
|
55
|
+
*/
|
|
56
|
+
onChange?: (dates: Date[]) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Close handler
|
|
59
|
+
*/
|
|
60
|
+
onClose?: () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Open handler
|
|
63
|
+
*/
|
|
64
|
+
onOpen?: () => void;
|
|
65
|
+
/**
|
|
66
|
+
* Additional CSS class names
|
|
67
|
+
*/
|
|
68
|
+
className?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Children (DatePickerInput components)
|
|
71
|
+
*/
|
|
72
|
+
children?: React.ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Initial value
|
|
75
|
+
*/
|
|
76
|
+
value?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* DatePicker component
|
|
80
|
+
* Main wrapper component that orchestrates date picker functionality
|
|
81
|
+
* Maintains 100% backwards compatibility with Carbon React v11
|
|
82
|
+
*/
|
|
83
|
+
export declare function DatePicker({ datePickerType, dateFormat, minDate, maxDate, locale, readOnly, light, short, allowInput, closeOnSelect, onChange, onClose, onOpen, className, children, value, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
84
|
+
export declare namespace DatePicker {
|
|
85
|
+
var displayName: string;
|
|
86
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { usePrefix } from "../../../../internal/usePrefix.js";
|
|
9
|
+
import { useDatePicker } from "../hooks/useDatePicker.js";
|
|
10
|
+
import { Calendar } from "./Calendar.js";
|
|
11
|
+
import React, { Children, isValidElement, useRef } from "react";
|
|
12
|
+
import cx from "classnames";
|
|
13
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { formatPlainDate } from "@carbon/utilities/date-picker";
|
|
15
|
+
//#region src/components/DatePicker/next/components/DatePicker.tsx
|
|
16
|
+
/**
|
|
17
|
+
* Copyright IBM Corp. 2026
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
20
|
+
* LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* DatePicker component
|
|
24
|
+
* Main wrapper component that orchestrates date picker functionality
|
|
25
|
+
* Maintains 100% backwards compatibility with Carbon React v11
|
|
26
|
+
*/
|
|
27
|
+
function DatePicker({ datePickerType = "single", dateFormat = "m/d/Y", minDate, maxDate, locale = "en", readOnly = false, light = false, short = false, allowInput = true, closeOnSelect = true, onChange, onClose, onOpen, className, children, value }) {
|
|
28
|
+
const containerRef = useRef(null);
|
|
29
|
+
const prefix = usePrefix();
|
|
30
|
+
const { context, isOpen, selectDate, openCalendar, closeCalendar, handleInputFocus, handleInputBlur, handleInputChange, send, startInputRef, endInputRef, calendarRef, exitSentinelRef, handleExitSentinelFocus } = useDatePicker({
|
|
31
|
+
datePickerType,
|
|
32
|
+
value,
|
|
33
|
+
minDate,
|
|
34
|
+
maxDate,
|
|
35
|
+
dateFormat,
|
|
36
|
+
allowInput,
|
|
37
|
+
closeOnSelect,
|
|
38
|
+
readOnly,
|
|
39
|
+
locale,
|
|
40
|
+
onChange,
|
|
41
|
+
onOpen,
|
|
42
|
+
onClose
|
|
43
|
+
});
|
|
44
|
+
const handleNavigate = (eventType) => {
|
|
45
|
+
send(eventType);
|
|
46
|
+
};
|
|
47
|
+
const handleIconClick = () => {
|
|
48
|
+
if (isOpen) closeCalendar();
|
|
49
|
+
else openCalendar();
|
|
50
|
+
};
|
|
51
|
+
const enhancedChildren = Children.toArray(children).map((child, index) => {
|
|
52
|
+
if (!isValidElement(child)) return child;
|
|
53
|
+
const isStartInput = index === 0;
|
|
54
|
+
const isEndInput = index === 1 && datePickerType === "range";
|
|
55
|
+
const inputRef = isStartInput ? startInputRef : isEndInput ? endInputRef : void 0;
|
|
56
|
+
let inputValue = child.props.value ?? "";
|
|
57
|
+
if (inputValue === "") {
|
|
58
|
+
if (isStartInput && context.startDate) inputValue = formatPlainDate(context.startDate, context.dateFormat);
|
|
59
|
+
else if (isEndInput && context.endDate) inputValue = formatPlainDate(context.endDate, context.dateFormat);
|
|
60
|
+
}
|
|
61
|
+
const enhancedProps = {
|
|
62
|
+
...child.props,
|
|
63
|
+
value: inputValue,
|
|
64
|
+
disabled: child.props.disabled || context.isDisabled,
|
|
65
|
+
readOnly: child.props.readOnly || readOnly,
|
|
66
|
+
onFocus: (e) => {
|
|
67
|
+
child.props.onFocus?.(e);
|
|
68
|
+
handleInputFocus(isEndInput ? "to" : "from");
|
|
69
|
+
},
|
|
70
|
+
onBlur: (e) => {
|
|
71
|
+
child.props.onBlur?.(e);
|
|
72
|
+
handleInputBlur();
|
|
73
|
+
},
|
|
74
|
+
onChange: (e) => {
|
|
75
|
+
child.props.onChange?.(e);
|
|
76
|
+
handleInputChange(e.target.value, isEndInput ? "to" : "from");
|
|
77
|
+
},
|
|
78
|
+
onClick: (e) => {
|
|
79
|
+
child.props.onClick?.(e);
|
|
80
|
+
if (!isOpen) openCalendar();
|
|
81
|
+
},
|
|
82
|
+
onKeyDown: (e) => {
|
|
83
|
+
child.props.onKeyDown?.(e);
|
|
84
|
+
if (!e.defaultPrevented && e.key === "Tab" && !e.shiftKey && !isOpen) {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
openCalendar();
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
onIconClick: () => {
|
|
90
|
+
child.props.onIconClick?.();
|
|
91
|
+
handleIconClick();
|
|
92
|
+
},
|
|
93
|
+
hideIcon: datePickerType === "simple" || child.props.hideIcon
|
|
94
|
+
};
|
|
95
|
+
return /* @__PURE__ */ jsx("div", {
|
|
96
|
+
className: cx(`${prefix}--date-picker-container`, {
|
|
97
|
+
[`${prefix}--date-picker-container--single`]: datePickerType === "single",
|
|
98
|
+
[`${prefix}--date-picker-container--from`]: isStartInput && datePickerType === "range",
|
|
99
|
+
[`${prefix}--date-picker-container--to`]: isEndInput && datePickerType === "range"
|
|
100
|
+
}),
|
|
101
|
+
children: React.createElement(child.type, {
|
|
102
|
+
...child.props,
|
|
103
|
+
...enhancedProps,
|
|
104
|
+
ref: inputRef
|
|
105
|
+
})
|
|
106
|
+
}, child.props.id);
|
|
107
|
+
});
|
|
108
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
109
|
+
ref: containerRef,
|
|
110
|
+
className: cx(`${prefix}--date-picker`, `${prefix}--date-picker--next`, {
|
|
111
|
+
[`${prefix}--date-picker--simple`]: datePickerType === "simple",
|
|
112
|
+
[`${prefix}--date-picker--single`]: datePickerType === "single",
|
|
113
|
+
[`${prefix}--date-picker--range`]: datePickerType === "range",
|
|
114
|
+
[`${prefix}--date-picker--light`]: light,
|
|
115
|
+
[`${prefix}--date-picker--short`]: short,
|
|
116
|
+
[`${prefix}--date-picker--open`]: isOpen
|
|
117
|
+
}, className),
|
|
118
|
+
children: [
|
|
119
|
+
enhancedChildren,
|
|
120
|
+
datePickerType !== "simple" && isOpen && /* @__PURE__ */ jsx("div", {
|
|
121
|
+
ref: calendarRef,
|
|
122
|
+
className: `${prefix}--date-picker__calendar-container`,
|
|
123
|
+
children: /* @__PURE__ */ jsx(Calendar, {
|
|
124
|
+
context,
|
|
125
|
+
onDateSelect: selectDate,
|
|
126
|
+
onNavigate: handleNavigate,
|
|
127
|
+
locale
|
|
128
|
+
})
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ jsx("span", {
|
|
131
|
+
ref: exitSentinelRef,
|
|
132
|
+
tabIndex: -1,
|
|
133
|
+
"aria-hidden": true,
|
|
134
|
+
onFocus: handleExitSentinelFocus,
|
|
135
|
+
style: {
|
|
136
|
+
position: "absolute",
|
|
137
|
+
width: 0,
|
|
138
|
+
height: 0,
|
|
139
|
+
overflow: "hidden"
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
DatePicker.displayName = "DatePicker";
|
|
146
|
+
//#endregion
|
|
147
|
+
export { DatePicker };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
/**
|
|
9
|
+
* DatePickerInput component props
|
|
10
|
+
* Maintains 100% backwards compatibility with Carbon React v11 API
|
|
11
|
+
*/
|
|
12
|
+
export interface DatePickerInputProps {
|
|
13
|
+
/**
|
|
14
|
+
* The unique identifier for the input (required)
|
|
15
|
+
*/
|
|
16
|
+
id: string;
|
|
17
|
+
/**
|
|
18
|
+
* The label text
|
|
19
|
+
*/
|
|
20
|
+
labelText?: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* The placeholder text
|
|
23
|
+
*/
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/**
|
|
26
|
+
* The input size
|
|
27
|
+
*/
|
|
28
|
+
size?: 'sm' | 'md' | 'lg';
|
|
29
|
+
/**
|
|
30
|
+
* Whether the input is disabled
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the input is invalid
|
|
35
|
+
*/
|
|
36
|
+
invalid?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The invalid text to display
|
|
39
|
+
*/
|
|
40
|
+
invalidText?: React.ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the input has a warning
|
|
43
|
+
*/
|
|
44
|
+
warn?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The warning text to display
|
|
47
|
+
*/
|
|
48
|
+
warnText?: React.ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Helper text to display below the input
|
|
51
|
+
*/
|
|
52
|
+
helperText?: React.ReactNode;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to hide the label visually (still accessible)
|
|
55
|
+
*/
|
|
56
|
+
hideLabel?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Additional CSS class names
|
|
59
|
+
*/
|
|
60
|
+
className?: string;
|
|
61
|
+
/**
|
|
62
|
+
* The input value
|
|
63
|
+
*/
|
|
64
|
+
value?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Default value for uncontrolled component
|
|
67
|
+
*/
|
|
68
|
+
defaultValue?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Change handler
|
|
71
|
+
*/
|
|
72
|
+
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Focus handler
|
|
75
|
+
*/
|
|
76
|
+
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Blur handler
|
|
79
|
+
*/
|
|
80
|
+
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Keydown handler
|
|
83
|
+
*/
|
|
84
|
+
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
85
|
+
/**
|
|
86
|
+
* Click handler
|
|
87
|
+
*/
|
|
88
|
+
onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;
|
|
89
|
+
/**
|
|
90
|
+
* Icon description for accessibility
|
|
91
|
+
*/
|
|
92
|
+
iconDescription?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Calendar icon click handler
|
|
95
|
+
*/
|
|
96
|
+
onIconClick?: () => void;
|
|
97
|
+
/**
|
|
98
|
+
* Whether to show the calendar icon
|
|
99
|
+
*/
|
|
100
|
+
hideIcon?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Pattern for input validation
|
|
103
|
+
*/
|
|
104
|
+
pattern?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Type of input
|
|
107
|
+
*/
|
|
108
|
+
type?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Whether the input is read-only
|
|
111
|
+
*/
|
|
112
|
+
readOnly?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Autocomplete attribute
|
|
115
|
+
*/
|
|
116
|
+
autoComplete?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Name attribute
|
|
119
|
+
*/
|
|
120
|
+
name?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Whether the field is required
|
|
123
|
+
*/
|
|
124
|
+
required?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Callback when calendar opens (for internal use)
|
|
127
|
+
*/
|
|
128
|
+
onOpen?: () => void;
|
|
129
|
+
/**
|
|
130
|
+
* Decorator component (e.g., AI Label)
|
|
131
|
+
*/
|
|
132
|
+
decorator?: React.ReactNode;
|
|
133
|
+
/**
|
|
134
|
+
* @deprecated Use `decorator` instead. Will be removed in next major version.
|
|
135
|
+
*/
|
|
136
|
+
slug?: React.ReactNode;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* DatePickerInput component
|
|
140
|
+
* Input field for date picker with Carbon Design System styling
|
|
141
|
+
* Maintains 100% backwards compatibility with Carbon React v11
|
|
142
|
+
*/
|
|
143
|
+
export declare const DatePickerInput: React.ForwardRefExoticComponent<DatePickerInputProps & React.RefAttributes<HTMLInputElement>>;
|