@spark-ui/components
Version:
Spark (Leboncoin design system) components.
1,693 lines (1,655 loc) • 48.6 kB
JavaScript
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/snackbar/index.ts
var snackbar_exports = {};
__export(snackbar_exports, {
Snackbar: () => Snackbar2,
addSnackbar: () => addSnackbar,
clearSnackbarQueue: () => clearSnackbarQueue
});
module.exports = __toCommonJS(snackbar_exports);
// src/snackbar/Snackbar.tsx
var import_toast3 = require("@react-stately/toast");
var import_react9 = require("react");
var import_react_dom = require("react-dom");
// src/snackbar/SnackbarRegion.tsx
var import_toast2 = require("@react-aria/toast");
var import_react7 = require("react");
// src/snackbar/SnackbarItem.tsx
var import_toast = require("@react-aria/toast");
var import_react6 = require("react");
// src/snackbar/SnackbarItem.styles.ts
var import_class_variance_authority = require("class-variance-authority");
// src/snackbar/snackbarVariants.ts
var filledVariants = [
{
design: "filled",
intent: "success",
class: ["bg-success text-on-success"]
},
{
design: "filled",
intent: "alert",
class: ["bg-alert text-on-alert"]
},
{
design: "filled",
intent: "error",
class: ["bg-error text-on-error"]
},
{
design: "filled",
intent: "info",
class: ["bg-info text-on-info"]
},
{
design: "filled",
intent: "neutral",
class: ["bg-neutral text-on-neutral"]
},
{
design: "filled",
intent: "main",
class: ["bg-main text-on-main"]
},
{
design: "filled",
intent: "basic",
class: ["bg-basic text-on-basic"]
},
{
design: "filled",
intent: "support",
class: ["bg-support text-on-support"]
},
{
design: "filled",
intent: "accent",
class: ["bg-accent text-on-accent"]
},
{
design: "filled",
intent: "inverse",
class: ["bg-surface-inverse text-on-surface-inverse"]
}
];
var tintedVariants = [
{
design: "tinted",
intent: "success",
class: ["bg-success-container text-on-success-container"]
},
{
design: "tinted",
intent: "alert",
class: ["bg-alert-container text-on-alert-container"]
},
{
design: "tinted",
intent: "error",
class: ["bg-error-container text-on-error-container"]
},
{
design: "tinted",
intent: "info",
class: ["bg-info-container text-on-info-container"]
},
{
design: "tinted",
intent: "neutral",
class: ["bg-neutral-container text-on-neutral-container"]
},
{
design: "tinted",
intent: "main",
class: ["bg-main-container text-on-main-container"]
},
{
design: "tinted",
intent: "basic",
class: ["bg-basic-container text-on-basic-container"]
},
{
design: "tinted",
intent: "support",
class: ["bg-support-container text-on-support-container"]
},
{
design: "tinted",
intent: "accent",
class: ["bg-accent-container text-on-accent-container"]
},
{
design: "tinted",
intent: "inverse",
class: ["bg-surface-inverse text-on-surface-inverse"]
}
];
// src/snackbar/SnackbarItem.styles.ts
var snackbarItemVariant = (0, import_class_variance_authority.cva)(
[
"rounded-md shadow-sm",
"max-w-[600px]",
"cursor-default pointer-events-auto touch-none select-none",
"absolute",
/**
* Focus
*/
"group-focus-visible:outline-hidden group-focus-visible:u-outline group-not-focus-visible:ring-inset",
/**
* Positionning
*/
"group-data-[position=bottom]:bottom-0 group-data-[position=bottom-left]:bottom-0 group-data-[position=bottom-right]:bottom-0",
"group-data-[position=top]:top-0 group-data-[position=top-left]:top-0 group-data-[position=top-right]:top-0",
/**
* Animation and opacity
*/
"[animation-fill-mode: forwards]!",
"data-[animation=queued]:animate-fade-in",
"data-[animation=entering]:easing-decelerate-back",
"data-[animation=exiting]:easing-standard",
// Parent position bottom|bottom-left|bottom-right
"data-[animation=entering]:group-data-[position=bottom]:[&:not([data-swipe])]:animate-slide-in-bottom",
"data-[animation=exiting]:opacity-0 data-[animation=exiting]:transition-opacity",
"data-[animation=exiting]:group-data-[position=bottom]:[&:not([data-swipe])]:animate-slide-out-bottom",
"data-[animation=entering]:group-data-[position=bottom-left]:[&:not([data-swipe])]:animate-slide-in-bottom",
"data-[animation=exiting]:group-data-[position=bottom-left]:[&:not([data-swipe])]:animate-slide-out-bottom",
"data-[animation=entering]:group-data-[position=bottom-right]:[&:not([data-swipe])]:animate-slide-in-bottom",
"data-[animation=exiting]:group-data-[position=bottom-right]:[&:not([data-swipe])]:animate-slide-out-bottom",
// Parent position top|top-left|top-right
"data-[animation=entering]:group-data-[position=top]:[&:not([data-swipe])]:animate-slide-in-top",
"data-[animation=exiting]:group-data-[position=top]:[&:not([data-swipe])]:animate-slide-out-top",
"data-[animation=entering]:group-data-[position=top-left]:[&:not([data-swipe])]:animate-slide-in-top",
"data-[animation=exiting]:group-data-[position=top-left]:[&:not([data-swipe])]:animate-slide-out-top",
"data-[animation=entering]:group-data-[position=top-right]:[&:not([data-swipe])]:animate-slide-in-top",
"data-[animation=exiting]:group-data-[position=top-right]:[&:not([data-swipe])]:animate-slide-out-top",
/**
* Swipe
*/
"data-[swipe=move]:data-[swipe-direction=right]:translate-x-(--swipe-position-x)",
"data-[swipe=move]:data-[swipe-direction=left]:translate-x-(--swipe-position-x)",
"data-[swipe=cancel]:translate-x-0",
"data-[swipe=end]:data-[swipe-direction=right]:animate-standalone-swipe-out-right",
"data-[swipe=end]:data-[swipe-direction=left]:animate-standalone-swipe-out-left"
],
{
variants: {
/**
* Set different look and feel
* @default 'filled'
*/
design: {
filled: "",
tinted: ""
},
/**
* Set color intent
* @default 'neutral'
*/
intent: {
success: "",
alert: "",
error: "",
info: "",
neutral: "",
main: "",
basic: "",
support: "",
accent: "",
inverse: ""
}
},
compoundVariants: [...filledVariants, ...tintedVariants],
defaultVariants: {
design: "filled",
intent: "neutral"
}
}
);
var snackbarItemVariantContent = (0, import_class_variance_authority.cva)(
[
"inline-grid items-center",
"col-start-1 row-start-1",
"px-md"
// applying padding on the parent prevents VoiceOver on Safari from reading snackbar content 🤷
],
{
variants: {
/**
* Force action button displaying on a new line
* @default false
*/
actionOnNewline: {
true: [
"grid-rows-[52px_1fr_52px]",
"grid-cols-[min-content_1fr_min-content]",
"[grid-template-areas:'icon_message_close'_'._message_.'_'action_action_action']"
],
false: [
"grid-cols-[min-content_1fr_min-content_min-content]",
"[grid-template-areas:'icon_message_action_close']"
]
}
},
defaultVariants: {
actionOnNewline: false
}
}
);
// src/snackbar/SnackbarItemAction.tsx
var import_class_variance_authority5 = require("class-variance-authority");
// src/button/Button.tsx
var import_class_variance_authority4 = require("class-variance-authority");
var import_react2 = require("react");
// src/slot/Slot.tsx
var import_radix_ui = require("radix-ui");
var import_react = require("react");
var import_jsx_runtime = require("react/jsx-runtime");
var Slottable = import_radix_ui.Slot.Slottable;
var Slot = ({ ref, ...props }) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Slot.Root, { ref, ...props });
};
var wrapPolymorphicSlot = (asChild, children, callback) => {
if (!asChild) return callback(children);
return (0, import_react.isValidElement)(children) ? (0, import_react.cloneElement)(
children,
void 0,
callback(children.props.children)
) : null;
};
// src/visually-hidden/VisuallyHidden.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var VisuallyHidden = ({ asChild = false, ref, ...props }) => {
const Component = asChild ? Slot : "span";
return /* @__PURE__ */ (0, import_jsx_runtime2.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/spinner/Spinner.styles.tsx
var import_internal_utils = require("@spark-ui/internal-utils");
var import_class_variance_authority2 = require("class-variance-authority");
var defaultVariants = {
intent: "current",
size: "current",
isBackgroundVisible: false
};
var spinnerStyles = (0, import_class_variance_authority2.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_utils.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_runtime3 = require("react/jsx-runtime");
var Spinner = ({
className,
size = "current",
intent = "current",
label,
isBackgroundVisible,
ref,
...others
}) => {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"span",
{
role: "status",
"data-spark-component": "spinner",
ref,
className: spinnerStyles({ className, size, intent, isBackgroundVisible }),
...others,
children: label && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(VisuallyHidden, { children: label })
}
);
};
// src/button/Button.styles.tsx
var import_internal_utils7 = require("@spark-ui/internal-utils");
var import_class_variance_authority3 = require("class-variance-authority");
// src/button/variants/filled.ts
var import_internal_utils2 = require("@spark-ui/internal-utils");
var filledVariants2 = [
// Main
{
intent: "main",
design: "filled",
class: (0, import_internal_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils2.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_utils3 = require("@spark-ui/internal-utils");
var ghostVariants = [
{
intent: "main",
design: "ghost",
class: (0, import_internal_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils3.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_utils4 = require("@spark-ui/internal-utils");
var outlinedVariants = [
{
intent: "main",
design: "outlined",
class: (0, import_internal_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils4.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_utils5 = require("@spark-ui/internal-utils");
var tintedVariants2 = [
{
intent: "main",
design: "tinted",
class: (0, import_internal_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils5.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_utils6 = require("@spark-ui/internal-utils");
var contrastVariants = [
{
intent: "main",
design: "contrast",
class: (0, import_internal_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_utils6.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_authority3.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_utils7.makeVariants)({
filled: [],
outlined: ["bg-transparent", "border-sm", "border-current"],
tinted: [],
ghost: [],
contrast: ["bg-surface"]
}),
/**
* Color scheme of the button.
*/
intent: (0, import_internal_utils7.makeVariants)({
main: [],
support: [],
accent: [],
basic: [],
success: [],
alert: [],
danger: [],
info: [],
neutral: [],
surface: []
}),
/**
* Size of the button.
*/
size: (0, import_internal_utils7.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_utils7.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: [
...filledVariants2,
...outlinedVariants,
...tintedVariants2,
...ghostVariants,
...contrastVariants
],
defaultVariants: {
design: "filled",
intent: "main",
size: "md",
shape: "rounded"
}
}
);
// src/button/Button.tsx
var import_jsx_runtime4 = 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_react2.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_runtime4.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_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Spinner, { ...spinnerProps }),
loadingText && loadingText,
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"div",
{
"aria-hidden": true,
className: (0, import_class_variance_authority4.cx)("gap-md", loadingText ? "hidden" : "inline-flex opacity-0"),
children: slotted
}
)
] }) : slotted
)
}
);
};
Button.displayName = "Button";
// src/snackbar/SnackbarItemContext.tsx
var import_react3 = require("react");
var SnackbarItemContext = (0, import_react3.createContext)({});
var useSnackbarItemContext = () => (0, import_react3.useContext)(SnackbarItemContext);
// src/snackbar/SnackbarItemAction.tsx
var import_jsx_runtime5 = require("react/jsx-runtime");
var SnackbarItemAction = ({
design: designProp = "filled",
intent: intentProp = "neutral",
onClick,
children,
className,
ref,
...rest
}) => {
const { toast, state } = useSnackbarItemContext();
const intent = intentProp ?? toast.content.intent;
const design = designProp ?? toast.content.design;
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Button,
{
ref,
size: "md",
shape: "rounded",
...intent === "inverse" ? {
design: "ghost",
intent: "surface"
} : {
design,
intent: intent === "error" ? "danger" : intent
},
onClick: (e) => {
onClick?.(e);
state.close(toast.key);
},
style: { gridArea: "action", ...rest.style },
className: (0, import_class_variance_authority5.cx)("ml-md justify-self-end", className),
...rest,
children
}
);
};
SnackbarItemAction.displayName = "Snackbar.ItemAction";
// src/snackbar/SnackbarItemClose.tsx
var import_Close = require("@spark-ui/icons/Close");
var import_class_variance_authority8 = require("class-variance-authority");
// src/icon/Icon.tsx
var import_react4 = require("react");
// src/icon/Icon.styles.tsx
var import_internal_utils8 = require("@spark-ui/internal-utils");
var import_class_variance_authority6 = require("class-variance-authority");
var iconStyles = (0, import_class_variance_authority6.cva)(["fill-current shrink-0"], {
variants: {
/**
* Color scheme of the icon.
*/
intent: (0, import_internal_utils8.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_utils8.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_runtime6 = require("react/jsx-runtime");
var Icon = ({
label,
className,
size = "current",
intent = "current",
children,
...others
}) => {
const child = import_react4.Children.only(children);
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
(0, import_react4.cloneElement)(child, {
className: iconStyles({ className, size, intent }),
"data-spark-component": "icon",
"aria-hidden": "true",
focusable: "false",
...others
}),
label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(VisuallyHidden, { children: label })
] });
};
Icon.displayName = "Icon";
// src/icon-button/IconButton.styles.tsx
var import_internal_utils9 = require("@spark-ui/internal-utils");
var import_class_variance_authority7 = require("class-variance-authority");
var iconButtonStyles = (0, import_class_variance_authority7.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_runtime7 = require("react/jsx-runtime");
var IconButton = ({
design = "filled",
disabled = false,
intent = "main",
shape = "rounded",
size = "md",
className,
ref,
...others
}) => {
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
Button,
{
ref,
className: iconButtonStyles({ size, className }),
design,
disabled,
intent,
shape,
size,
...others
}
);
};
IconButton.displayName = "IconButton";
// src/snackbar/SnackbarItemClose.tsx
var import_jsx_runtime8 = require("react/jsx-runtime");
var SnackbarItemClose = ({
design: designProp = "filled",
intent: intentProp = "neutral",
"aria-label": ariaLabel,
onClick,
className,
ref,
...rest
}) => {
const { toast, state } = useSnackbarItemContext();
const intent = intentProp ?? toast.content.intent;
const design = designProp ?? toast.content.design;
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
IconButton,
{
ref,
size: "md",
shape: "rounded",
...intent === "inverse" ? {
design: "ghost",
intent: "surface"
} : {
design,
intent: intent === "error" ? "danger" : intent
},
"aria-label": ariaLabel,
onClick: (e) => {
onClick?.(e);
state.close(toast.key);
},
style: { gridArea: "close", ...rest.style },
className: (0, import_class_variance_authority8.cx)("ml-md justify-self-end", className),
...rest,
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Close.Close, {}) })
}
);
};
SnackbarItemClose.displayName = "Snackbar.ItemClose";
// src/snackbar/SnackbarItemIcon.tsx
var import_class_variance_authority9 = require("class-variance-authority");
var import_jsx_runtime9 = require("react/jsx-runtime");
var SnackbarItemIcon = ({
children,
className,
...rest
}) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
Icon,
{
size: "md",
className: (0, import_class_variance_authority9.cx)("mx-md", className),
style: { gridArea: "icon", ...rest.style },
...rest,
children
}
);
SnackbarItemIcon.displayName = "Snackbar.ItemIcon";
// src/snackbar/useSwipe.ts
var import_react5 = require("react");
var SWIPE_THRESHOLD = 75;
var useSwipe = ({
swipeRef,
onSwipeStart,
onSwipeMove,
onSwipeCancel,
onSwipeEnd,
threshold = 10
}) => {
const [state, setState] = (0, import_react5.useState)();
const direction = (0, import_react5.useRef)(null);
const origin = (0, import_react5.useRef)(null);
const delta = (0, import_react5.useRef)(null);
const handleSwipeStart = (evt) => {
origin.current = { x: evt.clientX, y: evt.clientY };
document.addEventListener("selectstart", (e) => e.preventDefault());
};
const handleSwipeMove = (evt) => {
if (!origin.current) return;
const deltaX = Math.abs(evt.clientX - origin.current.x);
const deltaY = Math.abs(evt.clientY - origin.current.y);
let moveState;
if (deltaX > deltaY && deltaX > threshold) {
direction.current = evt.clientX > origin.current.x ? "right" : "left";
} else if (deltaY > threshold) {
direction.current = evt.clientY > origin.current.y ? "down" : "up";
}
if (!direction.current) return;
if (!delta.current) {
moveState = "start";
delta.current = { x: deltaX, y: deltaY };
onSwipeStart?.({ state: moveState, direction: direction.current });
} else {
moveState = "move";
delta.current = { x: deltaX, y: deltaY };
swipeRef.current.style.setProperty(
"--swipe-position-x",
`${deltaX > deltaY ? evt.clientX - origin.current.x : 0}px`
);
swipeRef.current.style.setProperty(
"--swipe-position-y",
`${!(deltaX > deltaY) ? evt.clientY - origin.current.y : 0}px`
);
onSwipeMove?.({ state: moveState, direction: direction.current });
}
setState(moveState);
};
const handleSwipeEnd = () => {
const proxyDelta = delta.current;
origin.current = null;
delta.current = null;
if (proxyDelta) {
const { x: deltaX, y: deltaY } = proxyDelta;
let endState;
if (deltaX > deltaY) {
if (deltaX > SWIPE_THRESHOLD) {
endState = "end";
onSwipeEnd?.({ state: endState, direction: direction.current });
} else {
endState = "cancel";
onSwipeCancel?.({ state: endState, direction: direction.current });
}
} else {
if (deltaY > SWIPE_THRESHOLD) {
endState = "end";
onSwipeEnd?.({ state: endState, direction: direction.current });
} else {
endState = "cancel";
onSwipeCancel?.({ state: endState, direction: direction.current });
}
}
setState(endState);
document.removeEventListener("selectstart", (e) => e.preventDefault());
}
};
(0, import_react5.useEffect)(() => {
if (!swipeRef.current) return;
const swipeElement = swipeRef.current;
swipeElement.addEventListener("pointerdown", handleSwipeStart);
document.addEventListener("pointermove", handleSwipeMove);
document.addEventListener("pointerup", handleSwipeEnd);
return () => {
swipeElement.removeEventListener("pointerdown", handleSwipeStart);
document.removeEventListener("pointermove", handleSwipeMove);
document.removeEventListener("pointerup", handleSwipeEnd);
};
}, []);
return {
state,
direction: direction.current
};
};
// src/snackbar/SnackbarItem.tsx
var import_jsx_runtime10 = require("react/jsx-runtime");
var SnackbarItem = ({
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
"aria-describedby": ariaDescribedby,
"aria-details": ariaDetails,
design: designProp,
intent: intentProp,
actionOnNewline: actionOnNewlineProp,
className,
children,
ref: forwardedRef,
...rest
}) => {
const innerRef = (0, import_react6.useRef)(null);
const ref = typeof forwardedRef !== "function" ? forwardedRef || innerRef : innerRef;
const { toast, state } = useSnackbarItemContext();
const { state: swipeState, direction: swipeDirection } = useSwipe({
swipeRef: ref,
onSwipeStart: state.pauseAll,
onSwipeCancel: state.resumeAll,
onSwipeEnd: ({ direction }) => {
;
["left", "right"].includes(`${direction}`) && state.close(toast.key);
}
});
const { message, icon, isClosable, onAction, actionLabel } = toast.content;
const intent = intentProp ?? toast.content.intent;
const design = designProp ?? toast.content.design;
const actionOnNewline = actionOnNewlineProp ?? toast.content.actionOnNewline;
const ariaProps = {
ariaLabel,
ariaLabelledby,
ariaDescribedby,
ariaDetails
};
const { toastProps, titleProps, closeButtonProps, contentProps } = (0, import_toast.useToast)(
{ toast, ...ariaProps },
state,
ref
);
const findElement = (0, import_react6.useCallback)(
(elementDisplayName) => {
const childrenArray = import_react6.Children.toArray(children);
const match = childrenArray.filter(import_react6.isValidElement).find(
(child) => !!child.type.displayName?.includes(
elementDisplayName
)
);
return match;
},
[children]
);
const iconFromChildren = findElement("Snackbar.ItemIcon");
const actionBtnFromChildren = findElement("Snackbar.ItemAction");
const closeBtnFromChildren = findElement("Snackbar.ItemClose");
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
"div",
{
className: snackbarItemVariant({ design, intent, className }),
"data-animation": toast.animation,
...!(swipeState === "cancel" && toast.animation === "exiting") && {
"data-swipe": swipeState,
"data-swipe-direction": swipeDirection
},
...toast.animation === "exiting" && {
// Remove snackbar when the exiting animation completes
onAnimationEnd: () => state.remove(toast.key)
},
ref,
...toastProps,
...rest,
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: snackbarItemVariantContent({ actionOnNewline }), ...contentProps, children: [
renderSubComponent(iconFromChildren, icon ? SnackbarItemIcon : null, {
children: icon
}),
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
"p",
{
className: "px-md py-lg text-body-2 row-span-3",
style: { gridArea: "message" },
...titleProps,
children: message
}
),
renderSubComponent(
actionBtnFromChildren,
actionLabel && onAction ? SnackbarItemAction : null,
{ intent, design, onClick: onAction, children: actionLabel }
),
renderSubComponent(closeBtnFromChildren, isClosable ? SnackbarItemClose : null, {
intent,
design,
/**
* React Spectrum typing of aria-label is inaccurate, and aria-label value should never be undefined.
* See https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/i18n/src/useLocalizedStringFormatter.ts#L40
*/
"aria-label": closeButtonProps["aria-label"]
})
] })
}
);
};
SnackbarItem.displayName = "Snackbar.Item";
var renderSubComponent = (childItem, defaultItem, props) => {
if (childItem) {
return (0, import_react6.cloneElement)(childItem, { ...props, ...childItem.props });
} else if (defaultItem) {
const Item = defaultItem;
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Item, { ...props });
} else {
return null;
}
};
// src/snackbar/SnackbarRegion.styles.ts
var import_class_variance_authority10 = require("class-variance-authority");
var snackbarRegionVariant = (0, import_class_variance_authority10.cva)(
[
"fixed inset-x-lg z-toast group",
"outline-hidden pointer-events-none",
"grid grid-rows-1 grid-cols-1 gap-lg"
],
{
variants: {
/**
* Set snackbar item position
* @default 'bottom'
*/
position: {
top: "top-lg justify-items-center",
"top-right": "top-lg justify-items-end",
"top-left": "top-lg justify-items-start",
bottom: "bottom-lg justify-items-center",
"bottom-right": "bottom-lg justify-items-end",
"bottom-left": "bottom-lg justify-items-start"
}
},
defaultVariants: {
position: "bottom"
}
}
);
// src/snackbar/SnackbarRegion.tsx
var import_jsx_runtime11 = require("react/jsx-runtime");
var SnackbarRegion = ({
children = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SnackbarItem, {}),
state,
position = "bottom",
className,
ref: forwardedRef,
...rest
}) => {
const innerRef = (0, import_react7.useRef)(null);
const ref = forwardedRef && typeof forwardedRef !== "function" ? forwardedRef : innerRef;
const { regionProps } = (0, import_toast2.useToastRegion)(rest, state, ref);
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
"div",
{
...regionProps,
ref,
"data-position": position,
className: snackbarRegionVariant({ position, className }),
children: state.visibleToasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SnackbarItemContext.Provider, { value: { toast, state }, children: (0, import_react7.cloneElement)(children, { key: toast.key }) }, toast.key))
}
);
};
// src/snackbar/useSnackbarGlobalStore.ts
var import_react8 = require("react");
var useSnackbarGlobalStore = ({
providers,
subscriptions
}) => {
const subscribe = (0, import_react8.useCallback)(
(listener) => {
subscriptions.add(listener);
return () => subscriptions.delete(listener);
},
[subscriptions]
);
const getLastSnackbarProvider = (0, import_react8.useCallback)(() => [...providers].reverse()[0], [providers]);
const addProvider = (0, import_react8.useCallback)(
(provider2) => {
providers.add(provider2);
for (const subscribeFn of subscriptions) {
subscribeFn();
}
},
[providers, subscriptions]
);
const deleteProvider = (0, import_react8.useCallback)(
(provider2) => {
providers.delete(provider2);
for (const subscribeFn of subscriptions) {
subscribeFn();
}
},
[providers, subscriptions]
);
const provider = (0, import_react8.useSyncExternalStore)(subscribe, getLastSnackbarProvider, getLastSnackbarProvider);
return {
provider,
addProvider,
deleteProvider
};
};
// src/snackbar/Snackbar.tsx
var import_jsx_runtime12 = require("react/jsx-runtime");
var GLOBAL_SNACKBAR_QUEUE = null;
var getGlobalSnackBarQueue = () => {
if (!GLOBAL_SNACKBAR_QUEUE) {
GLOBAL_SNACKBAR_QUEUE = new import_toast3.ToastQueue({
maxVisibleToasts: 1,
hasExitAnimation: true
});
}
return GLOBAL_SNACKBAR_QUEUE;
};
var clearSnackbarQueue = () => {
GLOBAL_SNACKBAR_QUEUE = null;
};
var GLOBAL_SNACKBAR_STORE = {
providers: /* @__PURE__ */ new Set(),
subscriptions: /* @__PURE__ */ new Set()
};
var Snackbar = ({ ref: forwardedRef, ...props }) => {
const ref = (0, import_react9.useRef)(null);
const state = (0, import_toast3.useToastQueue)(getGlobalSnackBarQueue());
const { provider, addProvider, deleteProvider } = useSnackbarGlobalStore(GLOBAL_SNACKBAR_STORE);
(0, import_react9.useEffect)(() => {
addProvider(ref);
return () => {
for (const toast of getGlobalSnackBarQueue().visibleToasts) {
toast.animation = void 0;
}
deleteProvider(ref);
};
}, []);
return ref === provider && state.visibleToasts.length > 0 ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SnackbarRegion, { ref: forwardedRef, state, ...props }), document.body) : null;
};
Snackbar.displayName = "Snackbar";
var addSnackbar = ({ onClose, timeout = 5e3, priority, ...content }) => {
const queue = getGlobalSnackBarQueue();
queue.add(content, {
onClose,
timeout: timeout && !content.onAction ? Math.max(timeout, 5e3) : void 0,
priority
});
};
// src/snackbar/index.ts
var Snackbar2 = Object.assign(Snackbar, {
Item: SnackbarItem,
ItemAction: SnackbarItemAction,
ItemClose: SnackbarItemClose,
ItemIcon: SnackbarItemIcon
});
Snackbar2.displayName = "Snackbar";
SnackbarItem.displayName = "Snackbar.Item";
SnackbarItemAction.displayName = "Snackbar.ItemAction";
SnackbarItemClose.displayName = "Snackbar.ItemClose";
SnackbarItemIcon.displayName = "Snackbar.ItemIcon";
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Snackbar,
addSnackbar,
clearSnackbarQueue
});
//# sourceMappingURL=index.js.map
;