UNPKG

braid-design-system

Version:
215 lines (214 loc) • 6.67 kB
import { jsxs, Fragment, jsx } from "react/jsx-runtime"; import { forwardRef, useRef, useEffect } from "react"; import { useBackgroundLightness } from "../../Box/BackgroundContext.mjs"; import { Box } from "../../Box/Box.mjs"; import { FieldOverlay } from "../FieldOverlay/FieldOverlay.mjs"; import { buildDataAttributes } from "../buildDataAttributes.mjs"; import { validateTabIndex } from "../validateTabIndex.mjs"; import { realField, sizeVars, isMixed, fakeField, selected, hideBorderOnDarkBackgroundInLightMode, hoverOverlay, checkboxIndicator, radioIndicator, disabledRadioIndicator } from "./InlineField.css.mjs"; import { IconMinus } from "../../icons/IconMinus/IconMinus.mjs"; import { IconTick } from "../../icons/IconTick/IconTick.mjs"; const tones = ["neutral", "critical"]; const Indicator = ({ type, checked, hover = false, disabled = false }) => { const isCheckbox = type === "checkbox"; const iconTone = (() => { if (disabled) { return "secondary"; } if (hover) { return "formAccent"; } })(); return isCheckbox ? /* @__PURE__ */ jsxs( Box, { height: "full", transition: "fast", position: "relative", className: checkboxIndicator, children: [ /* @__PURE__ */ jsx( Box, { position: "absolute", inset: 0, transition: "fast", opacity: checked !== "mixed" ? 0 : void 0, children: /* @__PURE__ */ jsx(IconMinus, { size: "fill", tone: iconTone }) } ), /* @__PURE__ */ jsx( Box, { position: "absolute", inset: 0, transition: "fast", opacity: checked !== true ? 0 : void 0, children: /* @__PURE__ */ jsx(IconTick, { size: "fill", tone: iconTone }) } ) ] } ) : /* @__PURE__ */ jsx( Box, { background: !disabled ? "formAccent" : void 0, transition: "fast", width: "full", height: "full", borderRadius: "full", className: [ radioIndicator, disabled ? disabledRadioIndicator : void 0 ] } ); }; const StyledInput = forwardRef( ({ id, name, value, checked, data, onChange, type, tone = "neutral", disabled = false, required, tabIndex, size = "standard", "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, ...restProps }, forwardedRef) => { const defaultRef = useRef(null); const ref = forwardedRef || defaultRef; if (tones.indexOf(tone) === -1) { throw new Error(`Invalid tone: ${tone}`); } if (process.env.NODE_ENV !== "production") { validateTabIndex(tabIndex); } const isCheckbox = type === "checkbox"; const fieldBorderRadius = isCheckbox ? "standard" : "full"; const accentBackground = disabled ? "neutralLight" : "formAccent"; const isMixed$1 = isCheckbox && checked === "mixed"; const fieldBackground = disabled ? { lightMode: "neutralSoft", darkMode: "neutral" } : { lightMode: "surface" }; const defaultBorder = checked ? "formAccent" : "default"; const indeterminateRef = useRef(isMixed$1); const lastChecked = useRef(null); indeterminateRef.current = isMixed$1; if (isCheckbox && checked !== lastChecked.current && ref && typeof ref === "object" && ref.current) { ref.current.indeterminate = indeterminateRef.current; } useEffect(() => { if (isCheckbox && ref && typeof ref === "object" && ref.current) { ref.current.indeterminate = indeterminateRef.current; } }, [ref, isCheckbox]); useEffect(() => { if (isCheckbox) { lastChecked.current = checked; } }, [isCheckbox, checked]); const { lightMode } = useBackgroundLightness(); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( Box, { component: "input", type, id, name, value, onChange: (e) => { if (isMixed$1) { e.currentTarget.indeterminate = isMixed$1; } if (typeof onChange === "function") { onChange(e); } }, checked: checked === "mixed" ? false : checked, position: "absolute", zIndex: 1, className: [ realField, sizeVars[size], isMixed$1 ? isMixed : void 0 ], cursor: !disabled ? "pointer" : void 0, opacity: 0, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, "aria-checked": isMixed$1 ? "mixed" : checked, "aria-required": required, disabled, ref, tabIndex, ...buildDataAttributes({ data, validateRestProps: restProps }) } ), /* @__PURE__ */ jsxs( Box, { flexShrink: 0, position: "relative", className: [fakeField, sizeVars[size]], background: fieldBackground, borderRadius: fieldBorderRadius, children: [ /* @__PURE__ */ jsx( FieldOverlay, { background: isCheckbox ? accentBackground : void 0, borderRadius: fieldBorderRadius, className: selected, children: /* @__PURE__ */ jsx(Indicator, { type, disabled, checked }) } ), /* @__PURE__ */ jsx( FieldOverlay, { variant: disabled ? "disabled" : defaultBorder, borderRadius: fieldBorderRadius, visible: type === "radio" || !checked || disabled, className: { [hideBorderOnDarkBackgroundInLightMode]: lightMode === "dark" } } ), /* @__PURE__ */ jsx( FieldOverlay, { variant: "critical", borderRadius: fieldBorderRadius, visible: tone === "critical" && !disabled } ), /* @__PURE__ */ jsx( FieldOverlay, { variant: "formAccent", borderRadius: fieldBorderRadius, className: hoverOverlay, children: /* @__PURE__ */ jsx(Indicator, { type, hover: true, checked: true }) } ) ] } ) ] }); } ); export { StyledInput };