gluestack / gluestack-ui

React & React Native Components & Patterns (copy-paste components & patterns crafted with Tailwind CSS (NativeWind))
https://gluestack.io/
MIT License
2.71k stars 120 forks source link

Dismissable Toast Issues #1801

Open haruki-m opened 9 months ago

haruki-m commented 9 months ago

Description

I was following the example on Dismissable Toasts, but there are clear UI issues when there are icons next to ToastTitle and ToastDescription. If the description spans the toast container width, it gets pushed out of the view port by the icon. Also, if variant="accent", I couldn't find a way to change the color of the vertical strip on the left (looks off on dark mode). Lastly if I omit duration or set duration={null} the toast still disappears after a few seconds.

CodeSandbox/Snack link

No response

Steps to reproduce

import {
  Button,
  Icon,
  Pressable,
  Toast,
  ToastDescription,
  VStack,
  useToast,
} from '@gluestack-ui/themed'
import { AlertCircle as AlertIcon, X as CloseIcon } from 'lucide-react-native'

function Example() {
  const toast = useToast()
  return (
    <Button
      onPress={() => {
        toast.show({
          placement: "top",
          render: ({ id }) => {
            const toastId = "toast-" + id
            return (
              <Toast bg="$backgroundDarkWarning" nativeID={toastId} variant="accent" action="warning">
                <Icon as={AlertIcon} color="$white" mt="$1" mr="$3" />
                <VStack space="xs">
                  <ToastTitle color="$textLight50">
                    Warning
                  </ToastTitle>
                  <ToastDescription color="$textLight50">
                    This is a sample warning that is supposed to be multiple lines on a smart phone in portrait mode.
                  </ToastDescription>
                </VStack>
                <Pressable mt="$1" onPress={() => toast.close(id)}>
                  <Icon as={CloseIcon} color="$coolGray50" />
                </Pressable>
              </Toast>
            )
          },
        })
      }}
    >
      <ButtonText>Press Me</ButtonText>
    </Button>
  )
}

gluestack-ui Version

1.1.6

Platform

Other Platform

No response

Additional Information

No response

RishabhSahu24 commented 8 months ago

@haruki-m Thanks for reporting this. We're working on it.

RishabhSahu24 commented 8 months ago

@haruki-m Thank you for reporting the issue. We have addressed it and a pull request (PR) has been submitted.

Here are the modifications we suggest:

  1. FlexShrink in Vstack: Please consider adding flexShrink={1} in the Vstack to properly wrap the description text.
  2. Border Color Modification: If variant="accent", to change the color of borderLeft, you can pass borderColor="red" (or any color you prefer) to the toast component.
  3. Preserving Toast: If you want to preserve the toast notification on the screen until explicitly dismissed, you can pass duration=null.

I have provided the full code, for reference.

import { config } from "@gluestack-ui/config";
import {
  GluestackUIProvider,
  Button,
  ButtonText,
  Toast,
  ToastDescription,
  ToastTitle,
  VStack,
  useToast,
  Icon,
  Pressable,
  SafeAreaView,
} from "@gluestack-ui/themed";
import "react-native-svg";
import { AlertCircle as AlertIcon, X as CloseIcon } from "lucide-react-native";
export default function App() {
  return (
    <GluestackUIProvider config={config}>
      <SafeAreaView>
        <Example />
      </SafeAreaView>
    </GluestackUIProvider>
  );
}
function Example() {
  const toast = useToast();
  return (
    <Button
      mt={100}
      onPress={() => {
        toast.show({
          placement: "top",
          duration: null,
          render: ({ id }) => {
            const toastId = "toast-" + id;
            return (
              <Toast
                bg="$backgroundDarkWarning"
                nativeID={toastId}
                variant="accent"
                action="warning"
                borderColor="red"
              >
                <Icon as={AlertIcon} color="$white" mt="$1" mr="$3" />
                <VStack flexShrink={1} space="xs">
                  <ToastTitle color="$textLight50">Warning</ToastTitle>
                  <ToastDescription color="$textLight50">
                    Lorem ipsum dolor sit amet consectetur adipisicing elit.
                    Nesciunt nemo animi laborum quod eveniet ex, voluptates
                    fugit optio alias quam saepe Lorem, ipsum dolor. Lorem,
                    ipsum dolor. Lorem, ipsum dolor.
                  </ToastDescription>
                </VStack>
                <Pressable mt="$1" onPress={() => toast.close(id)}>
                  <Icon as={CloseIcon} color="$coolGray50" />
                </Pressable>
              </Toast>
            );
          },
        });
      }}
    >
      <ButtonText>Press Me</ButtonText>
    </Button>
  );
}
haruki-m commented 8 months ago

@RishabhSahu24 Thank you!