UNPKG

@wordpress/components

Version:
269 lines (241 loc) 9.26 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.TimePicker = TimePicker; exports.default = void 0; var _element = require("@wordpress/element"); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = require("lodash"); var _moment = _interopRequireDefault(require("moment")); var _i18n = require("@wordpress/i18n"); var _button = _interopRequireDefault(require("../button")); var _buttonGroup = _interopRequireDefault(require("../button-group")); var _timezone = _interopRequireDefault(require("./timezone")); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ /** * Module Constants */ const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; /** * <UpdateOnBlurAsIntegerField> * A shared component to parse, validate, and handle remounting of the underlying form field element like <input> and <select>. * * @param {Object} props Component props. * @param {string} props.as Render the component as specific element tag, defaults to "input". * @param {number|string} props.value The default value of the component which will be parsed to integer. * @param {Function} props.onUpdate Call back when blurred and validated. */ function UpdateOnBlurAsIntegerField({ as, value, onUpdate, ...props }) { function handleBlur(event) { const { target } = event; if (value === target.value) { return; } const parsedValue = parseInt(target.value, 10); // Run basic number validation on the input. if (!(0, _lodash.isInteger)(parsedValue) || typeof props.max !== 'undefined' && parsedValue > props.max || typeof props.min !== 'undefined' && parsedValue < props.min) { // If validation failed, reset the value to the previous valid value. target.value = value; } else { // Otherwise, it's valid, call onUpdate. onUpdate(target.name, parsedValue); } } return (0, _element.createElement)(as || 'input', { // Re-mount the input value to accept the latest value as the defaultValue. key: value, defaultValue: value, onBlur: handleBlur, ...props }); } /** * <TimePicker> * * @typedef {Date|string|number} WPValidDateTimeFormat * * @param {Object} props Component props. * @param {boolean} props.is12Hour Should the time picker showed in 12 hour format or 24 hour format. * @param {WPValidDateTimeFormat} props.currentTime The initial current time the time picker should render. * @param {Function} props.onChange Callback function when the date changed. */ function TimePicker({ is12Hour, currentTime, onChange }) { const [date, setDate] = (0, _element.useState)(() => // Truncate the date at the minutes, see: #15495. (0, _moment.default)(currentTime).startOf('minutes')); // Reset the state when currentTime changed. (0, _element.useEffect)(() => { setDate(currentTime ? (0, _moment.default)(currentTime).startOf('minutes') : (0, _moment.default)()); }, [currentTime]); const { day, month, year, minutes, hours, am } = (0, _element.useMemo)(() => ({ day: date.format('DD'), month: date.format('MM'), year: date.format('YYYY'), minutes: date.format('mm'), hours: date.format(is12Hour ? 'hh' : 'HH'), am: date.format('H') <= 11 ? 'AM' : 'PM' }), [date, is12Hour]); /** * Function that sets the date state and calls the onChange with a new date. * The date is truncated at the minutes. * * @param {Object} newDate The date object. */ function changeDate(newDate) { setDate(newDate); onChange(newDate.format(TIMEZONELESS_FORMAT)); } function update(name, value) { // Clone the date and call the specific setter function according to `name`. const newDate = date.clone()[name](value); changeDate(newDate); } function updateAmPm(value) { return () => { if (am === value) { return; } const parsedHours = parseInt(hours, 10); const newDate = date.clone().hours(value === 'PM' ? (parsedHours % 12 + 12) % 24 : parsedHours % 12); changeDate(newDate); }; } const dayFormat = (0, _element.createElement)("div", { className: "components-datetime__time-field components-datetime__time-field-day" }, (0, _element.createElement)(UpdateOnBlurAsIntegerField, { "aria-label": (0, _i18n.__)('Day'), className: "components-datetime__time-field-day-input", type: "number" // The correct function to call in moment.js is "date" not "day". , name: "date", value: day, step: 1, min: 1, max: 31, onUpdate: update })); const monthFormat = (0, _element.createElement)("div", { className: "components-datetime__time-field components-datetime__time-field-month" }, (0, _element.createElement)(UpdateOnBlurAsIntegerField, { as: "select", "aria-label": (0, _i18n.__)('Month'), className: "components-datetime__time-field-month-select", name: "month", value: month // The value starts from 0, so we have to -1 when setting month. , onUpdate: (key, value) => update(key, value - 1) }, (0, _element.createElement)("option", { value: "01" }, (0, _i18n.__)('January')), (0, _element.createElement)("option", { value: "02" }, (0, _i18n.__)('February')), (0, _element.createElement)("option", { value: "03" }, (0, _i18n.__)('March')), (0, _element.createElement)("option", { value: "04" }, (0, _i18n.__)('April')), (0, _element.createElement)("option", { value: "05" }, (0, _i18n.__)('May')), (0, _element.createElement)("option", { value: "06" }, (0, _i18n.__)('June')), (0, _element.createElement)("option", { value: "07" }, (0, _i18n.__)('July')), (0, _element.createElement)("option", { value: "08" }, (0, _i18n.__)('August')), (0, _element.createElement)("option", { value: "09" }, (0, _i18n.__)('September')), (0, _element.createElement)("option", { value: "10" }, (0, _i18n.__)('October')), (0, _element.createElement)("option", { value: "11" }, (0, _i18n.__)('November')), (0, _element.createElement)("option", { value: "12" }, (0, _i18n.__)('December')))); const dayMonthFormat = is12Hour ? (0, _element.createElement)(_element.Fragment, null, dayFormat, monthFormat) : (0, _element.createElement)(_element.Fragment, null, monthFormat, dayFormat); return (0, _element.createElement)("div", { className: (0, _classnames.default)('components-datetime__time') }, (0, _element.createElement)("fieldset", null, (0, _element.createElement)("legend", { className: "components-datetime__time-legend invisible" }, (0, _i18n.__)('Date')), (0, _element.createElement)("div", { className: "components-datetime__time-wrapper" }, dayMonthFormat, (0, _element.createElement)("div", { className: "components-datetime__time-field components-datetime__time-field-year" }, (0, _element.createElement)(UpdateOnBlurAsIntegerField, { "aria-label": (0, _i18n.__)('Year'), className: "components-datetime__time-field-year-input", type: "number", name: "year", step: 1, min: 0, max: 9999, value: year, onUpdate: update })))), (0, _element.createElement)("fieldset", null, (0, _element.createElement)("legend", { className: "components-datetime__time-legend invisible" }, (0, _i18n.__)('Time')), (0, _element.createElement)("div", { className: "components-datetime__time-wrapper" }, (0, _element.createElement)("div", { className: "components-datetime__time-field components-datetime__time-field-time" }, (0, _element.createElement)(UpdateOnBlurAsIntegerField, { "aria-label": (0, _i18n.__)('Hours'), className: "components-datetime__time-field-hours-input", type: "number", name: "hours", step: 1, min: is12Hour ? 1 : 0, max: is12Hour ? 12 : 23, value: hours, onUpdate: update }), (0, _element.createElement)("span", { className: "components-datetime__time-separator", "aria-hidden": "true" }, ":"), (0, _element.createElement)(UpdateOnBlurAsIntegerField, { "aria-label": (0, _i18n.__)('Minutes'), className: "components-datetime__time-field-minutes-input", type: "number", name: "minutes", step: 1, min: 0, max: 59, value: minutes, onUpdate: update })), is12Hour && (0, _element.createElement)(_buttonGroup.default, { className: "components-datetime__time-field components-datetime__time-field-am-pm" }, (0, _element.createElement)(_button.default, { isPrimary: am === 'AM', isSecondary: am !== 'AM', onClick: updateAmPm('AM'), className: "components-datetime__time-am-button" }, (0, _i18n.__)('AM')), (0, _element.createElement)(_button.default, { isPrimary: am === 'PM', isSecondary: am !== 'PM', onClick: updateAmPm('PM'), className: "components-datetime__time-pm-button" }, (0, _i18n.__)('PM'))), (0, _element.createElement)(_timezone.default, null)))); } var _default = TimePicker; exports.default = _default; //# sourceMappingURL=time.js.map