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.

138 lines (131 loc) 4.33 kB
import { filterUndefined } from "../utils/object.js"; import { cs } from "../utils/styles.js"; import { disabled } from "../checkbox/consts.js"; import { radioColors } from "./consts.js"; import { omitThemingProps, th, useStyleConfig } from "../core/theme.js"; import styled from "../core/styled.js"; import vui from "../core/vui.js"; import { Icon } from "../icon/icon.js"; import { T } from "../t/t.js"; import { useRadioGroupContext } from "./context.js"; import { useEffect, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/radio/radio.tsx const RadioControl = styled.spanBox` border-radius: 50%; display: inline-flex; flex-shrink: 0; position: relative; transition-duration: fast; `; const RadioInput = styled.input` cursor: inherit; height: 100%; left: 0; margin: 0; opacity: 0; padding: 0; position: absolute; top: 0; width: 100%; z-index: 1; `; const RadioBase = styled.labelBox` align-items: center; cursor: pointer; display: inline-flex; width: fit-content; &:not([aria-disabled='true']):not([aria-readonly='true']):hover .vui-radioControl { color: ${(p) => th.color(p.controlHoverColor)}; } &[aria-readonly='true'] { cursor: auto; } &:not([aria-disabled='true']):not([aria-readonly='true']) .vui-radioControl:focus-within { color: ${radioColors.focus}; } &[aria-disabled='true'] { color: ${disabled.text}; cursor: not-allowed; .vui-radioControl { color: ${disabled.icon}; } } `; /** * Allows selection of a single choice from a set of items. Handles controlled and uncontrolled modes. * Uses icons to display itself in different states. */ const Radio = vui((props, ref) => { const { defaultValue: groupDefaultValue, isChecked: groupIsChecked, onChange: groupOnChange, value: groupValue, ...radioGroupProps } = useRadioGroupContext() ?? {}; const defaultIsChecked = groupIsChecked !== void 0 ? groupIsChecked === props.value : void 0; const mergedProps = { ...radioGroupProps, ...props }; const { checked = groupValue !== void 0 ? props.value === groupValue : void 0, children, className, defaultChecked = groupDefaultValue !== void 0 ? props.value === groupDefaultValue : void 0, disabled, readOnly, icon: iconProp = "uiRadioUnselected", iconChecked = "uiRadioSelected", id, inputProps, inputRef, label, name, onChange, required, value, ...rest } = omitThemingProps(mergedProps); const [isChecked, setIsChecked] = useState(defaultIsChecked ?? checked ?? defaultChecked); const styles = useStyleConfig("Radio", mergedProps); const { color: controlColor, hoverColor, ...controlStyles } = styles.control; const icon = isChecked ? iconChecked : iconProp; const controlMr = children || label ? 1 : 0; const color = isChecked ? readOnly ? radioColors.readOnly : radioColors.checked : controlColor; const controlHoverColor = hoverColor ? hoverColor : radioColors.hover; useEffect(() => { if (groupIsChecked !== void 0) setIsChecked(groupIsChecked === value); else if (checked !== void 0) setIsChecked(checked); }, [checked, groupIsChecked]); function handleOnChange(e) { if (readOnly) return; groupOnChange?.(e); onChange?.(e); } const aliasedProps = filterUndefined({ "aria-disabled": disabled, "aria-readonly": readOnly }); return /* @__PURE__ */ jsxs(RadioBase, { className: cs("vui-radio", className), controlHoverColor, ref, ...styles.container, ...aliasedProps, ...rest, children: [/* @__PURE__ */ jsxs(RadioControl, { bg: "white", className: "vui-radioControl", color, focusWithinRing: 3, mr: controlMr, ...controlStyles, children: [/* @__PURE__ */ jsx(RadioInput, { className: "vui-radioInput", onClick: handleOnChange, ref: inputRef, type: "radio", defaultChecked: checked, disabled, id, name, required, value, ...inputProps }), /* @__PURE__ */ jsx(Icon, { className: "vui-radioIcon", h: "100%", name: icon, w: "100%" })] }), children ?? (label && /* @__PURE__ */ jsx(T, { className: "vui-radioLabel", lineHeight: "normal", ...styles.label, children: label }))] }); }); Radio.displayName = "Radio"; //#endregion export { Radio, Radio as default, RadioBase }; globalThis.__vuiVersion__ = "5.3.1" //# sourceMappingURL=radio.js.map