package.dist.index.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of toast Show documentation
Show all versions of toast Show documentation
Core logic for the toast widget implemented as a state machine
The newest version!
'use strict';
var core = require('@zag-js/core');
var domQuery = require('@zag-js/dom-query');
var utils = require('@zag-js/utils');
var anatomy$1 = require('@zag-js/anatomy');
var dismissable = require('@zag-js/dismissable');
var domEvent = require('@zag-js/dom-event');
// src/toast-group.connect.ts
var anatomy = anatomy$1.createAnatomy("toast").parts(
"group",
"root",
"title",
"description",
"actionTrigger",
"closeTrigger"
);
var parts = anatomy.build();
var dom = domQuery.createScope({
getRegionId: (placement) => `toast-group:${placement}`,
getRegionEl: (ctx, placement) => dom.getById(ctx, `toast-group:${placement}`),
getRootId: (ctx) => `toast:${ctx.id}`,
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
getTitleId: (ctx) => `toast:${ctx.id}:title`,
getDescriptionId: (ctx) => `toast:${ctx.id}:description`,
getCloseTriggerId: (ctx) => `toast${ctx.id}:close`
});
function getToastsByPlacement(toasts, placement) {
return toasts.filter((toast) => toast.state.context.placement === placement);
}
var defaultTimeouts = {
info: 5e3,
error: 5e3,
success: 2e3,
loading: Infinity,
DEFAULT: 5e3
};
function getToastDuration(duration, type) {
return duration ?? defaultTimeouts[type] ?? defaultTimeouts.DEFAULT;
}
function getGroupPlacementStyle(ctx, placement) {
const offset = ctx.offsets;
const computedOffset = typeof offset === "string" ? { left: offset, right: offset, bottom: offset, top: offset } : offset;
const rtl = ctx.dir === "rtl";
const computedPlacement = placement.replace("-start", rtl ? "-right" : "-left").replace("-end", rtl ? "-left" : "-right");
const isRighty = computedPlacement.includes("right");
const isLefty = computedPlacement.includes("left");
const styles = {
position: "fixed",
pointerEvents: ctx.count > 0 ? void 0 : "none",
display: "flex",
flexDirection: "column",
"--gap": `${ctx.gap}px`,
"--first-height": `${ctx.heights[0]?.height || 0}px`,
zIndex: domQuery.MAX_Z_INDEX
};
let alignItems = "center";
if (isRighty) alignItems = "flex-end";
if (isLefty) alignItems = "flex-start";
styles.alignItems = alignItems;
if (computedPlacement.includes("top")) {
const offset2 = computedOffset.top;
styles.top = `max(env(safe-area-inset-top, 0px), ${offset2})`;
}
if (computedPlacement.includes("bottom")) {
const offset2 = computedOffset.bottom;
styles.bottom = `max(env(safe-area-inset-bottom, 0px), ${offset2})`;
}
if (!computedPlacement.includes("left")) {
const offset2 = computedOffset.right;
styles.insetInlineEnd = `calc(env(safe-area-inset-right, 0px) + ${offset2})`;
}
if (!computedPlacement.includes("right")) {
const offset2 = computedOffset.left;
styles.insetInlineStart = `calc(env(safe-area-inset-left, 0px) + ${offset2})`;
}
return styles;
}
function getPlacementStyle(ctx, visible) {
const [side] = ctx.placement.split("-");
const sibling = !ctx.frontmost;
const overlap = !ctx.stacked;
const styles = {
position: "absolute",
pointerEvents: "auto",
"--opacity": "0",
"--remove-delay": `${ctx.removeDelay}ms`,
"--duration": `${ctx.type === "loading" ? Number.MAX_SAFE_INTEGER : ctx.duration}ms`,
"--initial-height": `${ctx.height}px`,
"--offset": `${ctx.offset}px`,
"--index": ctx.index,
"--z-index": ctx.zIndex,
"--lift-amount": "calc(var(--lift) * var(--gap))",
"--y": "100%",
"--x": "0"
};
const assign = (overrides) => Object.assign(styles, overrides);
if (side === "top") {
assign({
top: "0",
"--sign": "-1",
"--y": "-100%",
"--lift": "1"
});
} else if (side === "bottom") {
assign({
bottom: "0",
"--sign": "1",
"--y": "100%",
"--lift": "-1"
});
}
if (ctx.mounted) {
assign({
"--y": "0",
"--opacity": "1"
});
if (ctx.stacked) {
assign({
"--y": "calc(var(--lift) * var(--offset))",
"--height": "var(--initial-height)"
});
}
}
if (!visible) {
assign({
"--opacity": "0",
pointerEvents: "none"
});
}
if (sibling && overlap) {
assign({
"--base-scale": "var(--index) * 0.05 + 1",
"--y": "calc(var(--lift-amount) * var(--index))",
"--scale": "calc(-1 * var(--base-scale))",
"--height": "var(--first-height)"
});
if (!visible) {
assign({
"--y": "calc(var(--sign) * 40%)"
});
}
}
if (sibling && ctx.stacked && !visible) {
assign({
"--y": "calc(var(--lift) * var(--offset) + var(--lift) * -100%)"
});
}
if (ctx.frontmost && !visible) {
assign({
"--y": "calc(var(--lift) * -100%)"
});
}
return styles;
}
function getGhostBeforeStyle(ctx, visible) {
const styles = {
position: "absolute",
inset: "0",
scale: "1 2",
pointerEvents: visible ? "none" : "auto"
};
const assign = (overrides) => Object.assign(styles, overrides);
if (ctx.frontmost && !visible) {
assign({
height: "calc(var(--initial-height) + 80%)"
});
}
return styles;
}
function getGhostAfterStyle(_ctx, _visible) {
return {
position: "absolute",
left: "0",
height: "calc(var(--gap) + 2px)",
bottom: "100%",
width: "100%"
};
}
// src/toast-group.connect.ts
function groupConnect(serviceOrState, send, normalize) {
function getState() {
const result = core.isMachine(serviceOrState) ? serviceOrState.getState() : serviceOrState;
return result;
}
function getToastsByPlacementImpl(placement) {
return getToastsByPlacement(getState().context.toasts, placement);
}
function isVisible(id) {
const toasts = getState().context.toasts;
if (!toasts.length) return false;
return !!toasts.find((toast) => toast.id == id);
}
function create(options) {
const uid = `toast:${utils.uuid()}`;
const id = options.id ? options.id : uid;
if (isVisible(id)) return id;
send({ type: "ADD_TOAST", toast: { ...options, id } });
return id;
}
function update(id, options) {
if (!isVisible(id)) return id;
send({ type: "UPDATE_TOAST", id, toast: options });
return id;
}
function upsert(options) {
const { id } = options;
const visible = id ? isVisible(id) : false;
if (visible && id != null) {
return update(id, options);
} else {
return create(options);
}
}
function dismiss(id) {
if (id == null) {
send("DISMISS_ALL");
} else if (isVisible(id)) {
send({ type: "DISMISS_TOAST", id });
}
}
return {
getCount() {
return getState().context.count;
},
getPlacements() {
const toasts = getState().context.toasts;
const placements = toasts.map((toast) => toast.state.context.placement);
return Array.from(new Set(placements));
},
getToastsByPlacement: getToastsByPlacementImpl,
isVisible,
create,
update,
upsert,
dismiss,
remove(id) {
if (id == null) {
send("REMOVE_ALL");
} else if (isVisible(id)) {
send({ type: "REMOVE_TOAST", id });
}
},
dismissByPlacement(placement) {
const toasts = getToastsByPlacementImpl(placement);
toasts.forEach((toast) => dismiss(toast.id));
},
loading(options) {
return upsert({ ...options, type: "loading" });
},
success(options) {
return upsert({ ...options, type: "success" });
},
error(options) {
return upsert({ ...options, type: "error" });
},
promise(promise, options, shared = {}) {
const id = upsert({ ...shared, ...options.loading, type: "loading" });
utils.runIfFn(promise).then((response) => {
const successOptions = utils.runIfFn(options.success, response);
upsert({ ...shared, ...successOptions, id, type: "success" });
}).catch((error) => {
const errorOptions = utils.runIfFn(options.error, error);
upsert({ ...shared, ...errorOptions, id, type: "error" });
}).finally(() => {
options.finally?.();
});
return id;
},
pause(id) {
if (id == null) {
send("PAUSE_ALL");
} else if (isVisible(id)) {
send({ type: "PAUSE_TOAST", id });
}
},
resume(id) {
if (id == null) {
send("RESUME_ALL");
} else if (isVisible(id)) {
send({ type: "RESUME_TOAST", id });
}
},
getGroupProps(options) {
const { placement, label = "Notifications" } = options;
const state = getState();
const hotkeyLabel = state.context.hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
const [side, align = "center"] = placement.split("-");
return normalize.element({
...parts.group.attrs,
dir: state.context.dir,
tabIndex: -1,
"aria-label": `${placement} ${label} ${hotkeyLabel}`,
id: dom.getRegionId(placement),
"data-placement": placement,
"data-side": side,
"data-align": align,
"aria-live": "polite",
role: "region",
style: getGroupPlacementStyle(state.context, placement),
onMouseMove() {
send({ type: "REGION.POINTER_ENTER", placement });
},
onMouseLeave() {
send({ type: "REGION.POINTER_LEAVE", placement });
},
onFocus(event) {
send({ type: "REGION.FOCUS", target: event.relatedTarget });
},
onBlur(event) {
if (state.context.isFocusWithin && !domQuery.contains(event.currentTarget, event.relatedTarget)) {
send({ type: "REGION.BLUR" });
}
}
});
},
subscribe(fn) {
const state = getState();
return core.subscribe(state.context.toasts, () => {
const toasts = getToastsByPlacementImpl(state.context.placement);
const contexts = toasts.map((toast) => toast.getState().context);
fn(contexts);
});
}
};
}
var { not, and, or } = core.guards;
function createToastMachine(options) {
const { type = "info", duration, id = "1", placement = "bottom", removeDelay = 200, ...restProps } = options;
const ctx = utils.compact(restProps);
const computedDuration = getToastDuration(duration, type);
return core.createMachine(
{
id,
context: {
id,
type,
remaining: computedDuration,
duration: computedDuration,
removeDelay,
createdAt: Date.now(),
placement,
...ctx,
height: 0,
offset: 0,
frontmost: false,
mounted: false,
index: -1,
zIndex: 0
},
initial: type === "loading" ? "visible:persist" : "visible",
on: {
UPDATE: [
{
guard: and("hasTypeChanged", "isChangingToLoading"),
target: "visible:persist",
actions: ["setContext"]
},
{
guard: or("hasDurationChanged", "hasTypeChanged"),
target: "visible:updating",
actions: ["setContext"]
},
{
actions: ["setContext"]
}
],
MEASURE: {
actions: ["measureHeight"]
}
},
entry: ["invokeOnVisible"],
activities: ["trackHeight"],
states: {
"visible:updating": {
tags: ["visible", "updating"],
after: {
0: "visible"
}
},
"visible:persist": {
tags: ["visible", "paused"],
on: {
RESUME: {
guard: not("isLoadingType"),
target: "visible",
actions: ["setCreatedAt"]
},
DISMISS: "dismissing"
}
},
visible: {
tags: ["visible"],
after: {
VISIBLE_DURATION: "dismissing"
},
on: {
DISMISS: "dismissing",
PAUSE: {
target: "visible:persist",
actions: "setRemainingDuration"
}
}
},
dismissing: {
entry: "invokeOnDismiss",
after: {
REMOVE_DELAY: {
target: "unmounted",
actions: "notifyParentToRemove"
}
}
},
unmounted: {
entry: "invokeOnUnmount",
type: "final"
}
}
},
{
activities: {
trackHeight(ctx2, _evt, { self }) {
let cleanup;
domQuery.raf(() => {
const rootEl = dom.getRootEl(ctx2);
if (!rootEl) return;
ctx2.mounted = true;
const ghosts = domQuery.queryAll(rootEl, "[data-ghost]");
utils.warn(
ghosts.length !== 2,
"[toast] No ghost element found in toast. Render the `ghostBefore` and `ghostAfter` elements"
);
const syncHeight = () => {
const originalHeight = rootEl.style.height;
rootEl.style.height = "auto";
const newHeight = rootEl.getBoundingClientRect().height;
rootEl.style.height = originalHeight;
ctx2.height = newHeight;
self.sendParent({ type: "UPDATE_HEIGHT", id: self.id, height: newHeight, placement: ctx2.placement });
};
syncHeight();
const win = dom.getWin(ctx2);
const observer = new win.MutationObserver(syncHeight);
observer.observe(rootEl, { childList: true, subtree: true, characterData: true });
cleanup = () => observer.disconnect();
});
return () => cleanup?.();
}
},
guards: {
isChangingToLoading: (_, evt) => evt.toast?.type === "loading",
isLoadingType: (ctx2) => ctx2.type === "loading",
hasTypeChanged: (ctx2, evt) => evt.toast?.type != null && evt.toast.type !== ctx2.type,
hasDurationChanged: (ctx2, evt) => evt.toast?.duration != null && evt.toast.duration !== ctx2.duration
},
delays: {
VISIBLE_DURATION: (ctx2) => ctx2.remaining,
REMOVE_DELAY: (ctx2) => ctx2.removeDelay
},
actions: {
measureHeight(ctx2, _evt, { self }) {
domQuery.raf(() => {
const rootEl = dom.getRootEl(ctx2);
if (!rootEl) return;
ctx2.mounted = true;
const originalHeight = rootEl.style.height;
rootEl.style.height = "auto";
const newHeight = rootEl.getBoundingClientRect().height;
rootEl.style.height = originalHeight;
ctx2.height = newHeight;
self.sendParent({ type: "UPDATE_HEIGHT", id: self.id, height: newHeight, placement: ctx2.placement });
});
},
setRemainingDuration(ctx2) {
ctx2.remaining -= Date.now() - ctx2.createdAt;
},
setCreatedAt(ctx2) {
ctx2.createdAt = Date.now();
},
notifyParentToRemove(_ctx, _evt, { self }) {
self.sendParent({ type: "REMOVE_TOAST", id: self.id });
},
invokeOnDismiss(ctx2) {
ctx2.onStatusChange?.({ status: "dismissing" });
},
invokeOnUnmount(ctx2) {
ctx2.onStatusChange?.({ status: "unmounted" });
},
invokeOnVisible(ctx2) {
ctx2.onStatusChange?.({ status: "visible" });
},
setContext(ctx2, evt) {
const duration2 = evt.toast?.duration;
const type2 = evt.toast?.type ?? ctx2.type;
const computedDuration2 = getToastDuration(duration2, type2);
Object.assign(ctx2, {
...evt.toast,
duration: computedDuration2,
remaining: computedDuration2
});
}
}
}
);
}
// src/toast-group.machine.ts
function groupMachine(userContext) {
const ctx = utils.compact(userContext);
return core.createMachine(
{
id: "toaster",
initial: ctx.overlap ? "overlap" : "stack",
context: {
dir: "ltr",
max: Number.MAX_SAFE_INTEGER,
gap: 16,
pauseOnPageIdle: false,
hotkey: ["altKey", "KeyT"],
offsets: "1rem",
placement: "bottom",
removeDelay: 200,
...ctx,
toasts: [],
lastFocusedEl: null,
isFocusWithin: false,
heights: []
},
computed: {
count: (ctx2) => ctx2.toasts.length
},
activities: ["trackDocumentVisibility", "trackHotKeyPress"],
watch: {
toasts: ["collapsedIfEmpty", "setDismissableBranch"]
},
exit: ["removeToasts", "clearDismissableBranch", "clearLastFocusedEl"],
on: {
PAUSE_TOAST: {
actions: ["pauseToast"]
},
PAUSE_ALL: {
actions: ["pauseToasts"]
},
RESUME_TOAST: {
actions: ["resumeToast"]
},
RESUME_ALL: {
actions: ["resumeToasts"]
},
ADD_TOAST: {
guard: "isWithinRange",
actions: ["createToast", "syncToastIndex"]
},
UPDATE_TOAST: {
actions: ["updateToast"]
},
DISMISS_TOAST: {
actions: ["dismissToast"]
},
DISMISS_ALL: {
actions: ["dismissToasts"]
},
REMOVE_TOAST: {
actions: ["removeToast", "syncToastIndex", "syncToastOffset"]
},
REMOVE_ALL: {
actions: ["removeToasts"]
},
UPDATE_HEIGHT: {
actions: ["syncHeights", "syncToastOffset"]
},
"DOC.HOTKEY": {
actions: ["focusRegionEl"]
},
"REGION.BLUR": [
{
guard: "isOverlapping",
target: "overlap",
actions: ["resumeToasts", "restoreLastFocusedEl"]
},
{
actions: ["resumeToasts", "restoreLastFocusedEl"]
}
]
},
states: {
stack: {
entry: ["expandToasts"],
on: {
"REGION.POINTER_LEAVE": [
{
guard: "isOverlapping",
target: "overlap",
actions: ["resumeToasts"]
},
{
actions: ["resumeToasts"]
}
],
"REGION.OVERLAP": {
target: "overlap"
},
"REGION.FOCUS": {
actions: ["setLastFocusedEl", "pauseToasts"]
},
"REGION.POINTER_ENTER": {
actions: ["pauseToasts"]
}
}
},
overlap: {
entry: ["collapseToasts"],
on: {
"REGION.STACK": {
target: "stack"
},
"REGION.POINTER_ENTER": {
target: "stack",
actions: ["pauseToasts"]
},
"REGION.FOCUS": {
target: "stack",
actions: ["setLastFocusedEl", "pauseToasts"]
}
}
}
}
},
{
guards: {
isWithinRange: (ctx2) => ctx2.toasts.length < ctx2.max,
isOverlapping: (ctx2) => !!ctx2.overlap
},
activities: {
trackHotKeyPress(ctx2, _evt, { send }) {
const handleKeyDown = (event) => {
const isHotkeyPressed = ctx2.hotkey.every((key) => event[key] || event.code === key);
if (!isHotkeyPressed) return;
send({ type: "DOC.HOTKEY" });
};
return domEvent.addDomEvent(document, "keydown", handleKeyDown, { capture: true });
},
trackDocumentVisibility(ctx2, _evt, { send }) {
if (!ctx2.pauseOnPageIdle) return;
const doc = dom.getDoc(ctx2);
return domEvent.addDomEvent(doc, "visibilitychange", () => {
send(doc.visibilityState === "hidden" ? "PAUSE_ALL" : "RESUME_ALL");
});
}
},
actions: {
setDismissableBranch(ctx2) {
const currentToasts = getToastsByPlacement(ctx2.toasts, ctx2.placement);
const hasToasts = currentToasts.length > 0;
if (!hasToasts) {
ctx2._cleanup?.();
return;
}
if (hasToasts && ctx2._cleanup) {
return;
}
const groupEl = () => dom.getRegionEl(ctx2, ctx2.placement);
ctx2._cleanup = dismissable.trackDismissableBranch(groupEl, { defer: true });
},
clearDismissableBranch(ctx2) {
ctx2._cleanup?.();
},
focusRegionEl(ctx2) {
queueMicrotask(() => {
dom.getRegionEl(ctx2, ctx2.placement)?.focus();
});
},
expandToasts(ctx2) {
each(ctx2, (toast) => {
toast.state.context.stacked = true;
});
},
collapseToasts(ctx2) {
each(ctx2, (toast) => {
toast.state.context.stacked = false;
});
},
collapsedIfEmpty(ctx2, _evt, { send }) {
if (!ctx2.overlap || ctx2.toasts.length > 1) return;
send("REGION.OVERLAP");
},
pauseToast(_ctx, evt, { self }) {
self.sendChild("PAUSE", evt.id);
},
pauseToasts(ctx2) {
ctx2.toasts.forEach((toast) => toast.send("PAUSE"));
},
resumeToast(_ctx, evt, { self }) {
self.sendChild("RESUME", evt.id);
},
resumeToasts(ctx2) {
ctx2.toasts.forEach((toast) => toast.send("RESUME"));
},
measureToasts(ctx2) {
ctx2.toasts.forEach((toast) => toast.send("MEASURE"));
},
createToast(ctx2, evt, { self, getState }) {
const options = {
placement: ctx2.placement,
duration: ctx2.duration,
removeDelay: ctx2.removeDelay,
...evt.toast,
dir: ctx2.dir,
getRootNode: ctx2.getRootNode,
stacked: getState().matches("stack")
};
const toast = createToastMachine(options);
const actor = self.spawn(toast);
ctx2.toasts = [actor, ...ctx2.toasts];
},
updateToast(_ctx, evt, { self }) {
self.sendChild({ type: "UPDATE", toast: evt.toast }, evt.id);
},
dismissToast(_ctx, evt, { self }) {
self.sendChild("DISMISS", evt.id);
},
dismissToasts(ctx2) {
ctx2.toasts.forEach((toast) => toast.send("DISMISS"));
},
removeToast(ctx2, evt, { self }) {
self.stopChild(evt.id);
ctx2.toasts = ctx2.toasts.filter((toast) => toast.id !== evt.id);
ctx2.heights = ctx2.heights.filter((height) => height.id !== evt.id);
},
removeToasts(ctx2, _evt, { self }) {
ctx2.toasts.forEach((toast) => self.stopChild(toast.id));
ctx2.toasts = [];
ctx2.heights = [];
},
syncHeights(ctx2, evt) {
const existing = ctx2.heights.find((height) => height.id === evt.id);
if (existing) {
existing.height = evt.height;
existing.placement = evt.placement;
} else {
const newHeight = { id: evt.id, height: evt.height, placement: evt.placement };
ctx2.heights = [newHeight, ...ctx2.heights];
}
},
syncToastIndex(ctx2) {
each(ctx2, (toast, index, toasts) => {
toast.state.context.index = index;
toast.state.context.frontmost = index === 0;
toast.state.context.zIndex = toasts.length - index;
});
},
syncToastOffset(ctx2, evt) {
const placement = evt.placement ?? ctx2.placement;
each({ ...ctx2, placement }, (toast) => {
const heightIndex = Math.max(
ctx2.heights.findIndex((height) => height.id === toast.id),
0
);
const toastsHeightBefore = ctx2.heights.reduce((prev, curr, reducerIndex) => {
if (reducerIndex >= heightIndex) return prev;
return prev + curr.height;
}, 0);
toast.state.context.offset = heightIndex * ctx2.gap + toastsHeightBefore;
});
},
setLastFocusedEl(ctx2, evt) {
if (ctx2.isFocusWithin || !evt.target) return;
ctx2.isFocusWithin = true;
ctx2.lastFocusedEl = core.ref(evt.target);
},
restoreLastFocusedEl(ctx2) {
ctx2.isFocusWithin = false;
if (!ctx2.lastFocusedEl) return;
ctx2.lastFocusedEl.focus({ preventScroll: true });
ctx2.lastFocusedEl = null;
},
clearLastFocusedEl(ctx2) {
if (!ctx2.lastFocusedEl) return;
ctx2.lastFocusedEl.focus({ preventScroll: true });
ctx2.lastFocusedEl = null;
ctx2.isFocusWithin = false;
}
}
}
);
}
function each(ctx, fn) {
const currentToasts = getToastsByPlacement(ctx.toasts, ctx.placement);
currentToasts.forEach(fn);
}
function connect(state, send, normalize) {
const visible = state.hasTag("visible");
const paused = state.hasTag("paused");
const placement = state.context.placement;
const type = state.context.type;
const [side, align = "center"] = placement.split("-");
return {
type,
title: state.context.title,
description: state.context.description,
placement,
visible,
paused,
pause() {
send("PAUSE");
},
resume() {
send("RESUME");
},
dismiss() {
send("DISMISS");
},
getRootProps() {
return normalize.element({
...parts.root.attrs,
dir: state.context.dir,
id: dom.getRootId(state.context),
"data-state": visible ? "open" : "closed",
"data-type": type,
"data-placement": placement,
"data-align": align,
"data-side": side,
"data-mounted": domQuery.dataAttr(state.context.mounted),
"data-paused": domQuery.dataAttr(paused),
"data-first": domQuery.dataAttr(state.context.frontmost),
"data-sibling": domQuery.dataAttr(!state.context.frontmost),
"data-stack": domQuery.dataAttr(state.context.stacked),
"data-overlap": domQuery.dataAttr(!state.context.stacked),
role: "status",
"aria-atomic": "true",
"aria-describedby": state.context.description ? dom.getDescriptionId(state.context) : void 0,
"aria-labelledby": state.context.title ? dom.getTitleId(state.context) : void 0,
tabIndex: 0,
style: getPlacementStyle(state.context, visible),
onKeyDown(event) {
if (event.defaultPrevented) return;
if (event.key == "Escape") {
send("DISMISS");
event.preventDefault();
}
}
});
},
/* Leave a ghost div to avoid setting hover to false when transitioning out */
getGhostBeforeProps() {
return normalize.element({
"data-ghost": "before",
style: getGhostBeforeStyle(state.context, visible)
});
},
/* Needed to avoid setting hover to false when in between toasts */
getGhostAfterProps() {
return normalize.element({
"data-ghost": "after",
style: getGhostAfterStyle()
});
},
getTitleProps() {
return normalize.element({
...parts.title.attrs,
id: dom.getTitleId(state.context)
});
},
getDescriptionProps() {
return normalize.element({
...parts.description.attrs,
id: dom.getDescriptionId(state.context)
});
},
getActionTriggerProps() {
return normalize.button({
...parts.actionTrigger.attrs,
type: "button",
onClick(event) {
if (event.defaultPrevented) return;
state.context.action?.onClick?.();
send("DISMISS");
}
});
},
getCloseTriggerProps() {
return normalize.button({
id: dom.getCloseTriggerId(state.context),
...parts.closeTrigger.attrs,
type: "button",
"aria-label": "Dismiss notification",
onClick(event) {
if (event.defaultPrevented) return;
send("DISMISS");
}
});
}
};
}
// src/index.ts
var group = {
connect: groupConnect,
machine: groupMachine
};
exports.anatomy = anatomy;
exports.connect = connect;
exports.createMachine = createToastMachine;
exports.group = group;
© 2015 - 2025 Weber Informatics LLC | Privacy Policy