diff options
author | Eric Bailey <git@esb.lol> | 2025-07-31 10:15:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-31 10:15:35 -0500 |
commit | 3bcfcba6d8176bac03202b496110915da748b0f1 (patch) | |
tree | 68c75c7c80945a8a5f5a32522dd9aa29f119e02a /src/view/com/util/Toast.web.tsx | |
parent | 33e071494881b13696e24b334857e594f29a4b1d (diff) | |
download | voidsky-3bcfcba6d8176bac03202b496110915da748b0f1.tar.zst |
Some toasts cleanup and reorg (#8748)
* Reorg * Move animation into css file * Update style comment * Extract core component, use platform-specific wrappers * Pull out platform specific styles * Just move styles into Toast component itself * Rename cleanup * Update API * Add duration optional prop * Add some type docs * add exp eased slide aniamtions * Make toasts full width on mobile web --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/view/com/util/Toast.web.tsx')
-rw-r--r-- | src/view/com/util/Toast.web.tsx | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx deleted file mode 100644 index 6b99b30bf..000000000 --- a/src/view/com/util/Toast.web.tsx +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Note: the dataSet properties are used to leverage custom CSS in public/index.html - */ - -import {useEffect, useState} from 'react' -import {Pressable, StyleSheet, Text, View} from 'react-native' - -import { - convertLegacyToastType, - getToastTypeStyles, - getToastWebAnimationStyles, - type LegacyToastType, - TOAST_TYPE_TO_ICON, - TOAST_WEB_KEYFRAMES, - type ToastType, -} from '#/view/com/util/Toast.style' -import {atoms as a, useTheme} from '#/alf' - -const DURATION = 3500 - -interface ActiveToast { - text: string - type: ToastType -} -type GlobalSetActiveToast = (_activeToast: ActiveToast | undefined) => void - -// globals -// = -let globalSetActiveToast: GlobalSetActiveToast | undefined -let toastTimeout: NodeJS.Timeout | undefined - -// components -// = -type ToastContainerProps = {} -export const ToastContainer: React.FC<ToastContainerProps> = ({}) => { - const [activeToast, setActiveToast] = useState<ActiveToast | undefined>() - const [isExiting, setIsExiting] = useState(false) - - useEffect(() => { - globalSetActiveToast = (t: ActiveToast | undefined) => { - if (!t && activeToast) { - setIsExiting(true) - setTimeout(() => { - setActiveToast(t) - setIsExiting(false) - }, 200) - } else { - setActiveToast(t) - setIsExiting(false) - } - } - }, [activeToast]) - - useEffect(() => { - const styleId = 'toast-animations' - if (!document.getElementById(styleId)) { - const style = document.createElement('style') - style.id = styleId - style.textContent = TOAST_WEB_KEYFRAMES - document.head.appendChild(style) - } - }, []) - - const t = useTheme() - - const toastTypeStyles = getToastTypeStyles(t) - const toastStyles = activeToast - ? toastTypeStyles[activeToast.type] - : toastTypeStyles.default - - const IconComponent = activeToast - ? TOAST_TYPE_TO_ICON[activeToast.type] - : TOAST_TYPE_TO_ICON.default - - const animationStyles = getToastWebAnimationStyles() - - return ( - <> - {activeToast && ( - <View - style={[ - styles.container, - { - backgroundColor: toastStyles.backgroundColor, - borderColor: toastStyles.borderColor, - ...(isExiting - ? animationStyles.exiting - : animationStyles.entering), - }, - ]}> - <View - style={[ - styles.iconContainer, - { - backgroundColor: 'transparent', - }, - ]}> - <IconComponent - fill={toastStyles.iconColor} - size="sm" - style={styles.icon} - /> - </View> - <Text - style={[ - styles.text, - a.text_sm, - a.font_bold, - {color: toastStyles.textColor}, - ]}> - {activeToast.text} - </Text> - <Pressable - style={styles.dismissBackdrop} - accessibilityLabel="Dismiss" - accessibilityHint="" - onPress={() => { - setActiveToast(undefined) - }} - /> - </View> - )} - </> - ) -} - -// methods -// = - -export function show( - text: string, - type: ToastType | LegacyToastType = 'default', -) { - if (toastTimeout) { - clearTimeout(toastTimeout) - } - - globalSetActiveToast?.({text, type: convertLegacyToastType(type)}) - toastTimeout = setTimeout(() => { - globalSetActiveToast?.(undefined) - }, DURATION) -} - -const styles = StyleSheet.create({ - container: { - // @ts-ignore web only - position: 'fixed', - left: 20, - bottom: 20, - // @ts-ignore web only - width: 'calc(100% - 40px)', - maxWidth: 380, - padding: 20, - flexDirection: 'row', - alignItems: 'center', - borderRadius: 10, - borderWidth: 1, - }, - dismissBackdrop: { - position: 'absolute', - top: 0, - left: 0, - bottom: 0, - right: 0, - }, - iconContainer: { - width: 32, - height: 32, - borderRadius: 16, - alignItems: 'center', - justifyContent: 'center', - flexShrink: 0, - }, - icon: { - flexShrink: 0, - }, - text: { - marginLeft: 10, - }, -}) |