@impulse-ui-native/toast 6.1.0 → 6.3.0
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/README.md +2 -2
- package/dist/components/toast-root.js +2 -2
- package/dist/components/toast-root.js.map +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/hooks/use-toast-lifecycle.hook.js +7 -3
- package/dist/hooks/use-toast-lifecycle.hook.js.map +1 -1
- package/package.json +7 -8
- package/dist/hooks/use-toast-timer.hook.d.mts +0 -3
- package/dist/hooks/use-toast-timer.hook.js +0 -50
- package/dist/hooks/use-toast-timer.hook.js.map +0 -1
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ Supply a stable `undoActionProps` object with your `onPress` handler.
|
|
|
69
69
|
Composable parts render the children you supply. They do not create fallback icons or content. Use `Toast.Root` when you want to assemble the whole notification yourself:
|
|
70
70
|
|
|
71
71
|
```tsx
|
|
72
|
-
import { Icon } from "@impulse-ui-native/icon
|
|
72
|
+
import { Icon } from "@impulse-ui-native/icon";
|
|
73
73
|
import { XIcon } from "@impulse-ui-native/icon/icons/x";
|
|
74
74
|
|
|
75
75
|
<Toast.Root id="custom" duration={0}>
|
|
@@ -109,4 +109,4 @@ Toast uses `theme.components.toast` for surfaces, geometry, typography, actions
|
|
|
109
109
|
|
|
110
110
|
## Verification
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
Use the Toast stories in the on-device Storybook host to verify rendering, touch interaction, timer pause/resume, and lifecycle cancellation on iOS and Android.
|
|
@@ -8,7 +8,7 @@ import Animated, {
|
|
|
8
8
|
withTiming
|
|
9
9
|
} from "react-native-reanimated";
|
|
10
10
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
11
|
-
import { useOverlayLayer } from "@impulse-ui-native/overlay";
|
|
11
|
+
import { OverlayOrder, useOverlayLayer } from "@impulse-ui-native/overlay";
|
|
12
12
|
import { useComponentsTokens, useThemedStyles } from "@impulse-ui-native/theme";
|
|
13
13
|
import { DefaultDuration, StackDuration } from "../constants/toast.constants";
|
|
14
14
|
import { ToastContext } from "../contexts/toast.context";
|
|
@@ -25,7 +25,7 @@ const ToastRoot = memo(function ToastRoot2(props) {
|
|
|
25
25
|
const insets = useSafeAreaInsets();
|
|
26
26
|
const tokens = useComponentsTokens().toast;
|
|
27
27
|
const lifecycle = useToastLifecycle(props, duration);
|
|
28
|
-
const toastLayer = useOverlayLayer(id, void 0,
|
|
28
|
+
const toastLayer = useOverlayLayer(id, void 0, OverlayOrder.NewestFirst);
|
|
29
29
|
const styles = useThemedStyles(themedStyles);
|
|
30
30
|
const { progress } = lifecycle;
|
|
31
31
|
const edgeOffset = tokens.edgeOffset;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/toast-root.tsx"],"sourcesContent":["import { memo, useEffect, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withTiming,\n} from \"react-native-reanimated\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { useOverlayLayer } from \"@impulse-ui-native/overlay\";\nimport { useComponentsTokens, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport type { ToastRootProps } from \"../types\";\nimport { DefaultDuration, StackDuration } from \"../constants/toast.constants\";\nimport { ToastContext } from \"../contexts/toast.context\";\nimport { useToastLifecycle } from \"../hooks/use-toast-lifecycle.hook\";\n\nexport const ToastRoot = memo(function ToastRoot(props: ToastRootProps) {\n const {\n id,\n children,\n placement = \"bottom\",\n tone = \"success\",\n duration = DefaultDuration,\n layer = 0,\n } = props;\n\n const insets = useSafeAreaInsets();\n\n const tokens = useComponentsTokens().toast;\n\n const lifecycle = useToastLifecycle(props, duration);\n const toastLayer = useOverlayLayer(id, undefined,
|
|
1
|
+
{"version":3,"sources":["../../src/components/toast-root.tsx"],"sourcesContent":["import { memo, useEffect, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withTiming,\n} from \"react-native-reanimated\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { OverlayOrder, useOverlayLayer } from \"@impulse-ui-native/overlay\";\nimport { useComponentsTokens, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport type { ToastRootProps } from \"../types\";\nimport { DefaultDuration, StackDuration } from \"../constants/toast.constants\";\nimport { ToastContext } from \"../contexts/toast.context\";\nimport { useToastLifecycle } from \"../hooks/use-toast-lifecycle.hook\";\n\nexport const ToastRoot = memo(function ToastRoot(props: ToastRootProps) {\n const {\n id,\n children,\n placement = \"bottom\",\n tone = \"success\",\n duration = DefaultDuration,\n layer = 0,\n } = props;\n\n const insets = useSafeAreaInsets();\n\n const tokens = useComponentsTokens().toast;\n\n const lifecycle = useToastLifecycle(props, duration);\n const toastLayer = useOverlayLayer(id, undefined, OverlayOrder.NewestFirst);\n const styles = useThemedStyles(themedStyles);\n const { progress } = lifecycle;\n const edgeOffset = tokens.edgeOffset;\n const stackDepth = Math.min(\n Math.max(0, toastLayer),\n Math.max(0, tokens.stackLimit - 1),\n );\n const animatedDepth = useSharedValue(stackDepth);\n const animatedStyle = useAnimatedStyle(() => ({\n opacity: progress.value,\n transform: [\n {\n translateY:\n (1 - progress.value) *\n (placement === \"top\" ? -edgeOffset : edgeOffset) +\n animatedDepth.value * tokens.gap,\n },\n { scale: Math.max(0, 1 - animatedDepth.value * tokens.stackScaleStep) },\n ],\n }));\n\n const context = useMemo(\n () => ({\n tone,\n interactive: lifecycle.interactive,\n close: lifecycle.close,\n }),\n [tone, lifecycle.interactive, lifecycle.close],\n );\n const containerStyle = useMemo(\n () => [\n styles.container,\n {\n left: insets.left + tokens.edgeOffset,\n right: insets.right + tokens.edgeOffset,\n [placement]:\n insets[placement] +\n (placement === \"top\" ? tokens.topOffset : tokens.edgeOffset),\n transformOrigin: \"center top\",\n zIndex: tokens.zIndexBase + layer,\n },\n animatedStyle,\n ],\n [styles.container, insets, tokens, placement, layer, animatedStyle],\n );\n\n useEffect(() => {\n animatedDepth.value = withTiming(stackDepth, { duration: StackDuration });\n\n return () => cancelAnimation(animatedDepth);\n }, [animatedDepth, stackDepth]);\n\n if (lifecycle.finished) {\n return null;\n }\n\n return (\n <ToastContext.Provider value={context}>\n <Animated.View\n pointerEvents={lifecycle.interactive ? \"auto\" : \"none\"}\n style={containerStyle}\n >\n {children}\n </Animated.View>\n </ToastContext.Provider>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n const tokens = theme.components.toast;\n\n return StyleSheet.create({\n container: {\n position: \"absolute\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: tokens.gap,\n padding: tokens.padding,\n borderRadius: tokens.borderRadius,\n borderWidth: tokens.borderWidth,\n borderColor: tokens.borderColor,\n backgroundColor: tokens.backgroundColor,\n },\n });\n}\n"],"mappings":"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","names":["ToastRoot"]}
|
package/dist/components/toast.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { memo } from "react";
|
|
3
|
-
import { Icon } from "@impulse-ui-native/icon
|
|
3
|
+
import { Icon } from "@impulse-ui-native/icon";
|
|
4
4
|
import { XIcon } from "@impulse-ui-native/icon/icons/x";
|
|
5
5
|
import { useComponentsTokens } from "@impulse-ui-native/theme";
|
|
6
6
|
import { ToastIcons } from "../constants/toast-icons.constants";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/toast.tsx"],"sourcesContent":["import { memo } from \"react\";\n\nimport { Icon } from \"@impulse-ui-native/icon
|
|
1
|
+
{"version":3,"sources":["../../src/components/toast.tsx"],"sourcesContent":["import { memo } from \"react\";\n\nimport { Icon } from \"@impulse-ui-native/icon\";\nimport { XIcon } from \"@impulse-ui-native/icon/icons/x\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { ToastProps } from \"../types\";\nimport { ToastIcons } from \"../constants/toast-icons.constants\";\nimport { Toast } from \"./toast-parts\";\n\nexport const ToastComponent = memo(function ToastComponent({\n children,\n title,\n description,\n action,\n actionProps,\n tone = \"success\",\n hideIcon = false,\n hideClose = false,\n ...props\n}: ToastProps) {\n const tokens = useComponentsTokens().toast;\n\n return (\n <Toast.Root {...props} tone={tone}>\n {!hideIcon ? (\n <Toast.Icon>\n <Icon\n icon={ToastIcons[tone]}\n size={tokens.iconSize}\n color={tokens.tones[tone].value}\n />\n </Toast.Icon>\n ) : null}\n <Toast.Content>\n {title ? <Toast.Title>{title}</Toast.Title> : null}\n {description !== null && description !== undefined ? (\n <Toast.Description>{description}</Toast.Description>\n ) : null}\n {children}\n </Toast.Content>\n {action !== null && action !== undefined ? (\n <Toast.Action {...actionProps}>{action}</Toast.Action>\n ) : null}\n {!hideClose ? (\n <Toast.Close>\n <Icon\n icon={XIcon}\n size={tokens.iconSize}\n color={tokens.descriptionColor}\n />\n </Toast.Close>\n ) : null}\n </Toast.Root>\n );\n});\n"],"mappings":"AA2BU,cAOJ,YAPI;AA3BV,SAAS,YAAY;AAErB,SAAS,YAAY;AACrB,SAAS,aAAa;AACtB,SAAS,2BAA2B;AAGpC,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AAEf,MAAM,iBAAiB,KAAK,SAASA,gBAAe;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,GAAG;AACL,GAAe;AACb,QAAM,SAAS,oBAAoB,EAAE;AAErC,SACE,qBAAC,MAAM,MAAN,EAAY,GAAG,OAAO,MACpB;AAAA,KAAC,WACA,oBAAC,MAAM,MAAN,EACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,WAAW,IAAI;AAAA,QACrB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO,MAAM,IAAI,EAAE;AAAA;AAAA,IAC5B,GACF,IACE;AAAA,IACJ,qBAAC,MAAM,SAAN,EACE;AAAA,cAAQ,oBAAC,MAAM,OAAN,EAAa,iBAAM,IAAiB;AAAA,MAC7C,gBAAgB,QAAQ,gBAAgB,SACvC,oBAAC,MAAM,aAAN,EAAmB,uBAAY,IAC9B;AAAA,MACH;AAAA,OACH;AAAA,IACC,WAAW,QAAQ,WAAW,SAC7B,oBAAC,MAAM,QAAN,EAAc,GAAG,aAAc,kBAAO,IACrC;AAAA,IACH,CAAC,YACA,oBAAC,MAAM,OAAN,EACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA;AAAA,IAChB,GACF,IACE;AAAA,KACN;AAEJ,CAAC;","names":["ToastComponent"]}
|
|
@@ -5,10 +5,9 @@ import {
|
|
|
5
5
|
withTiming
|
|
6
6
|
} from "react-native-reanimated";
|
|
7
7
|
import { scheduleOnRN } from "react-native-worklets";
|
|
8
|
-
import { useEventCallback } from "@impulse-ui-native/core";
|
|
8
|
+
import { useEventCallback, useTimer } from "@impulse-ui-native/core";
|
|
9
9
|
import { useOverlayContext } from "@impulse-ui-native/overlay";
|
|
10
10
|
import { EnterDuration, ExitDuration } from "../constants/toast.constants";
|
|
11
|
-
import { useToastTimer } from "./use-toast-timer.hook";
|
|
12
11
|
function useToastLifecycle(props, duration) {
|
|
13
12
|
const {
|
|
14
13
|
id,
|
|
@@ -51,7 +50,12 @@ function useToastLifecycle(props, duration) {
|
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
);
|
|
54
|
-
|
|
53
|
+
useTimer({
|
|
54
|
+
enabled: entered && open && !finished,
|
|
55
|
+
duration,
|
|
56
|
+
callback: close,
|
|
57
|
+
pauseOnBackground: true
|
|
58
|
+
});
|
|
55
59
|
useEffect(() => {
|
|
56
60
|
if (finished) {
|
|
57
61
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-toast-lifecycle.hook.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n cancelAnimation,\n useSharedValue,\n withTiming,\n} from \"react-native-reanimated\";\nimport { scheduleOnRN } from \"react-native-worklets\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { useOverlayContext } from \"@impulse-ui-native/overlay\";\n\nimport type { ToastRootProps } from \"../types\";\nimport { EnterDuration, ExitDuration } from \"../constants/toast.constants\";\
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-toast-lifecycle.hook.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n cancelAnimation,\n useSharedValue,\n withTiming,\n} from \"react-native-reanimated\";\nimport { scheduleOnRN } from \"react-native-worklets\";\n\nimport { useEventCallback, useTimer } from \"@impulse-ui-native/core\";\nimport { useOverlayContext } from \"@impulse-ui-native/overlay\";\n\nimport type { ToastRootProps } from \"../types\";\nimport { EnterDuration, ExitDuration } from \"../constants/toast.constants\";\n\nexport function useToastLifecycle(props: ToastRootProps, duration: number) {\n const {\n id,\n open = true,\n onOpen,\n onOpenFinished,\n onClose,\n onCloseFinished,\n } = props;\n\n const { store } = useOverlayContext();\n\n const [entered, setEntered] = useState(false);\n const [finished, setFinished] = useState(false);\n\n const opened = useRef(false);\n const closing = useRef(false);\n const settled = useRef(false);\n const transitionId = useRef(0);\n\n const progress = useSharedValue(0);\n\n const close = useEventCallback(() => store.close(id));\n\n const notifyOpen = useEventCallback(() => onOpen?.(id));\n\n const notifyEntered = useEventCallback(() => onOpenFinished?.(id));\n\n const notifyClose = useEventCallback(() => onClose?.(id));\n\n const finishClose = useEventCallback(() => {\n if (settled.current) {\n return;\n }\n\n settled.current = true;\n\n setFinished(true);\n\n onCloseFinished?.(id);\n });\n\n const finishTransition = useEventCallback(\n (completedTransitionId: number, entering: boolean) => {\n if (transitionId.current !== completedTransitionId || settled.current) {\n return;\n }\n\n if (entering) {\n setEntered(true);\n\n notifyEntered();\n } else {\n finishClose();\n }\n },\n );\n\n useTimer({\n enabled: entered && open && !finished,\n duration,\n callback: close,\n pauseOnBackground: true,\n });\n\n useEffect(() => {\n if (finished) {\n return;\n }\n\n const currentTransitionId = ++transitionId.current;\n\n if (!open) {\n const firstClose = !closing.current;\n\n closing.current = true;\n\n if (!opened.current) {\n try {\n if (firstClose) {\n notifyClose();\n }\n } finally {\n finishClose();\n }\n\n return;\n }\n\n try {\n if (firstClose) {\n notifyClose();\n }\n } finally {\n progress.value = withTiming(\n 0,\n { duration: ExitDuration },\n (completed) => {\n if (completed) {\n scheduleOnRN(finishTransition, currentTransitionId, false);\n }\n },\n );\n }\n\n return () => {\n transitionId.current += 1;\n\n cancelAnimation(progress);\n };\n }\n\n const firstOpen = !opened.current;\n\n opened.current = true;\n\n try {\n if (firstOpen) {\n notifyOpen();\n }\n } finally {\n progress.value = withTiming(\n 1,\n { duration: EnterDuration },\n (completed) => {\n if (completed) {\n scheduleOnRN(finishTransition, currentTransitionId, true);\n }\n },\n );\n }\n\n return () => {\n transitionId.current += 1;\n\n cancelAnimation(progress);\n };\n }, [\n finishClose,\n finishTransition,\n finished,\n notifyClose,\n notifyEntered,\n notifyOpen,\n open,\n progress,\n ]);\n\n return { progress, close, finished, interactive: open && !finished };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@impulse-ui-native/toast",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Compound toast notifications for ImpulseUI Native.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@impulse-ui-native/theme": "6.
|
|
31
|
-
"@impulse-ui-native/
|
|
32
|
-
"@impulse-ui-native/
|
|
33
|
-
"@impulse-ui-native/core": "6.
|
|
34
|
-
"@impulse-ui-native/icon": "6.
|
|
30
|
+
"@impulse-ui-native/theme": "6.3.0",
|
|
31
|
+
"@impulse-ui-native/overlay": "6.3.0",
|
|
32
|
+
"@impulse-ui-native/primitives": "6.3.0",
|
|
33
|
+
"@impulse-ui-native/core": "6.3.0",
|
|
34
|
+
"@impulse-ui-native/icon": "6.3.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/react": "~19.2.14",
|
|
@@ -64,7 +64,6 @@
|
|
|
64
64
|
"build": "tsup --config tsup.config.ts",
|
|
65
65
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
66
66
|
"lint": "pnpm exec eslint . --fix",
|
|
67
|
-
"format": "prettier --write \"./**/*.{ts,tsx,js,jsx,json,md}\" --ignore-path ../../.prettierignore"
|
|
68
|
-
"test": "node --test tests/*.test.mjs"
|
|
67
|
+
"format": "prettier --write \"./**/*.{ts,tsx,js,jsx,json,md}\" --ignore-path ../../.prettierignore"
|
|
69
68
|
}
|
|
70
69
|
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { AppState } from "react-native";
|
|
3
|
-
import { useEventCallback } from "@impulse-ui-native/core";
|
|
4
|
-
function useToastTimer(active, duration, close) {
|
|
5
|
-
const dismiss = useEventCallback(close);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
if (!active || !Number.isFinite(duration) || duration <= 0) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
let remaining = duration;
|
|
11
|
-
let startedAt = 0;
|
|
12
|
-
let timeout;
|
|
13
|
-
const pause = () => {
|
|
14
|
-
if (timeout === void 0) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
clearTimeout(timeout);
|
|
18
|
-
timeout = void 0;
|
|
19
|
-
remaining = Math.max(0, remaining - (Date.now() - startedAt));
|
|
20
|
-
};
|
|
21
|
-
const resume = () => {
|
|
22
|
-
if (timeout !== void 0) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
startedAt = Date.now();
|
|
26
|
-
timeout = setTimeout(() => {
|
|
27
|
-
timeout = void 0;
|
|
28
|
-
dismiss();
|
|
29
|
-
}, remaining);
|
|
30
|
-
};
|
|
31
|
-
const subscription = AppState.addEventListener("change", (state) => {
|
|
32
|
-
if (state === "active") {
|
|
33
|
-
resume();
|
|
34
|
-
} else {
|
|
35
|
-
pause();
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
if (AppState.currentState === "active") {
|
|
39
|
-
resume();
|
|
40
|
-
}
|
|
41
|
-
return () => {
|
|
42
|
-
pause();
|
|
43
|
-
subscription.remove();
|
|
44
|
-
};
|
|
45
|
-
}, [active, dismiss, duration]);
|
|
46
|
-
}
|
|
47
|
-
export {
|
|
48
|
-
useToastTimer
|
|
49
|
-
};
|
|
50
|
-
//# sourceMappingURL=use-toast-timer.hook.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-toast-timer.hook.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { AppState } from \"react-native\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\n\nexport function useToastTimer(\n active: boolean,\n duration: number,\n close: () => void,\n) {\n const dismiss = useEventCallback(close);\n\n useEffect(() => {\n if (!active || !Number.isFinite(duration) || duration <= 0) {\n return;\n }\n\n let remaining = duration;\n let startedAt = 0;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n const pause = () => {\n if (timeout === undefined) {\n return;\n }\n\n clearTimeout(timeout);\n\n timeout = undefined;\n remaining = Math.max(0, remaining - (Date.now() - startedAt));\n };\n\n const resume = () => {\n if (timeout !== undefined) {\n return;\n }\n\n startedAt = Date.now();\n timeout = setTimeout(() => {\n timeout = undefined;\n\n dismiss();\n }, remaining);\n };\n\n const subscription = AppState.addEventListener(\"change\", (state) => {\n if (state === \"active\") {\n resume();\n } else {\n pause();\n }\n });\n\n if (AppState.currentState === \"active\") {\n resume();\n }\n\n return () => {\n pause();\n subscription.remove();\n };\n }, [active, dismiss, duration]);\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AAEzB,SAAS,wBAAwB;AAE1B,SAAS,cACd,QACA,UACA,OACA;AACA,QAAM,UAAU,iBAAiB,KAAK;AAEtC,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,GAAG;AAC1D;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,QAAI,YAAY;AAChB,QAAI;AAEJ,UAAM,QAAQ,MAAM;AAClB,UAAI,YAAY,QAAW;AACzB;AAAA,MACF;AAEA,mBAAa,OAAO;AAEpB,gBAAU;AACV,kBAAY,KAAK,IAAI,GAAG,aAAa,KAAK,IAAI,IAAI,UAAU;AAAA,IAC9D;AAEA,UAAM,SAAS,MAAM;AACnB,UAAI,YAAY,QAAW;AACzB;AAAA,MACF;AAEA,kBAAY,KAAK,IAAI;AACrB,gBAAU,WAAW,MAAM;AACzB,kBAAU;AAEV,gBAAQ;AAAA,MACV,GAAG,SAAS;AAAA,IACd;AAEA,UAAM,eAAe,SAAS,iBAAiB,UAAU,CAAC,UAAU;AAClE,UAAI,UAAU,UAAU;AACtB,eAAO;AAAA,MACT,OAAO;AACL,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,SAAS,iBAAiB,UAAU;AACtC,aAAO;AAAA,IACT;AAEA,WAAO,MAAM;AACX,YAAM;AACN,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,QAAQ,CAAC;AAChC;","names":[]}
|