@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
JavaScript
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