@arbor-education/design-system.components 0.8.1 → 0.10.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/.github/workflows/release.yml +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +2 -2
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.js +10 -8
- package/dist/components/combobox/Combobox.js.map +1 -1
- package/dist/components/combobox/Combobox.stories.d.ts +1 -0
- package/dist/components/combobox/Combobox.stories.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.stories.js +16 -0
- package/dist/components/combobox/Combobox.stories.js.map +1 -1
- package/dist/components/combobox/Combobox.test.js +107 -61
- package/dist/components/combobox/Combobox.test.js.map +1 -1
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts +4 -2
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts.map +1 -1
- package/dist/components/combobox/ComboboxButtonTrigger.js +11 -4
- package/dist/components/combobox/ComboboxButtonTrigger.js.map +1 -1
- package/dist/components/combobox/ComboboxTrigger.d.ts +3 -1
- package/dist/components/combobox/ComboboxTrigger.d.ts.map +1 -1
- package/dist/components/combobox/ComboboxTrigger.js +10 -2
- package/dist/components/combobox/ComboboxTrigger.js.map +1 -1
- package/dist/components/combobox/types.d.ts +3 -0
- package/dist/components/combobox/types.d.ts.map +1 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts +3 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts.map +1 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.js +7 -6
- package/dist/components/combobox/useComboboxPopoverBehavior.js.map +1 -1
- package/dist/components/combobox/useComboboxState.d.ts.map +1 -1
- package/dist/components/combobox/useComboboxState.js +4 -1
- package/dist/components/combobox/useComboboxState.js.map +1 -1
- package/dist/components/datePicker/DatePicker.d.ts +4 -1
- package/dist/components/datePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.js +77 -37
- package/dist/components/datePicker/DatePicker.js.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.d.ts +28 -3
- package/dist/components/datePicker/DatePicker.stories.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.js +62 -9
- package/dist/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/components/datePicker/DatePicker.test.js +133 -66
- package/dist/components/datePicker/DatePicker.test.js.map +1 -1
- package/dist/components/datePicker/DatePickerCalendarHeader.d.ts +8 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.d.ts.map +1 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.js +36 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.js.map +1 -0
- package/dist/components/datePicker/dateInputUtils.d.ts +25 -0
- package/dist/components/datePicker/dateInputUtils.d.ts.map +1 -0
- package/dist/components/datePicker/dateInputUtils.js +60 -0
- package/dist/components/datePicker/dateInputUtils.js.map +1 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.d.ts +2 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.d.ts.map +1 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.js +4 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.d.ts +22 -0
- package/dist/components/dateTimePicker/DateTimePicker.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.js +132 -0
- package/dist/components/dateTimePicker/DateTimePicker.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts +77 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.js +163 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.d.ts +2 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.js +235 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.js.map +1 -0
- package/dist/components/formField/FormField.d.ts +4 -0
- package/dist/components/formField/FormField.d.ts.map +1 -1
- package/dist/components/formField/FormField.js +2 -1
- package/dist/components/formField/FormField.js.map +1 -1
- package/dist/components/formField/FormField.stories.d.ts.map +1 -1
- package/dist/components/formField/FormField.stories.js +4 -1
- package/dist/components/formField/FormField.stories.js.map +1 -1
- package/dist/components/formField/FormField.test.d.ts.map +1 -1
- package/dist/components/formField/FormField.test.js +10 -5
- package/dist/components/formField/FormField.test.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts +1 -0
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js +7 -3
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.test.js +12 -0
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.test.js.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.d.ts +4 -1
- package/dist/components/formField/inputs/text/TextInput.d.ts.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.js +5 -4
- package/dist/components/formField/inputs/text/TextInput.js.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.stories.d.ts +4 -1
- package/dist/components/formField/inputs/text/TextInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.d.ts +29 -0
- package/dist/components/formField/inputs/time/TimeInput.d.ts.map +1 -0
- package/dist/components/formField/inputs/time/TimeInput.js +67 -0
- package/dist/components/formField/inputs/time/TimeInput.js.map +1 -0
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +60 -0
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts.map +1 -0
- package/dist/components/formField/inputs/time/TimeInput.stories.js +132 -0
- package/dist/components/formField/inputs/time/TimeInput.stories.js.map +1 -0
- package/dist/components/formField/inputs/time/TimeInput.test.d.ts +2 -0
- package/dist/components/formField/inputs/time/TimeInput.test.d.ts.map +1 -0
- package/dist/components/formField/inputs/time/TimeInput.test.js +58 -0
- package/dist/components/formField/inputs/time/TimeInput.test.js.map +1 -0
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +2 -0
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts +1 -0
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +37 -0
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/cellRenderers/BooleanCellRenderer.d.ts +3 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.js +15 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.js.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.d.ts +2 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.js +31 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.js.map +1 -0
- package/dist/index.css +309 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.tsx +2 -1
- package/src/components/combobox/Combobox.stories.tsx +18 -0
- package/src/components/combobox/Combobox.test.tsx +131 -61
- package/src/components/combobox/Combobox.tsx +15 -6
- package/src/components/combobox/ComboboxButtonTrigger.tsx +54 -25
- package/src/components/combobox/ComboboxTrigger.tsx +39 -15
- package/src/components/combobox/combobox.scss +18 -0
- package/src/components/combobox/types.ts +3 -0
- package/src/components/combobox/useComboboxPopoverBehavior.ts +10 -5
- package/src/components/combobox/useComboboxState.ts +4 -1
- package/src/components/datePicker/DatePicker.stories.tsx +67 -9
- package/src/components/datePicker/DatePicker.test.tsx +157 -72
- package/src/components/datePicker/DatePicker.tsx +163 -69
- package/src/components/datePicker/DatePickerCalendarHeader.tsx +82 -0
- package/src/components/datePicker/date-field-hint.scss +152 -0
- package/src/components/datePicker/dateInputUtils.ts +117 -0
- package/src/components/datePicker/datePicker.scss +53 -29
- package/src/components/datePicker/datePickerTestUtils.test-helpers.ts +6 -0
- package/src/components/dateTimePicker/DateTimePicker.stories.tsx +202 -0
- package/src/components/dateTimePicker/DateTimePicker.test.tsx +295 -0
- package/src/components/dateTimePicker/DateTimePicker.tsx +293 -0
- package/src/components/dateTimePicker/dateTimePicker.scss +17 -0
- package/src/components/formField/FormField.stories.tsx +10 -1
- package/src/components/formField/FormField.test.tsx +11 -5
- package/src/components/formField/FormField.tsx +5 -0
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.test.tsx +28 -0
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.tsx +8 -2
- package/src/components/formField/inputs/text/TextInput.tsx +6 -3
- package/src/components/formField/inputs/time/TimeInput.stories.tsx +170 -0
- package/src/components/formField/inputs/time/TimeInput.test.tsx +86 -0
- package/src/components/formField/inputs/time/TimeInput.tsx +168 -0
- package/src/components/formField/inputs/time/timeInput.scss +33 -0
- package/src/components/row/row.scss +2 -2
- package/src/components/table/Table.stories.tsx +48 -0
- package/src/components/table/Table.tsx +2 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.test.tsx +37 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.tsx +34 -0
- package/src/components/table/cellRenderers/booleanCellRenderer.scss +7 -0
- package/src/index.scss +3 -0
- package/src/index.ts +5 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Test-only; do not barrel-export or import from app/library code. */
|
|
2
|
+
import { screen } from '@testing-library/react';
|
|
3
|
+
export const getDropdownTrigger = (name) => (screen.getAllByRole('button', { name }).find(button => button.className.includes('ds-button--dropdown')));
|
|
4
|
+
//# sourceMappingURL=datePickerTestUtils.test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datePickerTestUtils.test-helpers.js","sourceRoot":"","sources":["../../../src/components/datePicker/datePickerTestUtils.test-helpers.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAClD,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CACzG,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ComboboxSearchType } from '../combobox/types';
|
|
2
|
+
import { type DateTimePickerDisplayFormat } from '../datePicker/dateInputUtils';
|
|
3
|
+
import { type TimeGranularity, type TimeValue } from '../formField/inputs/time/TimeInput';
|
|
4
|
+
export type DateTimePickerProps = {
|
|
5
|
+
'className'?: string;
|
|
6
|
+
'onChange'?: (newDate?: Date) => void;
|
|
7
|
+
'id'?: string;
|
|
8
|
+
'hasError'?: boolean;
|
|
9
|
+
'aria-describedby'?: string;
|
|
10
|
+
'aria-invalid'?: boolean;
|
|
11
|
+
'value'?: Date;
|
|
12
|
+
'defaultValue'?: Date;
|
|
13
|
+
'granularity'?: TimeGranularity;
|
|
14
|
+
'displayFormat'?: DateTimePickerDisplayFormat;
|
|
15
|
+
'timeOptions'?: TimeValue[];
|
|
16
|
+
'searchType'?: ComboboxSearchType;
|
|
17
|
+
'highlightStringMatches'?: boolean;
|
|
18
|
+
'placeholder'?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const DateTimePicker: (props: DateTimePickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export type { DateTimePickerDisplayFormat } from '../datePicker/dateInputUtils';
|
|
22
|
+
//# sourceMappingURL=DateTimePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../../../src/components/dateTimePicker/DateTimePicker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAUL,KAAK,2BAA2B,EACjC,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAa,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,4CAA4C,CAAC;AAM7G,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,eAAe,CAAC,EAAE,2BAA2B,CAAC;IAC9C,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,mBAAmB,4CA0PxD,CAAC;AAEF,YAAY,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { Button } from '../button/Button';
|
|
4
|
+
import { formatDateTimeInputValue, formatNativeDateTimeInputValue, formatTimeInputValue, getDateTimePlaceholder, getNativeDateTimePlaceholder, mergeDateAndTime, parseDateTimeInputValue, parseNativeDateTimeInputValue, } from '../datePicker/dateInputUtils';
|
|
5
|
+
import { DatePickerCalendarHeader } from '../datePicker/DatePickerCalendarHeader';
|
|
6
|
+
import { TextInput } from '../formField/inputs/text/TextInput';
|
|
7
|
+
import { TimeInput } from '../formField/inputs/time/TimeInput';
|
|
8
|
+
import { Popover } from 'radix-ui';
|
|
9
|
+
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
|
10
|
+
import { DayPicker } from 'react-day-picker';
|
|
11
|
+
import { PopupParentContext } from '../../utils/PopupParentContext';
|
|
12
|
+
export const DateTimePicker = (props) => {
|
|
13
|
+
const { className, onChange, id, hasError, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, value, defaultValue, displayFormat = 'native', granularity = 'minute', timeOptions, searchType = 'prefix', highlightStringMatches = false, placeholder, } = props;
|
|
14
|
+
const isNative = displayFormat === 'native';
|
|
15
|
+
const formatInputValue = useCallback((date) => displayFormat === 'native'
|
|
16
|
+
? formatNativeDateTimeInputValue(date, granularity)
|
|
17
|
+
: formatDateTimeInputValue(date, displayFormat, granularity), [displayFormat, granularity]);
|
|
18
|
+
const parseInputValue = useCallback((raw) => displayFormat === 'native'
|
|
19
|
+
? parseNativeDateTimeInputValue(raw, granularity)
|
|
20
|
+
: parseDateTimeInputValue(raw, displayFormat, granularity), [displayFormat, granularity]);
|
|
21
|
+
const resolvedPlaceholder = placeholder ?? (isNative
|
|
22
|
+
? getNativeDateTimePlaceholder(granularity)
|
|
23
|
+
: getDateTimePlaceholder(displayFormat, granularity));
|
|
24
|
+
const initialValue = value ?? defaultValue;
|
|
25
|
+
const isControlled = value !== undefined;
|
|
26
|
+
const [month, setMonth] = useState(initialValue ?? new Date());
|
|
27
|
+
const [selectedDateTime, setSelectedDateTime] = useState(initialValue);
|
|
28
|
+
const [inputValue, setInputValue] = useState(initialValue ? formatInputValue(initialValue) : '');
|
|
29
|
+
const [timeInputValue, setTimeInputValue] = useState(initialValue ? formatTimeInputValue(initialValue, granularity) : '');
|
|
30
|
+
const [isPickerOpen, setIsPickerOpen] = useState(false);
|
|
31
|
+
const inputRef = useRef(null);
|
|
32
|
+
const selectedDateTimeRef = useRef(selectedDateTime);
|
|
33
|
+
selectedDateTimeRef.current = selectedDateTime;
|
|
34
|
+
const showFieldHint = isNative && selectedDateTime === undefined && inputValue === '';
|
|
35
|
+
const hasCustomEmptyHint = showFieldHint && placeholder !== undefined;
|
|
36
|
+
/** Custom empty hint in native mode: open only on pointer (not Tab focus). */
|
|
37
|
+
const onNativeFieldHintPointerDown = (e) => {
|
|
38
|
+
if (hasCustomEmptyHint) {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
setIsPickerOpen(true);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!isControlled) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const valueTime = value?.getTime();
|
|
48
|
+
const selectedTime = selectedDateTimeRef.current?.getTime();
|
|
49
|
+
if (valueTime !== selectedTime) {
|
|
50
|
+
setSelectedDateTime(value);
|
|
51
|
+
setMonth(value ?? new Date());
|
|
52
|
+
setInputValue(value ? formatInputValue(value) : '');
|
|
53
|
+
setTimeInputValue(value ? formatTimeInputValue(value, granularity) : '');
|
|
54
|
+
}
|
|
55
|
+
}, [value, isControlled, granularity, formatInputValue]);
|
|
56
|
+
const mountedRef = useRef(false);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
// Skip reformat on initial mount (`useState` already seeded input/time strings). Only re-run when
|
|
59
|
+
// `granularity` or `displayFormat` changes after mount.
|
|
60
|
+
if (!mountedRef.current) {
|
|
61
|
+
mountedRef.current = true;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const current = selectedDateTimeRef.current;
|
|
65
|
+
if (current) {
|
|
66
|
+
setInputValue(formatInputValue(current));
|
|
67
|
+
setTimeInputValue(formatTimeInputValue(current, granularity));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
setInputValue('');
|
|
71
|
+
setTimeInputValue('');
|
|
72
|
+
}
|
|
73
|
+
}, [granularity, displayFormat, formatInputValue]);
|
|
74
|
+
const onInputChange = (event) => {
|
|
75
|
+
const nextInputValue = event.target.value;
|
|
76
|
+
setInputValue(nextInputValue);
|
|
77
|
+
const parsedDate = parseInputValue(nextInputValue);
|
|
78
|
+
if (parsedDate) {
|
|
79
|
+
setSelectedDateTime(parsedDate);
|
|
80
|
+
setMonth(parsedDate);
|
|
81
|
+
setTimeInputValue(formatTimeInputValue(parsedDate, granularity));
|
|
82
|
+
onChange?.(parsedDate);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
setSelectedDateTime(undefined);
|
|
86
|
+
onChange?.(undefined);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const handleTimeChange = (nextTimeValue) => {
|
|
90
|
+
setTimeInputValue(nextTimeValue);
|
|
91
|
+
if (!selectedDateTime) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const nextDateTime = mergeDateAndTime(selectedDateTime, nextTimeValue, granularity);
|
|
95
|
+
setSelectedDateTime(nextDateTime);
|
|
96
|
+
setInputValue(formatInputValue(nextDateTime));
|
|
97
|
+
onChange?.(nextDateTime);
|
|
98
|
+
};
|
|
99
|
+
const handleDayPickerSelect = (nextDate) => {
|
|
100
|
+
if (!nextDate) {
|
|
101
|
+
setSelectedDateTime(undefined);
|
|
102
|
+
setInputValue('');
|
|
103
|
+
setIsPickerOpen(false);
|
|
104
|
+
onChange?.(undefined);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const nextDateTime = mergeDateAndTime(nextDate, timeInputValue, granularity);
|
|
108
|
+
setSelectedDateTime(nextDateTime);
|
|
109
|
+
setMonth(nextDateTime);
|
|
110
|
+
setInputValue(formatInputValue(nextDateTime));
|
|
111
|
+
// UX trade-off: closing here means the user must reopen the popover to set time if they picked the day first.
|
|
112
|
+
// Alternatives (keep open until time is chosen) are a deliberate product change.
|
|
113
|
+
setIsPickerOpen(false);
|
|
114
|
+
onChange?.(nextDateTime);
|
|
115
|
+
};
|
|
116
|
+
const handleTodayClick = () => {
|
|
117
|
+
const nextDate = mergeDateAndTime(new Date(), timeInputValue, granularity);
|
|
118
|
+
setSelectedDateTime(nextDate);
|
|
119
|
+
setMonth(nextDate);
|
|
120
|
+
setInputValue(formatInputValue(nextDate));
|
|
121
|
+
setIsPickerOpen(false);
|
|
122
|
+
onChange?.(nextDate);
|
|
123
|
+
};
|
|
124
|
+
const popupParentRef = useContext(PopupParentContext);
|
|
125
|
+
return (_jsxs("div", { className: classNames('ds-date-time-picker', className), children: [_jsxs("div", { className: classNames('ds-date-time-picker__field', { 'ds-date-time-picker__field--show-hint': showFieldHint }), children: [_jsx(TextInput, { ref: inputRef, type: isNative ? 'datetime-local' : 'text', value: inputValue, onChange: onInputChange, onPointerDown: onNativeFieldHintPointerDown, readOnly: hasCustomEmptyHint, id: id, step: isNative ? (granularity === 'second' ? 1 : 60) : undefined, placeholder: showFieldHint ? '' : resolvedPlaceholder, hasError: hasError, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, className: "ds-date-time-picker__input" }), showFieldHint
|
|
126
|
+
? (_jsx("span", { className: "ds-date-time-picker__field-hint", "aria-hidden": "true", children: resolvedPlaceholder }))
|
|
127
|
+
: null] }), _jsxs(Popover.Root, { open: isPickerOpen, onOpenChange: open => setIsPickerOpen(open), children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx(Button, { className: "ds-date-time-picker__button", variant: "text-link", iconLeftName: "date", iconLeftScreenReaderText: "Open date and time picker" }) }), _jsx(Popover.Portal, { container: popupParentRef.current, children: _jsx(Popover.Content, { align: "end", sideOffset: 5, onOpenAutoFocus: e => e.preventDefault(), onCloseAutoFocus: (e) => {
|
|
128
|
+
e.preventDefault();
|
|
129
|
+
inputRef.current?.focus();
|
|
130
|
+
}, children: _jsxs("div", { className: "ds-date-time-picker__popup", children: [_jsx(TimeInput, { className: "ds-date-time-picker__time", "aria-label": "Select time", value: timeInputValue, onValueChange: handleTimeChange, granularity: granularity, options: timeOptions, searchType: searchType, highlightStringMatches: highlightStringMatches, hasError: hasError }), _jsx(DatePickerCalendarHeader, { month: month, onMonthChange: setMonth }), _jsx(DayPicker, { className: "ds-date-time-picker__calendar", month: month, onMonthChange: setMonth, autoFocus: true, role: "application", mode: "single", selected: selectedDateTime, onSelect: handleDayPickerSelect, hideNavigation: true, footer: (_jsx(Button, { variant: "text-link", onClick: handleTodayClick, className: "ds-date-time-picker__today-button", children: "Today" })) })] }) }) })] })] }));
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=DateTimePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.js","sourceRoot":"","sources":["../../../src/components/dateTimePicker/DateTimePicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { type DateTimePickerProps } from './DateTimePicker';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: (props: DateTimePickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn<import("@storybook/react-vite").ReactRenderer, {
|
|
7
|
+
className?: string | undefined;
|
|
8
|
+
onChange?: ((newDate?: Date) => void) | undefined;
|
|
9
|
+
id?: string | undefined;
|
|
10
|
+
hasError?: boolean | undefined;
|
|
11
|
+
'aria-describedby'?: string | undefined;
|
|
12
|
+
'aria-invalid'?: boolean | undefined;
|
|
13
|
+
value?: Date | undefined;
|
|
14
|
+
defaultValue?: Date | undefined;
|
|
15
|
+
granularity?: import("../..").TimeGranularity | undefined;
|
|
16
|
+
displayFormat?: import("../datePicker/dateInputUtils").DateTimePickerDisplayFormat | undefined;
|
|
17
|
+
timeOptions?: import("../..").TimeValue[] | undefined;
|
|
18
|
+
searchType?: import("../..").ComboboxSearchType | undefined;
|
|
19
|
+
highlightStringMatches?: boolean | undefined;
|
|
20
|
+
placeholder?: string | undefined;
|
|
21
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
22
|
+
parameters: {
|
|
23
|
+
layout: string;
|
|
24
|
+
docs: {
|
|
25
|
+
description: {
|
|
26
|
+
component: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
tags: string[];
|
|
31
|
+
args: {
|
|
32
|
+
onChange: import("@vitest/spy").Mock<(...args: any[]) => any>;
|
|
33
|
+
};
|
|
34
|
+
argTypes: {
|
|
35
|
+
displayFormat: {
|
|
36
|
+
control: "inline-radio";
|
|
37
|
+
options: string[];
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
granularity: {
|
|
41
|
+
control: "inline-radio";
|
|
42
|
+
options: string[];
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
timeOptions: {
|
|
46
|
+
control: "object";
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
value: {
|
|
50
|
+
control: false;
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
53
|
+
defaultValue: {
|
|
54
|
+
control: false;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
onChange: {
|
|
58
|
+
action: string;
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
placeholder: {
|
|
62
|
+
control: "text";
|
|
63
|
+
description: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export default meta;
|
|
68
|
+
type Story = StoryObj<typeof meta>;
|
|
69
|
+
export declare const NativeTime: Story;
|
|
70
|
+
export declare const TimeList: Story;
|
|
71
|
+
export declare const ControlledValuePreview: Story;
|
|
72
|
+
export declare const PlaceholderNativeMinuteHint: Story;
|
|
73
|
+
export declare const PlaceholderNativeSecondHint: Story;
|
|
74
|
+
export declare const DisplayFormatDefault: Story;
|
|
75
|
+
export declare const DisplayFormatFriendly: Story;
|
|
76
|
+
export declare const PlaceholderCustomOverride: Story;
|
|
77
|
+
//# sourceMappingURL=DateTimePicker.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.stories.d.ts","sourceRoot":"","sources":["../../../src/components/dateTimePicker/DateTimePicker.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI5E,QAAA,MAAM,IAAI;;;;;4BAkBR,CAAF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCuC,CAAC;AAExC,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAiCnC,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAMtB,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KAMpC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAYzC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAYzC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAelC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAenC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAcvC,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { formatNativeDateTimeInputValue } from '../datePicker/dateInputUtils';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { fn } from 'storybook/test';
|
|
5
|
+
import { DateTimePicker } from './DateTimePicker';
|
|
6
|
+
const timeOptions = ['09:00', '09:30', '10:00', '10:30', '11:00'];
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Components/DateTimePicker',
|
|
9
|
+
component: DateTimePicker,
|
|
10
|
+
decorators: [
|
|
11
|
+
Story => (_jsx("div", { style: { maxWidth: '280px', width: '100%' }, children: _jsx(Story, {}) })),
|
|
12
|
+
],
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: 'centered',
|
|
15
|
+
docs: {
|
|
16
|
+
description: {
|
|
17
|
+
component: '`DateTimePicker` combines a date field with the existing `TimeInput`, keeping a single combined `Date` value. `displayFormat="native"` (default) uses a `datetime-local` input with a decorative empty-state hint span (browsers do not reliably show placeholders on native date/time fields). `"default"` and `"friendly"` use a plain text input with locale-style formatting and a real HTML placeholder.',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
tags: ['autodocs'],
|
|
22
|
+
args: {
|
|
23
|
+
onChange: fn(),
|
|
24
|
+
},
|
|
25
|
+
argTypes: {
|
|
26
|
+
displayFormat: {
|
|
27
|
+
control: 'inline-radio',
|
|
28
|
+
options: ['native', 'default', 'friendly'],
|
|
29
|
+
description: '`native`: ISO `datetime-local` (default). `default` / `friendly`: plain text field using the same date patterns as `DatePicker` plus time.',
|
|
30
|
+
},
|
|
31
|
+
granularity: {
|
|
32
|
+
control: 'inline-radio',
|
|
33
|
+
options: ['minute', 'second'],
|
|
34
|
+
description: 'Controls whether the native `datetime-local` input and embedded time input use minute or second precision.',
|
|
35
|
+
},
|
|
36
|
+
timeOptions: {
|
|
37
|
+
control: 'object',
|
|
38
|
+
description: 'When provided, the embedded time input switches to list-backed time selection.',
|
|
39
|
+
},
|
|
40
|
+
value: {
|
|
41
|
+
control: false,
|
|
42
|
+
description: 'Controlled combined datetime value for app-level state.',
|
|
43
|
+
},
|
|
44
|
+
defaultValue: {
|
|
45
|
+
control: false,
|
|
46
|
+
description: 'Uncontrolled initial combined datetime value.',
|
|
47
|
+
},
|
|
48
|
+
onChange: {
|
|
49
|
+
action: 'changed',
|
|
50
|
+
description: 'Called with the next combined `Date` value, or `undefined` when the date becomes invalid/cleared.',
|
|
51
|
+
},
|
|
52
|
+
placeholder: {
|
|
53
|
+
control: 'text',
|
|
54
|
+
description: 'Optional override for the field placeholder (defaults from `displayFormat` and `granularity`).',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export default meta;
|
|
59
|
+
const ControlledDateTimePicker = ({ showCurrentValue = false, ...args }) => {
|
|
60
|
+
const [value, setValue] = useState(args.value);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
setValue(args.value);
|
|
63
|
+
}, [args.value]);
|
|
64
|
+
return (_jsxs("div", { style: { display: 'grid', gap: 12, width: '100%', maxWidth: 320 }, children: [_jsx(DateTimePicker, { ...args, value: value, onChange: (nextValue) => {
|
|
65
|
+
setValue(nextValue);
|
|
66
|
+
args.onChange?.(nextValue);
|
|
67
|
+
} }), showCurrentValue && (_jsxs("span", { children: ["Current value:", ' ', value ? formatNativeDateTimeInputValue(value, args.granularity) : 'None'] }))] }));
|
|
68
|
+
};
|
|
69
|
+
export const NativeTime = {
|
|
70
|
+
args: {
|
|
71
|
+
value: new Date(2026, 3, 14, 14, 27),
|
|
72
|
+
granularity: 'minute',
|
|
73
|
+
},
|
|
74
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args }),
|
|
75
|
+
};
|
|
76
|
+
export const TimeList = {
|
|
77
|
+
args: {
|
|
78
|
+
value: new Date(2026, 3, 14, 10, 0),
|
|
79
|
+
timeOptions: [...timeOptions],
|
|
80
|
+
},
|
|
81
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args }),
|
|
82
|
+
};
|
|
83
|
+
export const ControlledValuePreview = {
|
|
84
|
+
args: {
|
|
85
|
+
value: new Date(2026, 3, 14, 14, 27),
|
|
86
|
+
granularity: 'minute',
|
|
87
|
+
},
|
|
88
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args, showCurrentValue: true }),
|
|
89
|
+
};
|
|
90
|
+
export const PlaceholderNativeMinuteHint = {
|
|
91
|
+
name: 'Placeholder · native minute hint',
|
|
92
|
+
args: {
|
|
93
|
+
granularity: 'minute',
|
|
94
|
+
},
|
|
95
|
+
parameters: {
|
|
96
|
+
docs: {
|
|
97
|
+
description: {
|
|
98
|
+
story: 'Uncontrolled, no initial value — empty-state hint shows `YYYY-MM-DDTHH:mm` (decorative span for native mode).',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
export const PlaceholderNativeSecondHint = {
|
|
104
|
+
name: 'Placeholder · native second hint',
|
|
105
|
+
args: {
|
|
106
|
+
granularity: 'second',
|
|
107
|
+
},
|
|
108
|
+
parameters: {
|
|
109
|
+
docs: {
|
|
110
|
+
description: {
|
|
111
|
+
story: 'Same as the minute story, but with `granularity="second"` so the hint includes seconds.',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
export const DisplayFormatDefault = {
|
|
117
|
+
name: 'Display format · default (text)',
|
|
118
|
+
args: {
|
|
119
|
+
displayFormat: 'default',
|
|
120
|
+
value: new Date(2026, 3, 14, 14, 27),
|
|
121
|
+
granularity: 'minute',
|
|
122
|
+
},
|
|
123
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args }),
|
|
124
|
+
parameters: {
|
|
125
|
+
docs: {
|
|
126
|
+
description: {
|
|
127
|
+
story: 'Combined value is shown and edited as **15/04/2026 14:27** instead of the native ISO string.',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
export const DisplayFormatFriendly = {
|
|
133
|
+
name: 'Display format · friendly (text)',
|
|
134
|
+
args: {
|
|
135
|
+
displayFormat: 'friendly',
|
|
136
|
+
value: new Date(2026, 3, 14, 14, 27),
|
|
137
|
+
granularity: 'minute',
|
|
138
|
+
},
|
|
139
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args }),
|
|
140
|
+
parameters: {
|
|
141
|
+
docs: {
|
|
142
|
+
description: {
|
|
143
|
+
story: 'Combined value uses friendly wording, e.g. **April 14th, 2026 14:27**.',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
export const PlaceholderCustomOverride = {
|
|
149
|
+
name: 'Placeholder · custom copy',
|
|
150
|
+
args: {
|
|
151
|
+
granularity: 'minute',
|
|
152
|
+
placeholder: 'Event start (local)',
|
|
153
|
+
},
|
|
154
|
+
parameters: {
|
|
155
|
+
docs: {
|
|
156
|
+
description: {
|
|
157
|
+
story: 'Pass `placeholder` to replace the default native empty-state hint.',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
render: args => _jsx(ControlledDateTimePicker, { ...args }),
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=DateTimePicker.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.stories.js","sourceRoot":"","sources":["../../../src/components/dateTimePicker/DateTimePicker.stories.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimePicker.test.d.ts","sourceRoot":"","sources":["../../../src/components/dateTimePicker/DateTimePicker.test.tsx"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC"}
|