@os-design/core 1.0.199 → 1.0.200
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/package.json +21 -13
- package/src/@types/emotion.d.ts +7 -0
- package/src/Alert/index.tsx +112 -0
- package/src/Avatar/index.tsx +173 -0
- package/src/Avatar/utils/nameToInitials.ts +12 -0
- package/src/Avatar/utils/strToHue.ts +13 -0
- package/src/AvatarSkeleton/index.tsx +29 -0
- package/src/Breadcrumb/index.tsx +93 -0
- package/src/BreadcrumbItem/index.tsx +83 -0
- package/src/Button/ButtonContent.tsx +91 -0
- package/src/Button/index.tsx +225 -0
- package/src/Button/utils/useButtonColors.ts +84 -0
- package/src/Checkbox/index.tsx +225 -0
- package/src/CheckboxSkeleton/index.tsx +50 -0
- package/src/DatePicker/DatePickerCalendar.tsx +220 -0
- package/src/DatePicker/index.tsx +568 -0
- package/src/Drawer/index.tsx +212 -0
- package/src/Form/FormConfigContext.ts +16 -0
- package/src/Form/index.tsx +49 -0
- package/src/FormDivider/index.tsx +74 -0
- package/src/FormItem/index.tsx +118 -0
- package/src/Gallery/Status.tsx +62 -0
- package/src/Gallery/index.tsx +290 -0
- package/src/GlobalStyles/index.tsx +17 -0
- package/src/GlobalStyles/resetStyles.ts +17 -0
- package/src/GlobalStyles/typographyStyles.ts +78 -0
- package/src/HeaderSkeleton/index.tsx +64 -0
- package/src/Image/index.tsx +104 -0
- package/src/ImageSkeleton/index.tsx +22 -0
- package/src/Input/index.tsx +330 -0
- package/src/Input/utils/getFocusableElements.ts +8 -0
- package/src/InputNumber/index.tsx +208 -0
- package/src/InputNumber/utils/defaultLocale.ts +9 -0
- package/src/InputPassword/index.tsx +201 -0
- package/src/InputPassword/utils/defaultLocale.ts +11 -0
- package/src/InputSearch/index.tsx +111 -0
- package/src/InputSearch/utils/defaultLocale.ts +9 -0
- package/src/InputSkeleton/index.tsx +28 -0
- package/src/Layout/LayoutContext.ts +21 -0
- package/src/Layout/index.tsx +44 -0
- package/src/Link/index.tsx +129 -0
- package/src/LinkButton/index.tsx +100 -0
- package/src/List/WindowScroller.tsx +53 -0
- package/src/List/index.tsx +255 -0
- package/src/List/utils/bodyPointerEvents.ts +24 -0
- package/src/List/utils/frameTimeout.ts +36 -0
- package/src/List/utils/useRWLoadNext.ts +38 -0
- package/src/ListItem/index.tsx +92 -0
- package/src/ListItemActions/index.tsx +207 -0
- package/src/ListItemLink/index.tsx +63 -0
- package/src/ListSkeleton/index.tsx +115 -0
- package/src/LogoLink/index.tsx +93 -0
- package/src/LogoLink/logo.example.svg +18 -0
- package/src/Menu/index.tsx +128 -0
- package/src/Menu/utils/useFocusWithArrows.ts +50 -0
- package/src/MenuDivider/index.tsx +22 -0
- package/src/MenuGroup/index.tsx +190 -0
- package/src/MenuItem/index.tsx +108 -0
- package/src/Modal/index.tsx +411 -0
- package/src/Modal/utils/defaultLocale.ts +9 -0
- package/src/Navigation/index.tsx +214 -0
- package/src/Navigation/utils/useScrollFlags.ts +39 -0
- package/src/NavigationItem/index.tsx +136 -0
- package/src/PageContent/index.tsx +99 -0
- package/src/PageHeader/index.tsx +246 -0
- package/src/PageHeader/utils/defaultLocale.ts +9 -0
- package/src/PageHeaderInputSearch/index.tsx +145 -0
- package/src/PageHeaderInputSearch/utils/defaultLocale.ts +16 -0
- package/src/PageHeaderSkeleton/index.tsx +33 -0
- package/src/ParagraphSkeleton/index.tsx +65 -0
- package/src/Popover/index.tsx +243 -0
- package/src/Popover/utils/usePopoverPosition.ts +216 -0
- package/src/Progress/index.tsx +100 -0
- package/src/RadioGroup/index.tsx +165 -0
- package/src/RadioGroupSkeleton/index.tsx +36 -0
- package/src/Result/index.tsx +109 -0
- package/src/ScrollButton/index.tsx +159 -0
- package/src/ScrollButton/utils/useContainerPosition.ts +41 -0
- package/src/ScrollButton/utils/useVisibility.ts +56 -0
- package/src/Select/index.tsx +970 -0
- package/src/Select/utils/defaultLocale.ts +11 -0
- package/src/Skeleton/index.tsx +52 -0
- package/src/Switch/index.tsx +217 -0
- package/src/SwitchSkeleton/index.tsx +30 -0
- package/src/Tag/index.tsx +75 -0
- package/src/TagLink/index.tsx +53 -0
- package/src/TagList/index.tsx +95 -0
- package/src/TagListSkeleton/index.tsx +38 -0
- package/src/TagSkeleton/index.tsx +40 -0
- package/src/TextArea/index.tsx +231 -0
- package/src/TextAreaSkeleton/index.tsx +20 -0
- package/src/ThemeSwitcher/index.tsx +39 -0
- package/src/TimePicker/index.tsx +142 -0
- package/src/Video/index.tsx +41 -0
- package/src/index.ts +125 -0
- package/src/message/AlertIcon.tsx +50 -0
- package/src/message/Message.tsx +108 -0
- package/src/message/index.tsx +64 -0
- package/src/message/styles.ts +25 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import {
|
|
3
|
+
DatePickerLocale,
|
|
4
|
+
defaultLocale,
|
|
5
|
+
getAccessibilityDateLabel,
|
|
6
|
+
useFormattedValue,
|
|
7
|
+
} from '@os-design/date-picker-utils';
|
|
8
|
+
import { Down, Up } from '@os-design/icons';
|
|
9
|
+
import { useIsMinWidth } from '@os-design/media';
|
|
10
|
+
import { WithSize } from '@os-design/styles';
|
|
11
|
+
import { ThemeOverrider } from '@os-design/theming';
|
|
12
|
+
import {
|
|
13
|
+
useForwardedRef,
|
|
14
|
+
useForwardedState,
|
|
15
|
+
useKeyPress,
|
|
16
|
+
} from '@os-design/utils';
|
|
17
|
+
import React, {
|
|
18
|
+
forwardRef,
|
|
19
|
+
useCallback,
|
|
20
|
+
useEffect,
|
|
21
|
+
useMemo,
|
|
22
|
+
useRef,
|
|
23
|
+
useState,
|
|
24
|
+
} from 'react';
|
|
25
|
+
import Button from '../Button';
|
|
26
|
+
import Modal from '../Modal';
|
|
27
|
+
import Popover from '../Popover';
|
|
28
|
+
import {
|
|
29
|
+
ClearIcon,
|
|
30
|
+
Placeholder,
|
|
31
|
+
SelectContainer,
|
|
32
|
+
Title,
|
|
33
|
+
ToggleContent,
|
|
34
|
+
ToggleIconContainer,
|
|
35
|
+
ToggleLeftAddon,
|
|
36
|
+
ToggleRightAddon,
|
|
37
|
+
} from '../Select';
|
|
38
|
+
import TimePicker from '../TimePicker';
|
|
39
|
+
import DatePickerCalendar from './DatePickerCalendar';
|
|
40
|
+
|
|
41
|
+
type JsxDivProps = Omit<
|
|
42
|
+
JSX.IntrinsicElements['div'],
|
|
43
|
+
'value' | 'defaultValue' | 'onChange' | 'ref'
|
|
44
|
+
>;
|
|
45
|
+
interface BaseDatePickerProps<T> extends JsxDivProps, WithSize {
|
|
46
|
+
/**
|
|
47
|
+
* The component located on the left side.
|
|
48
|
+
* @default undefined
|
|
49
|
+
*/
|
|
50
|
+
left?: React.ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* Adds padding to the left component.
|
|
53
|
+
* It can be useful when passing an icon or text in the left component.
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
leftHasPadding?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The component located on the right side.
|
|
59
|
+
* @default undefined
|
|
60
|
+
*/
|
|
61
|
+
right?: React.ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* Adds padding to the right component.
|
|
64
|
+
* It can be useful when passing an icon or text in the right component.
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
rightHasPadding?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* The placeholder of the date picker.
|
|
70
|
+
* @default undefined
|
|
71
|
+
*/
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Whether the date picker is disabled.
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
disabled?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the component have a focus.
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
82
|
+
autoFocus?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Whether the component opens the popup calendar.
|
|
85
|
+
* @default false
|
|
86
|
+
*/
|
|
87
|
+
autoOpen?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* The format of the date.
|
|
90
|
+
* @default undefined
|
|
91
|
+
*/
|
|
92
|
+
format?: (value: T) => string;
|
|
93
|
+
/**
|
|
94
|
+
* The first day of the week.
|
|
95
|
+
* @default sunday
|
|
96
|
+
*/
|
|
97
|
+
firstDayOfWeek?: 'sunday' | 'monday';
|
|
98
|
+
/**
|
|
99
|
+
* The locale of the date picker.
|
|
100
|
+
* @default undefined
|
|
101
|
+
*/
|
|
102
|
+
locale?: DatePickerLocale;
|
|
103
|
+
/**
|
|
104
|
+
* Whether the time is shown.
|
|
105
|
+
* @default false
|
|
106
|
+
*/
|
|
107
|
+
showTime?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* The time notation.
|
|
110
|
+
* @default 12-hour
|
|
111
|
+
*/
|
|
112
|
+
timeNotation?: '12-hour' | '24-hour';
|
|
113
|
+
/**
|
|
114
|
+
* Selected date.
|
|
115
|
+
* @default undefined
|
|
116
|
+
*/
|
|
117
|
+
value?: T | null;
|
|
118
|
+
/**
|
|
119
|
+
* The default value.
|
|
120
|
+
* @default undefined
|
|
121
|
+
*/
|
|
122
|
+
defaultValue?: T | null;
|
|
123
|
+
/**
|
|
124
|
+
* The change event handler.
|
|
125
|
+
* @default undefined
|
|
126
|
+
*/
|
|
127
|
+
onChange?: (value: T | null) => void;
|
|
128
|
+
/**
|
|
129
|
+
* The event handler that is called whenever a popup closes.
|
|
130
|
+
* @default undefined
|
|
131
|
+
*/
|
|
132
|
+
onClose?: () => void;
|
|
133
|
+
}
|
|
134
|
+
export interface DateNotRangePickerProps extends BaseDatePickerProps<Date> {
|
|
135
|
+
/**
|
|
136
|
+
* Whether the value is a range.
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
139
|
+
range?: false;
|
|
140
|
+
}
|
|
141
|
+
export interface DateRangePickerProps
|
|
142
|
+
extends BaseDatePickerProps<[Date, Date]> {
|
|
143
|
+
/**
|
|
144
|
+
* Whether the value is a range.
|
|
145
|
+
* @default false
|
|
146
|
+
*/
|
|
147
|
+
range: true;
|
|
148
|
+
}
|
|
149
|
+
export type DatePickerProps = DateNotRangePickerProps | DateRangePickerProps;
|
|
150
|
+
|
|
151
|
+
const StyledPopover = styled(Popover)`
|
|
152
|
+
padding: ${(p) => p.theme.datePickerPadding}em;
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
const TimeContainer = styled.div`
|
|
156
|
+
display: flex;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
margin-top: 0.5em;
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
const Dash = styled.div`
|
|
162
|
+
margin: 0 0.5em;
|
|
163
|
+
line-height: ${(p) => p.theme.baseHeight}em;
|
|
164
|
+
`;
|
|
165
|
+
|
|
166
|
+
const StyledTimePicker = styled(TimePicker)`
|
|
167
|
+
width: 2.5em;
|
|
168
|
+
text-align: center;
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
const timePickerStyle = { style: { width: 'auto' } };
|
|
172
|
+
|
|
173
|
+
const createDate = (date: Date, time?: Date | null) => {
|
|
174
|
+
const d = new Date(0);
|
|
175
|
+
d.setFullYear(date.getFullYear());
|
|
176
|
+
d.setMonth(date.getMonth());
|
|
177
|
+
d.setDate(date.getDate());
|
|
178
|
+
d.setHours(0);
|
|
179
|
+
d.setMinutes(0);
|
|
180
|
+
if (time) {
|
|
181
|
+
d.setHours(time.getHours());
|
|
182
|
+
d.setMinutes(time.getMinutes());
|
|
183
|
+
}
|
|
184
|
+
return d;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The component to choose a date.
|
|
189
|
+
*/
|
|
190
|
+
const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
191
|
+
(
|
|
192
|
+
{
|
|
193
|
+
left,
|
|
194
|
+
leftHasPadding = false,
|
|
195
|
+
right,
|
|
196
|
+
rightHasPadding = false,
|
|
197
|
+
placeholder,
|
|
198
|
+
disabled = false,
|
|
199
|
+
autoFocus = false,
|
|
200
|
+
autoOpen = false,
|
|
201
|
+
format,
|
|
202
|
+
firstDayOfWeek = 'sunday',
|
|
203
|
+
locale = defaultLocale,
|
|
204
|
+
showTime = false,
|
|
205
|
+
timeNotation = '12-hour',
|
|
206
|
+
range = false,
|
|
207
|
+
value,
|
|
208
|
+
defaultValue,
|
|
209
|
+
onChange,
|
|
210
|
+
onClose = () => {},
|
|
211
|
+
onBlur = () => {},
|
|
212
|
+
size,
|
|
213
|
+
...rest
|
|
214
|
+
},
|
|
215
|
+
ref
|
|
216
|
+
) => {
|
|
217
|
+
const [containerRef, mergedContainerRef] = useForwardedRef(ref);
|
|
218
|
+
const [opened, setOpened] = useState(autoOpen);
|
|
219
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
220
|
+
const [forwardedValue, setForwardedValue] = useForwardedState<any>({
|
|
221
|
+
value,
|
|
222
|
+
defaultValue,
|
|
223
|
+
onChange,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
useEffect(() => {
|
|
227
|
+
if (autoFocus) containerRef.current?.focus();
|
|
228
|
+
}, [autoFocus, containerRef]);
|
|
229
|
+
|
|
230
|
+
const onCloseRef = useRef(onClose);
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
onCloseRef.current = onClose;
|
|
233
|
+
}, [onClose]);
|
|
234
|
+
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
if (!opened) {
|
|
237
|
+
onCloseRef.current();
|
|
238
|
+
containerRef.current?.focus();
|
|
239
|
+
}
|
|
240
|
+
}, [containerRef, opened]);
|
|
241
|
+
|
|
242
|
+
const formattedValue = useFormattedValue({
|
|
243
|
+
forwardedValue,
|
|
244
|
+
format,
|
|
245
|
+
showTime,
|
|
246
|
+
timeNotation,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const closeHandler = useCallback(() => {
|
|
250
|
+
setOpened(false);
|
|
251
|
+
}, []);
|
|
252
|
+
|
|
253
|
+
useKeyPress(
|
|
254
|
+
(typeof window !== 'undefined' ? window : undefined) as EventTarget,
|
|
255
|
+
'Escape',
|
|
256
|
+
closeHandler
|
|
257
|
+
);
|
|
258
|
+
const isMinXs = useIsMinWidth('xs');
|
|
259
|
+
|
|
260
|
+
const blurHandler = useCallback(
|
|
261
|
+
(e) => {
|
|
262
|
+
if (!opened) onBlur(e);
|
|
263
|
+
},
|
|
264
|
+
[onBlur, opened]
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
const valueIsSpecified = useMemo(
|
|
268
|
+
() => formattedValue !== undefined && formattedValue !== null,
|
|
269
|
+
[formattedValue]
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const rightHasPaddingValue = useMemo(() => {
|
|
273
|
+
if (valueIsSpecified) return false;
|
|
274
|
+
return right ? rightHasPadding : true;
|
|
275
|
+
}, [right, rightHasPadding, valueIsSpecified]);
|
|
276
|
+
|
|
277
|
+
const rightValue = useMemo(() => {
|
|
278
|
+
if (valueIsSpecified) {
|
|
279
|
+
return (
|
|
280
|
+
<div aria-hidden>
|
|
281
|
+
<Button
|
|
282
|
+
type='ghost'
|
|
283
|
+
wide='never'
|
|
284
|
+
size='small'
|
|
285
|
+
disabled={disabled}
|
|
286
|
+
onClick={(e) => {
|
|
287
|
+
setForwardedValue(null);
|
|
288
|
+
e.stopPropagation();
|
|
289
|
+
}}
|
|
290
|
+
onKeyDown={(e) => {
|
|
291
|
+
if (disabled) return;
|
|
292
|
+
if (['Enter', ' '].includes(e.key)) {
|
|
293
|
+
setForwardedValue(null);
|
|
294
|
+
if (!containerRef.current) return;
|
|
295
|
+
containerRef.current.focus();
|
|
296
|
+
e.preventDefault();
|
|
297
|
+
e.stopPropagation();
|
|
298
|
+
}
|
|
299
|
+
}}
|
|
300
|
+
aria-label={locale.clearLabel}
|
|
301
|
+
>
|
|
302
|
+
<ClearIcon />
|
|
303
|
+
</Button>
|
|
304
|
+
</div>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
return (
|
|
308
|
+
right || (
|
|
309
|
+
<ToggleIconContainer>
|
|
310
|
+
{opened ? <Up /> : <Down />}
|
|
311
|
+
</ToggleIconContainer>
|
|
312
|
+
)
|
|
313
|
+
);
|
|
314
|
+
}, [
|
|
315
|
+
containerRef,
|
|
316
|
+
disabled,
|
|
317
|
+
locale.clearLabel,
|
|
318
|
+
opened,
|
|
319
|
+
right,
|
|
320
|
+
setForwardedValue,
|
|
321
|
+
valueIsSpecified,
|
|
322
|
+
]);
|
|
323
|
+
|
|
324
|
+
const firstTimePickerRef = useRef<HTMLInputElement>(null);
|
|
325
|
+
const secondTimePickerRef = useRef<HTMLInputElement>(null);
|
|
326
|
+
const rangeStartedRef = useRef(false);
|
|
327
|
+
|
|
328
|
+
useEffect(() => {
|
|
329
|
+
rangeStartedRef.current = false;
|
|
330
|
+
}, [opened]);
|
|
331
|
+
|
|
332
|
+
const changeHandler = useCallback(
|
|
333
|
+
(date: Date) => {
|
|
334
|
+
setForwardedValue((prev) => {
|
|
335
|
+
if (!range) return createDate(date, prev);
|
|
336
|
+
|
|
337
|
+
const d = createDate(date);
|
|
338
|
+
const nextValue =
|
|
339
|
+
prev && Array.isArray(prev) && rangeStartedRef.current
|
|
340
|
+
? [new Date(prev[0].getTime()), createDate(date, prev[1])]
|
|
341
|
+
: [d, d];
|
|
342
|
+
|
|
343
|
+
rangeStartedRef.current = !rangeStartedRef.current;
|
|
344
|
+
return nextValue.sort(
|
|
345
|
+
(a: Date, b: Date) => a.getTime() - b.getTime()
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
},
|
|
349
|
+
[range, setForwardedValue]
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const calendarComponent = useMemo(
|
|
353
|
+
() => (
|
|
354
|
+
<DatePickerCalendar
|
|
355
|
+
firstDayOfWeek={firstDayOfWeek}
|
|
356
|
+
locale={locale}
|
|
357
|
+
value={forwardedValue}
|
|
358
|
+
onSelect={(v) => {
|
|
359
|
+
changeHandler(v);
|
|
360
|
+
firstTimePickerRef.current?.focus();
|
|
361
|
+
if (!showTime && (!range || !rangeStartedRef.current)) {
|
|
362
|
+
closeHandler();
|
|
363
|
+
}
|
|
364
|
+
}}
|
|
365
|
+
/>
|
|
366
|
+
),
|
|
367
|
+
[
|
|
368
|
+
changeHandler,
|
|
369
|
+
closeHandler,
|
|
370
|
+
firstDayOfWeek,
|
|
371
|
+
forwardedValue,
|
|
372
|
+
locale,
|
|
373
|
+
range,
|
|
374
|
+
showTime,
|
|
375
|
+
]
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
const tabOnInputComplete = useCallback(
|
|
379
|
+
(e) => {
|
|
380
|
+
if (e.target.selectionStart < 5) return;
|
|
381
|
+
secondTimePickerRef.current?.focus();
|
|
382
|
+
setForwardedValue(([from]) => {
|
|
383
|
+
const nextTo = new Date(from.getTime());
|
|
384
|
+
nextTo.setHours(nextTo.getHours() + 1);
|
|
385
|
+
return [from, nextTo];
|
|
386
|
+
});
|
|
387
|
+
},
|
|
388
|
+
[setForwardedValue]
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
const closeOnInputComplete = useCallback(
|
|
392
|
+
(e) => {
|
|
393
|
+
if (e.target.selectionStart < 5) return;
|
|
394
|
+
closeHandler();
|
|
395
|
+
},
|
|
396
|
+
[closeHandler]
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
const timeComponent = useMemo(
|
|
400
|
+
() =>
|
|
401
|
+
showTime && forwardedValue ? (
|
|
402
|
+
<TimeContainer>
|
|
403
|
+
{Array.isArray(forwardedValue) ? (
|
|
404
|
+
<>
|
|
405
|
+
<StyledTimePicker
|
|
406
|
+
ref={firstTimePickerRef}
|
|
407
|
+
autoFocus
|
|
408
|
+
disabled={disabled}
|
|
409
|
+
notation={timeNotation}
|
|
410
|
+
containerProps={timePickerStyle}
|
|
411
|
+
value={forwardedValue[0]}
|
|
412
|
+
onChange={(v) => setForwardedValue([v, forwardedValue[1]])}
|
|
413
|
+
onKeyDown={(e) => {
|
|
414
|
+
if (disabled) return;
|
|
415
|
+
if (e.key === 'Enter') {
|
|
416
|
+
setOpened(!opened);
|
|
417
|
+
}
|
|
418
|
+
}}
|
|
419
|
+
onKeyUp={tabOnInputComplete}
|
|
420
|
+
/>
|
|
421
|
+
<Dash>–</Dash>
|
|
422
|
+
<StyledTimePicker
|
|
423
|
+
ref={secondTimePickerRef}
|
|
424
|
+
disabled={disabled}
|
|
425
|
+
notation={timeNotation}
|
|
426
|
+
containerProps={timePickerStyle}
|
|
427
|
+
value={forwardedValue[1]}
|
|
428
|
+
onChange={(v) => setForwardedValue([forwardedValue[0], v])}
|
|
429
|
+
onKeyDown={(e) => {
|
|
430
|
+
if (disabled) return;
|
|
431
|
+
if (e.key === 'Enter') {
|
|
432
|
+
setOpened(!opened);
|
|
433
|
+
}
|
|
434
|
+
}}
|
|
435
|
+
onKeyUp={closeOnInputComplete}
|
|
436
|
+
/>
|
|
437
|
+
</>
|
|
438
|
+
) : (
|
|
439
|
+
<StyledTimePicker
|
|
440
|
+
ref={firstTimePickerRef}
|
|
441
|
+
autoFocus
|
|
442
|
+
disabled={disabled}
|
|
443
|
+
notation={timeNotation}
|
|
444
|
+
containerProps={timePickerStyle}
|
|
445
|
+
value={forwardedValue}
|
|
446
|
+
onChange={setForwardedValue}
|
|
447
|
+
onKeyDown={(e) => {
|
|
448
|
+
if (disabled) return;
|
|
449
|
+
if (e.key === 'Enter') {
|
|
450
|
+
setOpened(!opened);
|
|
451
|
+
}
|
|
452
|
+
}}
|
|
453
|
+
onKeyUp={closeOnInputComplete}
|
|
454
|
+
/>
|
|
455
|
+
)}
|
|
456
|
+
</TimeContainer>
|
|
457
|
+
) : null,
|
|
458
|
+
[
|
|
459
|
+
closeOnInputComplete,
|
|
460
|
+
disabled,
|
|
461
|
+
forwardedValue,
|
|
462
|
+
opened,
|
|
463
|
+
setForwardedValue,
|
|
464
|
+
showTime,
|
|
465
|
+
tabOnInputComplete,
|
|
466
|
+
timeNotation,
|
|
467
|
+
]
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
return (
|
|
471
|
+
<>
|
|
472
|
+
<SelectContainer
|
|
473
|
+
opened={opened}
|
|
474
|
+
disabled={disabled}
|
|
475
|
+
size={size}
|
|
476
|
+
tabIndex={!disabled ? 0 : -1}
|
|
477
|
+
onClick={() => {
|
|
478
|
+
if (disabled) return;
|
|
479
|
+
setOpened(!opened);
|
|
480
|
+
}}
|
|
481
|
+
onKeyDown={(e) => {
|
|
482
|
+
if (disabled) return;
|
|
483
|
+
if (['Enter', ' '].includes(e.key)) {
|
|
484
|
+
setOpened(!opened);
|
|
485
|
+
e.preventDefault();
|
|
486
|
+
}
|
|
487
|
+
}}
|
|
488
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
489
|
+
onBlur={blurHandler}
|
|
490
|
+
role='combobox'
|
|
491
|
+
aria-label={
|
|
492
|
+
forwardedValue
|
|
493
|
+
? getAccessibilityDateLabel(forwardedValue, locale)
|
|
494
|
+
: undefined
|
|
495
|
+
}
|
|
496
|
+
aria-disabled={disabled}
|
|
497
|
+
{...rest}
|
|
498
|
+
ref={mergedContainerRef}
|
|
499
|
+
>
|
|
500
|
+
{left && (
|
|
501
|
+
<ThemeOverrider
|
|
502
|
+
overrides={(t) => ({
|
|
503
|
+
buttonPaddingHorizontal: 0.8,
|
|
504
|
+
baseHeight: t.selectToggleListItemHeight / t.sizes.small,
|
|
505
|
+
})}
|
|
506
|
+
>
|
|
507
|
+
<ToggleLeftAddon hasPadding={leftHasPadding}>
|
|
508
|
+
{left}
|
|
509
|
+
</ToggleLeftAddon>
|
|
510
|
+
</ThemeOverrider>
|
|
511
|
+
)}
|
|
512
|
+
|
|
513
|
+
<ToggleContent hasLeft={!!left} hasRight={!!right}>
|
|
514
|
+
{valueIsSpecified ? (
|
|
515
|
+
<Title disabled={disabled} aria-hidden>
|
|
516
|
+
{formattedValue}
|
|
517
|
+
</Title>
|
|
518
|
+
) : (
|
|
519
|
+
<Placeholder>{placeholder}</Placeholder>
|
|
520
|
+
)}
|
|
521
|
+
</ToggleContent>
|
|
522
|
+
|
|
523
|
+
{rightValue && (
|
|
524
|
+
<ThemeOverrider
|
|
525
|
+
overrides={(t) => ({
|
|
526
|
+
buttonPaddingHorizontal: 0.8,
|
|
527
|
+
baseHeight: t.selectToggleListItemHeight / t.sizes.small,
|
|
528
|
+
})}
|
|
529
|
+
>
|
|
530
|
+
<ToggleRightAddon hasPadding={rightHasPaddingValue}>
|
|
531
|
+
{rightValue}
|
|
532
|
+
</ToggleRightAddon>
|
|
533
|
+
</ThemeOverrider>
|
|
534
|
+
)}
|
|
535
|
+
</SelectContainer>
|
|
536
|
+
|
|
537
|
+
{isMinXs ? (
|
|
538
|
+
<StyledPopover
|
|
539
|
+
trigger={containerRef}
|
|
540
|
+
placement='bottom-start'
|
|
541
|
+
visible={opened}
|
|
542
|
+
onClose={closeHandler}
|
|
543
|
+
size={size}
|
|
544
|
+
>
|
|
545
|
+
{calendarComponent}
|
|
546
|
+
{timeComponent}
|
|
547
|
+
</StyledPopover>
|
|
548
|
+
) : (
|
|
549
|
+
<Modal
|
|
550
|
+
title={placeholder}
|
|
551
|
+
header={null}
|
|
552
|
+
footer={null}
|
|
553
|
+
visible={opened}
|
|
554
|
+
onClose={closeHandler}
|
|
555
|
+
size={size}
|
|
556
|
+
>
|
|
557
|
+
{calendarComponent}
|
|
558
|
+
{timeComponent}
|
|
559
|
+
</Modal>
|
|
560
|
+
)}
|
|
561
|
+
</>
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
DatePicker.displayName = 'DatePicker';
|
|
567
|
+
|
|
568
|
+
export default DatePicker;
|