UNPKG

@spark-ui/components

Version:

Spark (Leboncoin design system) components.

1,701 lines (1,662 loc) 78.9 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/combobox/index.ts var combobox_exports = {}; __export(combobox_exports, { Combobox: () => Combobox2, ComboboxProvider: () => ComboboxProvider, useComboboxContext: () => useComboboxContext }); module.exports = __toCommonJS(combobox_exports); // src/combobox/ComboboxContext.tsx var import_form_field = require("@spark-ui/components/form-field"); var import_use_combined_state = require("@spark-ui/hooks/use-combined-state"); var import_downshift3 = require("downshift"); var import_react7 = require("react"); // src/popover/Popover.tsx var import_radix_ui = require("radix-ui"); // src/popover/PopoverContext.tsx var import_react = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var PopoverContext = (0, import_react.createContext)(null); var ID_PREFIX = ":popover"; var PopoverProvider = ({ children, intent }) => { const [headerId, setHeaderId] = (0, import_react.useState)(null); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( PopoverContext.Provider, { value: { headerId, setHeaderId, intent }, children } ); }; var usePopover = () => { const context = (0, import_react.useContext)(PopoverContext); if (!context) { throw Error("usePopover must be used within a Popover provider"); } return context; }; // src/popover/Popover.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var Popover = ({ children, intent = "surface", modal = false, ...rest }) => { return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PopoverProvider, { intent, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_radix_ui.Popover.Root, { "data-spark-component": "popover", modal, ...rest, children }) }); }; Popover.displayName = "Popover"; // src/popover/PopoverAnchor.tsx var import_radix_ui2 = require("radix-ui"); var import_jsx_runtime3 = require("react/jsx-runtime"); var Anchor = ({ asChild = false, children, ref, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_radix_ui2.Popover.Anchor, { "data-spark-component": "popover-anchor", ref, asChild, ...rest, children }); Anchor.displayName = "Popover.Anchor"; // src/popover/PopoverArrow.tsx var import_class_variance_authority = require("class-variance-authority"); var import_radix_ui3 = require("radix-ui"); var import_jsx_runtime4 = require("react/jsx-runtime"); var Arrow = ({ asChild = false, width = 16, height = 8, className, ref, ...rest }) => { const { intent } = usePopover(); const styles4 = (0, import_class_variance_authority.cva)("visible", { variants: { intent: { surface: "fill-surface", main: "fill-main-container", support: "fill-support-container", accent: "fill-accent-container", basic: "fill-basic-container", success: "fill-success-container", alert: "fill-alert-container", danger: "fill-error-container", info: "fill-info-container", neutral: "fill-neutral-container" } }, defaultVariants: { intent: "surface" } }); return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( import_radix_ui3.Popover.Arrow, { "data-spark-component": "popover-arrow", ref, className: styles4({ intent, className }), asChild, width, height, ...rest } ); }; Arrow.displayName = "Popover.Arrow"; // src/popover/PopoverCloseButton.tsx var import_Close = require("@spark-ui/icons/Close"); var import_class_variance_authority7 = require("class-variance-authority"); var import_radix_ui5 = require("radix-ui"); // src/icon/Icon.tsx var import_react3 = require("react"); // src/slot/Slot.tsx var import_radix_ui4 = require("radix-ui"); var import_react2 = require("react"); var import_jsx_runtime5 = require("react/jsx-runtime"); var Slottable = import_radix_ui4.Slot.Slottable; var Slot = ({ ref, ...props }) => { return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_radix_ui4.Slot.Root, { ref, ...props }); }; var wrapPolymorphicSlot = (asChild, children, callback) => { if (!asChild) return callback(children); return (0, import_react2.isValidElement)(children) ? (0, import_react2.cloneElement)( children, void 0, callback(children.props.children) ) : null; }; // src/visually-hidden/VisuallyHidden.tsx var import_jsx_runtime6 = require("react/jsx-runtime"); var VisuallyHidden = ({ asChild = false, ref, ...props }) => { const Component = asChild ? Slot : "span"; return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( Component, { ...props, ref, style: { // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss position: "absolute", border: 0, width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0, 0, 0, 0)", whiteSpace: "nowrap", wordWrap: "normal", ...props.style } } ); }; VisuallyHidden.displayName = "VisuallyHidden"; // src/icon/Icon.styles.tsx var import_internal_utils = require("@spark-ui/internal-utils"); var import_class_variance_authority2 = require("class-variance-authority"); var iconStyles = (0, import_class_variance_authority2.cva)(["fill-current shrink-0"], { variants: { /** * Color scheme of the icon. */ intent: (0, import_internal_utils.makeVariants)({ current: ["text-current"], main: ["text-main"], support: ["text-support"], accent: ["text-accent"], basic: ["text-basic"], success: ["text-success"], alert: ["text-alert"], error: ["text-error"], info: ["text-info"], neutral: ["text-neutral"] }), /** * Sets the size of the icon. */ size: (0, import_internal_utils.makeVariants)({ current: ["u-current-font-size"], sm: ["w-sz-16", "h-sz-16"], md: ["w-sz-24", "h-sz-24"], lg: ["w-sz-32", "h-sz-32"], xl: ["w-sz-40", "h-sz-40"] }) } }); // src/icon/Icon.tsx var import_jsx_runtime7 = require("react/jsx-runtime"); var Icon = ({ label, className, size = "current", intent = "current", children, ...others }) => { const child = import_react3.Children.only(children); return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [ (0, import_react3.cloneElement)(child, { className: iconStyles({ className, size, intent }), "data-spark-component": "icon", "aria-hidden": "true", focusable: "false", ...others }), label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VisuallyHidden, { children: label }) ] }); }; Icon.displayName = "Icon"; // src/button/Button.tsx var import_class_variance_authority5 = require("class-variance-authority"); var import_react4 = require("react"); // src/spinner/Spinner.styles.tsx var import_internal_utils2 = require("@spark-ui/internal-utils"); var import_class_variance_authority3 = require("class-variance-authority"); var defaultVariants = { intent: "current", size: "current", isBackgroundVisible: false }; var spinnerStyles = (0, import_class_variance_authority3.cva)( ["inline-block", "border-solid", "rounded-full", "border-md", "animate-spin"], { variants: { /** * Use `size` prop to set the size of the spinner. If you want to set the full size for the spinner, don't forget to add a wrapping container with its own size. */ size: { current: ["u-current-font-size"], sm: ["w-sz-20", "h-sz-20"], md: ["w-sz-28", "h-sz-28"], full: ["w-full", "h-full"] }, /** * Color scheme of the spinner. */ intent: (0, import_internal_utils2.makeVariants)({ current: ["border-current"], main: ["border-main"], support: ["border-support"], accent: ["border-accent"], basic: ["border-basic"], success: ["border-success"], alert: ["border-alert"], error: ["border-error"], info: ["border-info"], neutral: ["border-neutral"] }), /** * Size of the button. */ isBackgroundVisible: { true: ["border-b-neutral-container", "border-l-neutral-container"], false: ["border-b-transparent", "border-l-transparent"] } }, defaultVariants } ); // src/spinner/Spinner.tsx var import_jsx_runtime8 = require("react/jsx-runtime"); var Spinner = ({ className, size = "current", intent = "current", label, isBackgroundVisible, ref, ...others }) => { return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( "span", { role: "status", "data-spark-component": "spinner", ref, className: spinnerStyles({ className, size, intent, isBackgroundVisible }), ...others, children: label && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(VisuallyHidden, { children: label }) } ); }; // src/button/Button.styles.tsx var import_internal_utils8 = require("@spark-ui/internal-utils"); var import_class_variance_authority4 = require("class-variance-authority"); // src/button/variants/filled.ts var import_internal_utils3 = require("@spark-ui/internal-utils"); var filledVariants = [ // Main { intent: "main", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-main", "text-on-main", "hover:bg-main-hovered", "enabled:active:bg-main-hovered", "focus-visible:bg-main-hovered" ]) }, // Support { intent: "support", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-support", "text-on-support", "hover:bg-support-hovered", "enabled:active:bg-support-hovered", "focus-visible:bg-support-hovered" ]) }, // Accent { intent: "accent", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-accent", "text-on-accent", "hover:bg-accent-hovered", "enabled:active:bg-accent-hovered", "focus-visible:bg-accent-hovered" ]) }, // Basic { intent: "basic", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-basic", "text-on-basic", "hover:bg-basic-hovered", "enabled:active:bg-basic-hovered", "focus-visible:bg-basic-hovered" ]) }, // Success { intent: "success", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-success", "text-on-success", "hover:bg-success-hovered", "enabled:active:bg-success-hovered", "focus-visible:bg-success-hovered" ]) }, // Alert { intent: "alert", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-alert", "text-on-alert", "hover:bg-alert-hovered", "enabled:active:bg-alert-hovered", "focus-visible:bg-alert-hovered" ]) }, // Danger { intent: "danger", design: "filled", class: (0, import_internal_utils3.tw)([ "text-on-error bg-error", "hover:bg-error-hovered enabled:active:bg-error-hovered", "focus-visible:bg-error-hovered" ]) }, // Info { intent: "info", design: "filled", class: (0, import_internal_utils3.tw)([ "text-on-error bg-info", "hover:bg-info-hovered enabled:active:bg-info-hovered", "focus-visible:bg-info-hovered" ]) }, // Neutral { intent: "neutral", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-neutral", "text-on-neutral", "hover:bg-neutral-hovered", "enabled:active:bg-neutral-hovered", "focus-visible:bg-neutral-hovered" ]) }, // Surface { intent: "surface", design: "filled", class: (0, import_internal_utils3.tw)([ "bg-surface", "text-on-surface", "hover:bg-surface-hovered", "enabled:active:bg-surface-hovered", "focus-visible:bg-surface-hovered" ]) } ]; // src/button/variants/ghost.ts var import_internal_utils4 = require("@spark-ui/internal-utils"); var ghostVariants = [ { intent: "main", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-main", "hover:bg-main/dim-5", "enabled:active:bg-main/dim-5", "focus-visible:bg-main/dim-5" ]) }, { intent: "support", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-support", "hover:bg-support/dim-5", "enabled:active:bg-support/dim-5", "focus-visible:bg-support/dim-5" ]) }, { intent: "accent", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-accent", "hover:bg-accent/dim-5", "enabled:active:bg-accent/dim-5", "focus-visible:bg-accent/dim-5" ]) }, { intent: "basic", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-basic", "hover:bg-basic/dim-5", "enabled:active:bg-basic/dim-5", "focus-visible:bg-basic/dim-5" ]) }, { intent: "success", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-success", "hover:bg-success/dim-5", "enabled:active:bg-success/dim-5", "focus-visible:bg-success/dim-5" ]) }, { intent: "alert", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-alert", "hover:bg-alert/dim-5", "enabled:active:bg-alert/dim-5", "focus-visible:bg-alert/dim-5" ]) }, { intent: "danger", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-error", "hover:bg-error/dim-5", "enabled:active:bg-error/dim-5", "focus-visible:bg-error/dim-5" ]) }, { intent: "info", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-info", "hover:bg-info/dim-5", "enabled:active:bg-info/dim-5", "focus-visible:bg-info/dim-5" ]) }, { intent: "neutral", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-neutral", "hover:bg-neutral/dim-5", "enabled:active:bg-neutral/dim-5", "focus-visible:bg-neutral/dim-5" ]) }, { intent: "surface", design: "ghost", class: (0, import_internal_utils4.tw)([ "text-surface", "hover:bg-surface/dim-5", "enabled:active:bg-surface/dim-5", "focus-visible:bg-surface/dim-5" ]) } ]; // src/button/variants/outlined.ts var import_internal_utils5 = require("@spark-ui/internal-utils"); var outlinedVariants = [ { intent: "main", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-main/dim-5", "enabled:active:bg-main/dim-5", "focus-visible:bg-main/dim-5", "text-main" ]) }, { intent: "support", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-support/dim-5", "enabled:active:bg-support/dim-5", "focus-visible:bg-support/dim-5", "text-support" ]) }, { intent: "accent", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-accent/dim-5", "enabled:active:bg-accent/dim-5", "focus-visible:bg-accent/dim-5", "text-accent" ]) }, { intent: "basic", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-basic/dim-5", "enabled:active:bg-basic/dim-5", "focus-visible:bg-basic/dim-5", "text-basic" ]) }, { intent: "success", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-success/dim-5", "enabled:active:bg-success/dim-5", "focus-visible:bg-success/dim-5", "text-success" ]) }, { intent: "alert", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-alert/dim-5", "enabled:active:bg-alert/dim-5", "focus-visible:bg-alert/dim-5", "text-alert" ]) }, { intent: "danger", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-error/dim-5", "enabled:active:bg-error/dim-5", "focus-visible:bg-error/dim-5", "text-error" ]) }, { intent: "info", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-info/dim-5", "enabled:active:bg-info/dim-5", "focus-visible:bg-info/dim-5", "text-info" ]) }, { intent: "neutral", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-neutral/dim-5", "enabled:active:bg-neutral/dim-5", "focus-visible:bg-neutral/dim-5", "text-neutral" ]) }, { intent: "surface", design: "outlined", class: (0, import_internal_utils5.tw)([ "hover:bg-surface/dim-5", "enabled:active:bg-surface/dim-5", "focus-visible:bg-surface/dim-5", "text-surface" ]) } ]; // src/button/variants/tinted.ts var import_internal_utils6 = require("@spark-ui/internal-utils"); var tintedVariants = [ { intent: "main", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-main-container", "text-on-main-container", "hover:bg-main-container-hovered", "enabled:active:bg-main-container-hovered", "focus-visible:bg-main-container-hovered" ]) }, { intent: "support", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-support-container", "text-on-support-container", "hover:bg-support-container-hovered", "enabled:active:bg-support-container-hovered", "focus-visible:bg-support-container-hovered" ]) }, { intent: "accent", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-accent-container", "text-on-accent-container", "hover:bg-accent-container-hovered", "enabled:active:bg-accent-container-hovered", "focus-visible:bg-accent-container-hovered" ]) }, { intent: "basic", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-basic-container", "text-on-basic-container", "hover:bg-basic-container-hovered", "enabled:active:bg-basic-container-hovered", "focus-visible:bg-basic-container-hovered" ]) }, { intent: "success", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-success-container", "text-on-success-container", "hover:bg-success-container-hovered", "enabled:active:bg-success-container-hovered", "focus-visible:bg-success-container-hovered" ]) }, { intent: "alert", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-alert-container", "text-on-alert-container", "hover:bg-alert-container-hovered", "enabled:active:bg-alert-container-hovered", "focus-visible:bg-alert-container-hovered" ]) }, { intent: "danger", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-error-container", "text-on-error-container", "hover:bg-error-container-hovered", "enabled:active:bg-error-container-hovered", "focus-visible:bg-error-container-hovered" ]) }, { intent: "info", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-info-container", "text-on-info-container", "hover:bg-info-container-hovered", "enabled:active:bg-info-container-hovered", "focus-visible:bg-info-container-hovered" ]) }, { intent: "neutral", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-neutral-container", "text-on-neutral-container", "hover:bg-neutral-container-hovered", "enabled:active:bg-neutral-container-hovered", "focus-visible:bg-neutral-container-hovered" ]) }, { intent: "surface", design: "tinted", class: (0, import_internal_utils6.tw)([ "bg-surface", "text-on-surface", "hover:bg-surface-hovered", "enabled:active:bg-surface-hovered", "focus-visible:bg-surface-hovered" ]) } ]; // src/button/variants/contrast.ts var import_internal_utils7 = require("@spark-ui/internal-utils"); var contrastVariants = [ { intent: "main", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-main", "hover:bg-main-container-hovered", "enabled:active:bg-main-container-hovered", "focus-visible:bg-main-container-hovered" ]) }, { intent: "support", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-support", "hover:bg-support-container-hovered", "enabled:active:bg-support-container-hovered", "focus-visible:bg-support-container-hovered" ]) }, { intent: "accent", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-accent", "hover:bg-accent-container-hovered", "enabled:active:bg-accent-container-hovered", "focus-visible:bg-accent-container-hovered" ]) }, { intent: "basic", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-basic", "hover:bg-basic-container-hovered", "enabled:active:bg-basic-container-hovered", "focus-visible:bg-basic-container-hovered" ]) }, { intent: "success", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-success", "hover:bg-success-container-hovered", "enabled:active:bg-success-container-hovered", "focus-visible:bg-success-container-hovered" ]) }, { intent: "alert", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-alert", "hover:bg-alert-container-hovered", "enabled:active:bg-alert-container-hovered", "focus-visible:bg-alert-container-hovered" ]) }, { intent: "danger", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-error", "hover:bg-error-container-hovered", "enabled:active:bg-error-container-hovered", "focus-visible:bg-error-container-hovered" ]) }, { intent: "info", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-info", "hover:bg-info-container-hovered", "enabled:active:bg-info-container-hovered", "focus-visible:bg-info-container-hovered" ]) }, { intent: "neutral", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-neutral", "hover:bg-neutral-container-hovered", "enabled:active:bg-neutral-container-hovered", "focus-visible:bg-neutral-container-hovered" ]) }, { intent: "surface", design: "contrast", class: (0, import_internal_utils7.tw)([ "text-on-surface", "hover:bg-surface-hovered", "enabled:active:bg-surface-hovered", "focus-visible:bg-surface-hovered" ]) } ]; // src/button/Button.styles.tsx var buttonStyles = (0, import_class_variance_authority4.cva)( [ "u-shadow-border-transition", "box-border inline-flex items-center justify-center gap-md whitespace-nowrap", "px-lg", "text-body-1 font-bold", "focus-visible:u-outline" ], { variants: { /** * Main style of the button. * * - `filled`: Button will be plain. * * - `outlined`: Button will be transparent with an outline. * * - `tinted`: Button will be filled but using a lighter color scheme. * * - `ghost`: Button will look like a link. No borders, plain text. * * - `contrast`: Button will be surface filled. No borders, plain text. * */ design: (0, import_internal_utils8.makeVariants)({ filled: [], outlined: ["bg-transparent", "border-sm", "border-current"], tinted: [], ghost: [], contrast: ["bg-surface"] }), /** * Color scheme of the button. */ intent: (0, import_internal_utils8.makeVariants)({ main: [], support: [], accent: [], basic: [], success: [], alert: [], danger: [], info: [], neutral: [], surface: [] }), /** * Size of the button. */ size: (0, import_internal_utils8.makeVariants)({ sm: ["min-w-sz-32", "h-sz-32"], md: ["min-w-sz-44", "h-sz-44"], lg: ["min-w-sz-56", "h-sz-56"] }), /** * Shape of the button. */ shape: (0, import_internal_utils8.makeVariants)({ rounded: ["rounded-lg"], square: ["rounded-0"], pill: ["rounded-full"] }), /** * Disable the button, preventing user interaction and adding opacity. */ disabled: { true: ["cursor-not-allowed", "opacity-dim-3"], false: ["cursor-pointer"] } }, compoundVariants: [ ...filledVariants, ...outlinedVariants, ...tintedVariants, ...ghostVariants, ...contrastVariants ], defaultVariants: { design: "filled", intent: "main", size: "md", shape: "rounded" } } ); // src/button/Button.tsx var import_jsx_runtime9 = require("react/jsx-runtime"); var blockedEventHandlers = [ "onClick", "onMouseDown", "onMouseUp", "onMouseEnter", "onMouseLeave", "onMouseOver", "onMouseOut", "onKeyDown", "onKeyPress", "onKeyUp", "onSubmit" ]; var Button = ({ children, design = "filled", disabled = false, intent = "main", isLoading = false, loadingLabel, loadingText, shape = "rounded", size = "md", asChild, className, ref, ...others }) => { const Component = asChild ? Slot : "button"; const shouldNotInteract = !!disabled || isLoading; const disabledEventHandlers = (0, import_react4.useMemo)(() => { const result = {}; if (shouldNotInteract) { blockedEventHandlers.forEach((eventHandler) => result[eventHandler] = void 0); } return result; }, [shouldNotInteract]); const spinnerProps = { size: "current", className: loadingText ? "inline-block" : "absolute", ...loadingLabel && { "aria-label": loadingLabel } }; return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( Component, { "data-spark-component": "button", ...Component === "button" && { type: "button" }, ref, className: buttonStyles({ className, design, disabled: shouldNotInteract, intent, shape, size }), disabled: !!disabled, "aria-busy": isLoading, "aria-live": isLoading ? "assertive" : "off", ...others, ...disabledEventHandlers, children: wrapPolymorphicSlot( asChild, children, (slotted) => isLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner, { ...spinnerProps }), loadingText && loadingText, /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( "div", { "aria-hidden": true, className: (0, import_class_variance_authority5.cx)("gap-md", loadingText ? "hidden" : "inline-flex opacity-0"), children: slotted } ) ] }) : slotted ) } ); }; Button.displayName = "Button"; // src/icon-button/IconButton.styles.tsx var import_internal_utils9 = require("@spark-ui/internal-utils"); var import_class_variance_authority6 = require("class-variance-authority"); var iconButtonStyles = (0, import_class_variance_authority6.cva)(["pl-0 pr-0"], { variants: { /** * Sets the size of the icon. */ size: (0, import_internal_utils9.makeVariants)({ sm: ["text-body-1"], md: ["text-body-1"], lg: ["text-display-3"] }) } }); // src/icon-button/IconButton.tsx var import_jsx_runtime10 = require("react/jsx-runtime"); var IconButton = ({ design = "filled", disabled = false, intent = "main", shape = "rounded", size = "md", className, ref, ...others }) => { return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( Button, { ref, className: iconButtonStyles({ size, className }), design, disabled, intent, shape, size, ...others } ); }; IconButton.displayName = "IconButton"; // src/popover/PopoverCloseButton.tsx var import_jsx_runtime11 = require("react/jsx-runtime"); var CloseButton = ({ "aria-label": ariaLabel, className, ref, ...rest }) => { return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)( import_radix_ui5.Popover.Close, { "data-spark-component": "popover-close-button", ref, className: (0, import_class_variance_authority7.cx)("right-md top-md absolute", className), asChild: true, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconButton, { size: "sm", intent: "neutral", design: "ghost", "aria-label": ariaLabel, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_Close.Close, {}) }) }) } ); }; CloseButton.displayName = "Popover.CloseButton"; // src/popover/PopoverContent.tsx var import_radix_ui6 = require("radix-ui"); // src/popover/PopoverContent.styles.ts var import_class_variance_authority8 = require("class-variance-authority"); var styles = (0, import_class_variance_authority8.cva)( [ "rounded-md", "shadow-sm", "focus-visible:outline-hidden focus-visible:u-outline", "max-h-(--radix-popper-available-height) overflow-y-auto" ], { variants: { intent: { surface: "bg-surface text-on-surface", main: "bg-main-container text-on-main-container", support: "bg-support-container text-on-support-container", accent: "bg-accent-container text-on-accent-container", basic: "bg-basic-container text-on-basic-container", success: "bg-success-container text-on-success-container", alert: "bg-alert-container text-on-alert-container", danger: "bg-error-container text-on-error-container", info: "bg-info-container text-on-info-container", neutral: "bg-neutral-container text-on-neutral-container" }, matchTriggerWidth: { true: "w-(--radix-popper-anchor-width)" }, enforceBoundaries: { true: ["max-w-(--radix-popper-available-width)"] }, inset: { true: "overflow-hidden", false: "p-lg" }, elevation: { dropdown: "z-dropdown", popover: "z-popover" } }, compoundVariants: [ { inset: false, /** * When there is a close button, padding to the right side must be adjusted to avoid content overlapping with it. */ class: "has-data-[spark-component=popover-close-button]:pr-3xl" }, { enforceBoundaries: false, matchTriggerWidth: false, class: "max-w-[min(var(--spacing-sz-384),100vw)]" } ], defaultVariants: { matchTriggerWidth: false, enforceBoundaries: false, inset: false, intent: "surface", elevation: "popover" } } ); // src/popover/PopoverContent.tsx var import_jsx_runtime12 = require("react/jsx-runtime"); var Content = ({ // Spark props className, children, matchTriggerWidth = false, // Radix props align = "center", arrowPadding = 16, // In order not to overlap the arrow on the rounded corners of the popover. asChild = false, avoidCollisions = true, "aria-labelledby": ariaLabelledBy, collisionBoundary, collisionPadding = 0, hideWhenDetached = false, side = "bottom", sideOffset = 8, sticky = "partial", inset = false, elevation = "popover", ref, ...rest }) => { const { headerId, intent } = usePopover(); return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)( import_radix_ui6.Popover.Content, { "aria-labelledby": headerId || ariaLabelledBy, className: styles({ enforceBoundaries: !!collisionBoundary, matchTriggerWidth, inset, elevation, intent, className }), "data-spark-component": "popover-content", ref, ...{ align, arrowPadding, asChild, avoidCollisions, collisionBoundary, collisionPadding, hideWhenDetached, side, sideOffset, sticky }, ...rest, children } ); }; Content.displayName = "Popover.Content"; // src/popover/PopoverHeader.tsx var import_class_variance_authority9 = require("class-variance-authority"); var import_react5 = require("react"); var import_jsx_runtime13 = require("react/jsx-runtime"); var Header = ({ children, className, ref, ...rest }) => { const id = `${ID_PREFIX}-header-${(0, import_react5.useId)()}`; const { setHeaderId } = usePopover(); (0, import_react5.useLayoutEffect)(() => { setHeaderId(id); return () => setHeaderId(null); }, [id, setHeaderId]); return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("header", { id, ref, className: (0, import_class_variance_authority9.cx)("mb-md text-headline-2", className), ...rest, children }); }; Header.displayName = "Popover.Header"; // src/popover/PopoverPortal.tsx var import_radix_ui7 = require("radix-ui"); var import_jsx_runtime14 = require("react/jsx-runtime"); var Portal = ({ children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_radix_ui7.Popover.Portal, { ...rest, children }); Portal.displayName = "Popover.Portal"; // src/popover/PopoverTrigger.tsx var import_radix_ui8 = require("radix-ui"); var import_jsx_runtime15 = require("react/jsx-runtime"); var Trigger = ({ asChild = false, children, ref, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)( import_radix_ui8.Popover.Trigger, { "data-spark-component": "popover-trigger", ref, asChild, ...rest, children } ); Trigger.displayName = "Popover.Trigger"; // src/popover/index.ts var Popover2 = Object.assign(Popover, { Anchor, Arrow, CloseButton, Content, Header, Portal, Trigger }); Popover2.displayName = "Popover"; Anchor.displayName = "Popover.Anchor"; Arrow.displayName = "Popover.Arrow"; CloseButton.displayName = "Popover.CloseButton"; Content.displayName = "Popover.Content"; Header.displayName = "Popover.Header"; Portal.displayName = "Popover.Portal"; Trigger.displayName = "Popover.Trigger"; // src/combobox/useCombobox/multipleSelectionReducer.ts var import_downshift = require("downshift"); // src/combobox/utils/index.ts var import_react6 = require("react"); function getIndexByKey(map, targetKey) { let index = 0; for (const [key] of map.entries()) { if (key === targetKey) { return index; } index++; } return -1; } var getKeyAtIndex = (map, index) => { let i = 0; for (const key of map.keys()) { if (i === index) return key; i++; } return void 0; }; var getElementByIndex = (map, index) => { const key = getKeyAtIndex(map, index); return key !== void 0 ? map.get(key) : void 0; }; var getElementDisplayName = (element) => { return element ? element.type.displayName : ""; }; var getOrderedItems = (children, result = []) => { import_react6.Children.forEach(children, (child) => { if (!(0, import_react6.isValidElement)(child)) return; if (getElementDisplayName(child) === "Combobox.Item") { const childProps = child.props; result.push({ value: childProps.value, disabled: !!childProps.disabled, text: getItemText(childProps.children) }); } if (child.props.children) { getOrderedItems(child.props.children, result); } }); return result; }; var findNestedItemText = (children) => { if (!children) return ""; for (const child of import_react6.Children.toArray(children)) { if ((0, import_react6.isValidElement)(child)) { const childElement = child; if (getElementDisplayName(childElement) === "Combobox.ItemText") { return childElement.props.children; } const foundText = findNestedItemText(childElement.props.children); if (foundText) return foundText; } } return ""; }; var getItemText = (children) => { return typeof children === "string" ? children : findNestedItemText(children); }; var getItemsFromChildren = (children) => { const newMap = /* @__PURE__ */ new Map(); getOrderedItems(children).forEach((itemData) => { newMap.set(itemData.value, itemData); }); return newMap; }; var hasChildComponent = (children, displayName) => { return import_react6.Children.toArray(children).some((child) => { if (!(0, import_react6.isValidElement)(child)) return false; if (getElementDisplayName(child) === displayName) { return true; } else if (child.props.children) { return hasChildComponent(child.props.children, displayName); } return false; }); }; var findElement = (children, value) => { return import_react6.Children.toArray(children).filter(import_react6.isValidElement).find((child) => value === getElementDisplayName(child) || ""); }; // src/combobox/useCombobox/multipleSelectionReducer.ts var multipleSelectionReducer = ({ multiselect, selectedItems, allowCustomValue = false, setSelectedItems, triggerAreaRef, items }) => { const reducer = (_, { changes, type }) => { const isFocusInsideTriggerArea = triggerAreaRef.current?.contains?.(document.activeElement); switch (type) { case import_downshift.useCombobox.stateChangeTypes.InputClick: return { ...changes, isOpen: true // keep menu opened }; case import_downshift.useCombobox.stateChangeTypes.InputKeyDownEnter: case import_downshift.useCombobox.stateChangeTypes.ItemClick: { const newState = { ...changes }; if (changes.selectedItem != null) { newState.inputValue = ""; newState.isOpen = true; const highlightedIndex = getIndexByKey(items, changes.selectedItem.value); newState.highlightedIndex = highlightedIndex; const isAlreadySelected = multiselect.selectedItems.some( (selectedItem) => selectedItem.value === changes.selectedItem?.value ); const updatedItems = isAlreadySelected ? selectedItems.filter((item) => item.value !== changes.selectedItem?.value) : [...selectedItems, changes.selectedItem]; setSelectedItems(updatedItems); } return newState; } case import_downshift.useCombobox.stateChangeTypes.ToggleButtonClick: return { ...changes, inputValue: allowCustomValue ? changes.inputValue : "" }; case import_downshift.useCombobox.stateChangeTypes.InputChange: return { ...changes, selectedItem: changes.highlightedIndex === -1 ? null : changes.selectedItem }; case import_downshift.useCombobox.stateChangeTypes.InputBlur: return { ...changes, inputValue: allowCustomValue ? changes.inputValue : "", isOpen: isFocusInsideTriggerArea }; default: return changes; } }; return reducer; }; // src/combobox/useCombobox/singleSelectionReducer.ts var import_downshift2 = require("downshift"); var singleSelectionReducer = ({ filteredItems, allowCustomValue = false, setSelectedItem }) => { const reducer = (state, { changes, type }) => { const exactMatch = filteredItems.find( (item) => item.text.toLowerCase() === state.inputValue.toLowerCase() ); switch (type) { case import_downshift2.useCombobox.stateChangeTypes.InputKeyDownEscape: if (!changes.selectedItem) { setSelectedItem(null); } return changes; case import_downshift2.useCombobox.stateChangeTypes.ItemClick: case import_downshift2.useCombobox.stateChangeTypes.InputKeyDownEnter: if (changes.selectedItem) { setSelectedItem(changes.selectedItem); } return changes; case import_downshift2.useCombobox.stateChangeTypes.InputClick: return { ...changes, isOpen: true }; case import_downshift2.useCombobox.stateChangeTypes.ToggleButtonClick: case import_downshift2.useCombobox.stateChangeTypes.InputBlur: if (allowCustomValue) return changes; if (state.inputValue === "") { setSelectedItem(null); return { ...changes, selectedItem: null }; } if (exactMatch) { setSelectedItem(exactMatch); return { ...changes, selectedItem: exactMatch, inputValue: exactMatch.text }; } if (state.selectedItem) { return { ...changes, inputValue: state.selectedItem.text }; } return { ...changes, inputValue: "" }; default: return changes; } }; return reducer; }; // src/combobox/ComboboxContext.tsx var import_jsx_runtime16 = require("react/jsx-runtime"); var ComboboxContext = (0, import_react7.createContext)(null); var getFilteredItemsMap = (map, inputValue) => { if (!inputValue) return map; return new Map( Array.from(map).filter(([_, { text }]) => text.toLowerCase().includes(inputValue.toLowerCase())) ); }; var ID_PREFIX2 = ":combobox"; var ComboboxProvider = ({ children, state: stateProp, allowCustomValue = false, filtering = "auto", disabled: disabledProp = false, multiple = false, readOnly: readOnlyProp = false, wrap = true, // Value value: controlledValue, defaultValue, onValueChange, // Open open: controlledOpen, defaultOpen, onOpenChange, isLoading }) => { const isMounted = (0, import_react7.useRef)(false); const [inputValue, setInputValue] = (0, import_react7.useState)(""); const [isTyping, setIsTyping] = (0, import_react7.useState)(filtering === "strict"); const triggerAreaRef = (0, import_react7.useRef)(null); const innerInputRef = (0, import_react7.useRef)(null); const [onInputValueChange, setOnInputValueChange] = (0, import_react7.useState)(null); const [comboboxValue] = (0, import_use_combined_state.useCombinedState)(controlledValue, defaultValue); const shouldFilterItems = filtering === "strict" || filtering === "auto" && isTyping; const [itemsMap, setItemsMap] = (0, import_react7.useState)(getItemsFromChildren(children)); const [filteredItemsMap, setFilteredItems] = (0, import_react7.useState)( shouldFilterItems ? getFilteredItemsMap(itemsMap, inputValue) : itemsMap ); const [selectedItem, setSelectedItem] = (0, import_react7.useState)( itemsMap.get(comboboxValue) || null ); const [selectedItems, setSelectedItems] = (0, import_react7.useState)( comboboxValue ? [...itemsMap.values()].filter((item) => comboboxValue.includes(item.value)) : [] ); const onInternalSelectedItemChange = (item) => { setIsTyping(false); if (item?.value !== selectedItem?.value) { setSelectedItem(item); setTimeout(() => { onValueChange?.(item?.value); }, 0); } }; const onInternalSelectedItemsChange = (items) => { setSelectedItems(items); setTimeout(() => { onValueChange?.(items.map((i) => i.value)); }, 0); }; (0, import_react7.useEffect)(() => { if (!isMounted.current) { isMounted.current = true; return; } if (multiple) { const newSelectedItems = comboboxValue.reduce( (accum, value) => { const match = itemsMap.get(value); return match ? [...accum, match] : accum; }, [] ); setSelectedItems(comboboxValue ? newSelectedItems : []); } else { setSelectedItem(itemsMap.get(comboboxValue) || null); } }, [multiple ? JSON.stringify(comboboxValue) : comboboxValue]); const field = (0, import_form_field.useFormFieldControl)(); const internalFieldLabelID = `${ID_PREFIX2}-label-${(0, import_react7.useId)()}`; const internalFieldID = `${ID_PREFIX2}-field-${(0, import_react7.useId)()}`; const id = field.id || internalFieldID; const labelId = field.labelId || internalFieldLabelID; const state = field.state || stateProp; const disabled = field.disabled ?? disabledProp; const readOnly = field.readOnly ?? readOnlyProp; const [hasPopover, setHasPopover] = (0, import_react7.useState)( hasChildComponent(children, "Combobox.Popover") ); const [lastInteractionType, setLastInteractionType] = (0, import_react7.useState)("mouse"); (0, import_react7.useEffect)(() => { setFilteredItems(shouldFilterItems ? getFilteredItemsMap(itemsMap, inputValue) : itemsMap); }, [inputValue, itemsMap]); const multiselect = (0, import_downshift3.useMultipleSelection)({ selectedItems, stateReducer: (state2, { type, changes }) => { const types = import_downshift3.useMultipleSelection.stateChangeTypes; switch (type) { case types.SelectedItemKeyDownBackspace: case types.SelectedItemKeyDownDelete: { onInternalSelectedItemsChange(changes.selectedItems || []); let activeIndex; if (type === types.SelectedItemKeyDownDelete) { const isLastItem = state2?.activeIndex === changes.selectedItems?.length; activeIndex = isLastItem ? -1 : state2.activeIndex; } else { const hasItemBefore = (changes?.activeIndex || 0) - 1 >= 0; activeIndex = hasItemBefore ? state2.activeIndex - 1 : changes?.activeIndex; } return { ...changes, activeIndex }; } case types.SelectedItemClick: if (innerInputRef.current) { innerInputRef.current.focus(); } return { ...changes, activeIndex: -1 // the focus will remain on the input }; case types.FunctionRemoveSelectedItem: return { ...changes, activeIndex: -1 // the focus will remain on the input }; case types.DropdownKeyDownNavigationPrevious: downshift.closeMenu(); return changes; default: return changes; } } }); const filteredItems = Array.from(filteredItemsMap.values()); (0, import_react7.useEffect)(() => { onInputValueChange?.(inputValue || ""); }, [inputValue]); const downshift = (0, import_downshift3.useCombobox)({ inputId: id, items: filteredItems, selectedItem: multiple ? void 0 : selectedItem, id, labelId, // Input inputValue, onInputValueChange: ({ inputValue: newInputValue }) => { setInputValue(newInputValue); if (shouldFilterItems) { const filtered = getFilteredItemsMap(itemsMap, newInputValue || ""); setFilteredItems(filtered); } }, // Open initialIsOpen: defaultOpen, ...controlledOpen != null && { isOpen: controlledOpen }, onIsOpenChange: (changes) => { if (changes.isOpen != null) { onOpenChange?.(changes.isOpen); } }, // Custom Spark item object parsing itemToString: (item) => { return item?.text; }, isItemDisabled: (item) => { const isFilteredOut = !!inputValue && !filteredItems.some((filteredItem) => { return item.value === filteredItem.value; }); return item.disabled || isFilteredOut; }, // Main reducer stateReducer: multiple ? multipleSelectionReducer({ multiselect, selectedItems, allowCustomValue, setSelectedItems: onInternalSelectedItemsChange, triggerAreaRef, items: itemsMap }) : singleSelectionReducer({ allowCustomValue, setSelectedItem: onInternalSelectedItemChange, filteredItems: [...filteredItemsMap.values()] }), /** * Downshift default behaviour is to scroll into view the highlighted item when the dropdown opens. This behaviour is not stable and scrolls the dropdown to the bottom of the screen. */ scrollIntoView: (node) => { if (node) { node.scrollIntoView({ block: "nearest" }); } return void 0; } }); (0, import_react7.useEffect)(() => { const newMap = getItemsFromChildren(children); const previousItems = [...itemsMap.values()]; const newItems = [...newMap.values()]; const hasItemsChanges = previousItems.length !== newItems.length || previousItems.some((item, index) => { const hasUpdatedValue = item.value !== newItems[index]?.value; const hasUpdatedText = item.text !== newItems[index]?.text; return hasUpdatedValue || hasUpdatedText; }); if (hasItemsChanges) { setItemsMap(newMap); } }, [children]); const [WrapperComponent, wrapperProps] = hasPopover ? [Popover2, { open: true }] : [import_react7.Fragment, {}]; return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)( ComboboxContext.Provider, { value: { // Data itemsMap, filteredItemsMap, highlightedItem: getElementByIndex(filteredItemsMap, downshift.highlightedIndex), // State multiple, disabled, readOnly, hasPopover, setHasPopover