@spark-ui/components
Version:
Spark (Leboncoin design system) components.
347 lines (335 loc) • 11.5 kB
JavaScript
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