UNPKG

@wordpress/components

Version:
219 lines (218 loc) 6.69 kB
// packages/components/src/date-time/time/index.tsx import { startOfMinute } from "date-fns"; import { useState, useMemo, useEffect } from "@wordpress/element"; import { __ } from "@wordpress/i18n"; import { date as formatDate } from "@wordpress/date"; import BaseControl from "../../base-control/index.mjs"; import { VisuallyHidden } from "../../visually-hidden/index.mjs"; import SelectControl from "../../select-control/index.mjs"; import TimeZone from "./timezone.mjs"; import { Wrapper, Fieldset, MonthSelectWrapper, DayInput, YearInput } from "./styles.mjs"; import { HStack } from "../../h-stack/index.mjs"; import { Spacer } from "../../spacer/index.mjs"; import { inputToDate, buildPadInputStateReducer, validateInputElementTarget, setInConfiguredTimezone, getDaysInMonth } from "../utils.mjs"; import { TIMEZONELESS_FORMAT } from "../constants.mjs"; import { TimeInput } from "./time-input/index.mjs"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; var VALID_DATE_ORDERS = ["dmy", "mdy", "ymd"]; function TimePicker({ is12Hour, currentTime, onChange, dateOrder: dateOrderProp, hideLabelFromVision = false }) { const [date, setDate] = useState(() => ( // Truncate the date at the minutes, see: #15495. startOfMinute(inputToDate(currentTime ?? /* @__PURE__ */ new Date())) )); useEffect(() => { setDate(startOfMinute(inputToDate(currentTime ?? /* @__PURE__ */ new Date()))); }, [currentTime]); const monthOptions = [{ value: "01", label: __("January") }, { value: "02", label: __("February") }, { value: "03", label: __("March") }, { value: "04", label: __("April") }, { value: "05", label: __("May") }, { value: "06", label: __("June") }, { value: "07", label: __("July") }, { value: "08", label: __("August") }, { value: "09", label: __("September") }, { value: "10", label: __("October") }, { value: "11", label: __("November") }, { value: "12", label: __("December") }]; const { day, month, year, minutes, hours } = useMemo(() => ({ day: formatDate("d", date), month: formatDate("m", date), year: formatDate("Y", date), minutes: formatDate("i", date), hours: formatDate("H", date) }), [date]); const buildNumberControlChangeCallback = (method) => { const callback = (value, { event }) => { if (!validateInputElementTarget(event)) { return; } const numberValue = Number(value); const newDate = setInConfiguredTimezone(date, { [method]: numberValue }); setDate(newDate); onChange?.(formatDate(TIMEZONELESS_FORMAT, newDate)); }; return callback; }; const onTimeInputChangeCallback = ({ hours: newHours, minutes: newMinutes }) => { const newDate = setInConfiguredTimezone(date, { hours: newHours, minutes: newMinutes }); setDate(newDate); onChange?.(formatDate(TIMEZONELESS_FORMAT, newDate)); }; const dayField = /* @__PURE__ */ _jsx(DayInput, { className: "components-datetime__time-field components-datetime__time-field-day", label: __("Day"), hideLabelFromVision: true, __next40pxDefaultSize: true, value: day, step: 1, min: 1, max: getDaysInMonth(Number(year), Number(month) - 1), required: true, spinControls: "none", isPressEnterToChange: true, isDragEnabled: false, isShiftStepEnabled: false, onChange: buildNumberControlChangeCallback("date") }, "day"); const monthField = /* @__PURE__ */ _jsx(MonthSelectWrapper, { children: /* @__PURE__ */ _jsx(SelectControl, { className: "components-datetime__time-field components-datetime__time-field-month", label: __("Month"), hideLabelFromVision: true, __next40pxDefaultSize: true, value: month, options: monthOptions, onChange: (value) => { const newDate = setInConfiguredTimezone(date, { month: Number(value) - 1 }); setDate(newDate); onChange?.(formatDate(TIMEZONELESS_FORMAT, newDate)); } }) }, "month"); const yearField = /* @__PURE__ */ _jsx(YearInput, { className: "components-datetime__time-field components-datetime__time-field-year", label: __("Year"), hideLabelFromVision: true, __next40pxDefaultSize: true, value: year, step: 1, min: 1, max: 9999, required: true, spinControls: "none", isPressEnterToChange: true, isDragEnabled: false, isShiftStepEnabled: false, onChange: buildNumberControlChangeCallback("year"), __unstableStateReducer: buildPadInputStateReducer(4) }, "year"); const defaultDateOrder = is12Hour ? "mdy" : "dmy"; const dateOrder = dateOrderProp && VALID_DATE_ORDERS.includes(dateOrderProp) ? dateOrderProp : defaultDateOrder; const fields = dateOrder.split("").map((field) => { switch (field) { case "d": return dayField; case "m": return monthField; case "y": return yearField; default: return null; } }); return /* @__PURE__ */ _jsxs(Wrapper, { className: "components-datetime__time", children: [/* @__PURE__ */ _jsxs(Fieldset, { children: [hideLabelFromVision ? /* @__PURE__ */ _jsx(VisuallyHidden, { as: "legend", children: __("Time") }) : /* @__PURE__ */ _jsx(BaseControl.VisualLabel, { as: "legend", className: "components-datetime__time-legend", children: __("Time") }), /* @__PURE__ */ _jsxs(HStack, { className: "components-datetime__time-wrapper", children: [/* @__PURE__ */ _jsx(TimeInput, { value: { hours: Number(hours), minutes: Number(minutes) }, is12Hour, onChange: onTimeInputChangeCallback }), /* @__PURE__ */ _jsx(Spacer, {}), /* @__PURE__ */ _jsx(TimeZone, {})] })] }), /* @__PURE__ */ _jsxs(Fieldset, { children: [hideLabelFromVision ? /* @__PURE__ */ _jsx(VisuallyHidden, { as: "legend", children: __("Date") }) : /* @__PURE__ */ _jsx(BaseControl.VisualLabel, { as: "legend", className: "components-datetime__time-legend", children: __("Date") }), /* @__PURE__ */ _jsx(HStack, { className: "components-datetime__time-wrapper", children: fields })] })] }); } TimePicker.TimeInput = TimeInput; Object.assign(TimePicker.TimeInput, { displayName: "TimePicker.TimeInput" }); var time_default = TimePicker; export { TimePicker, time_default as default }; //# sourceMappingURL=index.mjs.map