UNPKG

@yandex/ui

Version:

Yandex UI components

83 lines (82 loc) 4.35 kB
import { __read, __spread } from "tslib"; import React, { useCallback, useRef, useMemo, useEffect, } from 'react'; import { cn } from '@bem-react/classname'; import { Keys, isKeyCode } from '../lib/keyboard'; import { mergeRefs } from '../lib/mergeRefs'; import { useUniqId } from '../useUniqId'; import { TumblerLabel as Label } from './Label/Tumbler-Label'; import { TumblerButton as Button } from './Button/Tumbler-Button'; import { TumblerControl as Control } from './Control/Tumbler-Control'; import './Tumbler.css'; export var CHECKED_KEYS = [Keys.RIGHT, Keys.UP]; export var UNCHECKED_KEYS = [Keys.LEFT, Keys.DOWN]; export var cnTumbler = cn('Tumbler'); /** * Компонент, предназначенный для создания переключателя. * * @param {TumblerProps} props Свойства компонента. */ export var Tumbler = function (_a) { var checked = _a.checked, className = _a.className, htmlControlRef = _a.controlRef, disabled = _a.disabled, // eslint-disable-next-line react-hooks/rules-of-hooks _b = _a.id, // eslint-disable-next-line react-hooks/rules-of-hooks id = _b === void 0 ? useUniqId() : _b, innerRef = _a.innerRef, labelAfter = _a.labelAfter, labelBefore = _a.labelBefore, name = _a.name, onBlur = _a.onBlur, onChange = _a.onChange, htmlOnClick = _a.onClick, onFocus = _a.onFocus, htmlOnKeyDown = _a.onKeyDown, onKeyUp = _a.onKeyUp, tabIndex = _a.tabIndex, title = _a.title, autoFocus = _a.autoFocus, required = _a.required; var buttonRef = useRef(null); var controlRef = useRef(null); var controlId = "control-" + id; var beforeLabelId = "before-label-" + id; var afterLabelId = "after-label-" + id; useEffect(function () { if (autoFocus && buttonRef.current !== null) { buttonRef.current.focus(); } }, []); var labelledById = useMemo(function () { if (labelBefore && labelAfter) return checked ? beforeLabelId : afterLabelId; if (labelBefore) return beforeLabelId; if (labelAfter) return afterLabelId; return undefined; }, [checked, labelBefore, labelAfter, beforeLabelId, afterLabelId]); // prettier-ignore var onButtonClick = useCallback(function (event) { if (controlRef.current !== null) { controlRef.current.click(); } if (buttonRef.current !== null) { buttonRef.current.focus(); } if (htmlOnClick !== undefined) { htmlOnClick(event); } }, [htmlOnClick]); // prettier-ignore var onLabelClick = useCallback(function () { if (buttonRef.current !== null) { buttonRef.current.focus(); } }, []); // prettier-ignore var onKeyDown = useCallback(function (event) { if (isKeyCode(event.keyCode, __spread([Keys.ENTER], UNCHECKED_KEYS, CHECKED_KEYS))) { event.preventDefault(); } var shouldForceChange = (checked && isKeyCode(event.keyCode, UNCHECKED_KEYS)) || (!checked && isKeyCode(event.keyCode, CHECKED_KEYS)); if (shouldForceChange && controlRef.current !== null) { controlRef.current.click(); } if (htmlOnKeyDown !== undefined) { htmlOnKeyDown(event); } }, [checked, htmlOnKeyDown]); return (React.createElement("span", { ref: innerRef, className: cnTumbler(null, [className]), id: id, title: title, "aria-disabled": disabled }, labelBefore && (React.createElement(Label, { disabled: Boolean(!checked && labelBefore && labelAfter), htmlFor: controlId, id: beforeLabelId, onClick: onLabelClick }, labelBefore)), React.createElement(Button, { tabIndex: disabled ? -1 : tabIndex, innerRef: buttonRef, checked: checked, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onBlur: onBlur, onFocus: onFocus, onClick: onButtonClick, labelledBy: labelledById, required: required }), React.createElement(Control, { id: controlId, name: name, checked: checked, innerRef: mergeRefs(controlRef, htmlControlRef), onChange: onChange, required: required }), labelAfter && (React.createElement(Label, { disabled: Boolean(checked && labelBefore && labelAfter), htmlFor: controlId, id: afterLabelId, onClick: onLabelClick }, labelAfter)))); }; Tumbler.displayName = 'Tumbler';