@funstack/ui 0.1.0-alpha.1 → 0.1.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion/accordion-context.mjs.map +1 -1
- package/dist/accordion/accordion-item.mjs +18 -4
- package/dist/accordion/accordion-item.mjs.map +1 -1
- package/dist/accordion/accordion-panel.mjs +2 -3
- package/dist/accordion/accordion-panel.mjs.map +1 -1
- package/dist/accordion/accordion-root.d.mts.map +1 -1
- package/dist/accordion/accordion-root.mjs +32 -14
- package/dist/accordion/accordion-root.mjs.map +1 -1
- package/dist/accordion/accordion-trigger.mjs +4 -5
- package/dist/accordion/accordion-trigger.mjs.map +1 -1
- package/dist/checkbox/checkbox.d.mts +5 -3
- package/dist/checkbox/checkbox.d.mts.map +1 -1
- package/dist/checkbox/checkbox.mjs +25 -9
- package/dist/checkbox/checkbox.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-context.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-item.d.mts +2 -1
- package/dist/checkbox-group/checkbox-group-item.d.mts.map +1 -1
- package/dist/checkbox-group/checkbox-group-item.mjs +3 -1
- package/dist/checkbox-group/checkbox-group-item.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-root.d.mts +5 -2
- package/dist/checkbox-group/checkbox-group-root.d.mts.map +1 -1
- package/dist/checkbox-group/checkbox-group-root.mjs +24 -5
- package/dist/checkbox-group/checkbox-group-root.mjs.map +1 -1
- package/dist/combobox/combobox-clear.d.mts +34 -0
- package/dist/combobox/combobox-clear.d.mts.map +1 -0
- package/dist/combobox/combobox-clear.mjs +58 -0
- package/dist/combobox/combobox-clear.mjs.map +1 -0
- package/dist/combobox/combobox-context.mjs +23 -0
- package/dist/combobox/combobox-context.mjs.map +1 -0
- package/dist/combobox/combobox-group.d.mts +72 -0
- package/dist/combobox/combobox-group.d.mts.map +1 -0
- package/dist/combobox/combobox-group.mjs +104 -0
- package/dist/combobox/combobox-group.mjs.map +1 -0
- package/dist/combobox/combobox-input.d.mts +42 -0
- package/dist/combobox/combobox-input.d.mts.map +1 -0
- package/dist/combobox/combobox-input.mjs +102 -0
- package/dist/combobox/combobox-input.mjs.map +1 -0
- package/dist/combobox/combobox-label.d.mts +22 -0
- package/dist/combobox/combobox-label.d.mts.map +1 -0
- package/dist/combobox/combobox-label.mjs +32 -0
- package/dist/combobox/combobox-label.mjs.map +1 -0
- package/dist/combobox/combobox-list.d.mts +37 -0
- package/dist/combobox/combobox-list.d.mts.map +1 -0
- package/dist/combobox/combobox-list.mjs +70 -0
- package/dist/combobox/combobox-list.mjs.map +1 -0
- package/dist/combobox/combobox-option.d.mts +45 -0
- package/dist/combobox/combobox-option.d.mts.map +1 -0
- package/dist/combobox/combobox-option.mjs +88 -0
- package/dist/combobox/combobox-option.mjs.map +1 -0
- package/dist/combobox/combobox-popup.d.mts +49 -0
- package/dist/combobox/combobox-popup.d.mts.map +1 -0
- package/dist/combobox/combobox-popup.mjs +86 -0
- package/dist/combobox/combobox-popup.mjs.map +1 -0
- package/dist/combobox/combobox-root.d.mts +135 -0
- package/dist/combobox/combobox-root.d.mts.map +1 -0
- package/dist/combobox/combobox-root.mjs +523 -0
- package/dist/combobox/combobox-root.mjs.map +1 -0
- package/dist/combobox/combobox-trigger.d.mts +36 -0
- package/dist/combobox/combobox-trigger.d.mts.map +1 -0
- package/dist/combobox/combobox-trigger.mjs +92 -0
- package/dist/combobox/combobox-trigger.mjs.map +1 -0
- package/dist/combobox/index.d.mts +36 -0
- package/dist/combobox/index.d.mts.map +1 -0
- package/dist/combobox/index.mjs +36 -0
- package/dist/combobox/index.mjs.map +1 -0
- package/dist/dialog/dialog-close.d.mts +17 -10
- package/dist/dialog/dialog-close.d.mts.map +1 -1
- package/dist/dialog/dialog-close.mjs +31 -20
- package/dist/dialog/dialog-close.mjs.map +1 -1
- package/dist/dialog/dialog-context.mjs.map +1 -1
- package/dist/dialog/dialog-form.d.mts +12 -5
- package/dist/dialog/dialog-form.d.mts.map +1 -1
- package/dist/dialog/dialog-form.mjs +16 -28
- package/dist/dialog/dialog-form.mjs.map +1 -1
- package/dist/dialog/dialog-popup.d.mts +10 -4
- package/dist/dialog/dialog-popup.d.mts.map +1 -1
- package/dist/dialog/dialog-popup.mjs +106 -41
- package/dist/dialog/dialog-popup.mjs.map +1 -1
- package/dist/dialog/dialog-root.d.mts +14 -8
- package/dist/dialog/dialog-root.d.mts.map +1 -1
- package/dist/dialog/dialog-root.mjs +66 -11
- package/dist/dialog/dialog-root.mjs.map +1 -1
- package/dist/dialog/dialog-trigger.d.mts +3 -2
- package/dist/dialog/dialog-trigger.d.mts.map +1 -1
- package/dist/dialog/dialog-trigger.mjs.map +1 -1
- package/dist/dialog/index.d.mts +4 -2
- package/dist/dialog/index.d.mts.map +1 -1
- package/dist/dialog/index.mjs +4 -2
- package/dist/dialog/index.mjs.map +1 -1
- package/dist/field/field-control.d.mts +33 -0
- package/dist/field/field-control.d.mts.map +1 -0
- package/dist/field/field-control.mjs +68 -0
- package/dist/field/field-control.mjs.map +1 -0
- package/dist/field/field-description.d.mts +24 -0
- package/dist/field/field-description.d.mts.map +1 -0
- package/dist/field/field-description.mjs +34 -0
- package/dist/field/field-description.mjs.map +1 -0
- package/dist/field/field-error.d.mts +30 -0
- package/dist/field/field-error.d.mts.map +1 -0
- package/dist/field/field-error.mjs +42 -0
- package/dist/field/field-error.mjs.map +1 -0
- package/dist/field/field-label.d.mts +25 -0
- package/dist/field/field-label.d.mts.map +1 -0
- package/dist/field/field-label.mjs +46 -0
- package/dist/field/field-label.mjs.map +1 -0
- package/dist/field/field-root.d.mts +53 -0
- package/dist/field/field-root.d.mts.map +1 -0
- package/dist/field/field-root.mjs +317 -0
- package/dist/field/field-root.mjs.map +1 -0
- package/dist/field/index.d.mts +18 -0
- package/dist/field/index.d.mts.map +1 -0
- package/dist/field/index.mjs +17 -0
- package/dist/field/index.mjs.map +1 -0
- package/dist/form/form-root.d.mts +58 -0
- package/dist/form/form-root.d.mts.map +1 -0
- package/dist/form/form-root.mjs +146 -0
- package/dist/form/form-root.mjs.map +1 -0
- package/dist/form/form-submit.d.mts +31 -0
- package/dist/form/form-submit.d.mts.map +1 -0
- package/dist/form/form-submit.mjs +52 -0
- package/dist/form/form-submit.mjs.map +1 -0
- package/dist/form/index.d.mts +11 -0
- package/dist/form/index.d.mts.map +1 -0
- package/dist/form/index.mjs +11 -0
- package/dist/form/index.mjs.map +1 -0
- package/dist/index.d.mts +46 -2
- package/dist/index.mjs +8 -1
- package/dist/internal/content-focus-probe.mjs +42 -0
- package/dist/internal/content-focus-probe.mjs.map +1 -0
- package/dist/internal/field-context.d.mts +19 -0
- package/dist/internal/field-context.d.mts.map +1 -0
- package/dist/internal/field-context.mjs +14 -0
- package/dist/internal/field-context.mjs.map +1 -0
- package/dist/internal/focus-first-invalid.mjs +67 -0
- package/dist/internal/focus-first-invalid.mjs.map +1 -0
- package/dist/internal/form-status-watcher.mjs +31 -0
- package/dist/internal/form-status-watcher.mjs.map +1 -0
- package/dist/internal/modal-registry.mjs +39 -0
- package/dist/internal/modal-registry.mjs.map +1 -0
- package/dist/internal/platform-attributes.d.mts +12 -1
- package/dist/internal/platform-attributes.d.mts.map +1 -1
- package/dist/internal/types.d.mts +11 -1
- package/dist/internal/types.d.mts.map +1 -1
- package/dist/internal/use-controllable-action.mjs +35 -13
- package/dist/internal/use-controllable-action.mjs.map +1 -1
- package/dist/internal/use-field-control.mjs +107 -0
- package/dist/internal/use-field-control.mjs.map +1 -0
- package/dist/internal/use-form-owner-event.mjs +44 -0
- package/dist/internal/use-form-owner-event.mjs.map +1 -0
- package/dist/internal/use-form-reset.mjs +12 -31
- package/dist/internal/use-form-reset.mjs.map +1 -1
- package/dist/internal/use-hydrated-mount.mjs +21 -0
- package/dist/internal/use-hydrated-mount.mjs.map +1 -0
- package/dist/internal/use-latest.mjs +32 -0
- package/dist/internal/use-latest.mjs.map +1 -0
- package/dist/internal/use-modal-registration.mjs +47 -0
- package/dist/internal/use-modal-registration.mjs.map +1 -0
- package/dist/internal/use-native-group-reconciliation.mjs +6 -5
- package/dist/internal/use-native-group-reconciliation.mjs.map +1 -1
- package/dist/internal/use-native-select-value.mjs +184 -0
- package/dist/internal/use-native-select-value.mjs.map +1 -0
- package/dist/internal/use-popover-popup.mjs +8 -22
- package/dist/internal/use-popover-popup.mjs.map +1 -1
- package/dist/internal/use-popover-root.mjs +58 -23
- package/dist/internal/use-popover-root.mjs.map +1 -1
- package/dist/internal/validity.d.mts +24 -0
- package/dist/internal/validity.d.mts.map +1 -0
- package/dist/internal/validity.mjs +108 -0
- package/dist/internal/validity.mjs.map +1 -0
- package/dist/menu/menu-group.d.mts.map +1 -1
- package/dist/menu/menu-group.mjs +3 -2
- package/dist/menu/menu-group.mjs.map +1 -1
- package/dist/menu/menu-radio-group.mjs +9 -4
- package/dist/menu/menu-radio-group.mjs.map +1 -1
- package/dist/menu/menu-root.mjs.map +1 -1
- package/dist/radio-group/radio-group-root.d.mts +4 -2
- package/dist/radio-group/radio-group-root.d.mts.map +1 -1
- package/dist/radio-group/radio-group-root.mjs +34 -8
- package/dist/radio-group/radio-group-root.mjs.map +1 -1
- package/dist/select/index.d.mts +30 -0
- package/dist/select/index.d.mts.map +1 -0
- package/dist/select/index.mjs +30 -0
- package/dist/select/index.mjs.map +1 -0
- package/dist/select/select-context.mjs +13 -0
- package/dist/select/select-context.mjs.map +1 -0
- package/dist/select/select-dom.mjs +44 -0
- package/dist/select/select-dom.mjs.map +1 -0
- package/dist/select/select-group-label.d.mts +22 -0
- package/dist/select/select-group-label.d.mts.map +1 -0
- package/dist/select/select-group-label.mjs +39 -0
- package/dist/select/select-group-label.mjs.map +1 -0
- package/dist/select/select-group.d.mts +28 -0
- package/dist/select/select-group.d.mts.map +1 -0
- package/dist/select/select-group.mjs +47 -0
- package/dist/select/select-group.mjs.map +1 -0
- package/dist/select/select-option.d.mts +42 -0
- package/dist/select/select-option.d.mts.map +1 -0
- package/dist/select/select-option.mjs +65 -0
- package/dist/select/select-option.mjs.map +1 -0
- package/dist/select/select-root.d.mts +68 -0
- package/dist/select/select-root.d.mts.map +1 -0
- package/dist/select/select-root.mjs +114 -0
- package/dist/select/select-root.mjs.map +1 -0
- package/dist/select/select-separator.d.mts +20 -0
- package/dist/select/select-separator.d.mts.map +1 -0
- package/dist/select/select-separator.mjs +30 -0
- package/dist/select/select-separator.mjs.map +1 -0
- package/dist/select/select-trigger.d.mts +29 -0
- package/dist/select/select-trigger.d.mts.map +1 -0
- package/dist/select/select-trigger.mjs +48 -0
- package/dist/select/select-trigger.mjs.map +1 -0
- package/dist/select/select-value.d.mts +31 -0
- package/dist/select/select-value.d.mts.map +1 -0
- package/dist/select/select-value.mjs +101 -0
- package/dist/select/select-value.mjs.map +1 -0
- package/dist/slider/index.d.mts +32 -0
- package/dist/slider/index.d.mts.map +1 -0
- package/dist/slider/index.mjs +27 -0
- package/dist/slider/index.mjs.map +1 -0
- package/dist/slider/slider-arithmetic.mjs +120 -0
- package/dist/slider/slider-arithmetic.mjs.map +1 -0
- package/dist/slider/slider-context.mjs +13 -0
- package/dist/slider/slider-context.mjs.map +1 -0
- package/dist/slider/slider-indicator.d.mts +22 -0
- package/dist/slider/slider-indicator.d.mts.map +1 -0
- package/dist/slider/slider-indicator.mjs +36 -0
- package/dist/slider/slider-indicator.mjs.map +1 -0
- package/dist/slider/slider-label.d.mts +23 -0
- package/dist/slider/slider-label.d.mts.map +1 -0
- package/dist/slider/slider-label.mjs +44 -0
- package/dist/slider/slider-label.mjs.map +1 -0
- package/dist/slider/slider-root.d.mts +111 -0
- package/dist/slider/slider-root.d.mts.map +1 -0
- package/dist/slider/slider-root.mjs +582 -0
- package/dist/slider/slider-root.mjs.map +1 -0
- package/dist/slider/slider-thumb.d.mts +58 -0
- package/dist/slider/slider-thumb.d.mts.map +1 -0
- package/dist/slider/slider-thumb.mjs +145 -0
- package/dist/slider/slider-thumb.mjs.map +1 -0
- package/dist/slider/slider-track.d.mts +29 -0
- package/dist/slider/slider-track.d.mts.map +1 -0
- package/dist/slider/slider-track.mjs +54 -0
- package/dist/slider/slider-track.mjs.map +1 -0
- package/dist/slider/slider-value.d.mts +34 -0
- package/dist/slider/slider-value.d.mts.map +1 -0
- package/dist/slider/slider-value.mjs +38 -0
- package/dist/slider/slider-value.mjs.map +1 -0
- package/dist/switch/switch.d.mts +5 -3
- package/dist/switch/switch.d.mts.map +1 -1
- package/dist/switch/switch.mjs +24 -8
- package/dist/switch/switch.mjs.map +1 -1
- package/dist/tabs/tabs-root.mjs +13 -3
- package/dist/tabs/tabs-root.mjs.map +1 -1
- package/dist/toast/index.d.mts +25 -0
- package/dist/toast/index.d.mts.map +1 -0
- package/dist/toast/index.mjs +26 -0
- package/dist/toast/index.mjs.map +1 -0
- package/dist/toast/toast-action.d.mts +39 -0
- package/dist/toast/toast-action.d.mts.map +1 -0
- package/dist/toast/toast-action.mjs +64 -0
- package/dist/toast/toast-action.mjs.map +1 -0
- package/dist/toast/toast-close.d.mts +25 -0
- package/dist/toast/toast-close.d.mts.map +1 -0
- package/dist/toast/toast-close.mjs +46 -0
- package/dist/toast/toast-close.mjs.map +1 -0
- package/dist/toast/toast-context.mjs +19 -0
- package/dist/toast/toast-context.mjs.map +1 -0
- package/dist/toast/toast-description.d.mts +24 -0
- package/dist/toast/toast-description.d.mts.map +1 -0
- package/dist/toast/toast-description.mjs +35 -0
- package/dist/toast/toast-description.mjs.map +1 -0
- package/dist/toast/toast-root.d.mts +43 -0
- package/dist/toast/toast-root.d.mts.map +1 -0
- package/dist/toast/toast-root.mjs +204 -0
- package/dist/toast/toast-root.mjs.map +1 -0
- package/dist/toast/toast-title.d.mts +24 -0
- package/dist/toast/toast-title.d.mts.map +1 -0
- package/dist/toast/toast-title.mjs +33 -0
- package/dist/toast/toast-title.mjs.map +1 -0
- package/dist/toast/toast-viewport.d.mts +52 -0
- package/dist/toast/toast-viewport.d.mts.map +1 -0
- package/dist/toast/toast-viewport.mjs +621 -0
- package/dist/toast/toast-viewport.mjs.map +1 -0
- package/dist/toast/toast.d.mts +119 -0
- package/dist/toast/toast.d.mts.map +1 -0
- package/dist/toast/toast.mjs +153 -0
- package/dist/toast/toast.mjs.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { ToastItem, ToastPriority } from "./toast.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/toast/toast-root.d.ts
|
|
5
|
+
export interface ToastRootState {
|
|
6
|
+
readonly toast: ToastItem;
|
|
7
|
+
/** `toast.pending`: its promise is unsettled or its Action runs. */
|
|
8
|
+
readonly pending: boolean;
|
|
9
|
+
/** `toast.ending`: closed, kept for its exit animation. */
|
|
10
|
+
readonly ending: boolean;
|
|
11
|
+
readonly type: string | undefined;
|
|
12
|
+
readonly priority: ToastPriority;
|
|
13
|
+
}
|
|
14
|
+
export interface ToastRootProps extends Omit<ComponentPropsWithRef<"div">, "role" | "className" | "style" | "children" | "onKeyDown"> {
|
|
15
|
+
/** The toast to render: an item of the Viewport's `state.toasts`. */
|
|
16
|
+
toast: ToastItem;
|
|
17
|
+
children?: StateValue<ReactNode, ToastRootState>;
|
|
18
|
+
className?: StateValue<string | undefined, ToastRootState>;
|
|
19
|
+
style?: StateValue<CSSProperties | undefined, ToastRootState>;
|
|
20
|
+
render?: RenderProp<ComponentPropsWithRef<"div">, ToastRootState>;
|
|
21
|
+
/**
|
|
22
|
+
* Rendered by the Root's own Suspense guard while `children` suspend, in place of the
|
|
23
|
+
* invisible default. The toast's timer and announcement wait for the reveal either way.
|
|
24
|
+
* Parts inside it (a visually hidden `<Toast.Title>` giving the toast a name) gate nothing.
|
|
25
|
+
*/
|
|
26
|
+
fallback?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One toast: a focusable `div[role=dialog]` (`alertdialog` for `priority: "high"`) named by its
|
|
30
|
+
* Title and described by its Description. Escape dismisses it, ArrowDown / ArrowUp move to the
|
|
31
|
+
* next / previous toast. Its children render inside a Suspense guard whose fallback is the
|
|
32
|
+
* `fallback` prop (invisible by default), so a toast whose content suspends does not pull the whole Viewport into a boundary above it.
|
|
33
|
+
* When the toast closes it stays with `data-ending` (and `inert`) until its exit animations end.
|
|
34
|
+
*
|
|
35
|
+
* Owned keys (conventions 1.2): `role`, `tabIndex`, `aria-labelledby`, `aria-describedby`,
|
|
36
|
+
* `inert`, `data-type`, `data-pending`, `data-ending`, `onKeyDown`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function ToastRoot({ toast: item, children, className, style, render, fallback, ...rest }: ToastRootProps): import("react").JSX.Element;
|
|
39
|
+
export declare namespace ToastRoot {
|
|
40
|
+
var displayName: string;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//# sourceMappingURL=toast-root.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-root.d.mts","names":[],"sources":["../../src/toast/toast-root.tsx"],"mappings":";;;;iBAaiB;WACN,OAAO;;WAEP;;WAEA;WACA;WACA,UAAU;;iBAGJ,uBAAuB,KACtC;;EAIA,OAAO;EACP,WAAW,WAAW,WAAW;EACjC,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,SAAS,WAAW,8BAA8B;;;;;;EAMlD,WAAW;;;;;;;;;;;;wBA2BG,YACd,OAAO,MACP,UACA,WACA,OACA,QACA,aACG,QACF,iCAAc,IAAA;yBARD"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { dataAttr } from "../internal/data-attr.mjs";
|
|
3
|
+
import { useLatest } from "../internal/use-latest.mjs";
|
|
4
|
+
import { resolveStateValue, useRender } from "../internal/use-render.mjs";
|
|
5
|
+
import { exitAnimations } from "../internal/use-exit-animation.mjs";
|
|
6
|
+
import { ToastRootContext, useToastRootContext, useToastViewportContext } from "./toast-context.mjs";
|
|
7
|
+
import { Suspense, useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
//#region src/toast/toast-root.tsx
|
|
10
|
+
/**
|
|
11
|
+
* The Suspense guard's fallback: renders the Root's `fallback` (nothing by default) and tells
|
|
12
|
+
* the Root its content is suspended, so the timer and the announcement wait for the reveal
|
|
13
|
+
* (design 3.5, 21).
|
|
14
|
+
*/
|
|
15
|
+
function SuspenseGuard({ children }) {
|
|
16
|
+
const { setSuspended } = useToastRootContext("Toast.Root");
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
setSuspended(true);
|
|
19
|
+
return () => setSuspended(false);
|
|
20
|
+
}, [setSuspended]);
|
|
21
|
+
return children;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* One toast: a focusable `div[role=dialog]` (`alertdialog` for `priority: "high"`) named by its
|
|
25
|
+
* Title and described by its Description. Escape dismisses it, ArrowDown / ArrowUp move to the
|
|
26
|
+
* next / previous toast. Its children render inside a Suspense guard whose fallback is the
|
|
27
|
+
* `fallback` prop (invisible by default), so a toast whose content suspends does not pull the whole Viewport into a boundary above it.
|
|
28
|
+
* When the toast closes it stays with `data-ending` (and `inert`) until its exit animations end.
|
|
29
|
+
*
|
|
30
|
+
* Owned keys (conventions 1.2): `role`, `tabIndex`, `aria-labelledby`, `aria-describedby`,
|
|
31
|
+
* `inert`, `data-type`, `data-pending`, `data-ending`, `onKeyDown`.
|
|
32
|
+
*/
|
|
33
|
+
function ToastRoot({ toast: item, children, className, style, render, fallback = null, ...rest }) {
|
|
34
|
+
const viewport = useToastViewportContext("Toast.Root");
|
|
35
|
+
const id = item.id;
|
|
36
|
+
const baseId = useId();
|
|
37
|
+
const ids = useMemo(() => ({
|
|
38
|
+
title: `${baseId}title`,
|
|
39
|
+
description: `${baseId}description`
|
|
40
|
+
}), [baseId]);
|
|
41
|
+
const elementRef = useRef(null);
|
|
42
|
+
const titleRef = useRef(null);
|
|
43
|
+
const descriptionRef = useRef(null);
|
|
44
|
+
const pendingTokens = useRef(/* @__PURE__ */ new Set());
|
|
45
|
+
const [actionPending, setActionPendingState] = useState(false);
|
|
46
|
+
const suspendedRef = useRef(false);
|
|
47
|
+
const [suspended, setSuspendedState] = useState(false);
|
|
48
|
+
const idRef = useLatest(id);
|
|
49
|
+
const announcedOnce = useRef(false);
|
|
50
|
+
const revealQueued = useRef(false);
|
|
51
|
+
const setActionPending = useCallback((token, pending) => {
|
|
52
|
+
const tokens = pendingTokens.current;
|
|
53
|
+
if (pending) tokens.add(token);
|
|
54
|
+
else tokens.delete(token);
|
|
55
|
+
const any = tokens.size > 0;
|
|
56
|
+
setActionPendingState(any);
|
|
57
|
+
viewport.setActionPending(idRef.current, any);
|
|
58
|
+
}, [viewport, idRef]);
|
|
59
|
+
const setSuspended = useCallback((value) => {
|
|
60
|
+
suspendedRef.current = value;
|
|
61
|
+
setSuspendedState(value);
|
|
62
|
+
viewport.setSuspended(idRef.current, value);
|
|
63
|
+
}, [viewport, idRef]);
|
|
64
|
+
const close = useCallback((reason, event) => viewport.close([idRef.current], reason, event), [viewport, idRef]);
|
|
65
|
+
const registerTitle = useCallback((element) => {
|
|
66
|
+
titleRef.current = element;
|
|
67
|
+
}, []);
|
|
68
|
+
const registerDescription = useCallback((element) => {
|
|
69
|
+
descriptionRef.current = element;
|
|
70
|
+
}, []);
|
|
71
|
+
const pending = item.pending || actionPending;
|
|
72
|
+
const priority = item.priority ?? "normal";
|
|
73
|
+
const announceNow = () => {
|
|
74
|
+
if (item.ending || suspendedRef.current) return;
|
|
75
|
+
const resolver = item.announce ?? viewport.announcer();
|
|
76
|
+
let text;
|
|
77
|
+
if (resolver !== void 0) text = resolver(item);
|
|
78
|
+
else text = [titleRef.current?.textContent, descriptionRef.current?.textContent].map((t) => (t ?? "").trim()).filter((t) => t !== "").join(" ");
|
|
79
|
+
viewport.announce(item.id, text, priority);
|
|
80
|
+
};
|
|
81
|
+
const announceRef = useLatest(announceNow);
|
|
82
|
+
const contentCommitted = useCallback(() => {
|
|
83
|
+
if (!announcedOnce.current || revealQueued.current) return;
|
|
84
|
+
revealQueued.current = true;
|
|
85
|
+
queueMicrotask(() => {
|
|
86
|
+
revealQueued.current = false;
|
|
87
|
+
announceRef.current();
|
|
88
|
+
});
|
|
89
|
+
}, [announceRef]);
|
|
90
|
+
const state = useMemo(() => ({
|
|
91
|
+
toast: item,
|
|
92
|
+
pending,
|
|
93
|
+
ending: item.ending,
|
|
94
|
+
type: item.type,
|
|
95
|
+
priority
|
|
96
|
+
}), [
|
|
97
|
+
item,
|
|
98
|
+
pending,
|
|
99
|
+
priority
|
|
100
|
+
]);
|
|
101
|
+
const context = useMemo(() => ({
|
|
102
|
+
toast: item,
|
|
103
|
+
ids,
|
|
104
|
+
state,
|
|
105
|
+
registerTitle,
|
|
106
|
+
registerDescription,
|
|
107
|
+
contentCommitted,
|
|
108
|
+
setActionPending,
|
|
109
|
+
setSuspended,
|
|
110
|
+
close
|
|
111
|
+
}), [
|
|
112
|
+
item,
|
|
113
|
+
ids,
|
|
114
|
+
state,
|
|
115
|
+
registerTitle,
|
|
116
|
+
registerDescription,
|
|
117
|
+
contentCommitted,
|
|
118
|
+
setActionPending,
|
|
119
|
+
setSuspended,
|
|
120
|
+
close
|
|
121
|
+
]);
|
|
122
|
+
const rootRef = useCallback((element) => {
|
|
123
|
+
elementRef.current = element;
|
|
124
|
+
viewport.registerRoot(id, element);
|
|
125
|
+
return () => {
|
|
126
|
+
if (elementRef.current === element) elementRef.current = null;
|
|
127
|
+
viewport.registerRoot(id, null);
|
|
128
|
+
};
|
|
129
|
+
}, [viewport, id]);
|
|
130
|
+
useLayoutEffect(() => {
|
|
131
|
+
announcedOnce.current = true;
|
|
132
|
+
announceRef.current();
|
|
133
|
+
}, [
|
|
134
|
+
item,
|
|
135
|
+
suspended,
|
|
136
|
+
priority,
|
|
137
|
+
announceRef
|
|
138
|
+
]);
|
|
139
|
+
useLayoutEffect(() => {
|
|
140
|
+
if (!item.ending) return;
|
|
141
|
+
const element = elementRef.current;
|
|
142
|
+
const baseline = viewport.exitBaseline(item.id);
|
|
143
|
+
const animations = element === null ? [] : exitAnimations(element).filter((animation) => !baseline?.has(animation));
|
|
144
|
+
if (animations.length === 0) {
|
|
145
|
+
viewport.drop(item.id);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
let cancelled = false;
|
|
149
|
+
Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {
|
|
150
|
+
if (!cancelled) viewport.drop(item.id);
|
|
151
|
+
});
|
|
152
|
+
return () => {
|
|
153
|
+
cancelled = true;
|
|
154
|
+
};
|
|
155
|
+
}, [
|
|
156
|
+
item.ending,
|
|
157
|
+
item.id,
|
|
158
|
+
viewport
|
|
159
|
+
]);
|
|
160
|
+
const onKeyDown = (event) => {
|
|
161
|
+
if (event.defaultPrevented || item.ending) return;
|
|
162
|
+
if (event.key === "Escape") {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
close("dismiss", event.nativeEvent);
|
|
165
|
+
} else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
166
|
+
event.preventDefault();
|
|
167
|
+
viewport.focusSibling(id, event.key === "ArrowDown" ? 1 : -1);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const libraryProps = {
|
|
171
|
+
role: priority === "high" ? "alertdialog" : "dialog",
|
|
172
|
+
tabIndex: 0,
|
|
173
|
+
"aria-labelledby": ids.title,
|
|
174
|
+
"aria-describedby": ids.description,
|
|
175
|
+
inert: item.ending || void 0,
|
|
176
|
+
"data-type": item.type,
|
|
177
|
+
"data-pending": dataAttr(pending),
|
|
178
|
+
"data-ending": dataAttr(item.ending),
|
|
179
|
+
onKeyDown
|
|
180
|
+
};
|
|
181
|
+
const element = useRender({
|
|
182
|
+
defaultElement: "div",
|
|
183
|
+
render,
|
|
184
|
+
state,
|
|
185
|
+
className,
|
|
186
|
+
style,
|
|
187
|
+
children: (s) => /* @__PURE__ */ jsx(Suspense, {
|
|
188
|
+
fallback: /* @__PURE__ */ jsx(SuspenseGuard, { children: fallback }),
|
|
189
|
+
children: resolveStateValue(children, s)
|
|
190
|
+
}),
|
|
191
|
+
props: rest,
|
|
192
|
+
libraryProps,
|
|
193
|
+
ref: rootRef
|
|
194
|
+
});
|
|
195
|
+
return /* @__PURE__ */ jsx(ToastRootContext, {
|
|
196
|
+
value: context,
|
|
197
|
+
children: element
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
ToastRoot.displayName = "ToastRoot";
|
|
201
|
+
//#endregion
|
|
202
|
+
export { ToastRoot };
|
|
203
|
+
|
|
204
|
+
//# sourceMappingURL=toast-root.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-root.mjs","names":[],"sources":["../../src/toast/toast-root.tsx"],"sourcesContent":["\"use client\";\nimport { Suspense, useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, KeyboardEvent, ReactNode } from \"react\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { exitAnimations } from \"../internal/use-exit-animation.js\";\nimport { useLatest } from \"../internal/use-latest.js\";\nimport { resolveStateValue, useRender } from \"../internal/use-render.js\";\nimport type { DataAttributes } from \"../internal/use-render.js\";\nimport type { ToastItem, ToastPriority } from \"./toast.js\";\nimport { ToastRootContext, useToastRootContext, useToastViewportContext } from \"./toast-context.js\";\nimport type { ToastRootContextValue } from \"./toast-context.js\";\n\nexport interface ToastRootState {\n readonly toast: ToastItem;\n /** `toast.pending`: its promise is unsettled or its Action runs. */\n readonly pending: boolean;\n /** `toast.ending`: closed, kept for its exit animation. */\n readonly ending: boolean;\n readonly type: string | undefined;\n readonly priority: ToastPriority;\n}\n\nexport interface ToastRootProps extends Omit<\n ComponentPropsWithRef<\"div\">,\n \"role\" | \"className\" | \"style\" | \"children\" | \"onKeyDown\"\n> {\n /** The toast to render: an item of the Viewport's `state.toasts`. */\n toast: ToastItem;\n children?: StateValue<ReactNode, ToastRootState>;\n className?: StateValue<string | undefined, ToastRootState>;\n style?: StateValue<CSSProperties | undefined, ToastRootState>;\n render?: RenderProp<ComponentPropsWithRef<\"div\">, ToastRootState>;\n /**\n * Rendered by the Root's own Suspense guard while `children` suspend, in place of the\n * invisible default. The toast's timer and announcement wait for the reveal either way.\n * Parts inside it (a visually hidden `<Toast.Title>` giving the toast a name) gate nothing.\n */\n fallback?: ReactNode;\n}\n\n/**\n * The Suspense guard's fallback: renders the Root's `fallback` (nothing by default) and tells\n * the Root its content is suspended, so the timer and the announcement wait for the reveal\n * (design 3.5, 21).\n */\nfunction SuspenseGuard({ children }: { children: ReactNode }) {\n const { setSuspended } = useToastRootContext(\"Toast.Root\");\n useLayoutEffect(() => {\n setSuspended(true);\n return () => setSuspended(false);\n }, [setSuspended]);\n return children;\n}\n\n/**\n * One toast: a focusable `div[role=dialog]` (`alertdialog` for `priority: \"high\"`) named by its\n * Title and described by its Description. Escape dismisses it, ArrowDown / ArrowUp move to the\n * next / previous toast. Its children render inside a Suspense guard whose fallback is the\n * `fallback` prop (invisible by default), so a toast whose content suspends does not pull the whole Viewport into a boundary above it.\n * When the toast closes it stays with `data-ending` (and `inert`) until its exit animations end.\n *\n * Owned keys (conventions 1.2): `role`, `tabIndex`, `aria-labelledby`, `aria-describedby`,\n * `inert`, `data-type`, `data-pending`, `data-ending`, `onKeyDown`.\n */\nexport function ToastRoot({\n toast: item,\n children,\n className,\n style,\n render,\n fallback = null,\n ...rest\n}: ToastRootProps) {\n const viewport = useToastViewportContext(\"Toast.Root\");\n const id = item.id;\n const baseId = useId();\n const ids = useMemo(\n () => ({ title: `${baseId}title`, description: `${baseId}description` }),\n [baseId],\n );\n const elementRef = useRef<HTMLElement | null>(null);\n const titleRef = useRef<HTMLElement | null>(null);\n const descriptionRef = useRef<HTMLElement | null>(null);\n\n // Action pending, aggregated over the Action parts inside (normally one).\n const pendingTokens = useRef(new Set<object>());\n const [actionPending, setActionPendingState] = useState(false);\n // Suspended content behind the guard: a ref for effects of the same commit, state to re-run\n // the announcement once it reveals.\n const suspendedRef = useRef(false);\n const [suspended, setSuspendedState] = useState(false);\n\n const idRef = useLatest(id);\n // The Root's announcement effect has run once: later Title / Description commits are reveals.\n const announcedOnce = useRef(false);\n const revealQueued = useRef(false);\n\n const setActionPending = useCallback(\n (token: object, pending: boolean) => {\n const tokens = pendingTokens.current;\n if (pending) tokens.add(token);\n else tokens.delete(token);\n const any = tokens.size > 0;\n setActionPendingState(any);\n viewport.setActionPending(idRef.current, any);\n },\n [viewport, idRef],\n );\n\n const setSuspended = useCallback(\n (value: boolean) => {\n suspendedRef.current = value;\n setSuspendedState(value);\n viewport.setSuspended(idRef.current, value);\n },\n [viewport, idRef],\n );\n\n const close = useCallback(\n (reason: Parameters<ToastRootContextValue[\"close\"]>[0], event: Event | undefined) =>\n viewport.close([idRef.current], reason, event),\n [viewport, idRef],\n );\n\n const registerTitle = useCallback((element: HTMLElement | null) => {\n titleRef.current = element;\n }, []);\n const registerDescription = useCallback((element: HTMLElement | null) => {\n descriptionRef.current = element;\n }, []);\n\n const pending = item.pending || actionPending;\n const priority = item.priority ?? \"normal\";\n\n // Announce once the content has committed un-suspended (design 5): the Title and Description\n // text exists now. The Viewport skips text it already announced for this toast and speaks the\n // batch a microtask later.\n const announceNow = (): void => {\n if (item.ending || suspendedRef.current) return;\n const resolver = item.announce ?? viewport.announcer();\n let text: string | null;\n if (resolver !== undefined) text = resolver(item);\n else {\n text = [titleRef.current?.textContent, descriptionRef.current?.textContent]\n .map((t) => (t ?? \"\").trim())\n .filter((t) => t !== \"\")\n .join(\" \");\n }\n viewport.announce(item.id, text, priority);\n };\n const announceRef = useLatest(announceNow);\n\n // A Title or Description inside the consumer's own `<Suspense>` commits after the Root (the\n // boundary's retry does not re-run the Root's effect). Read once the whole reveal committed,\n // so a Title and a Description revealed together are announced as one text.\n const contentCommitted = useCallback(() => {\n if (!announcedOnce.current || revealQueued.current) return;\n revealQueued.current = true;\n queueMicrotask(() => {\n revealQueued.current = false;\n announceRef.current();\n });\n }, [announceRef]);\n const state = useMemo<ToastRootState>(\n () => ({ toast: item, pending, ending: item.ending, type: item.type, priority }),\n [item, pending, priority],\n );\n\n const context = useMemo<ToastRootContextValue>(\n () => ({\n toast: item,\n ids,\n state,\n registerTitle,\n registerDescription,\n contentCommitted,\n setActionPending,\n setSuspended,\n close,\n }),\n [\n item,\n ids,\n state,\n registerTitle,\n registerDescription,\n contentCommitted,\n setActionPending,\n setSuspended,\n close,\n ],\n );\n\n const rootRef = useCallback(\n (element: HTMLElement) => {\n elementRef.current = element;\n viewport.registerRoot(id, element);\n return () => {\n if (elementRef.current === element) elementRef.current = null;\n viewport.registerRoot(id, null);\n };\n },\n [viewport, id],\n );\n\n // A layout effect, so toasts announce in queue order (before the Viewport's own effect\n // announces the queued ones).\n useLayoutEffect(() => {\n announcedOnce.current = true;\n announceRef.current();\n }, [item, suspended, priority, announceRef]);\n\n // Exit (design 10.2): keep the ending toast until the animations the ending state started\n // settle, then drop it. Animations that ran before (a progress bar, paused with the region or\n // not) are not waited for: the Viewport recorded them just before marking the toast ending.\n useLayoutEffect(() => {\n if (!item.ending) return;\n const element = elementRef.current;\n const baseline = viewport.exitBaseline(item.id);\n const animations =\n element === null\n ? []\n : exitAnimations(element).filter((animation) => !baseline?.has(animation));\n if (animations.length === 0) {\n viewport.drop(item.id);\n return;\n }\n let cancelled = false;\n void Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {\n if (!cancelled) viewport.drop(item.id);\n });\n return () => {\n cancelled = true;\n };\n }, [item.ending, item.id, viewport]);\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>): void => {\n if (event.defaultPrevented || item.ending) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n close(\"dismiss\", event.nativeEvent);\n } else if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n viewport.focusSibling(id, event.key === \"ArrowDown\" ? 1 : -1);\n }\n };\n\n const libraryProps: ComponentPropsWithRef<\"div\"> & DataAttributes = {\n role: priority === \"high\" ? \"alertdialog\" : \"dialog\",\n tabIndex: 0,\n \"aria-labelledby\": ids.title,\n \"aria-describedby\": ids.description,\n inert: item.ending || undefined,\n \"data-type\": item.type,\n \"data-pending\": dataAttr(pending),\n \"data-ending\": dataAttr(item.ending),\n onKeyDown,\n };\n\n const element = useRender<ComponentPropsWithRef<\"div\">, ToastRootState>({\n defaultElement: \"div\",\n render,\n state,\n className,\n style,\n children: (s: ToastRootState) => (\n <Suspense fallback={<SuspenseGuard>{fallback}</SuspenseGuard>}>\n {resolveStateValue(children, s)}\n </Suspense>\n ),\n props: rest,\n libraryProps,\n ref: rootRef,\n });\n\n return <ToastRootContext value={context}>{element}</ToastRootContext>;\n}\n\nToastRoot.displayName = \"ToastRoot\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { ToastRootState } from "./toast-root.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/toast/toast-title.d.ts
|
|
5
|
+
export interface ToastTitleProps extends Omit<ComponentPropsWithRef<"div">, "id" | "className" | "style" | "children"> {
|
|
6
|
+
/** Default: the toast's `title`. */
|
|
7
|
+
children?: StateValue<ReactNode, ToastRootState>;
|
|
8
|
+
className?: StateValue<string | undefined, ToastRootState>;
|
|
9
|
+
style?: StateValue<CSSProperties | undefined, ToastRootState>;
|
|
10
|
+
render?: RenderProp<ComponentPropsWithRef<"div">, ToastRootState>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The toast's name: a `div` whose id the Root references with `aria-labelledby`. Not a heading,
|
|
14
|
+
* so transient notifications stay out of heading navigation. Its text is part of the default
|
|
15
|
+
* announcement.
|
|
16
|
+
*
|
|
17
|
+
* Owned key (conventions 1.2): `id`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ToastTitle({ children, className, style, render, ...rest }: ToastTitleProps): ReactNode;
|
|
20
|
+
export declare namespace ToastTitle {
|
|
21
|
+
var displayName: string;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//# sourceMappingURL=toast-title.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-title.d.mts","names":[],"sources":["../../src/toast/toast-title.tsx"],"mappings":";;;;iBAQiB,wBAAwB,KACvC;;EAIA,WAAW,WAAW,WAAW;EACjC,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,SAAS,WAAW,8BAA8B;;;;;;;;;wBAUpC,aAAa,UAAU,WAAW,OAAO,WAAW,QAAQ,kBAAe;yBAA3E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
3
|
+
import { useToastRootContext } from "./toast-context.mjs";
|
|
4
|
+
import { useLayoutEffect } from "react";
|
|
5
|
+
//#region src/toast/toast-title.tsx
|
|
6
|
+
/**
|
|
7
|
+
* The toast's name: a `div` whose id the Root references with `aria-labelledby`. Not a heading,
|
|
8
|
+
* so transient notifications stay out of heading navigation. Its text is part of the default
|
|
9
|
+
* announcement.
|
|
10
|
+
*
|
|
11
|
+
* Owned key (conventions 1.2): `id`.
|
|
12
|
+
*/
|
|
13
|
+
function ToastTitle({ children, className, style, render, ...rest }) {
|
|
14
|
+
const root = useToastRootContext("Toast.Title");
|
|
15
|
+
const { contentCommitted } = root;
|
|
16
|
+
useLayoutEffect(() => contentCommitted(), [contentCommitted]);
|
|
17
|
+
return useRender({
|
|
18
|
+
defaultElement: "div",
|
|
19
|
+
render,
|
|
20
|
+
state: root.state,
|
|
21
|
+
className,
|
|
22
|
+
style,
|
|
23
|
+
children: children ?? root.toast.title,
|
|
24
|
+
props: rest,
|
|
25
|
+
libraryProps: { id: root.ids.title },
|
|
26
|
+
ref: root.registerTitle
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
ToastTitle.displayName = "ToastTitle";
|
|
30
|
+
//#endregion
|
|
31
|
+
export { ToastTitle };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=toast-title.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-title.mjs","names":[],"sources":["../../src/toast/toast-title.tsx"],"sourcesContent":["\"use client\";\nimport { useLayoutEffect } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useToastRootContext } from \"./toast-context.js\";\nimport type { ToastRootState } from \"./toast-root.js\";\n\nexport interface ToastTitleProps extends Omit<\n ComponentPropsWithRef<\"div\">,\n \"id\" | \"className\" | \"style\" | \"children\"\n> {\n /** Default: the toast's `title`. */\n children?: StateValue<ReactNode, ToastRootState>;\n className?: StateValue<string | undefined, ToastRootState>;\n style?: StateValue<CSSProperties | undefined, ToastRootState>;\n render?: RenderProp<ComponentPropsWithRef<\"div\">, ToastRootState>;\n}\n\n/**\n * The toast's name: a `div` whose id the Root references with `aria-labelledby`. Not a heading,\n * so transient notifications stay out of heading navigation. Its text is part of the default\n * announcement.\n *\n * Owned key (conventions 1.2): `id`.\n */\nexport function ToastTitle({ children, className, style, render, ...rest }: ToastTitleProps) {\n const root = useToastRootContext(\"Toast.Title\");\n // Mounted, or revealed by a Suspense boundary inside the Root: announce the text now present.\n const { contentCommitted } = root;\n useLayoutEffect(() => contentCommitted(), [contentCommitted]);\n return useRender<ComponentPropsWithRef<\"div\">, ToastRootState>({\n defaultElement: \"div\",\n render,\n state: root.state,\n className,\n style,\n children: children ?? root.toast.title,\n props: rest,\n libraryProps: { id: root.ids.title },\n ref: root.registerTitle,\n });\n}\n\nToastTitle.displayName = \"ToastTitle\";\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgB,WAAW,EAAE,UAAU,WAAW,OAAO,QAAQ,GAAG,QAAyB;CAC3F,MAAM,OAAO,oBAAoB,aAAa;CAE9C,MAAM,EAAE,qBAAqB;CAC7B,sBAAsB,iBAAiB,GAAG,CAAC,gBAAgB,CAAC;CAC5D,OAAO,UAAwD;EAC7D,gBAAgB;EAChB;EACA,OAAO,KAAK;EACZ;EACA;EACA,UAAU,YAAY,KAAK,MAAM;EACjC,OAAO;EACP,cAAc,EAAE,IAAI,KAAK,IAAI,MAAM;EACnC,KAAK,KAAK;CACZ,CAAC;AACH;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { ToastItem, ToastManager } from "./toast.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/toast/toast-viewport.d.ts
|
|
5
|
+
export interface ToastViewportState {
|
|
6
|
+
/** Rendered toasts, chronological (oldest first), exiting ones included. */
|
|
7
|
+
readonly toasts: readonly ToastItem[];
|
|
8
|
+
/** Toasts waiting beyond `limit`. */
|
|
9
|
+
readonly queued: number;
|
|
10
|
+
/** A viewport-wide pause holds (pointer over the region, focus inside, hidden document, blurred window). */
|
|
11
|
+
readonly paused: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ToastViewportProps extends Omit<ComponentPropsWithRef<"section">, "popover" | "className" | "style" | "children" | "onPointerEnter" | "onPointerLeave" | "onFocus" | "onBlur" | "onKeyDown"> {
|
|
14
|
+
/** The queue to render. Default: the module-level `toast`. */
|
|
15
|
+
manager?: ToastManager;
|
|
16
|
+
/** Toasts rendered at once; further ones wait in order (never dropped). Default `3`. */
|
|
17
|
+
limit?: number;
|
|
18
|
+
/** Default `duration` of a toast in milliseconds; `null` for persistent. Default `5000`. */
|
|
19
|
+
duration?: number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Keys that focus the newest toast: `event.code` values and modifier names (`"altKey"`,
|
|
22
|
+
* `"ctrlKey"`, `"metaKey"`, `"shiftKey"`), all of which must match, with no other modifier
|
|
23
|
+
* held. Default `["F8"]`; `null` installs no listener.
|
|
24
|
+
*/
|
|
25
|
+
hotkey?: readonly string[] | null;
|
|
26
|
+
/**
|
|
27
|
+
* The text `document.ariaNotify()` speaks for a toast (localisation); `null` announces nothing.
|
|
28
|
+
* A toast's own `announce` wins. Default: the text of its Title and Description.
|
|
29
|
+
*/
|
|
30
|
+
announce?: (toast: ToastItem) => string | null;
|
|
31
|
+
/** Usually a function of the state mapping `state.toasts` to `Toast.Root`s. */
|
|
32
|
+
children?: StateValue<ReactNode, ToastViewportState>;
|
|
33
|
+
className?: StateValue<string | undefined, ToastViewportState>;
|
|
34
|
+
style?: StateValue<CSSProperties | undefined, ToastViewportState>;
|
|
35
|
+
/** Must render an element that can carry `popover` (a `<section>` by default). */
|
|
36
|
+
render?: RenderProp<ComponentPropsWithRef<"section">, ToastViewportState>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The toast region: a `<section popover="manual">` named "Notifications (F8)", shown in the top
|
|
40
|
+
* layer while it has toasts. Owns the queue (urgent state fed by `toast()`), the timers and their
|
|
41
|
+
* pausing, the hotkey, focus return, announcements through `document.ariaNotify()`, and the move
|
|
42
|
+
* into the topmost open modal `Dialog` (a region outside it would be inert).
|
|
43
|
+
*
|
|
44
|
+
* Owned keys (conventions 1.2): `popover`, `aria-label` (the consumer's own `aria-label` wins
|
|
45
|
+
* verbatim), `data-paused`, `data-empty`, and the pointer / focus handlers.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ToastViewport({ manager, limit, duration, hotkey, announce, children, className, style, render, ...rest }: ToastViewportProps): import("react").JSX.Element | null;
|
|
48
|
+
export declare namespace ToastViewport {
|
|
49
|
+
var displayName: string;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//# sourceMappingURL=toast-viewport.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-viewport.d.mts","names":[],"sources":["../../src/toast/toast-viewport.tsx"],"mappings":";;;;iBAwCiB;;WAEN,iBAAiB;;WAEjB;;WAEA;;iBAGM,2BAA2B,KAC1C;;EAYA,UAAU;;EAEV;;EAEA;;;;;;EAMA;;;;;EAKA,YAAY,OAAO;;EAEnB,WAAW,WAAW,WAAW;EACjC,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,kCAAkC;;;;;;;;;;;wBA0JxC,gBACd,SACA,OACA,UACA,QACA,UACA,UACA,WACA,OACA,WACG,QACF,qCAAkB,IAAA;yBAXL"}
|