forked from gitcoinco/gitcoin-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
creates modular toast component (gitcoinco#39)
* creates modular toast component * chore: extended tailwind theme * chore: toast - changed styles and added override of close button * removed shadcn toast * seperated toast and toaster migrated story to components/toaster * fixed interface nicer --------- Co-authored-by: Hussein Martinez <husse.dev@gmail.com>
- Loading branch information
Showing
13 changed files
with
549 additions
and
158 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { Meta } from "@storybook/blocks"; | ||
|
||
import * as ToasterStories from "./Toaster.stories"; | ||
|
||
<Meta of={ToasterStories} /> | ||
|
||
# Toaster Component | ||
|
||
The `Toaster` component works with the `useToast` hook to display toast notifications in your app. | ||
|
||
## Usage | ||
|
||
1. **Add the Toaster**: Place the `Toaster` at the root of your app. | ||
|
||
```tsx | ||
import { Toaster } from "./Toaster"; | ||
|
||
function App() { | ||
return ( | ||
<> | ||
<Toaster /> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
2. **Trigger a Toast**: Use the `useToast` hook in your components. | ||
|
||
```tsx | ||
import { useToast } from "@/hooks/use-toast"; | ||
import { Button } from "@/primitives/Button"; | ||
|
||
function TriggerButton() { | ||
const { toast } = useToast(); | ||
|
||
const triggerToast = () => { | ||
toast({ | ||
status: "error", // Variant of the toast (success, error, warning, info) | ||
description: "Something went wrong! Please try again.", // Message content | ||
timeout: 5000, // Duration before auto-dismissal | ||
toastPosition: "bottom-right", // Where the toast appears on screen | ||
toastSize: "large", // Size of the toast (small, medium, large) | ||
descriptionSize: "large", // Size of the description text | ||
toastCloseVariant: "alwaysVisible", // Style for the close action | ||
}); | ||
}; | ||
} | ||
``` | ||
|
||
# ToasterStories Component | ||
|
||
The `ToasterStories` component is a flexible UI element used to display brief messages to users. It can be customized in various ways to suit different needs. | ||
|
||
## Toast Component Variations | ||
|
||
### Status Variations | ||
|
||
- **Success**: Indicates a successful operation. | ||
- **Error**: Represents an error or failure. | ||
- **Info**: Provides informational messages. `(WIP)` | ||
- **Warning**: Alerts the user to a potential issue. `(WIP)` | ||
|
||
### Description | ||
|
||
- A string that provides additional context or information about the toast message. | ||
|
||
### Timeout | ||
|
||
- An optional number specifying how long the toast should be visible before automatically dismissing. | ||
|
||
### Position Variations (`toastPosition`) | ||
|
||
- Determines where on the viewport the toast will appear. The position is defined by the keys of the `viewportVariants.variants.position` object. | ||
|
||
### Description Size Variations (`descriptionSize`) | ||
|
||
- Specifies the size of the description text, based on the keys of the `toastDescriptionVariants.variants.size` object. | ||
|
||
### Toast Size Variations (`toastSize`) | ||
|
||
- Defines the overall size of the toast, based on the keys of the `toastVariants.variants.size` object. | ||
|
||
### Toast Close Variant (`toastCloseVariant`) | ||
|
||
- Specifies the style of the close button, based on the keys of the `toastCloseVariants.variants.variant` object. | ||
|
||
These variations allow the `Toast` component to be highly customizable, providing flexibility in both appearance and behavior to suit different use cases. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Toast.stories.tsx | ||
import { Meta } from "@storybook/react"; | ||
|
||
import { useToast } from "@/hooks/use-toast"; | ||
import { Button } from "@/primitives/Button"; | ||
|
||
import { Toaster } from "./Toaster"; | ||
|
||
export default { | ||
title: "components/Toaster", | ||
decorators: [ | ||
(Story) => ( | ||
<> | ||
<Story /> | ||
<Toaster /> | ||
</> | ||
), | ||
], | ||
} as Meta; | ||
|
||
export const SuccessToast = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "success", | ||
description: "Your evaluation has been saved", | ||
timeout: 5000, | ||
}); | ||
}; | ||
return <Button onClick={showToast} variant="primary" value="Show Default Success Toast" />; | ||
}; | ||
|
||
export const ErrorToast = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "error", | ||
description: "Error: Your evaluation has not been saved. Please try again.", | ||
timeout: 5000, | ||
}); | ||
}; | ||
|
||
return <Button onClick={showToast} variant="primary" value="Show Default Error Toast" />; | ||
}; | ||
|
||
// You can add more stories for different positions and variants as needed. | ||
|
||
export const SuccessToastTopLeft = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "success", | ||
description: "Your evaluation has been saved", | ||
timeout: 5000, | ||
toastPosition: "top-left", | ||
}); | ||
}; | ||
return <Button onClick={showToast} variant="primary" value="Show Success Toast Top Left" />; | ||
}; | ||
|
||
export const ErrorToastTopRight = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "error", | ||
description: "Error: Your evaluation has not been saved. Please try again.", | ||
timeout: 5000, | ||
toastPosition: "top-right", | ||
}); | ||
}; | ||
return <Button onClick={showToast} variant="primary" value="Show Error Toast Top Right" />; | ||
}; | ||
|
||
export const SuccessToastBottomLeft = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "success", | ||
description: "Your evaluation has been saved", | ||
timeout: 5000, | ||
toastPosition: "bottom-left", | ||
}); | ||
}; | ||
return <Button onClick={showToast} variant="primary" value="Show Success Toast Bottom Left" />; | ||
}; | ||
|
||
export const ErrorToastTopCenter = () => { | ||
const { toast } = useToast(); | ||
|
||
const showToast = () => { | ||
toast({ | ||
status: "error", | ||
description: "Error: Your evaluation has not been saved. Please try again.", | ||
timeout: 5000, | ||
toastPosition: "top-center", | ||
}); | ||
}; | ||
return <Button onClick={showToast} variant="primary" value="Show Error Toast Bottom Right" />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Toast.tsx | ||
import { match } from "ts-pattern"; | ||
|
||
import { useToast, ToasterToast } from "@/hooks/use-toast"; | ||
import { Icon, IconType } from "@/primitives/Icon"; | ||
import { | ||
Toast, | ||
ToastProvider, | ||
ToastViewport, | ||
type viewportVariants, | ||
} from "@/primitives/Toast/Toast"; | ||
|
||
const Toaster = () => { | ||
const { toasts } = useToast(); | ||
|
||
// Group toasts by their toastPosition | ||
const toastsByPosition = toasts.reduce( | ||
(acc, toast) => { | ||
const position = (toast.toastPosition || "bottom-right") as string; | ||
if (!acc[position]) { | ||
acc[position] = []; | ||
} | ||
acc[position].push(toast); | ||
return acc; | ||
}, | ||
{} as Record<string, ToasterToast[]>, | ||
); | ||
|
||
return ( | ||
<ToastProvider> | ||
{Object.entries(toastsByPosition).map(([position, toasts]) => ( | ||
<ToastViewport | ||
key={position} | ||
position={position as keyof typeof viewportVariants.variants.position} | ||
> | ||
{toasts.map((toast) => { | ||
const ToastIcon = match(toast.status) | ||
.with("success", () => ( | ||
<Icon type={IconType.SOLID_CHECK} className="size-5 rounded-full" /> | ||
)) | ||
.with("error", () => <Icon type={IconType.SOLID_X} className="size-5 rounded-full" />) | ||
// .with("info", () => ( | ||
// <Icon type={IconType.SOLID_INFO} className="size-5 rounded-full" /> | ||
// )) | ||
// .with("warning", () => ( | ||
// <Icon type={IconType.SOLID_WARNING} className="size-5 rounded-full" /> | ||
// )) | ||
.otherwise(() => <Icon type={IconType.SOLID_X} className="size-5 rounded-full" />); | ||
return ( | ||
<Toast | ||
toast={{ | ||
...toast, | ||
icon: ToastIcon ?? IconType.SOLID_X, | ||
}} | ||
/> | ||
); | ||
})} | ||
</ToastViewport> | ||
))} | ||
</ToastProvider> | ||
); | ||
}; | ||
|
||
export { Toaster }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.