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.

194 lines (187 loc) • 6.33 kB
import { filterUndefined } from "../utils/object.js"; import { cs } from "../utils/styles.js"; import { selectionControlColors, selectionControlDisabled } from "../selectionControl/consts.js"; import { omitThemingProps, th, useStyleConfig } from "../core/theme.js"; import styled from "../core/styled.js"; import vui from "../core/vui.js"; import { Box } from "../box/box.js"; import { Icon } from "../icon/icon.js"; import { T } from "../t/t.js"; import { SelectionControlInput, useDeprecatedLgSize, useSelectionControlColors, useSelectionControlDescription } from "../selectionControl/selectionControl.js"; import { useCheckboxGroupContext } from "./context.js"; import { useEffect, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/checkbox/checkbox.tsx const controlGap = { lg: "10px", md: "10px", sm: "8px", xs: "6px" }; const jsxChildrenMt = { lg: "0px", md: "0px", sm: "2px", xs: "3px" }; const labelMt = { lg: "0px", md: "0px", sm: "0.5px", xs: "1px" }; const markSize = { lg: "16px", md: "16px", sm: "13px", xs: "10px" }; const markOffset = { lg: "3px", md: "3px", sm: "2.5px", xs: "2px" }; const CheckboxControl = styled.spanBox` border: 1px solid currentColor; border-radius: 0; display: inline-flex; flex-shrink: 0; position: relative; transition-duration: fast; `; const CheckboxBase = styled.labelBox` cursor: pointer; display: inline-flex; width: fit-content; &:not([aria-disabled='true']):not([aria-readonly='true']):hover .vui-checkboxControl { color: ${(p) => th.color(p.controlHoverColor)}; } &:not([aria-disabled='true']):not([aria-readonly='true']):active .vui-checkboxControl { color: ${(p) => th.color(p.controlPressedColor)}; } &[aria-readonly='true'] { cursor: auto; } &[aria-disabled='true'] { color: ${selectionControlDisabled.text}; cursor: not-allowed; .vui-checkboxControl { background-color: ${selectionControlDisabled.bg}; color: ${selectionControlDisabled.icon}; } } `; /** * Allows selection of one or more choices from a set of items. Handles controlled and uncontrolled modes. * The box itself is plain CSS (border/background); only the checkmark/minus mark is an icon. Can be * indeterminate when selecting some nested items. */ const Checkbox = vui((props, ref) => { const { defaultValue: groupDefaultValue, ...checkboxGroupProps } = useCheckboxGroupContext() ?? {}; const mergedProps = { ...checkboxGroupProps, ...props }; const { checked, children, className, defaultChecked = groupDefaultValue !== void 0 ? groupDefaultValue.includes(props.value) : void 0, disabled, errorText, readOnly, helpText, icon: iconProp, iconChecked = "uiCheck", iconIndeterminate = "uiMinus", id: idProp, inputProps, inputRef, isIndeterminate, label, name, onChange: onChangeProp, required, value, ...rest } = omitThemingProps(mergedProps); const [isChecked, setIsChecked] = useState(defaultChecked); const styles = useStyleConfig("Checkbox", mergedProps); const { color: controlColor, hoverColor, pressedColor, ...controlStyles } = styles.control; const size = mergedProps.size ?? "md"; const isCheckedOrIndeterminate = isChecked || isIndeterminate; const { description, descriptionId, errorText: effectiveErrorText, id } = useSelectionControlDescription(idProp, helpText, errorText, isCheckedOrIndeterminate); const markIcon = isIndeterminate ? iconIndeterminate : isChecked ? iconChecked : iconProp; const controlMr = children || label ? controlGap[size] ?? controlGap.md : 0; const { color, controlHoverColor, controlPressedColor, descriptionColor, labelColor } = useSelectionControlColors({ controlColor, differentiateUnchecked: true, disabled, errorText: effectiveErrorText, hoverColor, isActive: isCheckedOrIndeterminate, pressedColor, readOnly }); const markColor = disabled ? selectionControlDisabled.mark : isCheckedOrIndeterminate ? selectionControlColors.mark : color; const hasJsxChildren = !!children; useDeprecatedLgSize(size, "Checkbox"); useEffect(() => { checked !== void 0 && setIsChecked(checked); }, [checked]); const onChange = (e) => { if (readOnly) return; if (checked === void 0) setIsChecked(e.target.checked); onChangeProp?.(e); }; const aliasedProps = filterUndefined({ "aria-disabled": disabled, "aria-readonly": readOnly }); return /* @__PURE__ */ jsxs(CheckboxBase, { alignItems: label || hasJsxChildren ? "flex-start" : "center", className: cs("vui-checkbox", className), controlHoverColor, controlPressedColor, ref, ...styles.container, ...aliasedProps, ...rest, children: [/* @__PURE__ */ jsxs(CheckboxControl, { bg: isCheckedOrIndeterminate ? "currentColor" : "white", className: "vui-checkboxControl", color, focusWithinRing: 3, focusWithinRingColor: selectionControlColors.focus, mr: controlMr, mt: hasJsxChildren ? jsxChildrenMt[size] ?? jsxChildrenMt.md : label ? labelMt[size] ?? labelMt.md : void 0, role: "none", ...controlStyles, children: [/* @__PURE__ */ jsx(SelectionControlInput, { "aria-describedby": descriptionId, "aria-invalid": !!effectiveErrorText || void 0, className: "vui-checkboxInput", onChange, ref: inputRef, type: "checkbox", checked, defaultChecked, disabled, id, name, required, value, ...inputProps }), markIcon && /* @__PURE__ */ jsx(Icon, { className: "vui-checkboxIcon", color: markColor, h: markSize[size] ?? markSize.md, left: markOffset[size] ?? markOffset.md, name: markIcon, position: "absolute", top: markOffset[size] ?? markOffset.md, w: markSize[size] ?? markSize.md })] }), children ?? (label && /* @__PURE__ */ jsxs(Box, { column: true, children: [/* @__PURE__ */ jsx(T, { className: "vui-checkboxLabel", color: labelColor, variant: "caption", ...styles.label, children: label }), description && /* @__PURE__ */ jsx(T, { className: "vui-checkboxDescription", color: descriptionColor, id: descriptionId, mt: "2px", size: "sm", children: description })] }))] }); }); Checkbox.displayName = "Checkbox"; //#endregion export { Checkbox, Checkbox as default, CheckboxBase }; globalThis.__vuiVersion__ = "5.4.0" //# sourceMappingURL=checkbox.js.map