UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

73 lines (72 loc) 4.03 kB
'use client'; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Palette = void 0; const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const React = tslib_1.__importStar(require("react")); const hooks_1 = require("../../hooks/index.js"); const useForkRef_1 = require("../../hooks/useForkRef/useForkRef.js"); const Button_1 = require("../Button/index.js"); const cn_1 = require("../utils/cn.js"); const filterDOMProps_1 = require("../utils/filterDOMProps.js"); const hooks_2 = require("./hooks.js"); const utils_1 = require("./utils.js"); require("./Palette.css"); const b = (0, cn_1.block)('palette'); exports.Palette = React.forwardRef(function Palette(props, ref) { const { size = 'm', multiple = true, options = [], columns = 6, disabled, style, className, rowClassName, optionClassName, qa, onFocus, onBlur, } = props; const [focusedOptionIndex, setFocusedOptionIndex] = React.useState(undefined); const focusedOption = focusedOptionIndex === undefined ? undefined : options[focusedOptionIndex]; const innerRef = React.useRef(null); const handleRef = (0, useForkRef_1.useForkRef)(ref, innerRef); const { value, handleSelection } = (0, hooks_1.useSelect)({ value: props.value, defaultValue: props.defaultValue, multiple, onUpdate: props.onUpdate, }); const rows = React.useMemo(() => (0, utils_1.getPaletteRows)(options, columns), [columns, options]); const focusOnOptionWithIndex = React.useCallback((index) => { if (!innerRef.current) return; const $options = Array.from(innerRef.current.querySelectorAll(`.${b('option')}`)); if (!$options[index]) return; $options[index].focus(); setFocusedOptionIndex(index); }, []); const tryToFocus = (newIndex) => { if (newIndex === focusedOptionIndex || newIndex < 0 || newIndex >= options.length) { return; } focusOnOptionWithIndex(newIndex); }; const gridProps = (0, hooks_2.usePaletteGrid)({ disabled, onFocus: (event) => { focusOnOptionWithIndex(0); onFocus?.(event); }, onBlur: (event) => { setFocusedOptionIndex(undefined); onBlur?.(event); }, whenFocused: focusedOptionIndex !== undefined && focusedOption ? { selectItem: () => handleSelection(focusedOption), nextItem: () => tryToFocus(focusedOptionIndex + 1), previousItem: () => tryToFocus(focusedOptionIndex - 1), nextRow: () => tryToFocus(focusedOptionIndex + columns), previousRow: () => tryToFocus(focusedOptionIndex - columns), } : undefined, }); return ((0, jsx_runtime_1.jsx)("div", { ...(0, filterDOMProps_1.filterDOMProps)(props, { labelable: true }), ...gridProps, ref: handleRef, className: b({ size }, className), style: style, "data-qa": qa, children: rows.map((row, rowNumber) => ((0, jsx_runtime_1.jsx)("div", { className: b('row', rowClassName), role: "row", children: row.map((option) => { const isSelected = Boolean(value.includes(option.value)); const focused = option === focusedOption; return ((0, jsx_runtime_1.jsx)("div", { role: "gridcell", "aria-selected": focused ? 'true' : undefined, "aria-readonly": option.disabled, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { className: b('option', optionClassName), tabIndex: -1, style: style, disabled: disabled || option.disabled, title: option.title, view: isSelected ? 'normal' : 'flat', selected: isSelected, value: option.value, size: size, onClick: () => handleSelection(option), children: (0, jsx_runtime_1.jsx)(Button_1.Button.Icon, { children: option.content ?? option.value }) }) }, option.value)); }) }, `row-${rowNumber}`))) })); }); exports.Palette.displayName = 'Palette'; //# sourceMappingURL=Palette.js.map