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