UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

216 lines (213 loc) • 9.38 kB
import { c } from 'react-compiler-runtime'; import { clsx } from 'clsx'; import React, { useContext } from 'react'; import Select from '../Select/Select.js'; import ValidationAnimationContainer from '../internal/components/ValidationAnimationContainer.js'; import { useSlots } from '../hooks/useSlots.js'; import { useId } from '../hooks/useId.js'; import { FormControlCaption } from './FormControlCaption.js'; import FormControlLabel from './FormControlLabel.js'; import FormControlLeadingVisual from './FormControlLeadingVisual.js'; import FormControlValidation from './_FormControlValidation.js'; import { FormControlContextProvider } from './_FormControlContext.js'; import { warning } from '../utils/warning.js'; import classes from './FormControl.module.css.js'; import { isSlot } from '../utils/is-slot.js'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import CheckboxOrRadioGroupContext from '../internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupContext.js'; import Autocomplete from '../Autocomplete/Autocomplete.js'; import Checkbox from '../Checkbox/Checkbox.js'; import Radio from '../Radio/Radio.js'; import TextInput from '../TextInput/TextInput.js'; import TextInputWithTokens from '../TextInputWithTokens/TextInputWithTokens.js'; import Textarea from '../Textarea/Textarea.js'; import { SelectPanel } from '../SelectPanel/SelectPanel.js'; const FormControl = /*#__PURE__*/React.forwardRef((t0, ref) => { var _slots$validation, _slots$label; const $ = c(27); const { children, disabled: disabledProp, layout: t1, id: idProp, required, className, style } = t0; const layout = t1 === undefined ? "vertical" : t1; let t2; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { t2 = { caption: FormControlCaption, label: FormControlLabel, leadingVisual: FormControlLeadingVisual, validation: FormControlValidation }; $[0] = t2; } else { t2 = $[0]; } const [slots, childrenWithoutSlots] = useSlots(children, t2); const expectedInputComponents = [Autocomplete, Checkbox, Radio, Select, TextInput, TextInputWithTokens, Textarea, SelectPanel]; const choiceGroupContext = useContext(CheckboxOrRadioGroupContext); const disabled = choiceGroupContext.disabled || disabledProp; const id = useId(idProp); const validationMessageId = slots.validation ? `${id}-validationMessage` : undefined; const captionId = slots.caption ? `${id}-caption` : undefined; const validationStatus = (_slots$validation = slots.validation) === null || _slots$validation === void 0 ? void 0 : _slots$validation.props.variant; const InputComponent = childrenWithoutSlots.find(child => expectedInputComponents.some(inputComponent => /*#__PURE__*/React.isValidElement(child) && (child.type === inputComponent || isSlot(child, inputComponent)))); const inputProps = /*#__PURE__*/React.isValidElement(InputComponent) && InputComponent.props; const isChoiceInput = /*#__PURE__*/React.isValidElement(InputComponent) && (InputComponent.type === Checkbox || InputComponent.type === Radio || isSlot(InputComponent, Checkbox) || isSlot(InputComponent, Radio)); const isRadioInput = /*#__PURE__*/React.isValidElement(InputComponent) && (InputComponent.type === Radio || isSlot(InputComponent, Radio)); if (InputComponent) { process.env.NODE_ENV !== "production" ? warning(inputProps === null || inputProps === void 0 ? void 0 : inputProps.id, "instead of passing the 'id' prop directly to the input component, it should be passed to the parent component, <FormControl>") : void 0; process.env.NODE_ENV !== "production" ? warning(inputProps === null || inputProps === void 0 ? void 0 : inputProps.disabled, "instead of passing the 'disabled' prop directly to the input component, it should be passed to the parent component, <FormControl>") : void 0; process.env.NODE_ENV !== "production" ? warning(inputProps === null || inputProps === void 0 ? void 0 : inputProps.required, "instead of passing the 'required' prop directly to the input component, it should be passed to the parent component, <FormControl>") : void 0; } if (!slots.label) { console.error(`The input field with the id ${id} MUST have a FormControl.Label child.\n\nIf you want to hide the label, pass the 'visuallyHidden' prop to the FormControl.Label component.`); } if (isChoiceInput) { process.env.NODE_ENV !== "production" ? warning(!!slots.validation, "Validation messages are not rendered for an individual checkbox or radio. The validation message should be shown for all options.") : void 0; process.env.NODE_ENV !== "production" ? warning(isRadioInput && childrenWithoutSlots.find(_temp), "An individual radio cannot be a required field.") : void 0; } else { process.env.NODE_ENV !== "production" ? warning(!!slots.leadingVisual, "A leading visual is only rendered for a checkbox or radio form control. If you want to render a leading visual inside of your input, check if your input supports a leading visual.") : void 0; } const isLabelHidden = (_slots$label = slots.label) === null || _slots$label === void 0 ? void 0 : _slots$label.props.visuallyHidden; const t3 = /*#__PURE__*/React.isValidElement(InputComponent) ? /*#__PURE__*/React.cloneElement(InputComponent, { id, disabled, required: required && !isRadioInput, "aria-describedby": captionId }) : null; let t4; if ($[1] !== childrenWithoutSlots) { t4 = childrenWithoutSlots.filter(_temp2); $[1] = childrenWithoutSlots; $[2] = t4; } else { t4 = $[2]; } let t5; if ($[3] !== t3 || $[4] !== t4) { t5 = /*#__PURE__*/jsxs("div", { className: classes.ControlChoiceInputs, children: [t3, t4] }); $[3] = t3; $[4] = t4; $[5] = t5; } else { t5 = $[5]; } let t6; if ($[6] !== disabled || $[7] !== slots.caption || $[8] !== slots.leadingVisual) { t6 = slots.leadingVisual ? /*#__PURE__*/jsx("div", { className: classes.LeadingVisual, "data-disabled": disabled ? "" : undefined, "data-has-caption": slots.caption ? "" : undefined, children: slots.leadingVisual }) : null; $[6] = disabled; $[7] = slots.caption; $[8] = slots.leadingVisual; $[9] = t6; } else { t6 = $[9]; } let t7; if ($[10] !== slots.caption || $[11] !== slots.label) { t7 = /*#__PURE__*/jsxs("div", { className: classes.LabelContainer, children: [slots.label, slots.caption] }); $[10] = slots.caption; $[11] = slots.label; $[12] = t7; } else { t7 = $[12]; } let t8; if ($[13] !== t5 || $[14] !== t6 || $[15] !== t7) { t8 = /*#__PURE__*/jsxs(Fragment, { children: [t5, t6, t7] }); $[13] = t5; $[14] = t6; $[15] = t7; $[16] = t8; } else { t8 = $[16]; } const InputChildren = t8; const T0 = FormControlContextProvider; let t9; if ($[17] !== captionId || $[18] !== disabled || $[19] !== id || $[20] !== required || $[21] !== validationMessageId) { t9 = { captionId, disabled, id, required, validationMessageId }; $[17] = captionId; $[18] = disabled; $[19] = id; $[20] = required; $[21] = validationMessageId; $[22] = t9; } else { t9 = $[22]; } const t10 = isChoiceInput || layout === "horizontal" ? /*#__PURE__*/jsx("div", { ref: ref, "data-has-leading-visual": slots.leadingVisual ? "" : undefined, className: clsx(className, classes.ControlHorizontalLayout), style: style, children: InputChildren }) : /*#__PURE__*/jsxs("div", { ref: ref, "data-has-label": !isLabelHidden ? "" : undefined, className: clsx(className, classes.ControlVerticalLayout), style: style, children: [slots.label, /*#__PURE__*/React.isValidElement(InputComponent) && /*#__PURE__*/React.cloneElement(InputComponent, Object.assign({ id, required, disabled, validationStatus, "aria-describedby": [validationMessageId, captionId].filter(Boolean).join(" ") }, InputComponent.props)), childrenWithoutSlots.filter(child_2 => /*#__PURE__*/React.isValidElement(child_2) && !expectedInputComponents.some(inputComponent_1 => child_2.type === inputComponent_1 || isSlot(child_2, inputComponent_1))), slots.validation ? /*#__PURE__*/jsx(ValidationAnimationContainer, { show: true, children: slots.validation }) : null, slots.caption] }); let t11; if ($[23] !== T0 || $[24] !== t10 || $[25] !== t9) { t11 = /*#__PURE__*/jsx(T0, { value: t9, children: t10 }); $[23] = T0; $[24] = t10; $[25] = t9; $[26] = t11; } else { t11 = $[26]; } return t11; }); var FormControl$1 = Object.assign(FormControl, { __SLOT__: Symbol('FormControl'), Caption: FormControlCaption, Label: FormControlLabel, LeadingVisual: FormControlLeadingVisual, Validation: FormControlValidation }); function _temp(child_0) { var _child_0$props; return /*#__PURE__*/React.isValidElement(child_0) && ((_child_0$props = child_0.props) === null || _child_0$props === void 0 ? void 0 : _child_0$props.required); } function _temp2(child_1) { return /*#__PURE__*/React.isValidElement(child_1) && ![Checkbox, Radio].some(inputComponent_0 => child_1.type === inputComponent_0 || isSlot(child_1, inputComponent_0)); } export { FormControl$1 as default };