UNPKG

@veracity/vui

Version:

Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.

114 lines (112 loc) 3.65 kB
import { filterUndefined } from "../utils/object.js"; import { cs } from "../utils/styles.js"; import { selectionControlGroupGap, selectionControlLabelSize, selectionControlStackGap } from "../selectionControl/theme.js"; import { selectionControlColors } from "../selectionControl/consts.js"; import styled from "../core/styled.js"; import vui from "../core/vui.js"; import { Box } from "../box/box.js"; import { T } from "../t/t.js"; import { RadioGroupProvider } from "./context.js"; import { useCallback, useId, useMemo, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/radio/radioGroup.tsx const RadioGroupBase = styled.divBox` display: flex; flex-direction: column; `; /** * Organizes layout and display of multiple radio buttons as a row or column. * Exposes some props to the children via context. `label`/`helpText`/`errorText` render an optional * group heading/description around the stack; `errorText` overrides `helpText` and marks the group invalid. */ const RadioGroup = vui((props, ref) => { const { children, className, defaultValue, disabled, errorText, gap, groupGap, helpText, isRow, label, name, onBlur, onChange, onFocus, size, value, variant, ...rest } = props; const description = errorText ?? helpText; const [isChecked, setIsChecked] = useState(value ?? defaultValue); const handleOnChange = useCallback((e) => { setIsChecked(e.target.value); onChange?.(e); }, [onChange]); const context = useMemo(() => filterUndefined({ defaultValue, disabled, isChecked, name, onBlur, onChange: handleOnChange, onFocus, size, value, variant }), [ defaultValue, disabled, handleOnChange, isChecked, name, onBlur, onFocus, size, value, variant ]); const groupSize = size ?? "md"; const aliasedProps = filterUndefined({ flexDirection: isRow ? "row" : void 0, gap: gap ?? selectionControlStackGap[groupSize] ?? selectionControlStackGap.md }); const generatedId = useId(); const labelId = label ? `${generatedId}-label` : void 0; const descriptionId = description ? `${generatedId}-help-text` : void 0; if (!label && !description) return /* @__PURE__ */ jsx(RadioGroupProvider, { value: context, children: /* @__PURE__ */ jsx(RadioGroupBase, { className: cs("vui-radioGroup", className), ref, ...aliasedProps, ...rest, children }) }); return /* @__PURE__ */ jsx(RadioGroupProvider, { value: context, children: /* @__PURE__ */ jsxs(Box, { className: cs("vui-radioGroup", className), column: true, gap: groupGap ?? selectionControlGroupGap[groupSize] ?? selectionControlGroupGap.md, ref, ...rest, children: [ label && /* @__PURE__ */ jsx(T, { className: "vui-radioGroupLabel", color: selectionControlColors.label, fontWeight: "demi", id: labelId, size: selectionControlLabelSize[groupSize] ?? selectionControlLabelSize.md, children: label }), /* @__PURE__ */ jsx(RadioGroupBase, { "aria-describedby": descriptionId, "aria-invalid": !!errorText || void 0, "aria-labelledby": labelId, className: "vui-radioGroupStack", role: "group", ...aliasedProps, children }), description && /* @__PURE__ */ jsx(T, { className: "vui-radioGroupHelpText", color: errorText ? selectionControlColors.error : selectionControlColors.helper, id: descriptionId, size: "xs", children: description }) ] }) }); }); RadioGroup.displayName = "RadioGroup"; //#endregion export { RadioGroup, RadioGroup as default, RadioGroupBase }; globalThis.__vuiVersion__ = "5.4.0" //# sourceMappingURL=radioGroup.js.map