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