@gravity-ui/uikit
Version:
Gravity UI base styling and components
73 lines (72 loc) • 4.03 kB
JavaScript
'use client';
;
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