UNPKG

@renderlesskit/react

Version:

Collection of headless components/hooks that are accessible, composable, customizable from low level to build your own UI & Design System powered by Reakit

233 lines (195 loc) 8.44 kB
var _excluded = ["segment", "next"], _excluded2 = ["onMouseDown", "onKeyDown", "onFocus"]; function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import * as React from "react"; import { useCompositeItem } from "reakit"; import { callAllHandlers } from "@chakra-ui/utils"; import { useDateFormatter } from "@react-aria/i18n"; import { useSpinButton } from "@react-aria/spinbutton"; import { mergeProps } from "@react-aria/utils"; import { createComponent, createHook } from "../system"; import { dataAttr } from "../utils"; import { SEGMENT_KEYS } from "./__keys"; import { isNumeric, parseNumber } from "./helpers"; export var useSegment = createHook({ name: "Segment", compose: useCompositeItem, keys: SEGMENT_KEYS, useOptions(options, _) { return _objectSpread({ disabled: options.isDisabled || options.isReadOnly || options.segment.type === "literal" }, options); }, useProps(_ref, _ref2) { var { segment, next } = _ref, options = _objectWithoutProperties(_ref, _excluded); var { onMouseDown: htmlOnMouseDown, onKeyDown: htmlOnKeyDown, onFocus: htmlOnFocus } = _ref2, htmlProps = _objectWithoutProperties(_ref2, _excluded2); var [enteredKeys, setEnteredKeys] = React.useState(""); var textValue = segment.text; var monthDateFormatter = useDateFormatter({ month: "long" }); var hourDateFormatter = useDateFormatter({ hour: "numeric", hour12: options.dateFormatter.resolvedOptions().hour12 }); var hourFormattedValue = hourDateFormatter.format(options.fieldValue); if (segment.type === "month") { textValue = monthDateFormatter.format(options.fieldValue); } if (segment.type === "hour") { textValue = hourFormattedValue.split(" ")[0]; } if (segment.type === "dayPeriod") { textValue = hourFormattedValue.split(" ")[1]; } var { spinButtonProps } = useSpinButton({ value: segment.value, textValue, minValue: segment.minValue, maxValue: segment.maxValue, isDisabled: options.isDisabled, isReadOnly: options.isReadOnly, isRequired: options.isRequired, onIncrement: () => options.increment(segment.type), onDecrement: () => options.decrement(segment.type), onIncrementPage: () => options.incrementPage(segment.type), onDecrementPage: () => options.decrementPage(segment.type), onIncrementToMax: () => options.setSegment(segment.type, segment.maxValue), onDecrementToMin: () => options.setSegment(segment.type, segment.minValue) }); var onInput = React.useCallback(key => { var newValue = enteredKeys + key; switch (segment.type) { case "dayPeriod": if (key === "a") { options.setSegment("dayPeriod", 0); } else if (key === "p") { options.setSegment("dayPeriod", 12); } next(); break; case "day": case "hour": case "minute": case "second": case "month": case "year": { if (!isNumeric(newValue)) { return; } var numberValue = parseNumber(newValue); var segmentValue = numberValue; if (segment.type === "hour" && options.dateFormatter.resolvedOptions().hour12 && numberValue === 12) { segmentValue = 0; } else if (numberValue > segment.maxValue) { segmentValue = parseNumber(key); } options.setSegment(segment.type, segmentValue); if (Number(numberValue + "0") > segment.maxValue) { setEnteredKeys(""); next(); } else { setEnteredKeys(newValue); } break; } } }, [enteredKeys, next, options, segment.maxValue, segment.type]); var onKeyDown = React.useCallback(e => { if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) { return; } switch (e.key) { case "Enter": e.preventDefault(); if (segment.isPlaceholder && !options.isReadOnly) { options.confirmPlaceholder(segment.type); } next(); break; case "Tab": break; case "Backspace": { e.preventDefault(); if (isNumeric(segment.text) && !options.isReadOnly) { var newValue = segment.text.slice(0, -1); options.setSegment(segment.type, newValue.length === 0 ? segment.minValue : parseNumber(newValue)); setEnteredKeys(newValue); } break; } default: e.preventDefault(); e.stopPropagation(); if ((isNumeric(e.key) || /^[ap]$/.test(e.key)) && !options.isReadOnly) { onInput(e.key); } } }, [next, onInput, options, segment.isPlaceholder, segment.minValue, segment.text, segment.type]); var onFocus = React.useCallback(() => { setEnteredKeys(""); }, []); var onMouseDown = React.useCallback(e => e.stopPropagation(), []); switch (segment.type) { // A separator, e.g. punctuation case "literal": return _objectSpread({ "data-placeholder": dataAttr(false), children: segment.text }, htmlProps); // These segments cannot be directly edited by the user. case "weekday": case "timeZoneName": case "era": return _objectSpread({ "data-placeholder": true, children: segment.text }, htmlProps); // Editable segment default: return mergeProps(spinButtonProps, _objectSpread({ "aria-label": segment.type, onKeyDown: callAllHandlers(htmlOnKeyDown, onKeyDown), onFocus: callAllHandlers(htmlOnFocus, onFocus), onMouseDown: callAllHandlers(htmlOnMouseDown, onMouseDown), children: segment.text }, htmlProps)); } }, useComposeProps(options, htmlProps) { var composite = useCompositeItem(options, htmlProps); /* Haz: Ensure tabIndex={0} Tab is not the only thing that can move focus in web pages For example, on iOS you can move between form elements using the arrows above the keyboard */ return _objectSpread(_objectSpread({}, composite), {}, { tabIndex: options.disabled ? -1 : 0 }); } }); export var Segment = createComponent({ as: "div", memo: true, useHook: useSegment }); //# sourceMappingURL=Segment.js.map