@yamada-ui/calendar
Version:
Yamada UI calendar component
1 lines • 13.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/multi-date-picker.tsx"],"sourcesContent":["import type { CSSUIObject, FC, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport type { MotionProps } from \"@yamada-ui/motion\"\nimport type { PortalProps } from \"@yamada-ui/portal\"\nimport type {\n CSSProperties,\n Dispatch,\n MouseEventHandler,\n ReactElement,\n ReactNode,\n RefAttributes,\n SetStateAction,\n} from \"react\"\nimport type { DatePickerIconProps } from \"./date-picker\"\nimport type { UseMultiDatePickerProps } from \"./use-multi-date-picker\"\nimport {\n forwardRef,\n omitThemeProps,\n ui,\n useComponentMultiStyle,\n} from \"@yamada-ui/core\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@yamada-ui/popover\"\nimport { Portal } from \"@yamada-ui/portal\"\nimport { cx, mergeRefs, runIfFunc } from \"@yamada-ui/utils\"\nimport { cloneElement, useMemo, useRef } from \"react\"\nimport { Calendar } from \"./calendar\"\nimport { isSameDate } from \"./calendar-utils\"\nimport { DatePickerClearIcon, DatePickerIcon } from \"./date-picker\"\nimport { DatePickerProvider, useDatePickerContext } from \"./use-date-picker\"\nimport { useMultiDatePicker } from \"./use-multi-date-picker\"\n\ninterface MultiDatePickerOptions {\n children?: FC<{ value: Date[]; onClose: () => void }> | ReactNode\n /**\n * If `true`, display the date picker clear icon.\n *\n * @default true\n */\n clearable?: boolean\n /**\n * The custom display value to use.\n */\n component?: FC<{\n index: number\n label: string\n value: Date\n onRemove: MouseEventHandler<HTMLElement>\n }>\n /**\n * The border color when the input is invalid.\n */\n errorBorderColor?: string\n /**\n * The border color when the input is focused.\n */\n focusBorderColor?: string\n /**\n * If `true`, display the date picker clear icon.\n *\n * @default true\n *\n * @deprecated Use `clearable` instead.\n */\n isClearable?: boolean\n /**\n * If `true`, keep the placeholder.\n *\n * @default false\n */\n keepPlaceholder?: boolean\n /**\n * The visual separator between each value.\n *\n * @default ','\n */\n separator?: string\n /**\n * Props for date picker clear icon element.\n */\n clearIconProps?: DatePickerIconProps\n /**\n * Props for date picker container element.\n */\n containerProps?: Omit<HTMLUIProps, \"children\">\n /**\n * Props for date picker container element.\n */\n contentProps?: Omit<MotionProps, \"children\">\n /**\n * Props for date picker field element.\n */\n fieldProps?: Omit<HTMLUIProps, \"children\">\n /**\n * Props for date picker icon element.\n */\n iconProps?: DatePickerIconProps\n /**\n * Props for date picker input element.\n */\n inputProps?: HTMLUIProps<\"input\">\n /**\n * Props to be forwarded to the portal component.\n *\n * @default '{ disabled: true }'\n *\n */\n portalProps?: Omit<PortalProps, \"children\">\n}\n\nexport interface MultiDatePickerProps\n extends ThemeProps<\"DatePicker\">,\n MultiDatePickerOptions,\n UseMultiDatePickerProps {}\n\n/**\n * `MultiDatePicker` is a component used for users to select multiple dates.\n *\n * @see Docs https://yamada-ui.com/components/forms/multi-date-picker\n */\nexport const MultiDatePicker = forwardRef<MultiDatePickerProps, \"input\">(\n (props, ref) => {\n const [styles, mergedProps] = useComponentMultiStyle(\n \"MultiDatePicker\",\n props,\n )\n const {\n className,\n children,\n isClearable = true,\n clearable = isClearable,\n color,\n component,\n h,\n height = h,\n keepPlaceholder = false,\n minH,\n minHeight = minH,\n separator,\n clearIconProps,\n containerProps,\n contentProps,\n fieldProps,\n iconProps,\n inputProps,\n portalProps = { disabled: true },\n ...computedProps\n } = omitThemeProps(mergedProps)\n const {\n dateToString,\n open,\n setValue,\n value,\n getCalendarProps,\n getContainerProps,\n getFieldProps,\n getIconProps,\n getInputProps,\n getPopoverProps,\n onClose,\n } = useMultiDatePicker(computedProps)\n const css: CSSUIObject = {\n color,\n h: \"fit-content\",\n w: \"100%\",\n ...styles.container,\n }\n\n return (\n <DatePickerProvider value={styles}>\n <Popover {...getPopoverProps()}>\n <ui.div\n className={cx(\"ui-multi-date-picker\", className)}\n __css={css}\n {...getContainerProps(containerProps)}\n >\n <ui.div\n className=\"ui-multi-date-picker__inner\"\n __css={{ position: \"relative\", ...styles.inner }}\n >\n <MultiDatePickerField\n component={component}\n dateToString={dateToString}\n keepPlaceholder={keepPlaceholder}\n open={open}\n separator={separator}\n setValue={setValue}\n value={value}\n {...getFieldProps({ height, minHeight, ...fieldProps }, ref)}\n inputProps={getInputProps(inputProps)}\n />\n\n {clearable && !!value.length ? (\n <DatePickerClearIcon\n {...getIconProps({ clear: true, ...clearIconProps })}\n />\n ) : (\n <DatePickerIcon\n {...getIconProps({ clear: false, ...iconProps })}\n />\n )}\n </ui.div>\n\n <Portal {...portalProps}>\n <PopoverContent\n as=\"div\"\n className=\"ui-multi-date-picker__content\"\n __css={{ ...styles.content }}\n {...contentProps}\n >\n <Calendar\n className=\"ui-multi-date-picker__calendar\"\n {...getCalendarProps()}\n />\n\n {runIfFunc(children, { value, onClose })}\n </PopoverContent>\n </Portal>\n </ui.div>\n </Popover>\n </DatePickerProvider>\n )\n },\n)\n\nMultiDatePicker.displayName = \"MultiDatePicker\"\nMultiDatePicker.__ui__ = \"MultiDatePicker\"\n\ninterface MultiDatePickerFieldOptions {\n dateToString: (value: Date | undefined) => string | undefined\n open: boolean\n setValue: Dispatch<SetStateAction<Date[]>>\n value: Date[]\n}\n\nexport interface MultiDatePickerFieldProps\n extends HTMLUIProps,\n MultiDatePickerFieldOptions,\n Pick<\n MultiDatePickerProps,\n \"component\" | \"inputProps\" | \"keepPlaceholder\" | \"separator\"\n > {}\n\nexport const MultiDatePickerField = forwardRef<\n MultiDatePickerFieldProps,\n \"input\"\n>(\n (\n {\n className,\n component,\n dateToString,\n keepPlaceholder,\n open,\n separator = \",\",\n setValue,\n value = [],\n inputProps,\n ...rest\n },\n ref,\n ) => {\n const styles = useDatePickerContext()\n const inputRef = useRef<HTMLInputElement>(null)\n const {\n ref: inputPropRef,\n placeholder,\n ...computedInputProps\n } = (inputProps ?? {}) as HTMLUIProps<\"input\"> &\n RefAttributes<HTMLInputElement>\n\n const cloneChildren = useMemo(() => {\n if (component) {\n return value.map((date, index) => {\n const onRemove: MouseEventHandler<HTMLElement> = (ev) => {\n ev.stopPropagation()\n\n setValue((prev) => prev.filter((value) => !isSameDate(value, date)))\n\n inputRef.current?.focus()\n }\n\n const el = component({\n index,\n label: dateToString(date)!,\n value: date,\n onRemove,\n })\n\n const style: CSSProperties = {\n marginBlockEnd: \"0.125rem\",\n marginBlockStart: \"0.125rem\",\n marginInlineEnd: \"0.25rem\",\n }\n\n return el\n ? cloneElement(el as ReactElement, { key: index, style })\n : null\n })\n } else {\n return value.map((date, index) => {\n const last = value.length === index + 1\n\n return (\n <ui.span key={index} display=\"inline-block\" me=\"0.25rem\">\n {dateToString(date)}\n {!last || open ? separator : null}\n </ui.span>\n )\n })\n }\n }, [component, setValue, dateToString, open, separator, value])\n\n const css: CSSUIObject = {\n alignItems: \"center\",\n display: \"flex\",\n flexWrap: \"wrap\",\n pe: \"2rem\",\n ...styles.field,\n }\n\n return (\n <PopoverTrigger>\n <ui.div\n className={cx(\"ui-multi-date-picker__field\", className)}\n __css={css}\n {...rest}\n >\n {cloneChildren}\n\n <ui.input\n ref={mergeRefs(ref, inputPropRef, inputRef)}\n className=\"ui-multi-date-picker__field__input\"\n aria-label=\"Input date value\"\n display=\"inline-block\"\n flex=\"1\"\n marginBlockEnd=\"0.125rem\"\n marginBlockStart=\"0.125rem\"\n overflow=\"hidden\"\n placeholder={\n !value.length || (keepPlaceholder && open)\n ? placeholder\n : undefined\n }\n {...computedInputProps}\n />\n </ui.div>\n </PopoverTrigger>\n )\n },\n)\n\nMultiDatePickerField.displayName = \"MultiDatePickerField\"\nMultiDatePickerField.__ui__ = \"MultiDatePickerField\"\n"],"mappings":"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","names":["value"]}