-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vue): add component toast (#632)
Co-authored-by: TylerAPfledderer <TylerAPfledderer@users.noreply.github.com> Co-authored-by: codebender828 <codebender828@gmail.com> Co-authored-by: codebender828 <codebender828@users.noreply.github.com>
- Loading branch information
1 parent
fff5982
commit f8b1603
Showing
19 changed files
with
708 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@ark-ui/vue': minor | ||
--- | ||
|
||
Add component `Toast` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
--- | ||
id: toast | ||
name: Toast | ||
description: | ||
The toast component is used to give feedback to users after an action has | ||
taken place. | ||
--- | ||
|
||
## Import | ||
|
||
```ts | ||
import { | ||
Toast, | ||
ToastCloseTrigger, | ||
ToastDescription, | ||
ToastGroup, | ||
ToastPlacements, | ||
ToastProvider, | ||
ToastTitle, | ||
useToast, | ||
} from '@ark-ui/vue' | ||
``` | ||
|
||
## Usage | ||
|
||
### Create the AppToastProvider | ||
|
||
Use the toast components to compose a `ToastProvider` for your application. The | ||
granular component structure allows access to every DOM element. | ||
|
||
```vue | ||
// app-toast-provider.vue | ||
<template> | ||
<ToastProvider> | ||
<ToastPlacements v-slot="{ placements }"> | ||
<ToastGroup | ||
v-for="(placement, placementIdx) in placements" | ||
:key="placementIdx" | ||
:placement="placement" | ||
v-slot="{ toasts }" | ||
> | ||
<Toast v-for="toast in toasts" :key="toast.id" :toast="toast"> | ||
<ToastTitle /> | ||
<ToastDescription /> | ||
<ToastCloseTrigger> | ||
<button>Close</button> | ||
</ToastCloseTrigger> | ||
</Toast> | ||
</ToastGroup> | ||
</ToastPlacements> | ||
<slot></slot> | ||
</ToastProvider> | ||
</template> | ||
<script setup lang="ts"> | ||
import { | ||
ToastPlacements, | ||
ToastGroup, | ||
Toast, | ||
ToastTitle, | ||
ToastDescription, | ||
ToastCloseTrigger, | ||
ToastProvider, | ||
} from '@ark-ui/vue' | ||
</script> | ||
``` | ||
|
||
### Create toasts with useToast | ||
|
||
The `useToast` hook is your _central toast intelligence unit_ to control the | ||
toasts in your application. Create, update, remove and upsert toasts with the | ||
returned `toast` instance. | ||
|
||
```vue | ||
// example-component.vue | ||
<template> | ||
<button @click="handleOnClick">Show Toast</button> | ||
</template> | ||
<script lang="ts" setup> | ||
const toast = useToast() | ||
const handleOnClick = () => { | ||
toast.value.create({ | ||
type: 'success', | ||
title: 'Form submitted', | ||
placement: 'bottom', | ||
}) | ||
} | ||
</script> | ||
``` | ||
|
||
#### Use the shorthand type methods | ||
|
||
Omitting the type property is supported for toasts with type `success`, | ||
`loading` and `error`. | ||
|
||
```tsx | ||
toast.value.success({ | ||
title: 'Form submitted', | ||
}) | ||
``` | ||
|
||
```tsx | ||
toast.value.error({ | ||
title: 'An error occurred. Please try again!', | ||
}) | ||
``` | ||
|
||
```tsx | ||
toast.value.loading({ | ||
title: 'Submitting form', | ||
}) | ||
``` | ||
|
||
### Update a toast by id | ||
|
||
Update the description or other options for an existing toast. | ||
|
||
```vue | ||
<template> | ||
<button @click="handleOnClick">Show Toast</button> | ||
</template> | ||
<script lang="ts" setup> | ||
const toast.value = useToast() | ||
async function submitForm() { | ||
// simulate very slow request - wait for 3 seconds | ||
await new Promise((r) => setTimeout(r, 3000)) | ||
} | ||
const handleOnClick = async () => { | ||
toast.value.create({ | ||
id: 'my-toast', | ||
title: 'Submitting form', | ||
placement: 'bottom', | ||
}) | ||
await submitForm() | ||
toast.value.update('my-toast', { | ||
title: 'Form submitted successfully', | ||
}) | ||
} | ||
</script> | ||
``` | ||
|
||
### Remove a toast by id | ||
|
||
Remove a visible toast imperatively. E.g. on an event or after a async task. | ||
|
||
```vue | ||
<template> | ||
<button @click="handleOnClick">Show Toast</button> | ||
</template> | ||
<script lang="ts" setup> | ||
const toast = useToast() | ||
async function submitForm() { | ||
// simulate very slow request - wait for 3 seconds | ||
await new Promise((r) => setTimeout(r, 3000)) | ||
} | ||
const handleOnClick = async () => { | ||
toast.value.create({ | ||
id: 'my-toast', | ||
title: 'Submitting form', | ||
placement: 'bottom', | ||
}) | ||
await submitForm() | ||
toast.value.remove('my-toast') | ||
} | ||
</script> | ||
``` | ||
|
||
### Upsert a toast by id | ||
|
||
`upsert` updates a toast if it exists, or it creates a new toast. | ||
|
||
```vue | ||
<template> | ||
<button @click="handleOnClick">Show Toast</button> | ||
</template> | ||
<script lang="ts" setup> | ||
const toast = useToast() | ||
async function submitForm() { | ||
// simulate very slow request - wait for 3 seconds | ||
await new Promise((r) => setTimeout(r, 3000)) | ||
} | ||
const handleOnClick = async () => { | ||
toast.value.upsert({ | ||
id: 'my-toast', | ||
title: 'Submitting form', | ||
placement: 'bottom', | ||
}) | ||
await submitForm() | ||
toast.remove('my-toast') | ||
} | ||
</script> | ||
``` | ||
|
||
### Visualize a Promise | ||
|
||
```vue | ||
<template> | ||
<button @click="handleOnClick">Show toast</button> | ||
</template> | ||
<script lang="ts" setup> | ||
const toast = useToast() | ||
async function submitForm() { | ||
// simulate very slow request - wait for 3 seconds | ||
await new Promise((r) => setTimeout(r, 3000)) | ||
} | ||
const handleOnClick = async () => { | ||
await toast.value.promise(submitForm(), { | ||
error: { | ||
id: 'error', | ||
type: 'error', | ||
title: 'An error occurred. Please try again!', | ||
placement: 'bottom', | ||
duration: Infinity, | ||
}, | ||
loading: { | ||
id: 'loading', | ||
type: 'loading', | ||
title: 'Submitting form. Please wait.', | ||
placement: 'bottom', | ||
duration: Infinity, | ||
}, | ||
success: { | ||
id: 'success', | ||
type: 'success', | ||
title: 'Successfully submitted form.', | ||
placement: 'bottom', | ||
duration: 3_000, | ||
}, | ||
}) | ||
} | ||
</script> | ||
``` | ||
|
||
### Toast visibility | ||
|
||
Check if a toast is visible by id with `isVisible`. | ||
|
||
```tsx | ||
const toast = useToast() | ||
|
||
const isVisible = computed(() => toast.value.isVisible('my-toast')) | ||
``` |
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,51 @@ | ||
{ | ||
"ToastProps": { "toast": { "type": "Service", "isRequired": true } }, | ||
"ToastGroupProps": { "placement": { "type": "Placement", "isRequired": true } }, | ||
"ToastProviderProps": { | ||
"dir": { | ||
"type": "'ltr' | 'rtl'", | ||
"isRequired": false, | ||
"description": "The document's text/writing direction." | ||
}, | ||
"getRootNode": { | ||
"type": "() => ShadowRoot | Node | Document", | ||
"isRequired": false, | ||
"description": "A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron." | ||
}, | ||
"gutter": { | ||
"type": "string", | ||
"isRequired": false, | ||
"description": "The gutter or spacing between toasts" | ||
}, | ||
"id": { | ||
"type": "string", | ||
"isRequired": false, | ||
"description": "The unique identifier of the machine." | ||
}, | ||
"max": { | ||
"type": "number", | ||
"isRequired": false, | ||
"description": "The maximum number of toasts that can be shown at once" | ||
}, | ||
"offsets": { | ||
"type": "string | Record<'top' | 'right' | 'bottom' | 'left', string>", | ||
"isRequired": false, | ||
"description": "The offset from the safe environment edge of the viewport" | ||
}, | ||
"pauseOnInteraction": { | ||
"type": "boolean", | ||
"isRequired": false, | ||
"description": "Whether to pause the toast when interacted with" | ||
}, | ||
"pauseOnPageIdle": { | ||
"type": "boolean", | ||
"isRequired": false, | ||
"description": "Whether to pause toast when the user leaves the browser tab" | ||
}, | ||
"zIndex": { | ||
"type": "number", | ||
"isRequired": false, | ||
"description": "The z-index applied to each toast group" | ||
} | ||
} | ||
} |
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,8 @@ | ||
export { Toast, type ToastProps } from './toast' | ||
export { ToastCloseTrigger } from './toast-close-trigger' | ||
export { ToastDescription, type ToastDescriptionProps } from './toast-description' | ||
export { ToastGroup, type ToastGroupProps } from './toast-group' | ||
export { ToastPlacements } from './toast-placements' | ||
export { ToastProvider, useToast, type ToastProviderProps } from './toast-provider' | ||
export { ToastTitle, type ToastTitleProps } from './toast-title' | ||
export { toastAnatomy } from './toast.anatomy' |
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,10 @@ | ||
<script setup lang="ts"> | ||
import { ChakraToastProvider } from './chakra-toast.provider' | ||
import ExampleComponent from './example-component.vue' | ||
</script> | ||
<template> | ||
<ChakraToastProvider> | ||
<h1>Hello World</h1> | ||
<ExampleComponent /> | ||
</ChakraToastProvider> | ||
</template> |
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,44 @@ | ||
import { defineComponent } from 'vue' | ||
import { | ||
Toast, | ||
ToastCloseTrigger, | ||
ToastDescription, | ||
ToastGroup, | ||
ToastProvider, | ||
ToastTitle, | ||
} from '..' | ||
import type { ToastsContext } from '../toast-group' | ||
import { ToastPlacements, type PlacementsContext } from '../toast-placements' | ||
|
||
export const ChakraToastProvider = defineComponent((_, { slots }) => { | ||
return () => ( | ||
<ToastProvider> | ||
<ToastPlacements> | ||
{({ placements }: { placements: PlacementsContext['placements'] }) => ( | ||
<> | ||
{placements.map((placement) => ( | ||
<ToastGroup placement={placement} key={placement}> | ||
{{ | ||
default: ({ toasts }: { toasts: ToastsContext['toasts'] }) => ( | ||
<> | ||
{toasts.map((toast) => ( | ||
<Toast key={toast.id} toast={toast}> | ||
<ToastTitle /> | ||
<ToastDescription /> | ||
<ToastCloseTrigger> | ||
<button>Close</button> | ||
</ToastCloseTrigger> | ||
</Toast> | ||
))} | ||
</> | ||
), | ||
}} | ||
</ToastGroup> | ||
))} | ||
</> | ||
)} | ||
</ToastPlacements> | ||
{slots.default?.()} | ||
</ToastProvider> | ||
) | ||
}) |
Oops, something went wrong.
f8b1603
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
ark-website – ./
ark-website-chakra-ui.vercel.app
ark-website-three.vercel.app
ark-website-git-main-chakra-ui.vercel.app
ark-ui.com