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