@cdx-ui/components 0.0.1-beta.79 → 0.0.1-beta.80
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/lib/commonjs/animation/hooks/index.js +17 -0
- package/lib/commonjs/animation/hooks/index.js.map +1 -0
- package/lib/commonjs/animation/hooks/useCombinedAnimationDisabledState.js +50 -0
- package/lib/commonjs/animation/hooks/useCombinedAnimationDisabledState.js.map +1 -0
- package/lib/commonjs/animation/index.js +39 -0
- package/lib/commonjs/animation/index.js.map +1 -0
- package/lib/commonjs/animation/types.js +6 -0
- package/lib/commonjs/animation/types.js.map +1 -0
- package/lib/commonjs/animation/utils.js +223 -0
- package/lib/commonjs/animation/utils.js.map +1 -0
- package/lib/commonjs/components/CLAUDE.md +1 -1
- package/lib/commonjs/components/Card/index.js +45 -17
- package/lib/commonjs/components/Card/index.js.map +1 -1
- package/lib/commonjs/components/Toast/animation.js +329 -0
- package/lib/commonjs/components/Toast/animation.js.map +1 -0
- package/lib/commonjs/components/Toast/hooks.js +66 -0
- package/lib/commonjs/components/Toast/hooks.js.map +1 -0
- package/lib/commonjs/components/Toast/index.js +493 -0
- package/lib/commonjs/components/Toast/index.js.map +1 -0
- package/lib/commonjs/components/Toast/styles.js +141 -0
- package/lib/commonjs/components/Toast/styles.js.map +1 -0
- package/lib/commonjs/components/Toast/types.js +6 -0
- package/lib/commonjs/components/Toast/types.js.map +1 -0
- package/lib/commonjs/components/index.js +12 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/index.js +15 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/providers/animation-settings/index.js +31 -0
- package/lib/commonjs/providers/animation-settings/index.js.map +1 -0
- package/lib/commonjs/providers/animation-settings/provider.js +59 -0
- package/lib/commonjs/providers/animation-settings/provider.js.map +1 -0
- package/lib/commonjs/providers/animation-settings/types.js +6 -0
- package/lib/commonjs/providers/animation-settings/types.js.map +1 -0
- package/lib/commonjs/providers/forge-design/index.js +29 -0
- package/lib/commonjs/providers/forge-design/index.js.map +1 -0
- package/lib/commonjs/providers/forge-design/provider.js +71 -0
- package/lib/commonjs/providers/forge-design/provider.js.map +1 -0
- package/lib/commonjs/providers/forge-design/types.js +6 -0
- package/lib/commonjs/providers/forge-design/types.js.map +1 -0
- package/lib/commonjs/providers/text-component/index.js +28 -0
- package/lib/commonjs/providers/text-component/index.js.map +1 -0
- package/lib/commonjs/providers/text-component/provider.js +11 -0
- package/lib/commonjs/providers/text-component/provider.js.map +1 -0
- package/lib/commonjs/providers/text-component/types.js +6 -0
- package/lib/commonjs/providers/text-component/types.js.map +1 -0
- package/lib/commonjs/providers/toast/index.js +33 -0
- package/lib/commonjs/providers/toast/index.js.map +1 -0
- package/lib/commonjs/providers/toast/insets-container.js +160 -0
- package/lib/commonjs/providers/toast/insets-container.js.map +1 -0
- package/lib/commonjs/providers/toast/lifecycle.context.js +36 -0
- package/lib/commonjs/providers/toast/lifecycle.context.js.map +1 -0
- package/lib/commonjs/providers/toast/provider.js +508 -0
- package/lib/commonjs/providers/toast/provider.js.map +1 -0
- package/lib/commonjs/providers/toast/reducer.js +46 -0
- package/lib/commonjs/providers/toast/reducer.js.map +1 -0
- package/lib/commonjs/providers/toast/toast-config.context.js +29 -0
- package/lib/commonjs/providers/toast/toast-config.context.js.map +1 -0
- package/lib/commonjs/providers/toast/toast-item-renderer.js +43 -0
- package/lib/commonjs/providers/toast/toast-item-renderer.js.map +1 -0
- package/lib/commonjs/providers/toast/types.js +6 -0
- package/lib/commonjs/providers/toast/types.js.map +1 -0
- package/lib/module/animation/hooks/index.js +4 -0
- package/lib/module/animation/hooks/index.js.map +1 -0
- package/lib/module/animation/hooks/useCombinedAnimationDisabledState.js +47 -0
- package/lib/module/animation/hooks/useCombinedAnimationDisabledState.js.map +1 -0
- package/lib/module/animation/index.js +6 -0
- package/lib/module/animation/index.js.map +1 -0
- package/lib/module/animation/types.js +4 -0
- package/lib/module/animation/types.js.map +1 -0
- package/lib/module/animation/utils.js +212 -0
- package/lib/module/animation/utils.js.map +1 -0
- package/lib/module/components/CLAUDE.md +1 -1
- package/lib/module/components/Card/index.js +47 -19
- package/lib/module/components/Card/index.js.map +1 -1
- package/lib/module/components/Toast/animation.js +324 -0
- package/lib/module/components/Toast/animation.js.map +1 -0
- package/lib/module/components/Toast/hooks.js +61 -0
- package/lib/module/components/Toast/hooks.js.map +1 -0
- package/lib/module/components/Toast/index.js +487 -0
- package/lib/module/components/Toast/index.js.map +1 -0
- package/lib/module/components/Toast/styles.js +138 -0
- package/lib/module/components/Toast/styles.js.map +1 -0
- package/lib/module/components/Toast/types.js +4 -0
- package/lib/module/components/Toast/types.js.map +1 -0
- package/lib/module/components/index.js +1 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/providers/animation-settings/index.js +4 -0
- package/lib/module/providers/animation-settings/index.js.map +1 -0
- package/lib/module/providers/animation-settings/provider.js +52 -0
- package/lib/module/providers/animation-settings/provider.js.map +1 -0
- package/lib/module/providers/animation-settings/types.js +4 -0
- package/lib/module/providers/animation-settings/types.js.map +1 -0
- package/lib/module/providers/forge-design/index.js +5 -0
- package/lib/module/providers/forge-design/index.js.map +1 -0
- package/lib/module/providers/forge-design/provider.js +66 -0
- package/lib/module/providers/forge-design/provider.js.map +1 -0
- package/lib/module/providers/forge-design/types.js +4 -0
- package/lib/module/providers/forge-design/types.js.map +1 -0
- package/lib/module/providers/text-component/index.js +5 -0
- package/lib/module/providers/text-component/index.js.map +1 -0
- package/lib/module/providers/text-component/provider.js +6 -0
- package/lib/module/providers/text-component/provider.js.map +1 -0
- package/lib/module/providers/text-component/types.js +4 -0
- package/lib/module/providers/text-component/types.js.map +1 -0
- package/lib/module/providers/toast/index.js +6 -0
- package/lib/module/providers/toast/index.js.map +1 -0
- package/lib/module/providers/toast/insets-container.js +156 -0
- package/lib/module/providers/toast/insets-container.js.map +1 -0
- package/lib/module/providers/toast/lifecycle.context.js +32 -0
- package/lib/module/providers/toast/lifecycle.context.js.map +1 -0
- package/lib/module/providers/toast/provider.js +503 -0
- package/lib/module/providers/toast/provider.js.map +1 -0
- package/lib/module/providers/toast/reducer.js +42 -0
- package/lib/module/providers/toast/reducer.js.map +1 -0
- package/lib/module/providers/toast/toast-config.context.js +25 -0
- package/lib/module/providers/toast/toast-config.context.js.map +1 -0
- package/lib/module/providers/toast/toast-item-renderer.js +39 -0
- package/lib/module/providers/toast/toast-item-renderer.js.map +1 -0
- package/lib/module/providers/toast/types.js +4 -0
- package/lib/module/providers/toast/types.js.map +1 -0
- package/lib/typescript/animation/hooks/index.d.ts +2 -0
- package/lib/typescript/animation/hooks/index.d.ts.map +1 -0
- package/lib/typescript/animation/hooks/useCombinedAnimationDisabledState.d.ts +22 -0
- package/lib/typescript/animation/hooks/useCombinedAnimationDisabledState.d.ts.map +1 -0
- package/lib/typescript/animation/index.d.ts +4 -0
- package/lib/typescript/animation/index.d.ts.map +1 -0
- package/lib/typescript/animation/types.d.ts +105 -0
- package/lib/typescript/animation/types.d.ts.map +1 -0
- package/lib/typescript/animation/utils.d.ts +120 -0
- package/lib/typescript/animation/utils.d.ts.map +1 -0
- package/lib/typescript/components/Card/index.d.ts +4 -0
- package/lib/typescript/components/Card/index.d.ts.map +1 -1
- package/lib/typescript/components/Toast/animation.d.ts +21 -0
- package/lib/typescript/components/Toast/animation.d.ts.map +1 -0
- package/lib/typescript/components/Toast/hooks.d.ts +17 -0
- package/lib/typescript/components/Toast/hooks.d.ts.map +1 -0
- package/lib/typescript/components/Toast/index.d.ts +28 -0
- package/lib/typescript/components/Toast/index.d.ts.map +1 -0
- package/lib/typescript/components/Toast/styles.d.ts +73 -0
- package/lib/typescript/components/Toast/styles.d.ts.map +1 -0
- package/lib/typescript/components/Toast/types.d.ts +303 -0
- package/lib/typescript/components/Toast/types.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +1 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/providers/animation-settings/index.d.ts +3 -0
- package/lib/typescript/providers/animation-settings/index.d.ts.map +1 -0
- package/lib/typescript/providers/animation-settings/provider.d.ts +28 -0
- package/lib/typescript/providers/animation-settings/provider.d.ts.map +1 -0
- package/lib/typescript/providers/animation-settings/types.d.ts +35 -0
- package/lib/typescript/providers/animation-settings/types.d.ts.map +1 -0
- package/lib/typescript/providers/forge-design/index.d.ts +3 -0
- package/lib/typescript/providers/forge-design/index.d.ts.map +1 -0
- package/lib/typescript/providers/forge-design/provider.d.ts +24 -0
- package/lib/typescript/providers/forge-design/provider.d.ts.map +1 -0
- package/lib/typescript/providers/forge-design/types.d.ts +82 -0
- package/lib/typescript/providers/forge-design/types.d.ts.map +1 -0
- package/lib/typescript/providers/text-component/index.d.ts +3 -0
- package/lib/typescript/providers/text-component/index.d.ts.map +1 -0
- package/lib/typescript/providers/text-component/provider.d.ts +7 -0
- package/lib/typescript/providers/text-component/provider.d.ts.map +1 -0
- package/lib/typescript/providers/text-component/types.d.ts +51 -0
- package/lib/typescript/providers/text-component/types.d.ts.map +1 -0
- package/lib/typescript/providers/toast/index.d.ts +5 -0
- package/lib/typescript/providers/toast/index.d.ts.map +1 -0
- package/lib/typescript/providers/toast/insets-container.d.ts +72 -0
- package/lib/typescript/providers/toast/insets-container.d.ts.map +1 -0
- package/lib/typescript/providers/toast/lifecycle.context.d.ts +32 -0
- package/lib/typescript/providers/toast/lifecycle.context.d.ts.map +1 -0
- package/lib/typescript/providers/toast/provider.d.ts +32 -0
- package/lib/typescript/providers/toast/provider.d.ts.map +1 -0
- package/lib/typescript/providers/toast/reducer.d.ts +14 -0
- package/lib/typescript/providers/toast/reducer.d.ts.map +1 -0
- package/lib/typescript/providers/toast/toast-config.context.d.ts +20 -0
- package/lib/typescript/providers/toast/toast-config.context.d.ts.map +1 -0
- package/lib/typescript/providers/toast/toast-item-renderer.d.ts +7 -0
- package/lib/typescript/providers/toast/toast-item-renderer.d.ts.map +1 -0
- package/lib/typescript/providers/toast/types.d.ts +422 -0
- package/lib/typescript/providers/toast/types.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/animation/hooks/index.ts +1 -0
- package/src/animation/hooks/useCombinedAnimationDisabledState.ts +46 -0
- package/src/animation/index.ts +3 -0
- package/src/animation/types.ts +128 -0
- package/src/animation/utils.ts +249 -0
- package/src/components/CLAUDE.md +1 -1
- package/src/components/Card/index.tsx +58 -28
- package/src/components/Toast/animation.ts +387 -0
- package/src/components/Toast/hooks.ts +92 -0
- package/src/components/Toast/index.tsx +520 -0
- package/src/components/Toast/styles.ts +186 -0
- package/src/components/Toast/types.ts +332 -0
- package/src/components/index.ts +1 -0
- package/src/index.ts +2 -0
- package/src/providers/animation-settings/index.ts +11 -0
- package/src/providers/animation-settings/provider.tsx +54 -0
- package/src/providers/animation-settings/types.ts +37 -0
- package/src/providers/forge-design/index.ts +2 -0
- package/src/providers/forge-design/provider.tsx +61 -0
- package/src/providers/forge-design/types.ts +84 -0
- package/src/providers/text-component/index.ts +2 -0
- package/src/providers/text-component/provider.tsx +7 -0
- package/src/providers/text-component/types.ts +52 -0
- package/src/providers/toast/index.ts +4 -0
- package/src/providers/toast/insets-container.tsx +230 -0
- package/src/providers/toast/lifecycle.context.tsx +37 -0
- package/src/providers/toast/provider.tsx +567 -0
- package/src/providers/toast/reducer.ts +40 -0
- package/src/providers/toast/toast-config.context.ts +25 -0
- package/src/providers/toast/toast-item-renderer.tsx +40 -0
- package/src/providers/toast/types.ts +431 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import { Platform, View } from 'react-native';
|
|
4
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
|
+
import { FullWindowOverlay } from '@cdx-ui/primitives';
|
|
6
|
+
import type { ToastInsets } from './types';
|
|
7
|
+
|
|
8
|
+
interface InsetsContainerProps {
|
|
9
|
+
/**
|
|
10
|
+
* When true, uses a regular View instead of FullWindowOverlay on iOS.
|
|
11
|
+
* Enables element inspector but toasts won't appear above native modals.
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
disableFullWindowOverlay: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Controls whether VoiceOver treats the overlay window as a modal container.
|
|
17
|
+
* When `false`, VoiceOver can still access elements behind the overlay.
|
|
18
|
+
* When `true`, VoiceOver is restricted to elements inside the overlay.
|
|
19
|
+
* @default false
|
|
20
|
+
* @platform ios
|
|
21
|
+
* @unstable This prop maps directly to the native `accessibilityViewIsModal`
|
|
22
|
+
* on the container view and may change in a future react-native-screens release.
|
|
23
|
+
*/
|
|
24
|
+
unstable_accessibilityContainerViewIsModal?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Optional inset values for all edges
|
|
27
|
+
* If not provided, defaults to platform-specific values:
|
|
28
|
+
* - iOS: safe area insets + 0px (top), + 6px (bottom), + 12px (left/right)
|
|
29
|
+
* - Android: safe area insets + 12px (all edges)
|
|
30
|
+
*/
|
|
31
|
+
insets?: ToastInsets;
|
|
32
|
+
/**
|
|
33
|
+
* Accessible label for the toast notification region on web.
|
|
34
|
+
* @default 'Notifications'
|
|
35
|
+
* @platform web
|
|
36
|
+
*/
|
|
37
|
+
announceLabel?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Custom wrapper function to wrap the toast content
|
|
40
|
+
* Receives children and should return a component that wraps them
|
|
41
|
+
* The wrapper should apply flex: 1 (via className or style) to ensure proper layout
|
|
42
|
+
* Can be any component wrapper - KeyboardAvoidingView, View, or any custom component
|
|
43
|
+
*/
|
|
44
|
+
contentWrapper?: (children: ReactNode) => React.ReactElement;
|
|
45
|
+
/**
|
|
46
|
+
* Pause all auto-dismiss timers (WCAG 2.2.1).
|
|
47
|
+
*/
|
|
48
|
+
pauseAll: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Resume all auto-dismiss timers.
|
|
51
|
+
*/
|
|
52
|
+
resumeAll: () => void;
|
|
53
|
+
/**
|
|
54
|
+
* Hide the front-most toast. Used by the Escape key handler on web.
|
|
55
|
+
*/
|
|
56
|
+
hide: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Children to render inside the container
|
|
59
|
+
*/
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Container component that applies inset padding to position toasts
|
|
65
|
+
* away from screen edges and safe areas
|
|
66
|
+
*
|
|
67
|
+
* Combines custom insets with safe area insets:
|
|
68
|
+
* - If custom inset is provided, it overrides safe area + default padding
|
|
69
|
+
* - If not provided, uses platform-specific defaults:
|
|
70
|
+
* - iOS: safe area inset + 0px for top, + 6px for bottom, + 12px for left/right
|
|
71
|
+
* - Android: safe area inset + 12px for all edges
|
|
72
|
+
*
|
|
73
|
+
* On web, wires pointer/focus/visibility listeners to pause/resume timers
|
|
74
|
+
* per WCAG 2.2.1 (keyboard/pointer/hidden-tab pausing).
|
|
75
|
+
*/
|
|
76
|
+
export function InsetsContainer({
|
|
77
|
+
insets,
|
|
78
|
+
announceLabel = 'Notifications',
|
|
79
|
+
contentWrapper,
|
|
80
|
+
children,
|
|
81
|
+
disableFullWindowOverlay,
|
|
82
|
+
unstable_accessibilityContainerViewIsModal,
|
|
83
|
+
pauseAll,
|
|
84
|
+
resumeAll,
|
|
85
|
+
hide,
|
|
86
|
+
}: Readonly<InsetsContainerProps>) {
|
|
87
|
+
const safeAreaInsets = useSafeAreaInsets();
|
|
88
|
+
|
|
89
|
+
const finalInsets = useMemo(() => {
|
|
90
|
+
return {
|
|
91
|
+
top: insets?.top ?? safeAreaInsets.top + (Platform.OS === 'ios' ? 0 : 12),
|
|
92
|
+
bottom: insets?.bottom ?? safeAreaInsets.bottom + (Platform.OS === 'ios' ? 6 : 12),
|
|
93
|
+
left: insets?.left ?? safeAreaInsets.left + 12,
|
|
94
|
+
right: insets?.right ?? safeAreaInsets.right + 12,
|
|
95
|
+
};
|
|
96
|
+
}, [safeAreaInsets, insets]);
|
|
97
|
+
|
|
98
|
+
// Track pause sources independently so overlapping pointer + focus
|
|
99
|
+
// don't accidentally resume while the other source is still active.
|
|
100
|
+
const pauseSourcesRef = useRef<Set<string>>(new Set());
|
|
101
|
+
const pauseAllRef = useRef(pauseAll);
|
|
102
|
+
const resumeAllRef = useRef(resumeAll);
|
|
103
|
+
pauseAllRef.current = pauseAll;
|
|
104
|
+
resumeAllRef.current = resumeAll;
|
|
105
|
+
|
|
106
|
+
const addPauseSource = useCallback((source: string) => {
|
|
107
|
+
const wasEmpty = pauseSourcesRef.current.size === 0;
|
|
108
|
+
pauseSourcesRef.current.add(source);
|
|
109
|
+
if (wasEmpty) pauseAllRef.current();
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
const removePauseSource = useCallback((source: string) => {
|
|
113
|
+
pauseSourcesRef.current.delete(source);
|
|
114
|
+
if (pauseSourcesRef.current.size === 0) resumeAllRef.current();
|
|
115
|
+
}, []);
|
|
116
|
+
|
|
117
|
+
// Ref for the container so we can attach native DOM listeners on web.
|
|
118
|
+
const containerRef = useRef<View | null>(null);
|
|
119
|
+
const hideRef = useRef(hide);
|
|
120
|
+
hideRef.current = hide;
|
|
121
|
+
|
|
122
|
+
// Web-only: attach pointer, focus, visibility, and keyboard listeners
|
|
123
|
+
// via native DOM APIs to avoid RNW making the container focusable
|
|
124
|
+
// (RNW adds tabIndex when React onFocus/onBlur handlers are present).
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (Platform.OS !== 'web') return;
|
|
127
|
+
|
|
128
|
+
const node = containerRef.current as unknown as HTMLElement | null;
|
|
129
|
+
const sources = pauseSourcesRef.current;
|
|
130
|
+
|
|
131
|
+
const handleVisibilityChange = () => {
|
|
132
|
+
if (document.hidden) {
|
|
133
|
+
addPauseSource('visibility');
|
|
134
|
+
} else {
|
|
135
|
+
removePauseSource('visibility');
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// The container is `absolute inset-0` (full viewport). Using
|
|
140
|
+
// pointerenter/pointerleave here would pause as soon as the cursor
|
|
141
|
+
// is anywhere on the page — far too aggressive. Instead use
|
|
142
|
+
// pointerover/pointerout (which bubble) and gate on whether the
|
|
143
|
+
// pointer is actually over a toast element (identified by the
|
|
144
|
+
// `data-state` attribute emitted on every toast wrapper).
|
|
145
|
+
const isInsideToast = (el: EventTarget | null): boolean => {
|
|
146
|
+
if (!el || !(el instanceof HTMLElement)) return false;
|
|
147
|
+
return !!el.closest('[data-state]');
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handlePointerOver = (e: PointerEvent) => {
|
|
151
|
+
if (isInsideToast(e.target)) addPauseSource('pointer');
|
|
152
|
+
};
|
|
153
|
+
const handlePointerOut = (e: PointerEvent) => {
|
|
154
|
+
if (!isInsideToast(e.relatedTarget)) removePauseSource('pointer');
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const handleFocusIn = (e: FocusEvent) => {
|
|
158
|
+
if (isInsideToast(e.target)) addPauseSource('focus');
|
|
159
|
+
};
|
|
160
|
+
const handleFocusOut = (e: FocusEvent) => {
|
|
161
|
+
if (!isInsideToast(e.relatedTarget)) removePauseSource('focus');
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
165
|
+
if (event.key === 'Escape') {
|
|
166
|
+
event.stopPropagation();
|
|
167
|
+
hideRef.current();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
172
|
+
|
|
173
|
+
if (node && typeof node.addEventListener === 'function') {
|
|
174
|
+
node.addEventListener('pointerover', handlePointerOver);
|
|
175
|
+
node.addEventListener('pointerout', handlePointerOut);
|
|
176
|
+
node.addEventListener('focusin', handleFocusIn);
|
|
177
|
+
node.addEventListener('focusout', handleFocusOut);
|
|
178
|
+
node.addEventListener('keydown', handleKeyDown);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return () => {
|
|
182
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
183
|
+
if (node && typeof node.removeEventListener === 'function') {
|
|
184
|
+
node.removeEventListener('pointerover', handlePointerOver);
|
|
185
|
+
node.removeEventListener('pointerout', handlePointerOut);
|
|
186
|
+
node.removeEventListener('focusin', handleFocusIn);
|
|
187
|
+
node.removeEventListener('focusout', handleFocusOut);
|
|
188
|
+
node.removeEventListener('keydown', handleKeyDown);
|
|
189
|
+
}
|
|
190
|
+
if (sources.size > 0) {
|
|
191
|
+
sources.clear();
|
|
192
|
+
resumeAllRef.current();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}, [addPauseSource, removePauseSource]);
|
|
196
|
+
|
|
197
|
+
const content = (
|
|
198
|
+
<View
|
|
199
|
+
ref={containerRef}
|
|
200
|
+
className="absolute inset-0 pointer-events-box-none"
|
|
201
|
+
role="region"
|
|
202
|
+
aria-label={announceLabel}
|
|
203
|
+
{...(Platform.OS === 'web' && {
|
|
204
|
+
'aria-live': 'polite',
|
|
205
|
+
'aria-atomic': false,
|
|
206
|
+
})}
|
|
207
|
+
style={{
|
|
208
|
+
paddingTop: finalInsets.top,
|
|
209
|
+
paddingBottom: finalInsets.bottom,
|
|
210
|
+
paddingLeft: finalInsets.left,
|
|
211
|
+
paddingRight: finalInsets.right,
|
|
212
|
+
}}
|
|
213
|
+
>
|
|
214
|
+
{contentWrapper ? contentWrapper(children) : children}
|
|
215
|
+
</View>
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
if (Platform.OS !== 'ios') {
|
|
219
|
+
return content;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<FullWindowOverlay
|
|
224
|
+
disableFullWindowOverlay={disableFullWindowOverlay}
|
|
225
|
+
unstable_accessibilityContainerViewIsModal={unstable_accessibilityContainerViewIsModal}
|
|
226
|
+
>
|
|
227
|
+
{content}
|
|
228
|
+
</FullWindowOverlay>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Internal context that exposes the pending-removal lifecycle for web toasts.
|
|
5
|
+
*
|
|
6
|
+
* Web toasts stay mounted after `hide()` is dispatched so the CSS exit
|
|
7
|
+
* transition can play. The toast component reads `pendingRemovalIds` to
|
|
8
|
+
* flip its `data-state="closed"` attribute and calls `remove(id)` when
|
|
9
|
+
* the CSS transition completes (or a safety timeout fires).
|
|
10
|
+
*
|
|
11
|
+
* On native this context is provided but effectively unused — Reanimated's
|
|
12
|
+
* `exiting` layout animation plays before unmount, so nothing lingers.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export interface ToastLifecycleContextValue {
|
|
17
|
+
/** Force-remove a toast from the array once its exit transition has played. */
|
|
18
|
+
remove: (id: string) => void;
|
|
19
|
+
/** IDs of toasts that have been marked closed but are still mounted. */
|
|
20
|
+
pendingRemovalIds: ReadonlySet<string>;
|
|
21
|
+
/** ID of the front-most (last non-pending) toast, or null if none. */
|
|
22
|
+
frontmostId: string | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const ToastLifecycleContext = createContext<ToastLifecycleContextValue | null>(null);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Access the toast lifecycle context.
|
|
29
|
+
*
|
|
30
|
+
* Returns `null` when the styled Toast is rendered outside a `ToastProvider`
|
|
31
|
+
* (e.g. in isolated unit tests) so callers must handle the null case.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export function useToastLifecycle(): ToastLifecycleContextValue | null {
|
|
36
|
+
return useContext(ToastLifecycleContext);
|
|
37
|
+
}
|