@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
JavaScript
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