import { type Accessor, createContext, useContext } from "solid-js"; import type { TransitionStatus } from "../../internals/use-transition-status/use-transition-status"; import type { ToastObject } from "../use-toast-manager"; /** * State exposed by `` via `data-*` projection. `transitionStatus` * maps to `data-starting-style` / `data-ending-style` exactly like the * collapsible port. */ export interface ToastRootState { transitionStatus: TransitionStatus; /** Whether any toast in the viewport is being hovered or focused. */ expanded: boolean; /** Whether the toast was pushed out by the provider's `limit`. */ limited: boolean; /** The toast's `type` slot, forwarded from the toast object. */ type: string | undefined; /** * Placeholder slot — kept for parity with React's state shape so * consumers can style swipe states via `data-swiping` even though the * tier-3b Solid port doesn't emit it from internal gesture tracking. */ swiping: boolean; /** See {@link ToastRootState.swiping}. */ swipeDirection: "up" | "down" | "left" | "right" | undefined; } /** * Context consumed by compound parts (Title, Description, Action, Close) * to read the current toast + its identifiers. Every reactive slot is an * accessor so descendants stay subscribed without a top-level reactive * read. */ export interface ToastRootContextValue { toast: Accessor>; titleId: Accessor; setTitleId: (next: string | undefined) => void; descriptionId: Accessor; setDescriptionId: (next: string | undefined) => void; expanded: Accessor; /** Visible stack index (`0` = frontmost). `-1` while exiting. */ visibleIndex: Accessor; /** Re-measure the root and update stack `height` in the store. */ recalculateHeight: () => void; } export const ToastRootContext = createContext< ToastRootContextValue | undefined >(undefined); export function useToastRootContext(): ToastRootContextValue { const ctx = useContext(ToastRootContext); if (!ctx) { throw new Error( "Base UI: ToastRootContext is missing. Toast parts must be used within .", ); } return ctx; }