@primer/react
Version:
An implementation of GitHub's Primer Design System using React
108 lines (102 loc) • 5.16 kB
JavaScript
var React = require('react');
var ValidationAnimationContainer = require('../ValidationAnimationContainer.js');
var useId = require('../../../hooks/useId.js');
var CheckboxOrRadioGroupCaption = require('./CheckboxOrRadioGroupCaption.js');
var CheckboxOrRadioGroupLabel = require('./CheckboxOrRadioGroupLabel.js');
var CheckboxOrRadioGroupValidation = require('./CheckboxOrRadioGroupValidation.js');
var CheckboxOrRadioGroupContext = require('./CheckboxOrRadioGroupContext.js');
var _VisuallyHidden = require('../../../_VisuallyHidden.js');
var useSlots = require('../../../hooks/useSlots.js');
var CheckboxOrRadioGroup_module = require('./CheckboxOrRadioGroup.module.css.js');
var clsx = require('clsx');
var BoxWithFallback = require('../BoxWithFallback.js');
var jsxRuntime = require('react/jsx-runtime');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
const CheckboxOrRadioGroup = ({
'aria-labelledby': ariaLabelledby,
children,
disabled = false,
id: idProp,
required = false,
className,
sx
}) => {
const [slots, rest] = useSlots.useSlots(children, {
caption: CheckboxOrRadioGroupCaption,
label: CheckboxOrRadioGroupLabel,
validation: CheckboxOrRadioGroupValidation
});
const labelChild = React__default.default.Children.toArray(children).find(child => /*#__PURE__*/React__default.default.isValidElement(child) && child.type === CheckboxOrRadioGroupLabel);
const validationChild = React__default.default.Children.toArray(children).find(child => /*#__PURE__*/React__default.default.isValidElement(child) && child.type === CheckboxOrRadioGroupValidation ? child : null);
const captionChild = React__default.default.Children.toArray(children).find(child => /*#__PURE__*/React__default.default.isValidElement(child) && child.type === CheckboxOrRadioGroupCaption ? child : null);
const id = useId.useId(idProp);
const validationMessageId = validationChild ? `${id}-validationMessage` : undefined;
const captionId = captionChild ? `${id}-caption` : undefined;
if (!labelChild && !ariaLabelledby) {
// eslint-disable-next-line no-console
console.warn('A choice group must be labelled using a `CheckboxOrRadioGroup.Label` child, or by passing `aria-labelledby` to the CheckboxOrRadioGroup component.');
}
const isLegendVisible = /*#__PURE__*/React__default.default.isValidElement(labelChild) && !labelChild.props.visuallyHidden;
return /*#__PURE__*/jsxRuntime.jsx(CheckboxOrRadioGroupContext.Provider, {
value: {
disabled,
required,
captionId,
validationMessageId
},
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
children: [/*#__PURE__*/jsxRuntime.jsxs(BoxWithFallback.BoxWithFallback, {
className: clsx.clsx(className, CheckboxOrRadioGroup_module.GroupFieldset),
"data-validation": validationChild ? '' : undefined,
...(labelChild ? {
as: 'fieldset',
disabled
} : {}),
sx: sx,
children: [labelChild ?
/*#__PURE__*/
/*
Placing the caption text and validation text in the <legend> provides a better user
experience for more screenreaders.
Reference: https://blog.tenon.io/accessible-validation-of-checkbox-and-radiobutton-groups/
*/
jsxRuntime.jsxs("legend", {
className: CheckboxOrRadioGroup_module.GroupLegend,
"data-legend-visible": isLegendVisible ? '' : undefined,
children: [slots.label, slots.caption, /*#__PURE__*/React__default.default.isValidElement(slots.validation) && slots.validation.props.children && /*#__PURE__*/jsxRuntime.jsx(_VisuallyHidden, {
children: slots.validation.props.children
})]
}) : (
/*
If CheckboxOrRadioGroup.Label wasn't passed as a child, we don't render a <legend>
but we still want to render a caption
*/
slots.caption), /*#__PURE__*/jsxRuntime.jsx("div", {
className: CheckboxOrRadioGroup_module.Body,
...(!labelChild ? {
['aria-labelledby']: ariaLabelledby,
['aria-describedby']: [validationMessageId, captionId].filter(Boolean).join(' '),
as: 'div',
role: 'group'
} : {}),
children: React__default.default.Children.toArray(rest).filter(child => /*#__PURE__*/React__default.default.isValidElement(child))
})]
}), validationChild && /*#__PURE__*/jsxRuntime.jsx(ValidationAnimationContainer
// If we have CheckboxOrRadioGroup.Label as a child, we render a screenreader-accessible validation message in the <legend>
, {
"aria-hidden": Boolean(labelChild),
show: true,
children: slots.validation
})]
})
});
};
CheckboxOrRadioGroup.displayName = "CheckboxOrRadioGroup";
var CheckboxOrRadioGroup$1 = Object.assign(CheckboxOrRadioGroup, {
Caption: CheckboxOrRadioGroupCaption,
Label: CheckboxOrRadioGroupLabel,
Validation: CheckboxOrRadioGroupValidation
});
module.exports = CheckboxOrRadioGroup$1;
;