UNPKG

@spark-ui/components

Version:

Spark (Leboncoin design system) components.

1,706 lines (1,660 loc) 60.2 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/dropdown/index.ts var dropdown_exports = {}; __export(dropdown_exports, { Dropdown: () => Dropdown2, DropdownProvider: () => DropdownProvider, useDropdownContext: () => useDropdownContext }); module.exports = __toCommonJS(dropdown_exports); // src/dropdown/DropdownContext.tsx var import_form_field = require("@spark-ui/components/form-field"); 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/dropdown/useDropdown.ts var import_downshift = require("downshift"); var useDropdown = ({ itemsMap, defaultValue, value, onValueChange, open, onOpenChange, defaultOpen, multiple, id, labelId }) => { const items = [...itemsMap.values()]; const downshiftMultipleSelection = (0, import_downshift.useMultipleSelection)({ selectedItems: value != null && multiple ? items.filter( (item) => multiple ? value.includes(item.value) : value === item.value ) : void 0, initialSelectedItems: defaultValue != null && multiple ? items.filter( (item) => multiple ? defaultValue.includes(item.value) : defaultValue === item.value ) : void 0, onSelectedItemsChange: ({ selectedItems }) => { if (selectedItems != null && multiple) { onValueChange?.(selectedItems.map((item) => item.value)); } } }); const stateReducer = (state, { changes, type }) => { if (!multiple) return changes; const { selectedItems, removeSelectedItem, addSelectedItem } = downshiftMultipleSelection; switch (type) { case import_downshift.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter: case import_downshift.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton: case import_downshift.useSelect.stateChangeTypes.ItemClick: if (changes.selectedItem != null) { const isAlreadySelected = selectedItems.some( (selectedItem) => selectedItem.value === changes.selectedItem?.value ); if (isAlreadySelected) removeSelectedItem(changes.selectedItem); else addSelectedItem(changes.selectedItem); } return { ...changes, isOpen: true, // keep the menu open after selection. highlightedIndex: state.highlightedIndex // preserve highlighted index position }; default: return changes; } }; const downshift = (0, import_downshift.useSelect)({ items, isItemDisabled: (item) => item.disabled, itemToString: (item) => item ? item.text : "", // a11y attributes id, labelId, // Controlled open state isOpen: open, // undefined must be passed for stateful behaviour (uncontrolled) onIsOpenChange: ({ isOpen }) => { if (isOpen != null) onOpenChange?.(isOpen); }, initialIsOpen: defaultOpen ?? false, stateReducer, // Controlled mode (single selection) selectedItem: value != null && !multiple ? itemsMap.get(value) || null : void 0, initialSelectedItem: (defaultValue != null || value != null) && !multiple ? itemsMap.get(defaultValue) || null : void 0, onSelectedItemChange: ({ selectedItem }) => { if (selectedItem?.value != null && !multiple) { onValueChange?.(selectedItem?.value); } }, /** * 1. 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; } }); return { ...downshift, ...downshiftMultipleSelection, /** There is a Downshift bug in React 19, it duplicates some selectedItems */ selectedItems: [...new Set(downshiftMultipleSelection.selectedItems)] }; }; // src/dropdown/utils.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) === "Dropdown.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 getItemText = (children, itemText = "") => { if (typeof children === "string") { return children; } import_react6.Children.forEach(children, (child) => { if (!(0, import_react6.isValidElement)(child)) return; if (getElementDisplayName(child) === "Dropdown.ItemText") { itemText = child.props.children; } if (child.props.children) { getItemText(child.props.children, itemText); } }); return itemText; }; 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; }); }; // src/dropdown/DropdownContext.tsx var import_jsx_runtime16 = require("react/jsx-runtime"); var DropdownContext = (0, import_react7.createContext)(null); var ID_PREFIX2 = ":dropdown"; var DropdownProvider = ({ children, defaultValue, value, onValueChange, open, onOpenChange, defaultOpen, multiple = false, disabled: disabledProp = false, readOnly: readOnlyProp = false, state: stateProp }) => { const [itemsMap, setItemsMap] = (0, import_react7.useState)(getItemsFromChildren(children)); const [hasPopover, setHasPopover] = (0, import_react7.useState)( hasChildComponent(children, "Dropdown.Popover") ); const [lastInteractionType, setLastInteractionType] = (0, import_react7.useState)("mouse"); const field = (0, import_form_field.useFormFieldControl)(); const state = field.state || stateProp; const internalFieldLabelID = `${ID_PREFIX2}-label-${(0, import_react7.useId)()}`; const internalFieldID = `${ID_PREFIX2}-input-${(0, import_react7.useId)()}`; const id = field.id || internalFieldID; const labelId = field.labelId || internalFieldLabelID; const disabled = field.disabled ?? disabledProp; const readOnly = field.readOnly ?? readOnlyProp; const dropdownState = useDropdown({ itemsMap, defaultValue, value, onValueChange, open, onOpenChange, defaultOpen, multiple, id, labelId }); (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)( DropdownContext.Provider, { value: { multiple, disabled, readOnly, ...dropdownState, itemsMap, highlightedItem: getElementByIndex(itemsMap, dropdownState.highlightedIndex), hasPopover, setHasPopover, state, lastInteractionType, setLastInteractionType }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(WrapperComponent, { ...wrapperProps, children }) } ); }; var useDropdownContext = () => { const context = (0, import_react7.useContext)(DropdownContext); if (!context) { throw Error("useDropdownContext must be used within a Dropdown provider"); } return context; }; // src/dropdown/Dropdown.tsx var import_jsx_runtime17 = require("react/jsx-runtime"); var Dropdown = ({ children, ...props }) => { return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DropdownProvider, { ...props, children }); }; Dropdown.displayName = "Dropdown"; // src/dropdown/DropdownDivider.tsx var import_class_variance_authority10 = require("class-variance-authority"); var import_jsx_runtime18 = require("react/jsx-runtime"); var Divider = ({ className, ref: forwardedRef }) => { return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: forwardedRef, className: (0, import_class_variance_authority10.cx)("my-md border-b-sm border-outline", className) }); }; Divider.displayName = "Dropdown.Divider"; // src/dropdown/DropdownGroup.tsx var import_class_variance_authority11 = require("class-variance-authority"); // src/dropdown/DropdownItemsGroupContext.tsx var import_react8 = require("react"); var import_jsx_runtime19 = require("react/jsx-runtime"); var DropdownGroupContext = (0, import_react8.createContext)(null); var DropdownGroupProvider = ({ children }) => { const labelId = `${ID_PREFIX2}-group-label-${(0, import_react8.useId)()}`; return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownGroupContext.Provider, { value: { labelId }, children }); }; var useDropdownGroupContext = () => { const context = (0, import_react8.useContext)(DropdownGroupContext); if (!context) { throw Error("useDropdownGroupContext must be used within a DropdownGroup provider"); } return context; }; // src/dropdown/DropdownGroup.tsx var import_jsx_runtime20 = require("react/jsx-runtime"); var Group = ({ children, ref: forwardedRef, ...props }) => { return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownGroupProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GroupContent, { ref: forwardedRef, ...props, children }) }); }; var GroupContent = ({ children, className, ref: forwardedRef }) => { const { labelId } = useDropdownGroupContext(); return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { ref: forwardedRef, role: "group", "aria-labelledby": labelId, className: (0, import_class_variance_authority11.cx)(className), children }); }; Group.displayName = "Dropdown.Group"; // src/dropdown/DropdownItem.tsx var import_use_merge_refs = require("@spark-ui/hooks/use-merge-refs"); var import_class_variance_authority12 = require("class-variance-authority"); // src/dropdown/DropdownItemContext.tsx var import_react9 = require("react"); var import_jsx_runtime21 = require("react/jsx-runtime"); var DropdownItemContext = (0, import_react9.createContext)(null); var DropdownItemProvider = ({ value, disabled = false, children }) => { const { multiple, itemsMap, selectedItem, selectedItems } = useDropdownContext(); const [textId, setTextId] = (0, import_react9.useState)(void 0); const index = getIndexByKey(itemsMap, value); const itemData = { disabled, value, text: getItemText(children) }; const isSelected = multiple ? selectedItems.some((selectedItem2) => selectedItem2.value === value) : selectedItem?.value === value; return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)( DropdownItemContext.Provider, { value: { textId, setTextId, isSelected, itemData, index, disabled }, children } ); }; var useDropdownItemContext = () => { const context = (0, import_react9.useContext)(DropdownItemContext); if (!context) { throw Error("useDropdownItemContext must be used within a DropdownItem provider"); } return context; }; // src/dropdown/DropdownItem.tsx var import_jsx_runtime22 = require("react/jsx-runtime"); var Item = ({ children, ref: forwardedRef, ...props }) => { const { value, disabled } = props; return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownItemProvider, { value, disabled, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ItemContent, { ref: forwardedRef, ...props, children }) }); }; var styles2 = (0, import_class_variance_authority12.cva)("px-lg py-md text-body-1", { variants: { selected: { true: "font-bold" }, disabled: { true: "opacity-dim-3 cursor-not-allowed", false: "cursor-pointer" }, highlighted: { true: "" }, interactionType: { mouse: "", keyboard: "" } }, compoundVariants: [ { highlighted: true, interactionType: "mouse", class: "bg-surface-hovered" }, { highlighted: true, interactionType: "keyboard", class: "u-outline" } ] }); var ItemContent = ({ className, disabled = false, value, children, ref: forwardedRef }) => { const { getItemProps, highlightedItem, lastInteractionType } = useDropdownContext(); const { textId, index, itemData, isSelected } = useDropdownItemContext(); const isHighlighted = highlightedItem?.value === value; const { ref: downshiftRef, ...downshiftItemProps } = getItemProps({ item: itemData, index }); const ref = (0, import_use_merge_refs.useMergeRefs)(forwardedRef, downshiftRef); return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)( "li", { ref, className: (0, import_class_variance_authority12.cx)( styles2({ selected: isSelected, disabled, highlighted: isHighlighted, interactionType: lastInteractionType, className }) ), ...downshiftItemProps, "aria-selected": isSelected, "aria-labelledby": textId, children }, value ); }; Item.displayName = "Dropdown.Item"; // src/dropdown/DropdownItemIndicator.tsx var import_Check = require("@spark-ui/icons/Check"); var import_class_variance_authority13 = require("class-variance-authority"); var import_jsx_runtime23 = require("react/jsx-runtime"); var ItemIndicator = ({ className, children, label, ref: forwardedRef }) => { const { disabled, isSelected } = useDropdownItemContext(); const childElement = children || /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_Check.Check, { "aria-label": label }) }); return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)( "span", { ref: forwardedRef, className: (0, import_class_variance_authority13.cx)("min-h-sz-16 min-w-sz-16 flex", disabled && "opacity-dim-3", className), children: isSelected && chi