import type { JSX, ValidComponent } from "@solidjs/web"; import { dynamic } from "@solidjs/web"; import { createSignal, omit } from "solid-js"; import { mergeRootProps } from "../../internals/merge-root-props"; import { resolveClassStyle } from "../../internals/resolve-class-style"; import type { BaseUIComponentProps } from "../../internals/types"; import { useIsoLayoutEffect } from "../../internals/use-iso-layout-effect"; import { useToastRootContext } from "../root/toast-root-context"; export interface ToastContentState { expanded: boolean; behind: boolean; } export interface ToastContentProps extends BaseUIComponentProps<"div", ToastContentState> { as?: ValidComponent; } /** * Container for toast contents. Observes size changes and triggers root * height re-measurement. */ export function ToastContent(props: ToastContentProps): JSX.Element { const ctx = useToastRootContext(); const [contentEl, setContentEl] = createSignal(null, { ownedWrite: true, }); useIsoLayoutEffect( () => contentEl(), (node) => { if (!node) return undefined; ctx.recalculateHeight(); if ( typeof ResizeObserver !== "function" || typeof MutationObserver !== "function" ) { return undefined; } const resizeObserver = new ResizeObserver(() => { ctx.recalculateHeight(); }); const mutationObserver = new MutationObserver(() => { ctx.recalculateHeight(); }); resizeObserver.observe(node); mutationObserver.observe(node, { childList: true, subtree: true, characterData: true, }); return () => { resizeObserver.disconnect(); mutationObserver.disconnect(); }; }, ); const userClassStyle = resolveClassStyle(props, () => ({ expanded: ctx.expanded(), behind: ctx.visibleIndex() > 0, })); const userHtmlProps = omit( props, "as", "class", "style", "attrs", "children", ) as Record; const internalProps = { ref: setContentEl, get "data-expanded"(): "" | undefined { return ctx.expanded() ? "" : undefined; }, get "data-behind"(): "" | undefined { return ctx.visibleIndex() > 0 ? "" : undefined; }, }; const merged = mergeRootProps( mergeRootProps(internalProps, userClassStyle), userHtmlProps, ); const Tag = dynamic(() => props.as ?? "div"); return {props.children}; }