UNPKG

@mantine/dates

Version:

Calendars, date and time pickers based on Mantine components

1 lines 13 kB
{"version":3,"file":"DateTimePicker.cjs","names":["pickCalendarProps","useDatesContext","useUncontrolledDates","clampDate","PickerInputBase","InlineDateTimePicker","classes"],"sources":["../../../src/components/DateTimePicker/DateTimePicker.tsx"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useState } from 'react';\nimport {\n ActionIconProps,\n BoxProps,\n Factory,\n genericFactory,\n InputVariant,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { useDidUpdate, useDisclosure } from '@mantine/hooks';\nimport { useUncontrolledDates } from '../../hooks';\nimport { CalendarLevel, DatePickerType, DatePickerValue, DateStringValue } from '../../types';\nimport { clampDate } from '../../utils';\nimport {\n CalendarBaseProps,\n CalendarSettings,\n CalendarStylesNames,\n pickCalendarProps,\n} from '../Calendar';\nimport { DatePickerPreset } from '../DatePicker';\nimport { useDatesContext } from '../DatesProvider';\nimport {\n InlineDateTimePicker,\n InlineDateTimePickerStylesNames,\n} from '../InlineDateTimePicker/InlineDateTimePicker';\nimport {\n DateInputSharedProps,\n PickerInputBase,\n PickerInputBaseStylesNames,\n} from '../PickerInputBase';\nimport { TimePickerProps } from '../TimePicker/TimePicker';\nimport classes from './DateTimePicker.module.css';\n\nexport type DateTimePickerStylesNames =\n | InlineDateTimePickerStylesNames\n | 'placeholder'\n | PickerInputBaseStylesNames\n | CalendarStylesNames;\n\nexport interface DateTimePickerProps<Type extends DatePickerType = 'default'>\n extends\n BoxProps,\n Omit<\n DateInputSharedProps,\n 'classNames' | 'styles' | 'closeOnChange' | 'size' | 'valueFormatter'\n >,\n CalendarBaseProps,\n Omit<CalendarSettings, 'onYearMouseEnter' | 'onMonthMouseEnter' | 'hasNextLevel'>,\n StylesApiProps<DateTimePickerFactory> {\n /** Picker type: range or default @default 'default' */\n type?: Type;\n\n /** `dayjs` format for input value, or a function that receives the value as a `YYYY-MM-DD HH:mm:ss` string and returns the formatted value @default \"DD/MM/YYYY HH:mm\" */\n valueFormat?: string | ((date: DateStringValue) => string);\n\n /** Controlled component value */\n value?: DatePickerValue<Type>;\n\n /** Uncontrolled component default value */\n defaultValue?: DatePickerValue<Type>;\n\n /** Called when value changes */\n onChange?: (value: DatePickerValue<Type, DateStringValue>) => void;\n\n /** Default time value in HH:mm` or `HH:mm:ss` format. Assigned to time when date is selected. */\n defaultTimeValue?: string;\n\n /** Props passed down to `TimePicker` component */\n timePickerProps?: Omit<TimePickerProps, 'defaultValue' | 'value'>;\n\n /** Props passed down to the end time `TimePicker` component in range mode */\n endTimePickerProps?: Omit<TimePickerProps, 'defaultValue' | 'value'>;\n\n /** Props passed down to the submit button */\n submitButtonProps?: ActionIconProps & React.ComponentProps<'button'>;\n\n /** Determines whether the seconds input should be displayed @default false */\n withSeconds?: boolean;\n\n /** Max level that user can go up to @default 'decade' */\n maxLevel?: CalendarLevel;\n\n /** Presets values */\n presets?: DatePickerPreset<Type>[];\n\n /** Determines whether a single day can be selected as range, applicable only when type=\"range\" */\n allowSingleDateInRange?: Type extends 'range' ? boolean : never;\n\n /** Separator between range values */\n labelSeparator?: string;\n}\n\nexport type DateTimePickerFactory = Factory<{\n props: DateTimePickerProps;\n ref: HTMLButtonElement;\n stylesNames: DateTimePickerStylesNames;\n variant: InputVariant;\n signature: <Type extends DatePickerType = 'default'>(\n props: DateTimePickerProps<Type> & { ref?: React.Ref<HTMLButtonElement> }\n ) => React.JSX.Element;\n}>;\n\nconst defaultProps = {\n type: 'default',\n dropdownType: 'popover',\n size: 'sm',\n} satisfies Partial<DateTimePickerProps>;\n\nexport const DateTimePicker = genericFactory<DateTimePickerFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'DateTimePicker'], defaultProps as any, _props);\n const {\n value,\n defaultValue,\n onChange,\n valueFormat,\n locale,\n classNames,\n styles,\n unstyled,\n timePickerProps,\n endTimePickerProps,\n submitButtonProps,\n withSeconds,\n level,\n defaultLevel,\n size,\n variant,\n dropdownType,\n vars,\n minDate,\n maxDate,\n defaultDate,\n defaultTimeValue,\n presets,\n attributes,\n onDropdownClose,\n type,\n labelSeparator,\n allowSingleDateInRange,\n ...rest\n } = props;\n\n const isRange = (type as string) === 'range';\n\n useStyles<DateTimePickerFactory>({\n name: 'DateTimePicker',\n classes,\n props: props as DateTimePickerProps,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<DateTimePickerFactory>({\n classNames,\n styles,\n props: props as DateTimePickerProps,\n });\n\n const _withSeconds = withSeconds || timePickerProps?.withSeconds;\n const _valueFormat = valueFormat || (_withSeconds ? 'DD/MM/YYYY HH:mm:ss' : 'DD/MM/YYYY HH:mm');\n\n const {\n calendarProps: { allowSingleDateInRange: _asdir, ...calendarProps },\n others,\n } = pickCalendarProps(rest);\n\n const ctx = useDatesContext();\n const _labelSeparator = ctx.getLabelSeparator(labelSeparator);\n\n const [_value, setValue] = useUncontrolledDates({\n type: type as any,\n value,\n defaultValue,\n onChange: onChange as any,\n withTime: true,\n });\n\n const [dropdownOpened, dropdownHandlers] = useDisclosure(false);\n const [inlineKey, setInlineKey] = useState(0);\n\n const formatDate = (v: DateStringValue | null) => {\n if (!v) {\n return '';\n }\n if (typeof _valueFormat === 'function') {\n return _valueFormat(v);\n }\n return dayjs(v).locale(ctx.getLocale(locale)).format(_valueFormat);\n };\n\n const getFormattedValue = () => {\n if (isRange && Array.isArray(_value)) {\n const start = formatDate(_value[0]);\n const end = formatDate(_value[1]);\n if (start && end) {\n return `${start} ${_labelSeparator} ${end}`;\n }\n if (start) {\n return `${start} ${_labelSeparator} ...`;\n }\n return '';\n }\n\n return formatDate(_value as DateStringValue | null);\n };\n\n const formattedValue = getFormattedValue();\n\n useDidUpdate(() => {\n if (dropdownOpened) {\n setInlineKey((k) => k + 1);\n }\n }, [dropdownOpened]);\n\n const __stopPropagation = dropdownType === 'popover';\n\n const clearIncompleteRange = () => {\n if (isRange && Array.isArray(_value) && _value[0] && !_value[1]) {\n setValue([null, null] as any);\n }\n };\n\n const handleDropdownClose = () => {\n clearIncompleteRange();\n\n if (isRange && Array.isArray(_value)) {\n const clampedStart = _value[0] ? clampDate(minDate, maxDate, _value[0]) : null;\n const clampedEnd = _value[1] ? clampDate(minDate, maxDate, _value[1]) : null;\n if ((_value[0] && _value[0] !== clampedStart) || (_value[1] && _value[1] !== clampedEnd)) {\n setValue([clampedStart, clampedEnd] as any);\n }\n } else if (_value) {\n const clamped = clampDate(minDate, maxDate, _value as DateStringValue);\n if (_value !== clamped) {\n setValue(clamped);\n }\n }\n onDropdownClose?.();\n };\n\n const handleSubmitOrEnter = () => {\n handleDropdownClose();\n dropdownHandlers.close();\n };\n\n const onClear = () => {\n if (isRange) {\n setValue([null, null] as any);\n } else {\n setValue(null);\n }\n };\n\n const shouldClear = isRange ? Array.isArray(_value) && !!_value[0] : !!_value;\n\n const handlePresetSelect = (val: any) => {\n setValue(val);\n };\n\n return (\n <PickerInputBase\n formattedValue={formattedValue}\n dropdownOpened={!rest.disabled ? dropdownOpened : false}\n dropdownHandlers={dropdownHandlers}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n onClear={onClear}\n shouldClear={shouldClear}\n value={_value}\n size={size}\n variant={variant}\n dropdownType={dropdownType}\n {...others}\n type={type as any}\n __staticSelector=\"DateTimePicker\"\n onDropdownClose={handleDropdownClose}\n withTime\n attributes={attributes}\n >\n <InlineDateTimePicker\n key={inlineKey}\n {...calendarProps}\n fullWidth={false}\n type={type as any}\n value={_value as any}\n onChange={setValue as any}\n maxDate={maxDate}\n minDate={minDate}\n size={size}\n variant={variant}\n locale={locale}\n classNames={resolvedClassNames as any}\n styles={resolvedStyles as any}\n unstyled={unstyled}\n level={level}\n defaultLevel={defaultLevel}\n defaultDate={defaultDate}\n defaultTimeValue={defaultTimeValue}\n presets={presets as any}\n allowSingleDateInRange={allowSingleDateInRange}\n timePickerProps={timePickerProps}\n endTimePickerProps={endTimePickerProps}\n submitButtonProps={submitButtonProps}\n withSeconds={withSeconds}\n valueFormat={valueFormat}\n labelSeparator={labelSeparator}\n attributes={attributes}\n onSubmit={handleSubmitOrEnter}\n __stopPropagation={__stopPropagation}\n __staticSelector=\"DateTimePicker\"\n __onEnter={handleSubmitOrEnter}\n __onPresetSelect={handlePresetSelect}\n />\n </PickerInputBase>\n );\n});\n\nDateTimePicker.classes = {\n ...classes,\n ...PickerInputBase.classes,\n ...InlineDateTimePicker.classes,\n};\nDateTimePicker.displayName = '@mantine/dates/DateTimePicker';\n"],"mappings":"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"}