UNPKG

@zag-js/toast

Version:

Core logic for the toast widget implemented as a state machine

66 lines (65 loc) 2.26 kB
// src/toast-group.connect.ts import { contains } from "@zag-js/dom-query"; import { parts } from "./toast.anatomy.mjs"; import * as dom from "./toast.dom.mjs"; import { getGroupPlacementStyle } from "./toast.utils.mjs"; function groupConnect(service, normalize) { const { context, prop, send, refs, computed } = service; return { getCount() { return context.get("toasts").length; }, getToasts() { return context.get("toasts"); }, getGroupProps(options = {}) { const { label = "Notifications" } = options; const { hotkey } = prop("store").attrs; const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, ""); const placement = computed("placement"); const [side, align = "center"] = placement.split("-"); return normalize.element({ ...parts.group.attrs, dir: prop("dir"), tabIndex: -1, role: "region", "aria-label": `${label}, ${placement} (${hotkeyLabel})`, id: dom.getRegionId(placement), "data-placement": placement, "data-side": side, "data-align": align, "aria-live": "polite", "aria-relevant": "additions text", "aria-atomic": "false", style: getGroupPlacementStyle(service, placement), onMouseEnter() { if (refs.get("ignoreMouseTimer").isActive()) return; send({ type: "REGION.POINTER_ENTER", placement }); }, onMouseMove() { if (refs.get("ignoreMouseTimer").isActive()) return; send({ type: "REGION.POINTER_ENTER", placement }); }, onMouseLeave() { if (refs.get("ignoreMouseTimer").isActive()) return; send({ type: "REGION.POINTER_LEAVE", placement }); }, onFocus(event) { send({ type: "REGION.FOCUS", target: event.relatedTarget }); }, onBlur(event) { if (refs.get("isFocusWithin") && !contains(event.currentTarget, event.relatedTarget)) { queueMicrotask(() => send({ type: "REGION.BLUR" })); } } }); }, subscribe(fn) { const store = prop("store"); return store.subscribe(() => fn(context.get("toasts"))); } }; } export { groupConnect };