UNPKG

@spark-ui/components

Version:

Spark (Leboncoin design system) components.

793 lines (776 loc) 22.7 kB
import { Icon } from "../chunk-AESXFMCC.mjs"; import "../chunk-NBZKMCHF.mjs"; import { Slot } from "../chunk-4F5DOL57.mjs"; // src/chip/Chip.styles.tsx import { makeVariants } from "@spark-ui/internal-utils"; import { cva } from "class-variance-authority"; // src/chip/variants/outlined.ts import { tw } from "@spark-ui/internal-utils"; var outlinedVariants = [ /** Intents **/ { design: "outlined", intent: "main", class: tw([ "enabled:hover:bg-main/dim-5", "enabled:active:bg-main/dim-5", "focus-visible:bg-main/dim-5", "aria-pressed:bg-main-container aria-pressed:text-on-main-container aria-pressed:enabled:hover:bg-main-container/dim-1", "text-main" ]) }, { design: "outlined", intent: "support", class: tw([ "enabled:hover:bg-support/dim-5", "enabled:active:bg-support/dim-5", "focus-visible:bg-support/dim-5", "aria-pressed:bg-support-container aria-pressed:text-on-support-container aria-pressed:enabled:hover:bg-support-container/dim-1", "text-support" ]) }, { design: "outlined", intent: "basic", class: tw([ "enabled:hover:bg-basic/dim-5", "enabled:active:bg-basic/dim-5", "focus-visible:bg-basic/dim-5", "aria-pressed:bg-basic-container aria-pressed:text-on-basic-container aria-pressed:enabled:hover:bg-basic-container/dim-1", "text-basic" ]) }, { intent: "accent", design: "outlined", class: tw([ "enabled:hover:bg-accent/dim-5", "enabled:active:bg-accent/dim-5", "focus-visible:bg-accent/dim-5", "aria-pressed:bg-accent-container", "aria-pressed:bg-accent-container aria-pressed:text-on-accent-container aria-pressed:enabled:hover:bg-accent-container/dim-1", "text-accent" ]) }, { design: "outlined", intent: "success", class: tw([ "enabled:hover:bg-success/dim-5", "enabled:active:bg-success/dim-5", "focus-visible:bg-success/dim-5", "aria-pressed:bg-success-container aria-pressed:text-on-success-container aria-pressed:enabled:hover:bg-success-container/dim-1", "text-success" ]) }, { intent: "alert", design: "outlined", class: tw([ "enabled:hover:bg-alert/dim-5", "enabled:active:bg-alert/dim-5", "focus-visible:bg-alert/dim-5", "aria-pressed:bg-alert-container aria-pressed:text-on-alert-container aria-pressed:enabled:hover:bg-alert-container/dim-1", "text-alert" ]) }, { design: "outlined", intent: "danger", class: tw([ "enabled:hover:bg-error/dim-5", "enabled:active:bg-error/dim-5", "focus-visible:bg-error/dim-5", "aria-pressed:bg-error-container aria-pressed:text-on-error-container aria-pressed:enabled:hover:bg-error-container/dim-1", "text-error" ]) }, { design: "outlined", intent: "info", class: tw([ "enabled:hover:bg-info/dim-5", "enabled:active:bg-info/dim-5", "focus-visible:bg-info/dim-5", "aria-pressed:bg-info-container aria-pressed:text-on-info-container aria-pressed:enabled:hover:bg-info-container/dim-1", "text-info" ]) }, { design: "outlined", intent: "neutral", class: tw([ "enabled:hover:bg-neutral/dim-5", "enabled:active:bg-neutral/dim-5", "focus-visible:bg-neutral/dim-5", "aria-pressed:bg-neutral-container aria-pressed:text-on-neutral-container aria-pressed:enabled:hover:bg-neutral-container/dim-1", "text-neutral" ]) }, { design: "outlined", intent: "surface", class: tw([ "enabled:hover:bg-surface/dim-5", "enabled:active:bg-surface/dim-5", "focus-visible:bg-surface/dim-5", "aria-pressed:bg-surface aria-pressed:text-on-surface aria-pressed:enabled:hover:bg-surface-hovered", "text-surface" ]) }, /** Spacings **/ { design: "outlined", hasClearButton: false, class: tw(["px-[calc(var(--spacing-md)-var(--border-width-sm))]"]) }, { design: "outlined", hasClearButton: true, class: tw(["pl-[calc(var(--spacing-md)-var(--border-width-sm))]"]) } ]; // src/chip/variants/tinted.ts import { tw as tw2 } from "@spark-ui/internal-utils"; var tintedVariants = [ /** Intents **/ { intent: "main", design: "tinted", class: tw2([ "bg-main-container", "enabled:hover:bg-main-container-hovered", "enabled:active:bg-main-container-hovered", "focus-visible:bg-main-container-hovered", "aria-pressed:bg-main aria-pressed:text-on-main aria-pressed:enabled:hover:bg-main/dim-1", "text-on-main-container" ]) }, { intent: "support", design: "tinted", class: tw2([ "bg-support-container", "enabled:hover:bg-support-container-hovered", "enabled:active:bg-support-container-hovered", "focus-visible:bg-support-container-hovered", "aria-pressed:bg-support aria-pressed:text-on-support aria-pressed:enabled:hover:bg-support/dim-1", "text-on-support-container" ]) }, { intent: "basic", design: "tinted", class: tw2([ "bg-basic-container", "enabled:hover:bg-basic-container-hovered", "enabled:active:bg-basic-container-hovered", "focus-visible:bg-basic-container-hovered", "aria-pressed:bg-basic aria-pressed:text-on-basic aria-pressed:enabled:hover:bg-basic/dim-1", "text-on-basic-container" ]) }, { intent: "accent", design: "tinted", class: tw2([ "bg-accent-container", "enabled:hover:bg-accent-container-hovered", "enabled:active:bg-accent-container-hovered", "focus-visible:bg-accent-container-hovered", "aria-pressed:bg-accent aria-pressed:text-on-accent aria-pressed:enabled:hover:bg-accent/dim-1", "text-on-accent-container" ]) }, { intent: "success", design: "tinted", class: tw2([ "bg-success-container", "enabled:hover:bg-success-container-hovered", "enabled:active:bg-success-container-hovered", "focus-visible:bg-success-container-hovered", "aria-pressed:bg-success aria-pressed:text-on-success aria-pressed:enabled:hover:bg-success/dim-1", "text-on-success-container" ]) }, { intent: "alert", design: "tinted", class: tw2([ "bg-alert-container", "enabled:hover:bg-alert-container-hovered", "enabled:active:bg-alert-container-hovered", "focus-visible:bg-alert-container-hovered", "aria-pressed:bg-alert aria-pressed:text-on-alert aria-pressed:enabled:hover:bg-alert/dim-1", "text-on-alert-container" ]) }, { intent: "danger", design: "tinted", class: tw2([ "bg-error-container", "enabled:hover:bg-error-container-hovered", "enabled:active:bg-error-container-hovered", "focus-visible:bg-error-container-hovered", "aria-pressed:bg-error aria-pressed:text-on-error aria-pressed:enabled:hover:bg-error/dim-1", "text-on-error-container" ]) }, { intent: "info", design: "tinted", class: tw2([ "bg-info-container", "enabled:hover:bg-info-container-hovered", "enabled:active:bg-info-container-hovered", "focus-visible:bg-info-container-hovered", "aria-pressed:bg-info aria-pressed:text-on-info aria-pressed:enabled:hover:bg-info/dim-1", "text-on-info-container" ]) }, { intent: "neutral", design: "tinted", class: tw2([ "bg-neutral-container", "enabled:hover:bg-neutral-container-hovered", "enabled:active:bg-neutral-container-hovered", "focus-visible:bg-neutral-container-hovered", "aria-pressed:bg-neutral aria-pressed:text-on-neutral aria-pressed:enabled:hover:bg-neutral/dim-1", "text-on-neutral-container" ]) }, { intent: "surface", design: "tinted", class: tw2([ "bg-surface/dim-1", "enabled:hover:bg-surface-hovered/dim-1", "enabled:active:bg-surface-hovered/dim-1", "focus-visible:bg-surface-hovered/dim-1", "aria-pressed:bg-surface aria-pressed:text-on-surface aria-pressed:enabled:hover:bg-surface-hovered", "text-on-surface/dim-1" ]) }, /** Spacings **/ { design: "tinted", hasClearButton: false, class: tw2(["px-md"]) }, { design: "tinted", hasClearButton: true, class: tw2(["pl-md"]) } ]; // src/chip/variants/dashed.ts import { tw as tw3 } from "@spark-ui/internal-utils"; var dashedVariants = [ /** Intents **/ { intent: "main", design: "dashed", class: tw3([ "enabled:hover:bg-main/dim-5", "enabled:active:bg-main/dim-5", "focus-visible:bg-main/dim-5", "aria-pressed:bg-main-container aria-pressed:text-on-main-container aria-pressed:enabled:hover:bg-main-container/dim-1", "text-main" ]) }, { intent: "support", design: "dashed", class: tw3([ "enabled:hover:bg-support/dim-5", "enabled:active:bg-support/dim-5", "focus-visible:bg-support/dim-5", "aria-pressed:bg-support-container aria-pressed:text-on-support-container aria-pressed:enabled:hover:bg-support-container/dim-1", "text-support" ]) }, { intent: "basic", design: "dashed", class: tw3([ "enabled:hover:bg-basic/dim-5", "enabled:active:bg-basic/dim-5", "focus-visible:bg-basic/dim-5", "aria-pressed:bg-basic-container aria-pressed:text-on-basic-container aria-pressed:enabled:hover:bg-basic-container/dim-1", "text-basic" ]) }, { intent: "accent", design: "dashed", class: tw3([ "enabled:hover:bg-accent/dim-5", "enabled:active:bg-accent/dim-5", "focus-visible:bg-accent/dim-5", "aria-pressed:bg-accent-container aria-pressed:text-on-accent-container aria-pressed:enabled:hover:bg-accent-container/dim-1", "text-accent" ]) }, { intent: "success", design: "dashed", class: tw3([ "enabled:hover:bg-success/dim-5", "enabled:active:bg-success/dim-5", "focus-visible:bg-success/dim-5", "aria-pressed:bg-success-container aria-pressed:text-on-success-container aria-pressed:enabled:hover:bg-success-container/dim-1", "text-success" ]) }, { intent: "alert", design: "dashed", class: tw3([ "enabled:hover:bg-alert/dim-5", "enabled:active:bg-alert/dim-5", "focus-visible:bg-alert/dim-5", "aria-pressed:bg-alert-container aria-pressed:text-on-alert-container aria-pressed:enabled:hover:bg-alert-container/dim-1", "text-alert" ]) }, { intent: "danger", design: "dashed", class: tw3([ "enabled:hover:bg-error/dim-5", "enabled:active:bg-error/dim-5", "focus-visible:bg-error/dim-5", "aria-pressed:bg-error-container aria-pressed:text-on-error-container aria-pressed:enabled:hover:bg-error-container/dim-1", "text-error" ]) }, { intent: "info", design: "dashed", class: tw3([ "enabled:hover:bg-info/dim-5", "enabled:active:bg-info/dim-5", "focus-visible:bg-info/dim-5", "aria-pressed:bg-info-container aria-pressed:text-on-info-container aria-pressed:enabled:hover:bg-info-container/dim-1", "text-info" ]) }, { intent: "neutral", design: "dashed", class: tw3([ "enabled:hover:bg-neutral/dim-5", "enabled:active:bg-neutral/dim-5", "focus-visible:bg-neutral/dim-5", "aria-pressed:bg-neutral-container aria-pressed:text-on-neutral-container aria-pressed:enabled:hover:bg-neutral-container/dim-1", "text-neutral" ]) }, { intent: "surface", design: "dashed", class: tw3([ "enabled:hover:bg-surface/dim-5", "enabled:active:bg-surface/dim-5", "focus-visible:bg-surface/dim-5", "aria-pressed:bg-surface aria-pressed:text-on-surface aria-pressed:enabled:hover:bg-surface-hovered", "text-surface" ]) }, /** Spacings **/ { design: "dashed", hasClearButton: false, class: tw3(["px-[calc(var(--spacing-md)-var(--border-width-sm))]"]) }, { design: "dashed", hasClearButton: true, class: tw3(["pl-[calc(var(--spacing-md)-var(--border-width-sm))]"]) } ]; // src/chip/Chip.styles.tsx var chipStyles = cva( [ "box-border inline-flex h-sz-32 flex-nowrap items-center justify-center rounded-md text-body-1 font-regular", "focus-visible:u-outline", "ease-out duration-150" ], { variants: { /** * Main style of the chip. * * - `filled`: Chip will be plain. * * - `outlined`: Chip will be transparent with an outline. * * - `tinted`: Chip will be filled but using a lighter color scheme. * * - `dashed`: Chip will be transparent with an outline dashed. */ design: makeVariants({ outlined: ["bg-transparent border-sm border-solid border-current"], tinted: [""], dashed: [ "bg-transparent border-sm border-dashed shadow-none focus-visible:border-outline-high" ] }), /** * Color scheme of the chip. */ intent: makeVariants({ main: [], support: [], basic: [], accent: [], success: [], alert: [], danger: [], info: [], neutral: [], surface: [] }), /** * Disable the chip, preventing user interaction and adding opacity. */ disabled: { true: ["cursor-not-allowed", "opacity-dim-3"] }, hasClearButton: { true: [], false: [] } // 'pl-[calc(var(--spacing-md)-(var(--border-width-sm)))]' }, compoundVariants: [...outlinedVariants, ...tintedVariants, ...dashedVariants], defaultVariants: { design: "outlined", intent: "basic" } } ); // src/chip/useChipContext.tsx import { createContext, useContext } from "react"; var ChipContext = createContext({}); var useChipContext = () => useContext(ChipContext) || {}; // src/chip/useChipElement.tsx import { useCombinedState } from "@spark-ui/hooks/use-combined-state"; import { emulateTab } from "emulate-tab"; import { Children, isValidElement } from "react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var getDisplayName = (element) => { return element ? element.type.displayName : ""; }; var findElement = (children) => (...values) => { const validChildren = Children.toArray(children).filter(isValidElement); return validChildren.find((child) => { const displayName = getDisplayName(child); return values.includes(displayName || ""); }); }; var useChipElement = ({ onClick, asChild, pressed, defaultPressed, disabled, value, defaultValue, children, onClear }) => { const [isPressed, setIsPressed] = useCombinedState(pressed, defaultPressed); const [innerValue] = useCombinedState( value, defaultValue ); const findChipElement = findElement(children); const leadingIcon = findChipElement("Chip.LeadingIcon"); const trailingIcon = findChipElement("Chip.TrailingIcon"); const content = findChipElement("Chip.Content"); const clearButton = findChipElement("Chip.ClearButton"); const isButton = (onClick || isPressed) !== void 0; const formattedChildren = [leadingIcon, content, clearButton].every( (element) => element === void 0 ) ? /* @__PURE__ */ jsx("span", { className: "inline-block grow truncate", children }) : /* @__PURE__ */ jsxs(Fragment, { children: [ leadingIcon, content, leadingIcon === void 0 ? trailingIcon : null, clearButton ] }); const onKeyDown = (event) => { if (!!clearButton && !disabled && ["Delete", "Backspace"].includes(event.key)) { if (onClear) { onClear(); event.key === "Delete" && emulateTab(); event.key === "Backspace" && emulateTab.backwards(); } } }; if (isButton) { return { Element: asChild ? Slot : "button", chipProps: { type: "button", ...isPressed !== void 0 && { "aria-pressed": isPressed, "data-state": isPressed ? "on" : "off" }, onClick: (event) => { isPressed !== void 0 && setIsPressed(!isPressed); onClick && onClick(event, { pressed: isPressed, value: innerValue }); }, onKeyDown, disabled, children: formattedChildren }, compoundElements: { leadingIcon, trailingIcon, content, clearButton } }; } return { Element: asChild ? Slot : "div", chipProps: { "aria-disabled": disabled, children: formattedChildren, onKeyDown }, compoundElements: { leadingIcon, trailingIcon, content, clearButton } }; }; // src/chip/Chip.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var Chip = ({ design = "outlined", disabled, children, intent = "basic", defaultPressed, pressed, asChild, className, onClick, onClear, ref: forwardedRef, ...otherProps }) => { const { Element: ChipElement, chipProps: { children: formattedChildren, ...chipProps }, compoundElements } = useChipElement({ asChild, pressed, defaultPressed, onClick, disabled: !!disabled, value: otherProps.value, defaultValue: otherProps.defaultValue, children, onClear }); const { clearButton } = compoundElements; return /* @__PURE__ */ jsx2(ChipContext.Provider, { value: { disabled, design, intent, onClear }, children: /* @__PURE__ */ jsx2( ChipElement, { ref: forwardedRef, className: chipStyles({ className, design, disabled, intent, hasClearButton: !!clearButton }), ...{ ...chipProps, ...otherProps }, "data-spark-component": "chip", children: formattedChildren } ) }); }; Chip.displayName = "Chip"; // src/chip/ChipClearButton.tsx import { Close } from "@spark-ui/icons/Close"; import { cloneElement, useCallback } from "react"; // src/chip/ChipClearButton.styles.tsx import { tw as tw4 } from "@spark-ui/internal-utils"; import { cva as cva2 } from "class-variance-authority"; var chipClearButtonWrapperStyles = cva2( ["ml-md flex h-full items-center justify-center focus-visible:outline-hidden"], { variants: { disabled: { false: ["cursor-pointer"], true: ["cursor-not-allowed"] }, isBordered: { false: ["pr-md"], true: ["pr-[7px]"] }, design: { outlined: [], tinted: [], dashed: [] } }, compoundVariants: [ { design: "outlined", disabled: false, class: tw4(["hover:opacity-dim-1"]) }, { design: "outlined", disabled: true, class: tw4(["opacity-dim-3"]) }, { design: "tinted", disabled: false, class: tw4(["hover:opacity-dim-1"]) }, { design: "tinted", disabled: true, class: tw4(["opacity-dim-3"]) }, { design: "dashed", disabled: false, class: tw4(["hover:opacity-dim-1"]) }, { design: "dashed", disabled: true, class: tw4(["opacity-dim-3"]) } ] } ); var chipClearButtonStyles = cva2( ["rounded-full p-sz-2 [font-size:var(--spacing-sz-8)] border-sm", "focus-visible:u-outline"], { variants: { disabled: { true: ["cursor-not-allowed"], false: ["cursor-pointer"] } } } ); // src/chip/ChipClearButton.tsx import { jsx as jsx3 } from "react/jsx-runtime"; var ChipClearButton = ({ children = /* @__PURE__ */ jsx3(Icon, { children: /* @__PURE__ */ jsx3(Close, {}) }), tabIndex = 0, label, ref: forwardedRef }) => { const { design, disabled, onClear } = useChipContext(); const onClearHandler = useCallback( (event) => { event.stopPropagation(); !disabled && onClear && onClear(event); }, [disabled, onClear] ); return /* @__PURE__ */ jsx3( "span", { className: chipClearButtonWrapperStyles({ isBordered: ["outline", "dashed"].includes(`${design}`), disabled: !!disabled, design }), onClick: onClearHandler, ref: forwardedRef, children: /* @__PURE__ */ jsx3( "button", { tabIndex, type: "button", disabled: !!disabled, className: chipClearButtonStyles({ disabled }), "aria-label": label, children: children && cloneElement(children, { ariaLabel: label }) } ) } ); }; ChipClearButton.displayName = "Chip.ClearButton"; // src/chip/ChipContent.tsx import { cx } from "class-variance-authority"; import { jsx as jsx4 } from "react/jsx-runtime"; var ChipContent = ({ children, className, ref: forwardedRef }) => { return /* @__PURE__ */ jsx4("span", { className: cx("inline-block grow truncate", className), ref: forwardedRef, children }); }; ChipContent.displayName = "Chip.Content"; // src/chip/ChipLeadingIcon.tsx import { cx as cx3 } from "class-variance-authority"; // src/chip/ChipIcon.tsx import { cx as cx2 } from "class-variance-authority"; import { jsx as jsx5 } from "react/jsx-runtime"; var ChipIcon = ({ children, className, ref: forwardedRef }) => { return /* @__PURE__ */ jsx5("span", { className: cx2("flex h-full items-center justify-center", className), ref: forwardedRef, children }); }; ChipIcon.displayName = "Chip.Icon"; // src/chip/ChipLeadingIcon.tsx import { jsx as jsx6 } from "react/jsx-runtime"; var ChipLeadingIcon = ({ className, ref: forwardedRef, ...props }) => /* @__PURE__ */ jsx6(ChipIcon, { className: cx3("mr-sm", className), ref: forwardedRef, ...props }); ChipLeadingIcon.displayName = "Chip.LeadingIcon"; // src/chip/ChipTrailingIcon.tsx import { cx as cx4 } from "class-variance-authority"; import { jsx as jsx7 } from "react/jsx-runtime"; var ChipTrailingIcon = ({ className, ref: forwardedRef, ...props }) => /* @__PURE__ */ jsx7(ChipIcon, { className: cx4("ml-md", className), ref: forwardedRef, ...props }); ChipTrailingIcon.displayName = "Chip.TrailingIcon"; // src/chip/index.ts var Chip2 = Object.assign(Chip, { Content: ChipContent, LeadingIcon: ChipLeadingIcon, TrailingIcon: ChipTrailingIcon, ClearButton: ChipClearButton }); Chip2.displayName = "Chip"; Chip2.ClearButton.displayName = "Chip.ClearButton"; Chip2.Content.displayName = "Chip.Content"; Chip2.LeadingIcon.displayName = "Chip.LeadingIcon"; Chip2.TrailingIcon.displayName = "Chip.TrailingIcon"; export { Chip2 as Chip }; //# sourceMappingURL=index.mjs.map