feat(sonner): add sonner component (#301)

This commit is contained in:
Robert Shaw 2024-01-22 23:45:30 +08:00 committed by GitHub
parent f9ab01e11b
commit eba85c6b5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 224 additions and 0 deletions

View File

@ -299,6 +299,12 @@ export const docsConfig: DocsConfig = {
href: '/docs/components/slider',
items: [],
},
{
title: 'Sonner',
href: '/docs/components/sonner',
label: 'New',
items: [],
},
{
title: 'Switch',
href: '/docs/components/switch',

View File

@ -6,6 +6,7 @@ import EditLink from '../components/EditLink.vue'
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
import { Badge } from '@/lib/registry/default/ui/badge'
import RadixIconsCode from '~icons/radix-icons/code'
import RadixIconsExternalLink from '~icons/radix-icons/external-link'
import ChevronRightIcon from '~icons/lucide/chevron-right'
const $route = useRoute()
@ -81,6 +82,10 @@ const sourceLink = 'https://github.com/radix-vue/shadcn-vue/tree/dev/'
</div>
<div class="flex items-center space-x-2 pt-4">
<a v-if="frontmatter.docs" :href="frontmatter.docs" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
<RadixIconsExternalLink class="mr-1" />
Docs
</a>
<a v-if="frontmatter.source" :href="sourceLink + frontmatter.source" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
<RadixIconsCode class="mr-1" />
Component Source

View File

@ -17,6 +17,7 @@ import RadixIconsSun from '~icons/radix-icons/sun'
import { useConfigStore } from '@/stores/config'
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
import { Toaster as DefaultToaster } from '@/lib/registry/default/ui/toast'
import { Toaster as NewYorkSonner } from '@/lib/registry/new-york/ui/sonner'
import { Toaster as NewYorkToaster } from '@/lib/registry/new-york/ui/toast'
import File from '~icons/radix-icons/file'
@ -287,6 +288,7 @@ watch(() => $route.path, (n) => {
</DialogContent>
</Dialog>
<DefaultToaster />
<NewYorkSonner :theme="isDark ? 'dark' : 'light'" />
<NewYorkToaster />
</div>
</template>

View File

@ -576,6 +576,13 @@ export const Index = {
component: () => import('../src/lib/registry/default/example/SliderDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/SliderDemo.vue'],
},
SonnerDemo: {
name: 'SonnerDemo',
type: 'components:example',
registryDependencies: ['button'],
component: () => import('../src/lib/registry/default/example/SonnerDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/SonnerDemo.vue'],
},
SwitchDemo: {
name: 'SwitchDemo',
type: 'components:example',
@ -1467,6 +1474,13 @@ export const Index = {
component: () => import('../src/lib/registry/new-york/example/SliderDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/SliderDemo.vue'],
},
SonnerDemo: {
name: 'SonnerDemo',
type: 'components:example',
registryDependencies: ['button'],
component: () => import('../src/lib/registry/new-york/example/SonnerDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/SonnerDemo.vue'],
},
SwitchDemo: {
name: 'SwitchDemo',
type: 'components:example',

View File

@ -37,6 +37,7 @@
"v-calendar": "^3.1.2",
"vee-validate": "4.12.4",
"vue": "^3.4.15",
"vue-sonner": "^1.0.2",
"vue-wrap-balancer": "^1.1.3",
"zod": "^3.22.4"
},

View File

@ -0,0 +1,63 @@
---
title: Sonner
description: An opinionated toast component for Vue.
docs: https://vue-sonner.vercel.app
source: apps/www/src/lib/registry/default/ui/sonner
---
<ComponentPreview name="SonnerDemo" />
## About
The Sonner component is provided by [vue-sonner](https://vue-sonner.vercel.app/), which is a Vue port of Sonner, originally created by [Emil Kowalski](https://twitter.com/emilkowalski_) for React.
## Installation
<Steps>
### Run the following command
```bash
npx shadcn-vue@latest add sonner
```
### Add the Toaster component
Add the following `Toaster` component to your `App.vue` file:
```vue title="App.vue" {2,6}
<script setup lang="ts">
import { Toaster } from '@/components/ui/sonner'
</script>
<template>
<Toaster />
</template>
```
</Steps>
## Usage
```vue
<script setup lang="ts">
import { toast } from 'vue-sonner'
import { Button } from '@/components/ui/button'
</script>
<template>
<Button
variant="outline" @click="() => {
toast('Event has been created', {
description: 'Sunday, December 03, 2023 at 9:00 AM',
action: {
label: 'Undo',
onClick: () => console.log('Undo'),
},
})
}"
>
Add to calander
</Button>
</template>
```

View File

@ -0,0 +1,20 @@
<script setup lang="ts">
import { toast } from 'vue-sonner'
import { Button } from '@/lib/registry/default/ui/button'
</script>
<template>
<Button
variant="outline" @click="() => {
toast('Event has been created', {
description: 'Sunday, December 03, 2023 at 9:00 AM',
action: {
label: 'Undo',
onClick: () => console.log('Undo'),
},
})
}"
>
Add to calander
</Button>
</template>

View File

@ -0,0 +1,21 @@
<script lang="ts" setup>
import { Toaster as Sonner, type ToasterProps } from 'vue-sonner'
const props = defineProps<ToasterProps>()
</script>
<template>
<Sonner
class="toaster group"
:class-names="{
toast:
'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',
description: 'group-[.toast]:text-muted-foreground',
actionButton:
'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
cancelButton:
'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
}"
v-bind="props"
/>
</template>

View File

@ -0,0 +1 @@
export { default as Toaster } from './Sonner.vue'

View File

@ -0,0 +1,20 @@
<script setup lang="ts">
import { toast } from 'vue-sonner'
import { Button } from '@/lib/registry/new-york/ui/button'
</script>
<template>
<Button
variant="outline" @click="() => {
toast('Event has been created', {
description: 'Sunday, December 03, 2023 at 9:00 AM',
action: {
label: 'Undo',
onClick: () => console.log('Undo'),
},
})
}"
>
Add to calander
</Button>
</template>

View File

@ -0,0 +1,21 @@
<script lang="ts" setup>
import { Toaster as Sonner, type ToasterProps } from 'vue-sonner'
const props = defineProps<ToasterProps>()
</script>
<template>
<Sonner
class="toaster group"
:class-names="{
toast:
'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',
description: 'group-[.toast]:text-muted-foreground',
actionButton:
'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
cancelButton:
'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
}"
v-bind="props"
/>
</template>

View File

@ -0,0 +1 @@
export { default as Toaster } from './Sonner.vue'

View File

@ -517,6 +517,16 @@
],
"type": "components:ui"
},
{
"name": "sonner",
"dependencies": [],
"registryDependencies": [],
"files": [
"ui/sonner/Sonner.vue",
"ui/sonner/index.ts"
],
"type": "components:ui"
},
{
"name": "switch",
"dependencies": [],

View File

@ -0,0 +1,16 @@
{
"name": "sonner",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "Sonner.vue",
"content": "<script lang=\"ts\" setup>\nimport { Toaster as Sonner, type ToasterProps } from 'vue-sonner'\n\nconst props = defineProps<ToasterProps>()\n</script>\n\n<template>\n <Sonner\n class=\"toaster group\"\n :class-names=\"{\n toast:\n 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton:\n 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton:\n 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n }\"\n v-bind=\"props\"\n />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Toaster } from './Sonner.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,16 @@
{
"name": "sonner",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "Sonner.vue",
"content": "<script lang=\"ts\" setup>\nimport { Toaster as Sonner, type ToasterProps } from 'vue-sonner'\n\nconst props = defineProps<ToasterProps>()\n</script>\n\n<template>\n <Sonner\n class=\"toaster group\"\n :class-names=\"{\n toast:\n 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton:\n 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton:\n 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n }\"\n v-bind=\"props\"\n />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Toaster } from './Sonner.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -110,6 +110,9 @@ importers:
vue:
specifier: ^3.4.15
version: 3.4.15(typescript@5.3.3)
vue-sonner:
specifier: ^1.0.2
version: 1.0.2
vue-wrap-balancer:
specifier: ^1.1.3
version: 1.1.3(vue@3.4.15)
@ -14611,6 +14614,10 @@ packages:
vue: 3.4.15(typescript@5.3.3)
dev: false
/vue-sonner@1.0.2:
resolution: {integrity: sha512-BXIyb9lGSMUjTpOukISp7oV9nrczgbfYz+TnDeoap3io3ayGXiWv+/3eQ9UKnmofwUlC4nh/H5jzBOO89lRItQ==}
dev: false
/vue-template-compiler@2.7.14:
resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
dependencies: