UNPKG

@hypothesis/frontend-shared

Version:

Shared components, styles and utilities for Hypothesis projects

136 lines 3.9 kB
var _jsxFileName = "/home/runner/work/frontend-shared/frontend-shared/src/components/input/RadioGroup.tsx"; import classnames from 'classnames'; import { useContext, useRef } from 'preact/hooks'; import { useArrowKeyNavigation } from '../../hooks/use-arrow-key-navigation'; import { RadioCheckedIcon, RadioIcon } from '../icons'; import RadioGroupContext from './RadioGroupContext'; import { jsxDEV as _jsxDEV } from "preact/jsx-dev-runtime"; function Radio({ value, children, subtitle, disabled: radioDisabled }) { const radioGroupContext = useContext(RadioGroupContext); if (!radioGroupContext) { throw new Error('RadioGroup.Radio can only be used as RadioGroup child'); } const { selected, disabled = radioDisabled, onChange } = radioGroupContext; const isSelected = !disabled && selected === value; return _jsxDEV("div", { role: "radio", "aria-checked": isSelected, "aria-disabled": disabled, className: classnames('focus-visible-ring rounded-lg px-3 py-2 flex-1 group', { 'bg-grey-3/50': isSelected, 'hover:bg-grey-3/25': !isSelected && !disabled, 'opacity-70': disabled, 'cursor-pointer': !disabled }), "data-value": value, onClick: !disabled ? () => onChange(value) : undefined, onKeyDown: disabled ? undefined : e => { if (['Enter', ' '].includes(e.key)) { e.preventDefault(); onChange(value); } }, tabIndex: -1, children: [_jsxDEV("div", { className: "flex items-center gap-x-1.5", children: [isSelected ? _jsxDEV(RadioCheckedIcon, {}, void 0, false, { fileName: _jsxFileName, lineNumber: 68, columnNumber: 23 }, this) : _jsxDEV(RadioIcon, {}, void 0, false, { fileName: _jsxFileName, lineNumber: 68, columnNumber: 46 }, this), children] }, void 0, true, { fileName: _jsxFileName, lineNumber: 67, columnNumber: 7 }, this), subtitle && _jsxDEV("div", { className: classnames('pl-4 ml-1.5 mt-1 text-sm', { 'text-grey-7': isSelected, 'text-grey-6 group-hover:text-grey-7': !isSelected && !disabled }), children: subtitle }, void 0, false, { fileName: _jsxFileName, lineNumber: 72, columnNumber: 9 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 40, columnNumber: 5 }, this); } Radio.displayName = 'RadioGroup.Radio'; function RadioGroupMain({ direction = 'horizontal', children, selected, onChange, disabled, 'aria-label': label, 'aria-labelledby': labelledBy, name }) { const containerRef = useRef(null); useArrowKeyNavigation(containerRef, { loop: false, selector: '[role="radio"]:not([aria-disabled="true"])', focusElement: el => { onChange(el.dataset.value); el.focus(); } }); return _jsxDEV(RadioGroupContext.Provider, { value: { selected, disabled, onChange: onChange }, children: [_jsxDEV("div", { "aria-label": label, "aria-labelledby": labelledBy, ref: containerRef, role: "radiogroup", className: classnames('w-full flex gap-1.5', { 'flex-col': direction === 'vertical' }), children: children }, void 0, false, { fileName: _jsxFileName, lineNumber: 134, columnNumber: 7 }, this), name && _jsxDEV("input", { type: "hidden", "data-testid": "hidden-input", name: name, value: selected, disabled: disabled }, void 0, false, { fileName: _jsxFileName, lineNumber: 146, columnNumber: 9 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 131, columnNumber: 5 }, this); } const RadioGroup = Object.assign(RadioGroupMain, { Radio, displayName: 'RadioGroup' }); export default RadioGroup; //# sourceMappingURL=RadioGroup.js.map