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.

113 lines (112 loc) 5.13 kB
import { jsxs, jsx } from "react/jsx-runtime"; import { createStyles } from "@mantine/core"; import { useState, useEffect } from "react"; import { Button } from "../button/Button.js"; import { ChevronUpIconSolid, ChevronDownIconSolid } from "@airplane/views/icons/index.js"; import { Stack } from "../stack/Stack.js"; import { Text } from "../text/Text.js"; import { TextInput } from "../textinput/TextInput.js"; const useStyles = createStyles((theme) => ({ AMPMButton: { border: theme.other.borderStyles.default, "&:disabled": { backgroundColor: theme.colors.gray[1], color: theme.colors.gray[4], border: theme.other.borderStyles.light } } })); const IncDec = (props) => /* @__PURE__ */ jsx(Button, { variant: "subtle", compact: props.compact, disabled: props.disabled, onMouseDown: (e) => e.preventDefault(), onClick: props.onClick, children: props.isInc ? props.compact ? props.byFive ? /* @__PURE__ */ jsx(Text, { color: "gray.4", size: "sm", disableMarkdown: true, children: "+5" }) : /* @__PURE__ */ jsx(Text, { color: "gray.4", size: "lg", disableMarkdown: true, children: "+" }) : /* @__PURE__ */ jsx(ChevronUpIconSolid, { color: "gray" }) : props.compact ? props.byFive ? /* @__PURE__ */ jsx(Text, { color: "gray.4", size: "sm", disableMarkdown: true, children: "-5" }) : /* @__PURE__ */ jsx(Text, { color: "gray.4", size: "lg", disableMarkdown: true, children: "-" }) : /* @__PURE__ */ jsx(ChevronDownIconSolid, { color: "gray" }) }); const mod = (n, m) => (n % m + m) % m; const TimeInput = ({ readOnly, min, max, preventFocus, ...props }) => { const base = max - min + 1; const def = mod(-min, base) + min; const digits = 2; const increment = props.incByFive ? 5 : 1; const pad = (n) => String(n).padStart(digits, "0"); const [value, setValue] = useState(props.value); const [raw, setRaw] = useState(pad(value ?? def)); useEffect(() => { if (props.value !== value) { setRaw(pad(props.value ?? min)); setValue(props.value); } }, [props.value, value, min]); const onChange = (value2) => { setValue(value2); if (value2 !== void 0 && value2 >= min && value2 <= max) { props.onChange(value2); } }; const onBlur = () => { let v = value; if (v === void 0) { v = def; } else if (v < min) { v = min; } else if (v > max) { v = max; } setRaw(pad(v)); onChange(v); }; return /* @__PURE__ */ jsxs(Stack, { spacing: preventFocus ? 0 : "xs", align: "center", children: [ /* @__PURE__ */ jsx(IncDec, { isInc: true, disabled: readOnly, onClick: (e) => { const v = mod((value === void 0 ? def : value) - min + increment, base) + min; setRaw(pad(v)); onChange(v); }, byFive: props.incByFive, compact: preventFocus }), preventFocus ? /* @__PURE__ */ jsx(Text, { size: "xl", onMouseDown: preventFocus ? (e) => e.preventDefault() : void 0, sx: { margin: 10, minWidth: "3ch", textAlign: "center" }, weight: "bold", children: raw }) : /* @__PURE__ */ jsx(TextInput, { value: raw, disabled: readOnly, size: "lg", sx: { width: 60 }, onBlur, onMouseDown: preventFocus ? (e) => e.preventDefault() : void 0, onChange: (e) => { let v = e.target.value.replace(/[^0-9]/g, ""); v = v.substring(Math.max(0, v.length - digits)); setRaw(v); onChange(v == "" ? void 0 : Number(v)); } }), /* @__PURE__ */ jsx(IncDec, { isInc: false, disabled: readOnly, onClick: (e) => { const v = mod((value === void 0 ? def : value) - min - increment, base) + min; setRaw(pad(v)); onChange(v); }, byFive: props.incByFive, compact: preventFocus }) ] }); }; const TimePicker = (props) => { var _a; const hour = props.value ? mod(props.value.hour() - 1, 12) + 1 : void 0; const isAM = props.value && props.value.hour() < 12; const readOnly = props.readOnly; const { classes } = useStyles(); return /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: "sm", align: "center", children: [ /* @__PURE__ */ jsx(TimeInput, { value: hour, readOnly, onChange: (value) => { var _a2; props.onChange((_a2 = props.value) == null ? void 0 : _a2.set("hours", (isAM ? 0 : 12) + mod(value, 12))); }, preventFocus: true, min: 1, max: 12 }), /* @__PURE__ */ jsx(Text, { size: "xl", children: ":" }), /* @__PURE__ */ jsx(TimeInput, { value: (_a = props.value) == null ? void 0 : _a.minute(), readOnly, onChange: (value) => { var _a2; props.onChange((_a2 = props.value) == null ? void 0 : _a2.set("minutes", mod(value, 60))); }, preventFocus: true, incByFive: true, min: 0, max: 59 }), /* @__PURE__ */ jsx(Button, { size: "xs", variant: "outline", color: "gray", disabled: readOnly, onMouseDown: (e) => e.preventDefault(), onClick: (e) => { var _a2; props.onChange((_a2 = props.value) == null ? void 0 : _a2.set("hours", isAM ? props.value.hour() + 12 : props.value.hour() - 12)); }, className: classes.AMPMButton, children: isAM ? "AM" : "PM" }) ] }); }; export { TimePicker, useStyles }; //# sourceMappingURL=TimePicker.js.map