Snackbar 10.16.0

ARIA
RTL

The snackbar component is a non-disruptive message that appears on the interface to provide quick, at-a-glance feedback on the outcome of an action.

Based on Radix.

Anatomy

<Snackbar>
  <Snackbar.Icon>...</Snackbar.Icon>
  <Snackbar.Content>
    <Snackbar.Header>...</Snackbar.Header>
    <Snackbar.Message>...</Snackbar.Message>
  </Snackbar.Content>
  <Snackbar.Close />
</Snackbar>

Default

    "use client";
    
    import { Snackbar, Button } from "@heathmont/moon-core-tw";
    import { useState, useCallback } from "react";
    
    const Default = () => {
      const [snackbar, setSnackbar] = useState("");
    
      const openSnackbarHandler = useCallback(
        (type: string) => {
          if (snackbar) {
            setSnackbar("");
            setTimeout(() => {
              setSnackbar(type);
            }, 400);
          } else {
            setSnackbar(type);
          }
        },
        [snackbar],
      );
    
      return (
        <div>
          <Button variant="outline" onClick={() => openSnackbarHandler("default")}>
            Default
          </Button>
          <Snackbar isOpen={snackbar === "default"} onOpenChange={setSnackbar}>
            <Snackbar.Message>Snackbar message</Snackbar.Message>
          </Snackbar>
        </div>
      );
    };
    
    export default Default;
    

      Positions

      Using the position property allows you to position <Snackbar /> in six different locations where it is the most effective: top-left, top-center, top-right, bottom-left, bottom-center, and bottom-right. If not specified, top-right is the default position.

                  "use client";
                  
                  import { Snackbar, Button } from "@heathmont/moon-core-tw";
                  import { useCallback, useState } from "react";
                  
                  const Positions = () => {
                    const [snackbar, setSnackbar] = useState("");
                  
                    const openSnackbarHandler = useCallback(
                      (type: string) => {
                        if (snackbar) {
                          setSnackbar("");
                          setTimeout(() => {
                            setSnackbar(type);
                          }, 400);
                        } else {
                          setSnackbar(type);
                        }
                      },
                      [snackbar],
                    );
                  
                    return (
                      <>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("top-left")}
                          >
                            Top left
                          </Button>
                          <Snackbar
                            isOpen={snackbar === "top-left"}
                            onOpenChange={setSnackbar}
                            position="top-left"
                          >
                            <Snackbar.Message>
                              Snackbar at top-left screen corner
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("top-center")}
                          >
                            Top center
                          </Button>
                          <Snackbar
                            isOpen={snackbar === "top-center"}
                            onOpenChange={setSnackbar}
                            position="top-center"
                          >
                            <Snackbar.Message>
                              Snackbar at top-center screen edge
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("top-right")}
                          >
                            Top right
                          </Button>
                          <Snackbar isOpen={snackbar === "top-right"} onOpenChange={setSnackbar}>
                            <Snackbar.Message>
                              Snackbar at top-right screen corner
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("bottom-left")}
                          >
                            Bottom left
                          </Button>
                          <Snackbar
                            isOpen={snackbar === "bottom-left"}
                            onOpenChange={setSnackbar}
                            position="bottom-left"
                          >
                            <Snackbar.Message>
                              Snackbar at bottom-left screen corner
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("bottom-center")}
                          >
                            Bottom center
                          </Button>
                          <Snackbar
                            isOpen={snackbar === "bottom-center"}
                            onOpenChange={setSnackbar}
                            position="bottom-center"
                          >
                            <Snackbar.Message>
                              Snackbar at bottom-center screen edge
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                        <div>
                          <Button
                            variant="outline"
                            onClick={() => openSnackbarHandler("bottom-right")}
                          >
                            Bottom right
                          </Button>
                          <Snackbar
                            isOpen={snackbar === "bottom-right"}
                            onOpenChange={setSnackbar}
                            position="bottom-right"
                          >
                            <Snackbar.Message>
                              Snackbar at bottom-right screen corner
                            </Snackbar.Message>
                          </Snackbar>
                        </div>
                      </>
                    );
                  };
                  
                  export default Positions;
                  

                    Options

                    As a compound component, <Snackbar /> allows you to tailor its content according to your preferences. Utilize one or several <Snackbar.Message /> sub-components for a single-line or multiline option. Sub-elements like <Snackbar.Header />, <Snackbar.Close />, and <Snackbar.Icon /> add their respective content. Simply follow the component structure illustrated in the anatomy snippet above and combine the content as needed.

                                "use client";
                                
                                import { Snackbar, Button } from "@heathmont/moon-core-tw";
                                import { OtherFrame } from "@heathmont/moon-icons-tw";
                                import { useCallback, useState } from "react";
                                
                                const Options = () => {
                                  const [snackbar, setSnackbar] = useState("");
                                
                                  const openSnackbarHandler = useCallback(
                                    (type: string) => {
                                      if (snackbar) {
                                        setSnackbar("");
                                        setTimeout(() => {
                                          setSnackbar(type);
                                        }, 400);
                                      } else {
                                        setSnackbar(type);
                                      }
                                    },
                                    [snackbar],
                                  );
                                
                                  return (
                                    <>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("multiline")}
                                        >
                                          Multi Line
                                        </Button>
                                        <Snackbar isOpen={snackbar === "multiline"} onOpenChange={setSnackbar}>
                                          <Snackbar.Content>
                                            <Snackbar.Message>Snackbar message.</Snackbar.Message>
                                            <Snackbar.Message>
                                              Snackbar the second line message
                                            </Snackbar.Message>
                                          </Snackbar.Content>
                                        </Snackbar>
                                      </div>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("with-header")}
                                        >
                                          With Header
                                        </Button>
                                        <Snackbar
                                          isOpen={snackbar === "with-header"}
                                          onOpenChange={setSnackbar}
                                        >
                                          <Snackbar.Content>
                                            <Snackbar.Header>Info</Snackbar.Header>
                                            <Snackbar.Message>Snackbar message</Snackbar.Message>
                                          </Snackbar.Content>
                                        </Snackbar>
                                      </div>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("with-close")}
                                        >
                                          With Close
                                        </Button>
                                        <Snackbar isOpen={snackbar === "with-close"} onOpenChange={setSnackbar}>
                                          <Snackbar.Message>Snackbar message</Snackbar.Message>
                                          <Snackbar.Close />
                                        </Snackbar>
                                      </div>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("with-icon")}
                                        >
                                          With Icon
                                        </Button>
                                        <Snackbar isOpen={snackbar === "with-icon"} onOpenChange={setSnackbar}>
                                          <Snackbar.Icon>
                                            <OtherFrame />
                                          </Snackbar.Icon>
                                          <Snackbar.Message>Snackbar message</Snackbar.Message>
                                        </Snackbar>
                                      </div>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("multiline-with-icon")}
                                        >
                                          Multi Line with Icon
                                        </Button>
                                        <Snackbar
                                          isOpen={snackbar === "multiline-with-icon"}
                                          onOpenChange={setSnackbar}
                                        >
                                          <Snackbar.Icon className="h-10">
                                            <OtherFrame />
                                          </Snackbar.Icon>
                                          <Snackbar.Content>
                                            <Snackbar.Message>Snackbar message.</Snackbar.Message>
                                            <Snackbar.Message>
                                              Snackbar the second line message
                                            </Snackbar.Message>
                                          </Snackbar.Content>
                                        </Snackbar>
                                      </div>
                                      <div>
                                        <Button
                                          variant="outline"
                                          onClick={() => openSnackbarHandler("with-close-and-icon")}
                                        >
                                          With Close and Icon
                                        </Button>
                                        <Snackbar
                                          isOpen={snackbar === "with-close-and-icon"}
                                          onOpenChange={setSnackbar}
                                        >
                                          <Snackbar.Icon>
                                            <OtherFrame />
                                          </Snackbar.Icon>
                                          <Snackbar.Message>Snackbar message</Snackbar.Message>
                                          <Snackbar.Close />
                                        </Snackbar>
                                      </div>
                                    </>
                                  );
                                };
                                
                                export default Options;
                                

                                  Semantic types

                                  To apply semantic styles like success, warning or error to the <Snackbar />, utilize CSS classes that correspond with the desired appearance.

                                        "use client";
                                        
                                        import { Snackbar, Button } from "@heathmont/moon-core-tw";
                                        import { OtherFrame } from "@heathmont/moon-icons-tw";
                                        import { useCallback, useState } from "react";
                                        
                                        const SemanticTypes = () => {
                                          const [snackbar, setSnackbar] = useState("");
                                        
                                          const openSnackbarHandler = useCallback(
                                            (type: string) => {
                                              if (snackbar) {
                                                setSnackbar("");
                                                setTimeout(() => {
                                                  setSnackbar(type);
                                                }, 400);
                                              } else {
                                                setSnackbar(type);
                                              }
                                            },
                                            [snackbar],
                                          );
                                        
                                          return (
                                            <>
                                              <div>
                                                <Button
                                                  variant="outline"
                                                  onClick={() => openSnackbarHandler("success")}
                                                >
                                                  Success
                                                </Button>
                                                <Snackbar isOpen={snackbar === "success"} onOpenChange={setSnackbar}>
                                                  <Snackbar.Icon className="h-10 bg-roshi-10 text-roshi">
                                                    <OtherFrame />
                                                  </Snackbar.Icon>
                                                  <Snackbar.Content>
                                                    <Snackbar.Header>Success</Snackbar.Header>
                                                    <Snackbar.Message>Snackbar message</Snackbar.Message>
                                                  </Snackbar.Content>
                                                  <Snackbar.Close />
                                                </Snackbar>
                                              </div>
                                              <div>
                                                <Button
                                                  variant="outline"
                                                  onClick={() => openSnackbarHandler("warning")}
                                                >
                                                  Warning
                                                </Button>
                                                <Snackbar isOpen={snackbar === "warning"} onOpenChange={setSnackbar}>
                                                  <Snackbar.Icon className="h-10 bg-krillin-10 text-krillin">
                                                    <OtherFrame />
                                                  </Snackbar.Icon>
                                                  <Snackbar.Content>
                                                    <Snackbar.Header>Warning</Snackbar.Header>
                                                    <Snackbar.Message>Snackbar message</Snackbar.Message>
                                                  </Snackbar.Content>
                                                  <Snackbar.Close />
                                                </Snackbar>
                                              </div>
                                              <div>
                                                <Button variant="outline" onClick={() => openSnackbarHandler("error")}>
                                                  Error
                                                </Button>
                                                <Snackbar isOpen={snackbar === "error"} onOpenChange={setSnackbar}>
                                                  <Snackbar.Icon className="h-10 bg-chichi-10 text-chichi">
                                                    <OtherFrame />
                                                  </Snackbar.Icon>
                                                  <Snackbar.Content>
                                                    <Snackbar.Header>Error</Snackbar.Header>
                                                    <Snackbar.Message>Snackbar message</Snackbar.Message>
                                                  </Snackbar.Content>
                                                  <Snackbar.Close />
                                                </Snackbar>
                                              </div>
                                            </>
                                          );
                                        };
                                        
                                        export default SemanticTypes;
                                        

                                          Auto close

                                          The autoClose property allows you to adjust the duration of the <Snackbar /> visibility. If not defined, the default duration is 5000ms.

                                              "use client";
                                              
                                              import { Snackbar, Button } from "@heathmont/moon-core-tw";
                                              import { useState, useCallback } from "react";
                                              
                                              const AutoClose = () => {
                                                const [snackbar, setSnackbar] = useState("");
                                              
                                                const openSnackbarHandler = useCallback(
                                                  (type: string) => {
                                                    if (snackbar) {
                                                      setSnackbar("");
                                                      setTimeout(() => {
                                                        setSnackbar(type);
                                                      }, 400);
                                                    } else {
                                                      setSnackbar(type);
                                                    }
                                                  },
                                                  [snackbar],
                                                );
                                              
                                                return (
                                                  <>
                                                    <div>
                                                      <Button
                                                        variant="outline"
                                                        onClick={() => openSnackbarHandler("one-sec")}
                                                      >
                                                        Close after 1 sec
                                                      </Button>
                                                      <Snackbar
                                                        isOpen={snackbar === "one-sec"}
                                                        onOpenChange={setSnackbar}
                                                        autoClose={1000}
                                                      >
                                                        <Snackbar.Message>Snackbar message</Snackbar.Message>
                                                      </Snackbar>
                                                    </div>
                                                    <div>
                                                      <Button
                                                        variant="outline"
                                                        onClick={() => openSnackbarHandler("three-sec")}
                                                      >
                                                        Close after 3 sec
                                                      </Button>
                                                      <Snackbar
                                                        isOpen={snackbar === "three-sec"}
                                                        onOpenChange={setSnackbar}
                                                        autoClose={3000}
                                                      >
                                                        <Snackbar.Message>Snackbar message</Snackbar.Message>
                                                      </Snackbar>
                                                    </div>
                                                  </>
                                                );
                                              };
                                              
                                              export default AutoClose;
                                              

                                                Customization

                                                In case you need to add some extra styling to the <Snackbar/> component, you can easily use the className property. It applies not only to the <Snackbar /> component itself but also to all its sub-components - <Snackbar.Icon />, <Snackbar.Close />, <Snackbar.Content />, <Snackbar.Header /> and <Snackbar.Message />.

                                                            "use client";
                                                            
                                                            import { Snackbar, Button } from "@heathmont/moon-core-tw";
                                                            import { useState, useCallback } from "react";
                                                            
                                                            const Customization = () => {
                                                              const [snackbar, setSnackbar] = useState("");
                                                            
                                                              const openSnackbarHandler = useCallback(
                                                                (type: string) => {
                                                                  if (snackbar) {
                                                                    setSnackbar("");
                                                                    setTimeout(() => {
                                                                      setSnackbar(type);
                                                                    }, 400);
                                                                  } else {
                                                                    setSnackbar(type);
                                                                  }
                                                                },
                                                                [snackbar],
                                                              );
                                                            
                                                              return (
                                                                <>
                                                                  <div>
                                                                    <Button
                                                                      variant="outline"
                                                                      onClick={() => openSnackbarHandler("border-radius")}
                                                                    >
                                                                      Border radius
                                                                    </Button>
                                                                    <Snackbar
                                                                      isOpen={snackbar === "border-radius"}
                                                                      onOpenChange={setSnackbar}
                                                                      className="rounded-none"
                                                                    >
                                                                      <Snackbar.Message>Custom border radius</Snackbar.Message>
                                                                    </Snackbar>
                                                                  </div>
                                                                  <div>
                                                                    <Button
                                                                      variant="outline"
                                                                      onClick={() => openSnackbarHandler("background")}
                                                                    >
                                                                      Background
                                                                    </Button>
                                                                    <Snackbar
                                                                      isOpen={snackbar === "background"}
                                                                      onOpenChange={setSnackbar}
                                                                      className="bg-roshi"
                                                                    >
                                                                      <Snackbar.Message>Custom background color</Snackbar.Message>
                                                                    </Snackbar>
                                                                  </div>
                                                                  <div>
                                                                    <Button variant="outline" onClick={() => openSnackbarHandler("width")}>
                                                                      Width
                                                                    </Button>
                                                                    <Snackbar
                                                                      isOpen={snackbar === "width"}
                                                                      onOpenChange={setSnackbar}
                                                                      className="w-72"
                                                                    >
                                                                      <Snackbar.Message>Custom width</Snackbar.Message>
                                                                    </Snackbar>
                                                                  </div>
                                                                  <div>
                                                                    <Button
                                                                      variant="outline"
                                                                      onClick={() => openSnackbarHandler("always-light")}
                                                                    >
                                                                      Always light
                                                                    </Button>
                                                                    <Snackbar
                                                                      isOpen={snackbar === "always-light"}
                                                                      onOpenChange={setSnackbar}
                                                                      className="theme-moon-light"
                                                                    >
                                                                      <Snackbar.Message>Applying light theme</Snackbar.Message>
                                                                    </Snackbar>
                                                                  </div>
                                                                  <div>
                                                                    <Button
                                                                      variant="outline"
                                                                      onClick={() => openSnackbarHandler("always-dark")}
                                                                    >
                                                                      Always dark
                                                                    </Button>
                                                                    <Snackbar
                                                                      isOpen={snackbar === "always-dark"}
                                                                      onOpenChange={setSnackbar}
                                                                      className="theme-moon-dark"
                                                                    >
                                                                      <Snackbar.Message>Applying dark theme</Snackbar.Message>
                                                                    </Snackbar>
                                                                  </div>
                                                                  <div>
                                                                    <Button variant="outline" onClick={() => openSnackbarHandler("fonts")}>
                                                                      Fonts
                                                                    </Button>
                                                                    <Snackbar isOpen={snackbar === "fonts"} onOpenChange={setSnackbar}>
                                                                      <Snackbar.Content>
                                                                        <Snackbar.Message className="text-moon-24 text-chichi">
                                                                          Custom fonts.
                                                                        </Snackbar.Message>
                                                                        <Snackbar.Message className="text-moon-12 font-medium">
                                                                          Even more custom fonts.
                                                                        </Snackbar.Message>
                                                                      </Snackbar.Content>
                                                                    </Snackbar>
                                                                  </div>
                                                                </>
                                                              );
                                                            };
                                                            
                                                            export default Customization;
                                                            

                                                              Snackbar Queue

                                                              This example demonstrates the use of the <Snackbar /> component for managing queued notifications.

                                                                "use client";
                                                                
                                                                import { useState, useCallback } from "react";
                                                                import { Snackbar, Button } from "@heathmont/moon-core-tw";
                                                                
                                                                type NotificationType = {
                                                                  message: string;
                                                                  type: string;
                                                                };
                                                                
                                                                type QueueType = [
                                                                  list: NotificationType[],
                                                                  options: {
                                                                    dequeue: () => NotificationType | undefined;
                                                                    enqueue: (item: NotificationType) => number;
                                                                    length: number;
                                                                    peek: () => NotificationType | undefined;
                                                                  },
                                                                ];
                                                                
                                                                const useQueueState = (initialList: NotificationType[]): QueueType => {
                                                                  const [list, setList] = useState<NotificationType[]>([...initialList]);
                                                                  const enqueue = useCallback(
                                                                    (item: NotificationType) => {
                                                                      const newList = [...list, item];
                                                                      setList(newList);
                                                                      return newList.length;
                                                                    },
                                                                    [list],
                                                                  );
                                                                
                                                                  const dequeue = useCallback(() => {
                                                                    if (list.length > 0) {
                                                                      const firstItem = list[0];
                                                                      setList([...list.slice(1)]);
                                                                      return firstItem;
                                                                    }
                                                                    return undefined;
                                                                  }, [list]);
                                                                
                                                                  const peek = useCallback(() => {
                                                                    if (list.length > 0) {
                                                                      return list[0];
                                                                    }
                                                                    return undefined;
                                                                  }, [list]);
                                                                
                                                                  const options = {
                                                                    dequeue,
                                                                    enqueue,
                                                                    length: list.length,
                                                                    peek,
                                                                  };
                                                                
                                                                  return [list, options];
                                                                };
                                                                
                                                                const delay = (delayMs: number) =>
                                                                  new Promise<void>((resolve) => {
                                                                    setTimeout(() => {
                                                                      resolve();
                                                                    }, delayMs);
                                                                  });
                                                                
                                                                const SnackbarQueue = () => {
                                                                  const [list, options] = useQueueState([] as NotificationType[]);
                                                                  const [isAnimated, setIsAnimated] = useState(false);
                                                                  const onOpenChange = async () => {
                                                                    setIsAnimated(true);
                                                                    await delay(100);
                                                                    setIsAnimated(false);
                                                                    options.dequeue();
                                                                  };
                                                                  const openSnackbarHandler = useCallback(
                                                                    (notification: NotificationType) => {
                                                                      options.enqueue(notification);
                                                                    },
                                                                    [options],
                                                                  );
                                                                  const isOpen = options?.length > 0 && !isAnimated;
                                                                  return (
                                                                    <div>
                                                                      <Button
                                                                        variant="outline"
                                                                        onClick={() =>
                                                                          openSnackbarHandler({
                                                                            message: `Number ${options.length + 1} Snackbar`,
                                                                            type: "info",
                                                                          })
                                                                        }
                                                                      >
                                                                        Queue Snackbar
                                                                      </Button>
                                                                      <Snackbar isOpen={isOpen} onOpenChange={onOpenChange}>
                                                                        <Snackbar.Message>{options?.peek()?.message}</Snackbar.Message>
                                                                        <Snackbar.Close />
                                                                      </Snackbar>
                                                                    </div>
                                                                  );
                                                                };
                                                                
                                                                export default SnackbarQueue;
                                                                

                                                                  Snackbar

                                                                  These are props specific to the Snackbar component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  autoClose
                                                                  number5000
                                                                  children
                                                                  "React.ReactNode"-
                                                                  className
                                                                  string-
                                                                  isOpen*
                                                                  boolean-
                                                                  position
                                                                  top-right
                                                                  onOpenChange*
                                                                  "() => void"-

                                                                  Properties indicated with * are required.

                                                                  Snackbar.Content

                                                                  These are props specific to the Snackbar.Content component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  children
                                                                  "React.ReactNode"-
                                                                  className
                                                                  string-

                                                                  Snackbar.Header

                                                                  These are props specific to the Snackbar.Header component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  children
                                                                  "React.ReactNode"-
                                                                  className
                                                                  string-

                                                                  Snackbar.Message

                                                                  These are props specific to the Snackbar.Message component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  children
                                                                  "React.ReactNode"-
                                                                  className
                                                                  string-

                                                                  Snackbar.Icon

                                                                  These are props specific to the Snackbar.Icon component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  children
                                                                  "React.ReactNode"-
                                                                  className
                                                                  string-

                                                                  Snackbar.Close

                                                                  These are props specific to the Snackbar.Close component:

                                                                  Name
                                                                  Type
                                                                  Default
                                                                  ariaLabel
                                                                  stringClose
                                                                  className
                                                                  string-