Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 9x 22x 22x 22x 22x 22x 22x 9x 14x 1x | 'use client';
import React from 'react';
import type {DateTime} from '@gravity-ui/date-utils';
import {Calendar as CalendarIcon, Clock as ClockIcon} from '@gravity-ui/icons';
import {Button, Icon, Popup, TextInput, useMobile} from '@gravity-ui/uikit';
import {Calendar} from '../Calendar';
import type {CalendarProps} from '../Calendar';
import {DateField} from '../DateField';
import {HiddenInput} from '../HiddenInput/HiddenInput';
import type {
AccessibilityProps,
DomProps,
FocusableProps,
InputDOMProps,
KeyboardEvents,
PopupStyleProps,
StyleProps,
TextInputProps,
} from '../types';
import {MobileCalendar} from './MobileCalendar';
import {StubButton} from './StubButton';
import type {DatePickerStateOptions} from './hooks/datePickerStateFactory';
import {useDatePickerProps} from './hooks/useDatePickerProps';
import {useDatePickerState} from './hooks/useDatePickerState';
import {b} from './utils';
import './DatePicker.scss';
export interface DatePickerProps<T = DateTime>
extends
DatePickerStateOptions<T>,
TextInputProps,
FocusableProps,
KeyboardEvents,
DomProps,
InputDOMProps,
StyleProps,
AccessibilityProps,
PopupStyleProps {
children?: (props: CalendarProps<T>) => React.ReactNode;
disablePortal?: boolean;
disableFocusTrap?: boolean;
}
export function DatePicker({className, ...props}: DatePickerProps) {
const [anchor, setAnchor] = React.useState<HTMLDivElement | null>(null);
const state = useDatePickerState(props);
const {groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps} =
useDatePickerProps(state, props);
const isMobile = useMobile();
const isOnlyTime = state.formatInfo.hasTime && !state.formatInfo.hasDate;
return (
<div className={b(null, className)} {...groupProps}>
{isMobile ? (
<MobileCalendar props={props} state={state} />
) : (
!isOnlyTime && (
<div ref={setAnchor} className={b('popup-anchor')}>
<Popup anchorElement={anchor} {...popupProps}>
<div className={b('popup-content')}>
{typeof props.children === 'function' ? (
props.children(calendarProps)
) : (
<Calendar {...calendarProps} />
)}
{state.formatInfo.hasTime && (
<div className={b('time-field-wrapper')}>
<DateField {...timeInputProps} />
</div>
)}
</div>
</Popup>
</div>
)
)}
<TextInput
{...fieldProps}
className={b('field', {mobile: isMobile})}
hasClear={!isMobile && fieldProps.hasClear}
endContent={
<React.Fragment>
{!isMobile && !isOnlyTime && (
<Button {...calendarButtonProps}>
<Icon data={CalendarIcon} />
</Button>
)}
{(isMobile || isOnlyTime) && (
<StubButton
size={calendarButtonProps.size}
icon={isOnlyTime ? ClockIcon : CalendarIcon}
/>
)}
</React.Fragment>
}
/>
<HiddenInput
name={props.name}
value={state.value}
toStringValue={(value) => value?.toISOString() ?? ''}
onReset={(value) => {
state.setValue(value);
}}
disabled={state.disabled}
form={props.form}
/>
</div>
);
}
|