@codecademy/gamut 68.2.3-alpha.df0cb3.0 → 68.2.3-alpha.e3cc4a.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/dist/Alert/elements.d.ts +3 -3
- package/dist/Anchor/index.d.ts +19 -9
- package/dist/Anchor/index.js +9 -6
- package/dist/BarChart/BarRow/elements.d.ts +77 -61
- package/dist/BarChart/utils/hooks.d.ts +2 -2
- package/dist/BarChart/utils/hooks.js +1 -1
- package/dist/Box/Box.d.ts +1 -1
- package/dist/Box/FlexBox.d.ts +1 -1
- package/dist/Box/GridBox.d.ts +2 -1
- package/dist/Box/GridBox.js +1 -1
- package/dist/Box/props.d.ts +1 -1
- package/dist/Button/CTAButton.d.ts +2 -2
- package/dist/Button/FillButton.d.ts +4 -4
- package/dist/Button/IconButton.d.ts +4 -4
- package/dist/Button/StrokeButton.d.ts +4 -4
- package/dist/Button/TextButton.d.ts +4 -4
- package/dist/Button/shared/InlineIconButton.d.ts +2 -2
- package/dist/Button/shared/styles.d.ts +3 -3
- package/dist/Button/shared/types.d.ts +1 -1
- package/dist/ButtonBase/ButtonBase.d.ts +9 -4
- package/dist/ButtonBase/ButtonBase.js +11 -4
- package/dist/Card/elements.d.ts +187 -139
- package/dist/Card/styles.d.ts +8 -8
- package/dist/Coachmark/index.d.ts +1 -1
- package/dist/ConnectedForm/ConnectedForm.d.ts +1 -1
- package/dist/ConnectedForm/utils.d.ts +3 -3
- package/dist/ContentContainer/index.d.ts +1 -1
- package/dist/Disclosure/elements.d.ts +20 -14
- package/dist/FeatureShimmer/index.js +1 -1
- package/dist/FocusTrap/index.d.ts +2 -2
- package/dist/Form/SelectDropdown/elements/controls.js +2 -2
- package/dist/Form/SelectDropdown/elements/multi-value.js +2 -2
- package/dist/Form/SelectDropdown/types/internal.d.ts +2 -2
- package/dist/Form/elements/Form.d.ts +15 -15
- package/dist/Form/elements/FormGroup.d.ts +2 -2
- package/dist/Form/styles/Checkbox-styles.d.ts +1 -1
- package/dist/GridForm/GridFormButtons/index.d.ts +4 -4
- package/dist/InternalFloatingCard/InternalFloatingCard.d.ts +1 -1
- package/dist/Layout/Column.d.ts +1 -1
- package/dist/Layout/LayoutGrid.d.ts +1 -1
- package/dist/List/ListProvider.d.ts +1 -1
- package/dist/List/elements.d.ts +75 -59
- package/dist/List/hooks.d.ts +1 -1
- package/dist/Menu/Menu.d.ts +1 -1
- package/dist/Menu/MenuItem.js +10 -6
- package/dist/Menu/elements.d.ts +4 -4
- package/dist/Modals/elements.d.ts +1 -1
- package/dist/Pagination/AnimatedPaginationButtons.d.ts +58 -42
- package/dist/Pagination/EllipsisButton.d.ts +2 -2
- package/dist/Pagination/PaginationButton.d.ts +6 -6
- package/dist/Pagination/utils.d.ts +58 -42
- package/dist/Pagination/utils.js +14 -11
- package/dist/Popover/Popover.js +4 -4
- package/dist/Popover/elements.d.ts +2 -2
- package/dist/Popover/types.d.ts +3 -2
- package/dist/PopoverContainer/PopoverContainer.js +9 -13
- package/dist/PopoverContainer/hooks.d.ts +15 -4
- package/dist/PopoverContainer/hooks.js +31 -24
- package/dist/PopoverContainer/types.d.ts +3 -7
- package/dist/Tabs/TabButton.d.ts +2 -2
- package/dist/Tabs/TabNav.d.ts +1 -1
- package/dist/Tabs/TabNavLink.d.ts +2 -2
- package/dist/Tag/elements.d.ts +18 -12
- package/dist/Tip/InfoTip/InfoTipButton.d.ts +4 -4
- package/dist/Tip/InfoTip/styles.d.ts +1 -1
- package/dist/Tip/PreviewTip/elements.d.ts +13 -7
- package/dist/Tip/ToolTip/elements.d.ts +1 -1
- package/dist/Tip/__tests__/helpers.d.ts +3 -3
- package/dist/Tip/shared/FloatingTip.js +2 -2
- package/dist/Tip/shared/elements.d.ts +3 -3
- package/dist/Tip/shared/types.d.ts +2 -2
- package/dist/Toggle/elements.d.ts +1 -1
- package/dist/Typography/Text.d.ts +2 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/utils/react.js +2 -1
- package/package.json +9 -10
- package/dist/DatePicker/Calendar/CalendarBody.d.ts +0 -3
- package/dist/DatePicker/Calendar/CalendarBody.js +0 -139
- package/dist/DatePicker/Calendar/CalendarFooter.d.ts +0 -3
- package/dist/DatePicker/Calendar/CalendarFooter.js +0 -57
- package/dist/DatePicker/Calendar/CalendarHeader.d.ts +0 -3
- package/dist/DatePicker/Calendar/CalendarHeader.js +0 -46
- package/dist/DatePicker/Calendar/CalendarNavLastMonth.d.ts +0 -3
- package/dist/DatePicker/Calendar/CalendarNavLastMonth.js +0 -30
- package/dist/DatePicker/Calendar/CalendarNavNextMonth.d.ts +0 -3
- package/dist/DatePicker/Calendar/CalendarNavNextMonth.js +0 -30
- package/dist/DatePicker/Calendar/CalendarWrapper.d.ts +0 -8
- package/dist/DatePicker/Calendar/CalendarWrapper.js +0 -27
- package/dist/DatePicker/Calendar/index.d.ts +0 -6
- package/dist/DatePicker/Calendar/index.js +0 -6
- package/dist/DatePicker/Calendar/types.d.ts +0 -77
- package/dist/DatePicker/Calendar/types.js +0 -1
- package/dist/DatePicker/Calendar/utils/dateGrid.d.ts +0 -38
- package/dist/DatePicker/Calendar/utils/dateGrid.js +0 -103
- package/dist/DatePicker/Calendar/utils/elements.d.ts +0 -18
- package/dist/DatePicker/Calendar/utils/elements.js +0 -116
- package/dist/DatePicker/Calendar/utils/format.d.ts +0 -44
- package/dist/DatePicker/Calendar/utils/format.js +0 -128
- package/dist/DatePicker/Calendar/utils/keyHandler.d.ts +0 -12
- package/dist/DatePicker/Calendar/utils/keyHandler.js +0 -126
- package/dist/DatePicker/Calendar/utils/validation.d.ts +0 -13
- package/dist/DatePicker/Calendar/utils/validation.js +0 -23
- package/dist/DatePicker/DatePicker.d.ts +0 -7
- package/dist/DatePicker/DatePicker.js +0 -155
- package/dist/DatePicker/DatePickerCalendar.d.ts +0 -11
- package/dist/DatePicker/DatePickerCalendar.js +0 -163
- package/dist/DatePicker/DatePickerContext.d.ts +0 -10
- package/dist/DatePicker/DatePickerContext.js +0 -18
- package/dist/DatePicker/DatePickerInput.d.ts +0 -16
- package/dist/DatePicker/DatePickerInput.js +0 -134
- package/dist/DatePicker/index.d.ts +0 -5
- package/dist/DatePicker/index.js +0 -5
- package/dist/DatePicker/types.d.ts +0 -86
- package/dist/DatePicker/types.js +0 -1
- package/dist/DatePicker/utils/dateSelect.d.ts +0 -19
- package/dist/DatePicker/utils/dateSelect.js +0 -146
- package/dist/DatePicker/utils/locale.d.ts +0 -38
- package/dist/DatePicker/utils/locale.js +0 -93
- package/dist/DatePicker/utils/translations.d.ts +0 -15
- package/dist/DatePicker/utils/translations.js +0 -10
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { MiniArrowRightIcon } from '@codecademy/gamut-icons';
|
|
2
|
-
import { useCallback, useId, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { Box, FlexBox } from '../Box';
|
|
4
|
-
import { PopoverContainer } from '../PopoverContainer';
|
|
5
|
-
import { DatePickerCalendar } from './DatePickerCalendar';
|
|
6
|
-
import { DatePickerProvider } from './DatePickerContext';
|
|
7
|
-
import { DatePickerInput } from './DatePickerInput';
|
|
8
|
-
import { isRangeProps } from './utils/dateSelect';
|
|
9
|
-
import { useResolvedLocale } from './utils/locale';
|
|
10
|
-
import { DEFAULT_DATE_PICKER_TRANSLATIONS } from './utils/translations';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* DatePicker: single-date or range. Holds shared state and provides it via context.
|
|
14
|
-
* Single: selectedDate, setSelectedDate. Range: startDate, endDate, setStartDate, setEndDate.
|
|
15
|
-
* With no children, renders default layout (input + calendar popover).
|
|
16
|
-
*/
|
|
17
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
-
export const DatePicker = props => {
|
|
19
|
-
const {
|
|
20
|
-
locale,
|
|
21
|
-
disabledDates = [],
|
|
22
|
-
placeholder,
|
|
23
|
-
mode,
|
|
24
|
-
children,
|
|
25
|
-
translations: translationsProp,
|
|
26
|
-
inputSize
|
|
27
|
-
} = props;
|
|
28
|
-
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
|
29
|
-
const [focusGridSignal, setFocusGridSignal] = useState(false);
|
|
30
|
-
const [gridFocusRequested, setGridFocusRequested] = useState(false);
|
|
31
|
-
const [activeRangePart, setActiveRangePart] = useState(null);
|
|
32
|
-
const inputRef = useRef(null);
|
|
33
|
-
const dialogId = useId();
|
|
34
|
-
const calendarDialogId = `datepicker-dialog-${dialogId.replace(/:/g, '')}`;
|
|
35
|
-
const clearGridFocusRequest = useCallback(() => {
|
|
36
|
-
setGridFocusRequested(false);
|
|
37
|
-
}, []);
|
|
38
|
-
const resolvedLocale = useResolvedLocale(locale);
|
|
39
|
-
const openCalendar = useCallback(options => {
|
|
40
|
-
const moveFocus = options?.moveFocusIntoCalendar ?? false;
|
|
41
|
-
setIsCalendarOpen(true);
|
|
42
|
-
if (moveFocus) {
|
|
43
|
-
setGridFocusRequested(true);
|
|
44
|
-
setFocusGridSignal(signal => !signal);
|
|
45
|
-
} else {
|
|
46
|
-
setGridFocusRequested(false);
|
|
47
|
-
}
|
|
48
|
-
}, []);
|
|
49
|
-
const focusCalendarGrid = useCallback(() => {
|
|
50
|
-
setGridFocusRequested(true);
|
|
51
|
-
setFocusGridSignal(signal => !signal);
|
|
52
|
-
}, []);
|
|
53
|
-
const closeCalendar = useCallback(() => {
|
|
54
|
-
setIsCalendarOpen(false);
|
|
55
|
-
setActiveRangePart(null);
|
|
56
|
-
setGridFocusRequested(false);
|
|
57
|
-
inputRef.current?.focus();
|
|
58
|
-
}, []);
|
|
59
|
-
const startOrSelectedDate = isRangeProps(props) ? props.startDate : props.selectedDate;
|
|
60
|
-
const endDate = isRangeProps(props) ? props.endDate : null;
|
|
61
|
-
const setSelection = useCallback((start, end) => {
|
|
62
|
-
if (isRangeProps(props)) {
|
|
63
|
-
props.setStartDate(start);
|
|
64
|
-
props.setEndDate(end ?? null);
|
|
65
|
-
} else {
|
|
66
|
-
props.setSelectedDate(start);
|
|
67
|
-
}
|
|
68
|
-
}, [props]);
|
|
69
|
-
const contextValue = useMemo(() => {
|
|
70
|
-
const translations = {
|
|
71
|
-
...DEFAULT_DATE_PICKER_TRANSLATIONS,
|
|
72
|
-
...translationsProp
|
|
73
|
-
};
|
|
74
|
-
const base = {
|
|
75
|
-
startOrSelectedDate,
|
|
76
|
-
setSelection,
|
|
77
|
-
isCalendarOpen,
|
|
78
|
-
openCalendar,
|
|
79
|
-
focusCalendarGrid,
|
|
80
|
-
focusGridSignal,
|
|
81
|
-
gridFocusRequested,
|
|
82
|
-
clearGridFocusRequest,
|
|
83
|
-
closeCalendar,
|
|
84
|
-
locale: resolvedLocale,
|
|
85
|
-
disabledDates,
|
|
86
|
-
calendarDialogId,
|
|
87
|
-
translations
|
|
88
|
-
};
|
|
89
|
-
return mode === 'range' ? {
|
|
90
|
-
...base,
|
|
91
|
-
mode: 'range',
|
|
92
|
-
endDate,
|
|
93
|
-
activeRangePart,
|
|
94
|
-
setActiveRangePart
|
|
95
|
-
} : {
|
|
96
|
-
...base,
|
|
97
|
-
mode: 'single'
|
|
98
|
-
};
|
|
99
|
-
}, [mode, startOrSelectedDate, endDate, setSelection, activeRangePart, setActiveRangePart, isCalendarOpen, openCalendar, focusCalendarGrid, focusGridSignal, gridFocusRequested, clearGridFocusRequest, closeCalendar, resolvedLocale, disabledDates, calendarDialogId, translationsProp]);
|
|
100
|
-
const content = children !== undefined ? children : /*#__PURE__*/_jsxs(_Fragment, {
|
|
101
|
-
children: [/*#__PURE__*/_jsx(FlexBox, {
|
|
102
|
-
gap: inputSize === 'small' ? 4 : 8,
|
|
103
|
-
width: "fit-content",
|
|
104
|
-
children: mode === 'range' ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
105
|
-
children: [/*#__PURE__*/_jsx(DatePickerInput, {
|
|
106
|
-
label: props.startLabel,
|
|
107
|
-
placeholder: placeholder,
|
|
108
|
-
rangePart: "start",
|
|
109
|
-
ref: inputRef,
|
|
110
|
-
size: inputSize
|
|
111
|
-
}), /*#__PURE__*/_jsx(Box, {
|
|
112
|
-
alignSelf: "center",
|
|
113
|
-
mt: 32,
|
|
114
|
-
children: /*#__PURE__*/_jsx(MiniArrowRightIcon, {})
|
|
115
|
-
}), /*#__PURE__*/_jsx(DatePickerInput, {
|
|
116
|
-
label: props.endLabel,
|
|
117
|
-
placeholder: placeholder,
|
|
118
|
-
rangePart: "end",
|
|
119
|
-
size: inputSize
|
|
120
|
-
// does this need a ref?
|
|
121
|
-
})]
|
|
122
|
-
}) : /*#__PURE__*/_jsx(DatePickerInput, {
|
|
123
|
-
label: props.label,
|
|
124
|
-
placeholder: placeholder,
|
|
125
|
-
ref: inputRef,
|
|
126
|
-
size: inputSize
|
|
127
|
-
})
|
|
128
|
-
}), /*#__PURE__*/_jsx(PopoverContainer, {
|
|
129
|
-
alignment: "bottom-left",
|
|
130
|
-
allowPageInteraction: true,
|
|
131
|
-
focusOnProps: {
|
|
132
|
-
autoFocus: false,
|
|
133
|
-
focusLock: false
|
|
134
|
-
},
|
|
135
|
-
invertAxis: "x",
|
|
136
|
-
isOpen: isCalendarOpen,
|
|
137
|
-
targetRef: inputRef,
|
|
138
|
-
x: -20,
|
|
139
|
-
y: -16,
|
|
140
|
-
onRequestClose: closeCalendar,
|
|
141
|
-
children: /*#__PURE__*/_jsx("div", {
|
|
142
|
-
"aria-label": contextValue.translations.calendarDialogAriaLabel,
|
|
143
|
-
id: calendarDialogId,
|
|
144
|
-
role: "dialog",
|
|
145
|
-
children: /*#__PURE__*/_jsx(DatePickerCalendar, {
|
|
146
|
-
dialogId: calendarDialogId
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
})]
|
|
150
|
-
});
|
|
151
|
-
return /*#__PURE__*/_jsx(DatePickerProvider, {
|
|
152
|
-
value: contextValue,
|
|
153
|
-
children: content
|
|
154
|
-
});
|
|
155
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { CalendarBodyProps } from './Calendar/types';
|
|
2
|
-
export type DatePickerCalendarProps = Pick<CalendarBodyProps, 'weekStartsOn'> & {
|
|
3
|
-
/** id for the dialog (for aria-controls from input). */
|
|
4
|
-
dialogId: string;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Calendar that composes Calendar, CalendarHeader, CalendarBody, CalendarFooter.
|
|
8
|
-
* When inside DatePicker: owns local visibleDate and focusedDate; updates shared
|
|
9
|
-
* state via context. Supports single-date and range modes.
|
|
10
|
-
*/
|
|
11
|
-
export declare const DatePickerCalendar: React.FC<DatePickerCalendarProps>;
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { breakpoints } from '@codecademy/gamut-styles';
|
|
2
|
-
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { useMedia } from 'react-use';
|
|
4
|
-
import { Box, FlexBox } from '../Box';
|
|
5
|
-
import { CalendarBody, CalendarFooter, CalendarHeader, CalendarWrapper } from './Calendar';
|
|
6
|
-
import { useDatePicker } from './DatePickerContext';
|
|
7
|
-
import { handleDateSelectRange, handleDateSelectSingle } from './utils/dateSelect';
|
|
8
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
-
/**
|
|
10
|
-
* Calendar that composes Calendar, CalendarHeader, CalendarBody, CalendarFooter.
|
|
11
|
-
* When inside DatePicker: owns local visibleDate and focusedDate; updates shared
|
|
12
|
-
* state via context. Supports single-date and range modes.
|
|
13
|
-
*/
|
|
14
|
-
export const DatePickerCalendar = ({
|
|
15
|
-
dialogId,
|
|
16
|
-
weekStartsOn
|
|
17
|
-
}) => {
|
|
18
|
-
const context = useDatePicker();
|
|
19
|
-
const generatedId = useId();
|
|
20
|
-
const fallbackDialogId = `datepicker-calendar-${generatedId.replace(/:/g, '')}`;
|
|
21
|
-
const headingId = dialogId ?? context?.calendarDialogId ?? fallbackDialogId;
|
|
22
|
-
if (context == null) {
|
|
23
|
-
throw new Error('DatePickerCalendar must be used inside a DatePicker (it reads shared state from context).');
|
|
24
|
-
}
|
|
25
|
-
const {
|
|
26
|
-
mode,
|
|
27
|
-
startOrSelectedDate,
|
|
28
|
-
setSelection,
|
|
29
|
-
disabledDates,
|
|
30
|
-
locale,
|
|
31
|
-
closeCalendar,
|
|
32
|
-
isCalendarOpen,
|
|
33
|
-
translations,
|
|
34
|
-
focusGridSignal,
|
|
35
|
-
gridFocusRequested,
|
|
36
|
-
clearGridFocusRequest
|
|
37
|
-
} = context;
|
|
38
|
-
const focusGridSync = useMemo(() => ({
|
|
39
|
-
gridFocusRequested,
|
|
40
|
-
signal: focusGridSignal,
|
|
41
|
-
onGridFocusRequestHandled: clearGridFocusRequest
|
|
42
|
-
}), [gridFocusRequested, focusGridSignal, clearGridFocusRequest]);
|
|
43
|
-
const isRange = mode === 'range';
|
|
44
|
-
const endDate = isRange ? context.endDate : undefined;
|
|
45
|
-
const firstOfMonth = date => new Date(date.getFullYear(), date.getMonth(), 1);
|
|
46
|
-
const [displayDate, setDisplayDate] = useState(() => firstOfMonth(startOrSelectedDate ?? new Date()));
|
|
47
|
-
const [focusedDate, setFocusedDate] = useState(() => startOrSelectedDate ?? endDate ?? new Date());
|
|
48
|
-
const wasOpenRef = useRef(false);
|
|
49
|
-
|
|
50
|
-
// Sync visible month to selection only when the calendar opens, not on every
|
|
51
|
-
// date click. Otherwise clicking a date in the second month would jump the view.
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
const justOpened = isCalendarOpen && !wasOpenRef.current;
|
|
54
|
-
wasOpenRef.current = isCalendarOpen;
|
|
55
|
-
if (!justOpened) return;
|
|
56
|
-
const anchor = startOrSelectedDate ?? endDate;
|
|
57
|
-
if (anchor) {
|
|
58
|
-
setDisplayDate(firstOfMonth(anchor));
|
|
59
|
-
setFocusedDate(startOrSelectedDate ?? endDate ?? new Date());
|
|
60
|
-
}
|
|
61
|
-
}, [isCalendarOpen, startOrSelectedDate, endDate]);
|
|
62
|
-
const onDateSelect = date => {
|
|
63
|
-
if (!isRange) {
|
|
64
|
-
handleDateSelectSingle({
|
|
65
|
-
date,
|
|
66
|
-
selectedDate: startOrSelectedDate,
|
|
67
|
-
setSelection
|
|
68
|
-
});
|
|
69
|
-
} else {
|
|
70
|
-
context.setActiveRangePart(null);
|
|
71
|
-
handleDateSelectRange({
|
|
72
|
-
date,
|
|
73
|
-
activeRangePart: context.activeRangePart,
|
|
74
|
-
startDate: startOrSelectedDate,
|
|
75
|
-
endDate: context.endDate,
|
|
76
|
-
setSelection,
|
|
77
|
-
disabledDates
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const handleClearDate = () => {
|
|
82
|
-
setSelection(null);
|
|
83
|
-
setFocusedDate(displayDate);
|
|
84
|
-
};
|
|
85
|
-
const handleTodayClick = () => {
|
|
86
|
-
const today = new Date();
|
|
87
|
-
setSelection(today);
|
|
88
|
-
setDisplayDate(firstOfMonth(today));
|
|
89
|
-
setFocusedDate(today);
|
|
90
|
-
};
|
|
91
|
-
const focusTarget = focusedDate ?? startOrSelectedDate ?? endDate ?? new Date();
|
|
92
|
-
const addMonths = (date, n) => new Date(date.getFullYear(), date.getMonth() + n, 1);
|
|
93
|
-
const secondMonthDate = addMonths(displayDate, 1);
|
|
94
|
-
const isTwoMonthsVisible = useMedia(`(min-width: ${breakpoints.xs})`);
|
|
95
|
-
return /*#__PURE__*/_jsxs(CalendarWrapper, {
|
|
96
|
-
children: [/*#__PURE__*/_jsxs(FlexBox, {
|
|
97
|
-
p: 24,
|
|
98
|
-
pb: 16,
|
|
99
|
-
children: [/*#__PURE__*/_jsxs(Box, {
|
|
100
|
-
children: [/*#__PURE__*/_jsx(CalendarHeader, {
|
|
101
|
-
displayDate: displayDate,
|
|
102
|
-
headingId: headingId,
|
|
103
|
-
hideNextNav: isTwoMonthsVisible,
|
|
104
|
-
locale: locale,
|
|
105
|
-
onDisplayDateChange: setDisplayDate
|
|
106
|
-
}), /*#__PURE__*/_jsx(CalendarBody, {
|
|
107
|
-
disabledDates: disabledDates,
|
|
108
|
-
displayDate: displayDate,
|
|
109
|
-
endDate: endDate,
|
|
110
|
-
focusGridSync: focusGridSync,
|
|
111
|
-
focusedDate: focusTarget,
|
|
112
|
-
hasAdjacentMonthRight: isTwoMonthsVisible,
|
|
113
|
-
labelledById: headingId,
|
|
114
|
-
locale: locale,
|
|
115
|
-
selectedDate: startOrSelectedDate,
|
|
116
|
-
weekStartsOn: weekStartsOn,
|
|
117
|
-
onDateSelect: onDateSelect,
|
|
118
|
-
onDisplayDateChange: setDisplayDate,
|
|
119
|
-
onEscapeKeyPress: closeCalendar,
|
|
120
|
-
onFocusedDateChange: setFocusedDate
|
|
121
|
-
})]
|
|
122
|
-
}), /*#__PURE__*/_jsxs(Box, {
|
|
123
|
-
display: {
|
|
124
|
-
_: 'none',
|
|
125
|
-
xs: 'initial'
|
|
126
|
-
},
|
|
127
|
-
pl: {
|
|
128
|
-
_: 0,
|
|
129
|
-
xs: 32
|
|
130
|
-
},
|
|
131
|
-
children: [/*#__PURE__*/_jsx(CalendarHeader, {
|
|
132
|
-
displayDate: secondMonthDate,
|
|
133
|
-
headingId: headingId,
|
|
134
|
-
hideLastNav: true,
|
|
135
|
-
locale: locale,
|
|
136
|
-
onDisplayDateChange: setDisplayDate
|
|
137
|
-
}), /*#__PURE__*/_jsx(CalendarBody, {
|
|
138
|
-
disabledDates: disabledDates,
|
|
139
|
-
displayDate: secondMonthDate,
|
|
140
|
-
endDate: endDate,
|
|
141
|
-
focusGridSync: focusGridSync,
|
|
142
|
-
focusedDate: focusTarget,
|
|
143
|
-
hasAdjacentMonthLeft: isTwoMonthsVisible,
|
|
144
|
-
labelledById: headingId,
|
|
145
|
-
locale: locale,
|
|
146
|
-
selectedDate: startOrSelectedDate,
|
|
147
|
-
weekStartsOn: weekStartsOn,
|
|
148
|
-
onDateSelect: onDateSelect,
|
|
149
|
-
onDisplayDateChange: setDisplayDate,
|
|
150
|
-
onEscapeKeyPress: closeCalendar,
|
|
151
|
-
onFocusedDateChange: setFocusedDate
|
|
152
|
-
})]
|
|
153
|
-
})]
|
|
154
|
-
}), /*#__PURE__*/_jsx(CalendarFooter, {
|
|
155
|
-
clearText: translations.clearText,
|
|
156
|
-
disabled: startOrSelectedDate === null && endDate === null,
|
|
157
|
-
locale: locale,
|
|
158
|
-
showClearButton: isRange,
|
|
159
|
-
onClearDate: handleClearDate,
|
|
160
|
-
onTodayClick: handleTodayClick
|
|
161
|
-
})]
|
|
162
|
-
});
|
|
163
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { DatePickerContextValue as DatePickerContextValueType } from './types';
|
|
2
|
-
export declare const DatePickerContext: import("react").Context<DatePickerContextValueType | null>;
|
|
3
|
-
/** Provider component; DatePicker uses this to set the context value. */
|
|
4
|
-
export declare const DatePickerProvider: import("react").Provider<DatePickerContextValueType | null>;
|
|
5
|
-
/**
|
|
6
|
-
* Returns the DatePicker context value (shared state and callbacks).
|
|
7
|
-
* Must be used inside a DatePicker. For composed layouts, use this to get
|
|
8
|
-
* openCalendar, closeCalendar, isCalendarOpen, inputRef, calendarDialogId, etc.
|
|
9
|
-
*/
|
|
10
|
-
export declare const useDatePicker: () => DatePickerContextValueType;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
2
|
-
export const DatePickerContext = /*#__PURE__*/createContext(null);
|
|
3
|
-
|
|
4
|
-
/** Provider component; DatePicker uses this to set the context value. */
|
|
5
|
-
export const DatePickerProvider = DatePickerContext.Provider;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Returns the DatePicker context value (shared state and callbacks).
|
|
9
|
-
* Must be used inside a DatePicker. For composed layouts, use this to get
|
|
10
|
-
* openCalendar, closeCalendar, isCalendarOpen, inputRef, calendarDialogId, etc.
|
|
11
|
-
*/
|
|
12
|
-
export const useDatePicker = () => {
|
|
13
|
-
const value = useContext(DatePickerContext);
|
|
14
|
-
if (value == null) {
|
|
15
|
-
throw new Error('useDatePickerContext must be used within a DatePicker.');
|
|
16
|
-
}
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ComponentProps } from 'react';
|
|
2
|
-
import { Input } from '../Form/inputs/Input';
|
|
3
|
-
/**
|
|
4
|
-
* Props for DatePickerInput. When used inside DatePicker, only overrides (e.g. placeholder, label).
|
|
5
|
-
* In range mode, use rangePart to bind to start or end date. When outside DatePicker, pass value, onChange, etc.
|
|
6
|
-
*/
|
|
7
|
-
export type DatePickerInputProps = Omit<ComponentProps<typeof Input>, 'type' | 'icon'> & {
|
|
8
|
-
/** In range mode: which part of the range this input edits. Omit for single-date or combined display. */
|
|
9
|
-
rangePart?: 'start' | 'end';
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Date input. When inside DatePicker: owns local input value state and syncs to
|
|
13
|
-
* shared selectedDate via context on blur/parse; opens calendar on click/arrow down.
|
|
14
|
-
* When outside DatePicker: fully controlled by props.
|
|
15
|
-
*/
|
|
16
|
-
export declare const DatePickerInput: import("react").ForwardRefExoticComponent<Omit<DatePickerInputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { MiniCalendarIcon } from '@codecademy/gamut-icons';
|
|
2
|
-
import { forwardRef, useEffect, useId, useRef, useState } from 'react';
|
|
3
|
-
import { FormGroup } from '../Form/elements/FormGroup';
|
|
4
|
-
import { Input } from '../Form/inputs/Input';
|
|
5
|
-
import { formatDateForInput, getDateFormatPattern, parseDateFromInput } from './Calendar/utils/format';
|
|
6
|
-
import { useDatePicker } from './DatePickerContext';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Props for DatePickerInput. When used inside DatePicker, only overrides (e.g. placeholder, label).
|
|
10
|
-
* In range mode, use rangePart to bind to start or end date. When outside DatePicker, pass value, onChange, etc.
|
|
11
|
-
*/
|
|
12
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
/**
|
|
14
|
-
* Date input. When inside DatePicker: owns local input value state and syncs to
|
|
15
|
-
* shared selectedDate via context on blur/parse; opens calendar on click/arrow down.
|
|
16
|
-
* When outside DatePicker: fully controlled by props.
|
|
17
|
-
*/
|
|
18
|
-
export const DatePickerInput = /*#__PURE__*/forwardRef(({
|
|
19
|
-
placeholder,
|
|
20
|
-
label,
|
|
21
|
-
rangePart,
|
|
22
|
-
...rest
|
|
23
|
-
}, ref) => {
|
|
24
|
-
const context = useDatePicker();
|
|
25
|
-
if (context == null) {
|
|
26
|
-
throw new Error('DatePickerInput must be used inside a DatePicker (it reads shared state from context).');
|
|
27
|
-
}
|
|
28
|
-
const {
|
|
29
|
-
mode,
|
|
30
|
-
startOrSelectedDate,
|
|
31
|
-
setSelection,
|
|
32
|
-
openCalendar,
|
|
33
|
-
focusCalendarGrid,
|
|
34
|
-
locale,
|
|
35
|
-
isCalendarOpen,
|
|
36
|
-
calendarDialogId,
|
|
37
|
-
translations
|
|
38
|
-
} = context;
|
|
39
|
-
const isRange = mode === 'range';
|
|
40
|
-
const inputID = useId();
|
|
41
|
-
const inputId = `datepicker-input-${inputID.replace(/:/g, '')}`;
|
|
42
|
-
|
|
43
|
-
// Range with two inputs: each input binds to one part. Single or range combined: one value.
|
|
44
|
-
const boundDate = isRange && rangePart === 'end' ? context.endDate : startOrSelectedDate;
|
|
45
|
-
const formattedValue = boundDate != null ? formatDateForInput(boundDate, locale) : '';
|
|
46
|
-
const [inputValue, setInputValue] = useState(() => formattedValue);
|
|
47
|
-
const isInputFocusedRef = useRef(false);
|
|
48
|
-
|
|
49
|
-
// Sync input from shared state. Skip when focused so we don't overwrite while typing.
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
if (!isInputFocusedRef.current) {
|
|
52
|
-
setInputValue(formattedValue);
|
|
53
|
-
}
|
|
54
|
-
}, [formattedValue]);
|
|
55
|
-
|
|
56
|
-
/** Apply raw input string to selection state. Returns formatted string if parsed so caller can sync input (e.g. on blur). */
|
|
57
|
-
const applyValueToSelection = raw => {
|
|
58
|
-
const trimmed = raw.trim();
|
|
59
|
-
if (!trimmed) {
|
|
60
|
-
if (isRange && rangePart) {
|
|
61
|
-
if (rangePart === 'start') setSelection(null, context.endDate);else setSelection(startOrSelectedDate, null);
|
|
62
|
-
} else setSelection(null);
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
const parsed = parseDateFromInput(trimmed, locale);
|
|
66
|
-
if (!parsed) return undefined;
|
|
67
|
-
if (isRange && rangePart) {
|
|
68
|
-
if (rangePart === 'start') setSelection(parsed, context.endDate);else setSelection(startOrSelectedDate, parsed);
|
|
69
|
-
} else setSelection(parsed);
|
|
70
|
-
return formatDateForInput(parsed, locale);
|
|
71
|
-
};
|
|
72
|
-
const handleChange = e => {
|
|
73
|
-
const raw = e.target.value;
|
|
74
|
-
setInputValue(raw);
|
|
75
|
-
applyValueToSelection(raw);
|
|
76
|
-
};
|
|
77
|
-
const handleBlur = () => {
|
|
78
|
-
isInputFocusedRef.current = false;
|
|
79
|
-
const formatted = applyValueToSelection(inputValue.trim());
|
|
80
|
-
if (formatted) setInputValue(formatted);else if (inputValue.trim()) setInputValue(formattedValue);
|
|
81
|
-
};
|
|
82
|
-
const handleKeyDown = e => {
|
|
83
|
-
if (e.key === 'ArrowDown' || e.key === 'Down') {
|
|
84
|
-
e.preventDefault();
|
|
85
|
-
if (isCalendarOpen) {
|
|
86
|
-
focusCalendarGrid();
|
|
87
|
-
} else {
|
|
88
|
-
openCalendar({
|
|
89
|
-
moveFocusIntoCalendar: true
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
const handleOpenCalendar = () => {
|
|
95
|
-
openCalendar({
|
|
96
|
-
moveFocusIntoCalendar: false
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
const defaultLabel = !isRange ? translations.dateLabel : rangePart === 'end' ? translations.endDateLabel : translations.startDateLabel;
|
|
100
|
-
return /*#__PURE__*/_jsx(FormGroup, {
|
|
101
|
-
htmlFor: inputId,
|
|
102
|
-
isSoloField: true // should probaly be based on a prop
|
|
103
|
-
,
|
|
104
|
-
label: label ?? defaultLabel,
|
|
105
|
-
mb: 0,
|
|
106
|
-
pb: 0,
|
|
107
|
-
spacing: "tight",
|
|
108
|
-
width: "170px",
|
|
109
|
-
children: /*#__PURE__*/_jsx(Input, {
|
|
110
|
-
...rest,
|
|
111
|
-
"aria-autocomplete": "none",
|
|
112
|
-
"aria-controls": calendarDialogId,
|
|
113
|
-
"aria-expanded": isCalendarOpen,
|
|
114
|
-
"aria-haspopup": "dialog",
|
|
115
|
-
icon: () => /*#__PURE__*/_jsx(MiniCalendarIcon, {
|
|
116
|
-
size: 16
|
|
117
|
-
}),
|
|
118
|
-
id: inputId,
|
|
119
|
-
placeholder: placeholder ?? getDateFormatPattern(locale),
|
|
120
|
-
ref: ref,
|
|
121
|
-
role: "combobox",
|
|
122
|
-
type: "text",
|
|
123
|
-
value: inputValue,
|
|
124
|
-
onBlur: handleBlur,
|
|
125
|
-
onChange: handleChange,
|
|
126
|
-
onClick: handleOpenCalendar,
|
|
127
|
-
onFocus: () => {
|
|
128
|
-
isInputFocusedRef.current = true;
|
|
129
|
-
if (isRange && rangePart) context.setActiveRangePart(rangePart);
|
|
130
|
-
},
|
|
131
|
-
onKeyDown: handleKeyDown
|
|
132
|
-
})
|
|
133
|
-
});
|
|
134
|
-
});
|
package/dist/DatePicker/index.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { ComponentProps } from 'react';
|
|
2
|
-
import { Input } from '../Form/inputs/Input';
|
|
3
|
-
import { CalendarBaseProps } from './Calendar/types';
|
|
4
|
-
import { DatePickerTranslations } from './utils/translations';
|
|
5
|
-
export interface DatePickerBaseProps extends Pick<CalendarBaseProps, 'locale' | 'disabledDates'> {
|
|
6
|
-
/** When provided, only the provider is rendered and children compose Input + Calendar. */
|
|
7
|
-
children?: React.ReactNode;
|
|
8
|
-
/** Placeholder for the input. */
|
|
9
|
-
placeholder?: string;
|
|
10
|
-
/** Override UI strings (e.g. clear button). Merged with defaults. */
|
|
11
|
-
translations?: DatePickerTranslations;
|
|
12
|
-
inputSize?: ComponentProps<typeof Input>['size'];
|
|
13
|
-
}
|
|
14
|
-
export interface DatePickerSingleProps extends DatePickerBaseProps {
|
|
15
|
-
mode?: 'single';
|
|
16
|
-
/** Controlled selected date. */
|
|
17
|
-
selectedDate: Date | null;
|
|
18
|
-
/** Called when the user selects a date. */
|
|
19
|
-
setSelectedDate: (date: Date | null) => void;
|
|
20
|
-
/** Label for the input. */
|
|
21
|
-
label?: string;
|
|
22
|
-
}
|
|
23
|
-
export interface DatePickerRangeProps extends DatePickerBaseProps {
|
|
24
|
-
mode: 'range';
|
|
25
|
-
/** Controlled start date. */
|
|
26
|
-
startDate: Date | null;
|
|
27
|
-
/** Controlled end date. */
|
|
28
|
-
endDate: Date | null;
|
|
29
|
-
/** Called when the user changes the start date. */
|
|
30
|
-
setStartDate: (date: Date | null) => void;
|
|
31
|
-
/** Called when the user changes the end date. */
|
|
32
|
-
setEndDate: (date: Date | null) => void;
|
|
33
|
-
/** Label for the start date input. */
|
|
34
|
-
startLabel?: string;
|
|
35
|
-
/** Label for the end date input. */
|
|
36
|
-
endLabel?: string;
|
|
37
|
-
}
|
|
38
|
-
export type DatePickerProps = DatePickerSingleProps | DatePickerRangeProps;
|
|
39
|
-
export type OpenCalendarOptions = {
|
|
40
|
-
/**
|
|
41
|
-
* When true, move DOM focus into the date grid after open (keyboard / explicit request).
|
|
42
|
-
* When false (default), keep focus on the input so pointer users can type (WCAG 3.2.1).
|
|
43
|
-
*/
|
|
44
|
-
moveFocusIntoCalendar?: boolean;
|
|
45
|
-
};
|
|
46
|
-
export interface DatePickerBaseContextValue extends Pick<CalendarBaseProps, 'disabledDates'> {
|
|
47
|
-
/**
|
|
48
|
-
* Resolved `Intl.Locale` from the `locale` prop (or runtime default). Same instance passed to
|
|
49
|
-
* formatters and available for `getWeekInfo()` etc.
|
|
50
|
-
*/
|
|
51
|
-
locale: Intl.Locale;
|
|
52
|
-
isCalendarOpen: boolean;
|
|
53
|
-
openCalendar: (options?: OpenCalendarOptions) => void;
|
|
54
|
-
/** Move focus from the input into the grid when the calendar is already open (e.g. ArrowDown). */
|
|
55
|
-
focusCalendarGrid: () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Flips on each grid focus request so `CalendarBody` effects re-run when `focusTarget` is unchanged.
|
|
58
|
-
* Not a semantic true/false — only the change matters; pair with `gridFocusRequested`.
|
|
59
|
-
*/
|
|
60
|
-
focusGridSignal: boolean;
|
|
61
|
-
/** When true, `CalendarBody` runs a one-shot move of DOM focus into the grid if it is not already there. */
|
|
62
|
-
gridFocusRequested: boolean;
|
|
63
|
-
/** Clears `gridFocusRequested` after focus has moved into the grid (or call when closing). */
|
|
64
|
-
clearGridFocusRequest: () => void;
|
|
65
|
-
closeCalendar: () => void;
|
|
66
|
-
calendarDialogId: string;
|
|
67
|
-
/** UI string overrides (e.g. clear button). */
|
|
68
|
-
translations: Required<DatePickerTranslations>;
|
|
69
|
-
/** Start date (range) or selected date (single). */
|
|
70
|
-
startOrSelectedDate: Date | null;
|
|
71
|
-
/** Set selection. Single: (date). Range: (start, end). */
|
|
72
|
-
setSelection: (startOrSelectedDate: Date | null, endDate?: Date | null) => void;
|
|
73
|
-
}
|
|
74
|
-
export interface DatePickerSingleContextValue extends DatePickerBaseContextValue {
|
|
75
|
-
mode: 'single';
|
|
76
|
-
}
|
|
77
|
-
export type ActiveRangePart = 'start' | 'end' | null;
|
|
78
|
-
export interface DatePickerRangeContextValue extends DatePickerBaseContextValue {
|
|
79
|
-
mode: 'range';
|
|
80
|
-
endDate: Date | null;
|
|
81
|
-
/** Which input is active (start/end focused); null = selection mode. */
|
|
82
|
-
activeRangePart: ActiveRangePart;
|
|
83
|
-
/** Set which input is active (e.g. when input receives focus). */
|
|
84
|
-
setActiveRangePart: (part: ActiveRangePart) => void;
|
|
85
|
-
}
|
|
86
|
-
export type DatePickerContextValue = DatePickerSingleContextValue | DatePickerRangeContextValue;
|
package/dist/DatePicker/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { DatePickerBaseContextValue, DatePickerProps, DatePickerRangeContextValue, DatePickerRangeProps } from '../types';
|
|
2
|
-
export declare const isRangeProps: (props: DatePickerProps) => props is DatePickerRangeProps;
|
|
3
|
-
export type RangeContainsDisabledParams = {
|
|
4
|
-
start: Date;
|
|
5
|
-
end: Date;
|
|
6
|
-
disabledDates: Date[];
|
|
7
|
-
};
|
|
8
|
-
/** True if any disabled date falls within [start, end] (inclusive, by calendar day). */
|
|
9
|
-
export declare const rangeContainsDisabled: ({ start, end, disabledDates, }: RangeContainsDisabledParams) => boolean;
|
|
10
|
-
export type HandleDateSelectSingleParams = {
|
|
11
|
-
date: Date;
|
|
12
|
-
selectedDate: DatePickerBaseContextValue['startOrSelectedDate'];
|
|
13
|
-
} & Pick<DatePickerBaseContextValue, 'setSelection'>;
|
|
14
|
-
export declare const handleDateSelectSingle: ({ date, selectedDate, setSelection, }: HandleDateSelectSingleParams) => void;
|
|
15
|
-
export type HandleDateSelectRangeParams = {
|
|
16
|
-
date: Date;
|
|
17
|
-
startDate: DatePickerRangeContextValue['startOrSelectedDate'];
|
|
18
|
-
} & Pick<DatePickerRangeContextValue, 'activeRangePart' | 'endDate' | 'setSelection' | 'disabledDates'>;
|
|
19
|
-
export declare const handleDateSelectRange: ({ date, activeRangePart, startDate, endDate, setSelection, disabledDates, }: HandleDateSelectRangeParams) => void;
|