UNPKG

@spark-ui/components

Version:

Spark (Leboncoin design system) components.

347 lines (335 loc) 11.5 kB
import { Label } from "../chunk-HLXYG643.mjs"; import { Icon } from "../chunk-UMUMFMFB.mjs"; import "../chunk-KEGAAGJW.mjs"; import "../chunk-6QCEPQ3U.mjs"; // src/checkbox/Checkbox.tsx import { useFormFieldControl } from "@spark-ui/components/form-field"; import { useMergeRefs } from "@spark-ui/hooks/use-merge-refs"; import { cx } from "class-variance-authority"; import { useId, useMemo, useRef } from "react"; // src/checkbox/CheckboxGroupContext.tsx import { createContext, useContext } from "react"; var CheckboxGroupContext = createContext({}); var useCheckboxGroup = () => { const context = useContext(CheckboxGroupContext); return context; }; // src/checkbox/CheckboxInput.tsx import { Check } from "@spark-ui/icons/Check"; import { Minus } from "@spark-ui/icons/Minus"; import { Checkbox as Checkbox2 } from "radix-ui"; // src/checkbox/CheckboxIndicator.tsx import { Checkbox } from "radix-ui"; import { jsx } from "react/jsx-runtime"; var CheckboxIndicatorPrimitive = Checkbox.CheckboxIndicator; var CheckboxIndicator = (props) => /* @__PURE__ */ jsx(CheckboxIndicatorPrimitive, { className: "flex size-full items-center justify-center", ...props }); CheckboxIndicator.displayName = "CheckboxIndicator"; // src/checkbox/CheckboxInput.styles.ts import { makeVariants } from "@spark-ui/internal-utils"; import { cva } from "class-variance-authority"; var checkboxInputStyles = cva( [ "size-sz-24 shrink-0 items-center justify-center rounded-sm border-md bg-transparent", "disabled:cursor-not-allowed disabled:opacity-dim-3 disabled:hover:ring-0", "focus-visible:u-outline", "hover:ring-4 hover:cursor-pointer", "u-shadow-border-transition" ], { variants: { /** * Color scheme of the checkbox. */ intent: makeVariants({ main: [ "text-on-main", "hover:ring-main-container", "data-[state=unchecked]:border-outline", "data-[state=indeterminate]:border-main data-[state=indeterminate]:bg-main", "data-[state=checked]:border-main data-[state=checked]:bg-main" ], support: [ "text-on-support", "hover:ring-support-container", "data-[state=unchecked]:border-outline", "data-[state=indeterminate]:border-support data-[state=indeterminate]:bg-support", "data-[state=checked]:border-support data-[state=checked]:bg-support" ], accent: [ "text-on-accent", "hover:ring-accent-container", "data-[state=unchecked]:border-outline", "data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent", "data-[state=checked]:border-accent data-[state=checked]:bg-accent" ], basic: [ "text-on-basic", "hover:ring-basic-container", "data-[state=unchecked]:border-outline", "data-[state=indeterminate]:border-basic data-[state=indeterminate]:bg-basic", "data-[state=checked]:border-basic data-[state=checked]:bg-basic" ], success: [ "text-on-success", "hover:ring-success-container", "data-[state=unchecked]:border-success", "data-[state=indeterminate]:border-success data-[state=indeterminate]:bg-success", "data-[state=checked]:border-success data-[state=checked]:bg-success" ], alert: [ "text-on-alert", "hover:ring-alert-container", "data-[state=unchecked]:border-alert", "data-[state=indeterminate]:border-alert data-[state=indeterminate]:bg-alert", "data-[state=checked]:border-alert data-[state=checked]:bg-alert" ], error: [ "text-on-error", "hover:ring-error-container", "data-[state=unchecked]:border-error", "data-[state=indeterminate]:border-error data-[state=indeterminate]:bg-error", "data-[state=checked]:border-error data-[state=checked]:bg-error" ], info: [ "text-on-info", "hover:ring-info-container", "data-[state=unchecked]:border-info", "data-[state=indeterminate]:border-info data-[state=indeterminate]:bg-info", "data-[state=checked]:border-info data-[state=checked]:bg-info" ], neutral: [ "text-on-neutral", "hover:ring-neutral-container", "data-[state=unchecked]:border-outline", "data-[state=indeterminate]:border-neutral data-[state=indeterminate]:bg-neutral", "data-[state=checked]:border-neutral data-[state=checked]:bg-neutral" ] }) }, defaultVariants: { intent: "basic" } } ); // src/checkbox/CheckboxInput.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var CheckboxPrimitive = Checkbox2.Checkbox; var CheckboxInput = ({ className, icon = /* @__PURE__ */ jsx2(Check, {}), indeterminateIcon = /* @__PURE__ */ jsx2(Minus, {}), intent, checked, ref, ...others }) => /* @__PURE__ */ jsx2( CheckboxPrimitive, { ref, className: checkboxInputStyles({ intent, className }), checked, ...others, children: /* @__PURE__ */ jsx2(CheckboxIndicator, { children: /* @__PURE__ */ jsx2(Icon, { size: "sm", children: checked === "indeterminate" ? indeterminateIcon : icon }) }) } ); CheckboxInput.displayName = "CheckboxInput"; // src/checkbox/CheckboxLabel.styles.ts import { cva as cva2 } from "class-variance-authority"; var labelStyles = cva2("grow", { variants: { disabled: { true: ["text-neutral/dim-2", "cursor-not-allowed"], false: ["cursor-pointer"] } }, defaultVariants: { disabled: false } }); // src/checkbox/CheckboxLabel.tsx import { jsx as jsx3 } from "react/jsx-runtime"; var CheckboxLabel = ({ disabled, ...others }) => /* @__PURE__ */ jsx3(Label, { className: labelStyles({ disabled }), ...others }); CheckboxLabel.displayName = "CheckboxLabel"; // src/checkbox/Checkbox.tsx import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime"; var ID_PREFIX = ":checkbox"; var Checkbox3 = ({ id: idProp, className, intent: intentProp, checked: checkedProp, value, disabled, reverse = false, onCheckedChange, children, ref: forwardedRef, ...others }) => { const checkboxId = `${ID_PREFIX}-${useId()}`; const innerId = idProp || checkboxId; const innerLabelId = `${ID_PREFIX}-${useId()}`; const field = useFormFieldControl(); const group = useCheckboxGroup(); const rootRef = useRef(null); const ref = useMergeRefs(forwardedRef, rootRef); const getCheckboxAttributes = ({ fieldState, groupState, checkboxIntent }) => { const name2 = fieldState.name ?? groupState.name; const isRequired2 = fieldState.isRequired ?? groupState.isRequired; const state = fieldState.state ?? groupState.state; const isInvalid2 = fieldState.isInvalid ?? groupState.isInvalid; const isFieldEnclosed = fieldState.id !== groupState.id; const id2 = isFieldEnclosed ? fieldState.id : void 0; const description2 = isFieldEnclosed ? fieldState.description : void 0; const intent2 = state ?? checkboxIntent ?? groupState.intent; return { name: name2, isRequired: isRequired2, isInvalid: isInvalid2, id: id2, description: description2, intent: intent2 }; }; const checked = value ? group.value?.includes(value) : checkedProp; const handleCheckedChange = (isChecked) => { onCheckedChange?.(isChecked); const rootRefValue = rootRef.current?.value; if (rootRefValue && group.onCheckedChange) { group.onCheckedChange(isChecked, rootRefValue); } }; const { id, name, isInvalid, description, intent, isRequired: isRequiredAttr } = getCheckboxAttributes({ fieldState: field, groupState: group, checkboxIntent: intentProp }); const isRequired = useMemo(() => { if (!group) return isRequiredAttr; return isRequiredAttr ? !group.value?.length : false; }, [group, isRequiredAttr]); const checkboxLabel = children && /* @__PURE__ */ jsx4(CheckboxLabel, { disabled, htmlFor: id || innerId, id: innerLabelId, children }); const checkboxInput = /* @__PURE__ */ jsx4( CheckboxInput, { ref, id: id || innerId, name, value, intent, checked, disabled, required: isRequired, "aria-describedby": description, "aria-invalid": isInvalid, onCheckedChange: handleCheckedChange, "aria-labelledby": children ? innerLabelId : field.labelId, ...others } ); const content = group.reverse || reverse ? /* @__PURE__ */ jsxs(Fragment, { children: [ checkboxLabel, checkboxInput ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [ checkboxInput, checkboxLabel ] }); return /* @__PURE__ */ jsx4( "div", { "data-spark-component": "checkbox", className: cx("gap-md text-body-1 relative flex items-start", className), children: content } ); }; Checkbox3.displayName = "Checkbox"; // src/checkbox/CheckboxGroup.tsx import { useFormFieldControl as useFormFieldControl2 } from "@spark-ui/components/form-field"; import { useCombinedState } from "@spark-ui/hooks/use-combined-state"; import { useEffect, useMemo as useMemo2, useRef as useRef2 } from "react"; // src/checkbox/CheckboxGroup.styles.ts import { cva as cva3 } from "class-variance-authority"; var checkboxGroupStyles = cva3(["flex"], { variants: { /** * Prop to set the orientation of the checkbox group which could be `vertical` or `horizontal`. */ orientation: { vertical: ["flex-col", "gap-lg"], horizontal: ["gap-xl"] } } }); // src/checkbox/CheckboxGroup.tsx import { jsx as jsx5 } from "react/jsx-runtime"; var CheckboxGroup = ({ name: nameProp, value: valueProp, defaultValue, className, intent, orientation = "vertical", onCheckedChange: onCheckedChangeProp, reverse = false, children, ref, ...others }) => { const [value, setValue] = useCombinedState(valueProp, defaultValue); const field = useFormFieldControl2(); const onCheckedChangeRef = useRef2(onCheckedChangeProp); const { id, labelId, description, state, isInvalid, isRequired } = field; const name = nameProp ?? field.name; const current = useMemo2(() => { const handleCheckedChange = (checked, changed) => { const values = value || []; const modified = checked ? [...values, changed] : values.filter((val) => val !== changed); setValue(modified); if (onCheckedChangeRef.current) { onCheckedChangeRef.current(modified); } }; return { id, name, value, intent, state, isInvalid, description, isRequired, reverse, onCheckedChange: handleCheckedChange }; }, [id, name, value, intent, state, isInvalid, description, isRequired, setValue, reverse]); useEffect(() => { onCheckedChangeRef.current = onCheckedChangeProp; }, [onCheckedChangeProp]); return /* @__PURE__ */ jsx5(CheckboxGroupContext.Provider, { value: current, children: /* @__PURE__ */ jsx5( "div", { ref, className: checkboxGroupStyles({ className, orientation }), role: "group", "aria-labelledby": labelId, "aria-describedby": description, ...others, children } ) }); }; CheckboxGroup.displayName = "CheckboxGroup"; export { Checkbox3 as Checkbox, CheckboxGroup }; //# sourceMappingURL=index.mjs.map