import { Stack, Box, Wrap, WrapItem } from '@chakra-ui/react';
import { ArgsTable, Story, Canvas } from '@storybook/addon-docs';
import { useRef } from 'react';

import { useToast, createStandaloneToast } from '.';
import { Toast } from './toast';
import Button from '../button';

<Meta title="反馈/提示 Toast" />

# 提示 Toast

用于在覆盖层顶部显示警报。

## 导入

```typescript
import { useToast } from '@ahri-ui/core';
```

## 使用

<Canvas>
  <Story name="默认">
    {() => {
      const toast = useToast();
      return (
        <Button
          onClick={() =>
            toast({
              title: 'Account created.',
              description: "We've created your account for you.",
              duration: null,
            })
          }
        >
          Show Toast
        </Button>
      );
    }}
  </Story>
</Canvas>

### 自定义

<Canvas>
  <Story name="自定义">
    {() => {
      const toast = useToast();
      return (
        <Button
          onClick={() =>
            toast({
              position: 'bottom-left',
              render: () => (
                <Box color="red" p={3} bg="blue.500">
                  Hello World
                </Box>
              ),
            })
          }
        >
          Show Toast
        </Button>
      );
    }}
  </Story>
</Canvas>

### 关闭

Toast 可以命令式地、单独地（通过 `close` 实例方法）或一起（通过 `closeAll` 实例方法）关闭。

<Canvas>
  <Story name="关闭">
    {() => {
      const toast = useToast();
      const toastIdRef = React.useRef();
      return (
        <Stack isInline spacing={2}>
          <Button
            type="button"
            onClick={() => (toastIdRef.current = toast({ description: 'some text' }))}
          >
            Toast
          </Button>
          <Button
            type="button"
            variant="outline"
            onClick={() => {
              toastIdRef.current ? toast.close(toastIdRef.current) : null;
            }}
          >
            Close last toast
          </Button>
          <Button type="button" variant="outline" onClick={() => toast.closeAll()}>
            Close all toasts
          </Button>
        </Stack>
      );
    }}
  </Story>
</Canvas>

### 状态

传递 `status` 属性，并将其设置为 `success`、`error`、`warning`、`info` 更改提示的颜色。

<Canvas>
  <Story name="状态">
    {() => {
      const toast = useToast();
      const statuses = ['success', 'error', 'warning', 'info'];
      return (
        <Wrap>
          {statuses.map((status, i) => (
            <WrapItem key={i}>
              <Button
                onClick={() =>
                  toast({
                    title: `${status} toast`,
                    status: status,
                    isClosable: true,
                  })
                }
              >
                展示 {status} 状态
              </Button>
            </WrapItem>
          ))}
        </Wrap>
      );
    }}
  </Story>
</Canvas>

### 变种

传递 `variant` 属性，并将其设置为 `solid`、`subtle`、`left-accent`、`top-accent` 以获得不同的风格。

<Canvas>
  <Story name="变种">
    {() => {
      const toast = useToast();
      const variants = ['solid', 'subtle', 'left-accent', 'top-accent'];
      return (
        <Wrap>
          {variants.map((variant, i) => (
            <WrapItem key={i}>
              <Button
                onClick={() =>
                  toast({
                    title: `${variant} toast`,
                    variant: variant,
                    isClosable: true,
                  })
                }
              >
                展示 {variant} 风格
              </Button>
            </WrapItem>
          ))}
        </Wrap>
      );
    }}
  </Story>
</Canvas>

### 位置

传递 `position` 属性，并将其设置为 `top`、`top-right`、`top-left`、`bottom`、`bottom-right`、`bottom-left` 以调整提示的弹出位置。

<Canvas>
  <Story name="位置">
    {() => {
      const toast = useToast();
      const positions = ['top', 'top-right', 'top-left', 'bottom', 'bottom-right', 'bottom-left'];
      return (
        <Wrap>
          {positions.map((position, i) => (
            <WrapItem key={i}>
              <Button
                onClick={() =>
                  toast({
                    title: `${position} toast`,
                    position: position,
                    isClosable: true,
                  })
                }
              >
                在 {position} 展示
              </Button>
            </WrapItem>
          ))}
        </Wrap>
      );
    }}
  </Story>
</Canvas>

### 防止重复出现

在某些情况下，您可能需要防止重复特定的 toast。要实现，您需要传递 `id` 并使用该 `toast.isActive` 方法来确定何时调用 `toast(...)`。

<Canvas>
  <Story name="防止重复出现">
    {() => {
      const toast = useToast();
      const id = 'test-toast';
      return (
        <Button
          onClick={() => {
            if (!toast.isActive(id)) {
              toast({
                id,
                title: 'Hey! You can create a duplicate toast',
              });
            }
          }}
        >
          Click me!
        </Button>
      );
    }}
  </Story>
</Canvas>

### 独立的提示

用于 `createStandaloneToast` 从 React 组件外部创建 Toast。

<Canvas>
  <Story name="独立的提示">
    {() => {
      const toast = createStandaloneToast();
      return (
        <Button
          onClick={() =>
            toast({
              title: 'An error occurred.',
              description: 'Unable to create user account.',
              status: 'error',
              duration: 9000,
              isClosable: true,
            })
          }
        >
          Show Toast
        </Button>
      );
    }}
  </Story>
</Canvas>

### 更新

使用 update 方法传递 id 和新选择或使用 ref 存储 id 来更新

<Canvas>
  <Story name="更新">
    {() => {
      const toast = useToast();
      const toastIdRef = useRef();
      return (
        <Stack>
          <Stack isInline spacing={2}>
            <span>第一种</span>
            <Button
              onClick={() =>
                toast({
                  id: 'updateToast',
                  title: 'title',
                  description: 'some text',
                })
              }
            >
              自定义 id
            </Button>
            <Button
              onClick={() =>
                toast.update('updateToast', { title: '更新了', description: '更新了' })
              }
            >
              直接传递 id 更新
            </Button>
          </Stack>
          <Stack isInline spacing={2}>
            <span>第二种</span>
            <Button
              onClick={() => {
                toastIdRef.current = toast({
                  title: 'title',
                  description: 'some text',
                });
              }}
            >
              ref 保存 Toast id
            </Button>
            <Button
              onClick={() =>
                toast.update(toastIdRef.current, { title: '更新了', description: '更新了' })
              }
            >
              ref 传递 id 更新
            </Button>
          </Stack>
        </Stack>
      );
    }}
  </Story>
</Canvas>

## 参数

<ArgsTable of={Toast} />
