UNPKG

@airplane/views

Version:

A React library for building Airplane views. Views components are optimized in style and functionality to produce internal apps that are easy to build and maintain.

182 lines (181 loc) 6.05 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { createStyles } from "@mantine/core"; import { DatePickerBase, Calendar } from "@mantine/dates"; import { useUncontrolled } from "@mantine/hooks"; import dayjs from "dayjs"; import { forwardRef, useState, useEffect } from "react"; import { Divider } from "../divider/Divider.js"; import { ComponentErrorBoundary } from "../errorBoundary/ComponentErrorBoundary.js"; import { useCommonLayoutStyle } from "../layout/useCommonLayoutStyle.js"; import { Stack } from "../stack/Stack.js"; import { useDateTimePickerState } from "../../state/components/datepicker/useDatePickerState.js"; import { useRegisterFormInput } from "../../state/components/form/useRegisterFormInput.js"; import { useInput } from "../../state/components/input/useInput.js"; import { useComponentId } from "../../state/components/useId.js"; import { TimePicker } from "./TimePicker.js"; const useStyles = createStyles((theme) => { return { weekend: { color: `${theme.colors.dark[6]} !important` }, selected: { background: `${theme.colors.primary[5]} !important` } }; }); const DateTimePickerComponent = /* @__PURE__ */ forwardRef(({ value, size = "sm", onChange, width, height, grow, className, style, initiallyOpened = false, excludeDate, clearable = false, onDropdownClose, ...props }, ref) => { const { classes, cx } = useStyles(); const { classes: layoutClasses } = useCommonLayoutStyle({ width, height, grow }); const [opened, setOpened] = useState(initiallyOpened); const onChangeWrapper = onChange && ((d) => { if (d === null) { onChange(void 0); } else { onChange(d); } }); const [_value, setValue] = useUncontrolled({ value: value || null, finalValue: null, onChange: onChangeWrapper }); const [calendarMonth, setCalendarMonth] = useState(_value || /* @__PURE__ */ new Date()); const [focused, setFocused] = useState(false); const [inputState, setInputState] = useState(_value ? formatDatetime(_value) : ""); const closeDropdown = () => { setOpened(false); onDropdownClose == null ? void 0 : onDropdownClose(); }; useEffect(() => { if (!focused) { setInputState(value ? formatDatetime(value) : ""); } }, [value, focused]); const onChangeCalendar = (date) => { if (value) { date.setHours(value.getHours()); date.setMinutes(value.getMinutes()); } setValue(date); setInputState(formatDatetime(date)); }; const onChangeTimePicker = (dj) => { if (dj === void 0) { onChange == null ? void 0 : onChange(void 0); } else { const d = dj.toDate(); setInputState(formatDatetime(d)); onChange == null ? void 0 : onChange(d); } }; const setDateFromInput = () => { const date = typeof inputState === "string" ? parseDate(inputState) : inputState; if (dayjs(date).isValid()) { setValue(date); setCalendarMonth(date); } }; return /* @__PURE__ */ jsx(DatePickerBase, { ref, allowFreeInput: true, className: cx(layoutClasses.style, className), style, dropdownOpened: opened, setDropdownOpened: (b) => { if (b) { setOpened(true); } else { closeDropdown(); } }, onChange: (e) => { setOpened(true); const date = parseDate(e.target.value); if (dayjs(date).isValid()) { setValue(date); setCalendarMonth(date); } setInputState(e.target.value); }, onClear: () => { setValue(null); setInputState(""); }, onBlur: (e) => { setFocused(false); setDateFromInput(); }, onKeyDown: (e) => { if (e.key === "Enter") { closeDropdown(); setDateFromInput(); } }, onFocus: (e) => { setFocused(true); }, inputLabel: inputState, clearButtonLabel: "clear", clearable, size, ...props, children: /* @__PURE__ */ jsxs(Stack, { direction: "row", align: "center", children: [ /* @__PURE__ */ jsx(Calendar, { month: calendarMonth, onMonthChange: setCalendarMonth, value: _value || dayjs().toDate(), onChange: onChangeCalendar, size: size === "lg" || size === "xl" ? "md" : "sm", excludeDate, preventFocus: true, dayClassName: (date, modifiers) => cx({ [classes.weekend]: modifiers.weekend && !modifiers.outside && !modifiers.selected && !modifiers.disabled, [classes.selected]: modifiers.selected }) }), /* @__PURE__ */ jsx(Divider, { orientation: "vertical", color: "gray.3", sx: { height: "300px" } }), /* @__PURE__ */ jsx(TimePicker, { renderText: "pick", value: value ? dayjs(value) : dayjs().startOf("d"), onChange: onChangeTimePicker }) ] }) }); }); DateTimePickerComponent.displayName = "DateTimePickerComponent"; const DateTimePicker = /* @__PURE__ */ forwardRef((props, ref) => { return /* @__PURE__ */ jsx(ComponentErrorBoundary, { componentName: DISPLAY_NAME, children: /* @__PURE__ */ jsx(DateTimePickerWithoutRef, { ...props, innerRef: ref }) }); }); const DISPLAY_NAME = "DateTimePicker"; DateTimePicker.displayName = DISPLAY_NAME; const DateTimePickerWithoutRef = (props) => { const id = useComponentId(props.id); const { state, dispatch } = useDateTimePickerState(id, { initialState: { disabled: props.disabled ?? props.defaultDisabled, value: props.value ?? props.defaultValue } }); const { inputProps } = useInput(props, state, dispatch, (v) => v); useRegisterFormInput(id, "date-picker"); const { innerRef, validate: _, onChange: __, defaultDisabled: ___, defaultValue: ____, ...restProps } = props; return /* @__PURE__ */ jsx(DateTimePickerComponent, { ref: innerRef, ...inputProps, ...restProps }); }; const DATETIME_FORMAT = "MMM D, YYYY h:mm A"; const formatDatetime = (date) => { return dayjs(date).format(DATETIME_FORMAT); }; const parseDate = (date) => dayjs(date, DATETIME_FORMAT).toDate(); export { DateTimePicker, DateTimePickerComponent, DateTimePickerWithoutRef, formatDatetime }; //# sourceMappingURL=DateTimePicker.js.map