Merge branch 'dev' into carousel-dot-buttons
This commit is contained in:
commit
3f2dddfb74
16
.github/actions/setup/action.yml
vendored
Normal file
16
.github/actions/setup/action.yml
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
name: Setup
|
||||||
|
description: Installs Node, Enables Corepack and caches pnpm.
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Enable corepack
|
||||||
|
run: corepack enable
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Setup node & pnpm
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: pnpm
|
||||||
28
.github/workflows/publish.yaml
vendored
28
.github/workflows/publish.yaml
vendored
|
|
@ -48,32 +48,10 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
# Run a build step here
|
- name: Setup (Install Node & pnpm)
|
||||||
- name: Setup Node.js environment
|
uses: ./.github/actions/setup
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
|
||||||
name: Install pnpm
|
|
||||||
with:
|
|
||||||
version: 9.0.5
|
|
||||||
run_install: false
|
|
||||||
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
name: Setup pnpm cache
|
|
||||||
with:
|
|
||||||
path: ${{ env.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm i --frozen-lockfile
|
run: pnpm i --frozen-lockfile
|
||||||
|
|
|
||||||
9
.github/workflows/release.yaml
vendored
9
.github/workflows/release.yaml
vendored
|
|
@ -14,14 +14,13 @@ jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- name: Setup (Install Node & pnpm)
|
||||||
with:
|
uses: ./.github/actions/setup
|
||||||
node-version: 18.x
|
|
||||||
|
|
||||||
- run: npx changelogithub
|
- run: pnpm dlx changelogithub
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
|
|
||||||
27
.github/workflows/test.yaml
vendored
27
.github/workflows/test.yaml
vendored
|
|
@ -19,31 +19,10 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node.js environment
|
- name: Setup (Install Node & pnpm)
|
||||||
uses: actions/setup-node@v2
|
uses: ./.github/actions/setup
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
|
||||||
name: Install pnpm
|
|
||||||
with:
|
|
||||||
version: 9.0.5
|
|
||||||
run_install: false
|
|
||||||
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
name: Setup pnpm cache
|
|
||||||
with:
|
|
||||||
path: ${{ env.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm i --frozen-lockfile
|
run: pnpm i --frozen-lockfile
|
||||||
|
|
|
||||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
|
@ -1,5 +1,9 @@
|
||||||
{
|
{
|
||||||
"vue.server.hybridMode": true,
|
"vue.server.hybridMode": true,
|
||||||
|
"vue.server.includeLanguages": [
|
||||||
|
"vue",
|
||||||
|
"markdown"
|
||||||
|
],
|
||||||
"prettier.enable": false,
|
"prettier.enable": false,
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ import { defineConfig } from 'vitepress'
|
||||||
import Icons from 'unplugin-icons/vite'
|
import Icons from 'unplugin-icons/vite'
|
||||||
import tailwind from 'tailwindcss'
|
import tailwind from 'tailwindcss'
|
||||||
import autoprefixer from 'autoprefixer'
|
import autoprefixer from 'autoprefixer'
|
||||||
|
import { transformerMetaWordHighlight } from '@shikijs/transformers'
|
||||||
import { cssVariables } from './theme/config/shiki'
|
import { cssVariables } from './theme/config/shiki'
|
||||||
|
|
||||||
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
|
|
||||||
import { siteConfig } from './theme/config/site'
|
import { siteConfig } from './theme/config/site'
|
||||||
import ComponentPreviewPlugin from './theme/plugins/previewer'
|
import ComponentPreviewPlugin from './theme/plugins/previewer'
|
||||||
import CodeWrapperPlugin from './theme/plugins/codewrapper'
|
import CodeWrapperPlugin from './theme/plugins/codewrapper'
|
||||||
|
|
@ -56,8 +56,7 @@ export default defineConfig({
|
||||||
markdown: {
|
markdown: {
|
||||||
theme: cssVariables,
|
theme: cssVariables,
|
||||||
codeTransformers: [
|
codeTransformers: [
|
||||||
// transformerMetaWordHighlight(),
|
transformerMetaWordHighlight(),
|
||||||
// transformerNotationWordHighlight(),
|
|
||||||
],
|
],
|
||||||
config(md) {
|
config(md) {
|
||||||
md.use(ComponentPreviewPlugin)
|
md.use(ComponentPreviewPlugin)
|
||||||
|
|
@ -77,7 +76,7 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
Icons({ compiler: 'vue3', autoInstall: true }),
|
Icons({ compiler: 'vue3', autoInstall: true }) as any,
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { codeToHtml } from 'shiki'
|
import { codeToHtml } from 'shiki'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { cssVariables } from '../config/shiki'
|
import { cssVariables } from '../config/shiki'
|
||||||
import StyleSwitcher from './StyleSwitcher.vue'
|
import StyleSwitcher from './StyleSwitcher.vue'
|
||||||
import ComponentLoader from './ComponentLoader.vue'
|
import ComponentLoader from './ComponentLoader.vue'
|
||||||
|
|
@ -24,6 +25,7 @@ const { style, codeConfig } = useConfigStore()
|
||||||
|
|
||||||
const rawString = ref('')
|
const rawString = ref('')
|
||||||
const codeHtml = ref('')
|
const codeHtml = ref('')
|
||||||
|
const transformedRawString = computed(() => transformImportPath(rawString.value))
|
||||||
|
|
||||||
function transformImportPath(code: string) {
|
function transformImportPath(code: string) {
|
||||||
const s = new MagicString(code)
|
const s = new MagicString(code)
|
||||||
|
|
@ -35,7 +37,7 @@ function transformImportPath(code: string) {
|
||||||
watch([style, codeConfig], async () => {
|
watch([style, codeConfig], async () => {
|
||||||
try {
|
try {
|
||||||
rawString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
|
rawString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
|
||||||
codeHtml.value = await codeToHtml(transformImportPath(rawString.value), {
|
codeHtml.value = await codeToHtml(transformedRawString.value, {
|
||||||
lang: 'vue',
|
lang: 'vue',
|
||||||
theme: cssVariables,
|
theme: cssVariables,
|
||||||
})
|
})
|
||||||
|
|
@ -44,6 +46,8 @@ watch([style, codeConfig], async () => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true })
|
}, { immediate: true, deep: true })
|
||||||
|
|
||||||
|
const { copy, copied } = useClipboard()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -86,8 +90,12 @@ watch([style, codeConfig], async () => {
|
||||||
<ComponentLoader v-bind="$attrs" :key="style" :name="name" :type-name="'example'" />
|
<ComponentLoader v-bind="$attrs" :key="style" :name="name" :type-name="'example'" />
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="code">
|
<TabsContent value="code" class="vp-doc">
|
||||||
<div v-if="codeHtml" class="language-vue" style="flex: 1;" v-html="codeHtml" />
|
<div v-if="codeHtml" class="language-vue" style="flex: 1;">
|
||||||
|
<button title="Copy Code" class="copy" :class="{ copied }" @click="copy(transformedRawString)" />
|
||||||
|
|
||||||
|
<div v-html="codeHtml" />
|
||||||
|
</div>
|
||||||
<slot v-else />
|
<slot v-else />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import {
|
||||||
BreadcrumbItem,
|
BreadcrumbItem,
|
||||||
BreadcrumbLink,
|
BreadcrumbLink,
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
BreadcrumbPage,
|
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const examples = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Forms',
|
name: 'Forms',
|
||||||
href: '/examples/forms/forms',
|
href: '/examples/forms',
|
||||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/forms',
|
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/forms',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import Announcement from '../components/Announcement.vue'
|
||||||
import GitHubIcon from '~icons/radix-icons/github-logo'
|
import GitHubIcon from '~icons/radix-icons/github-logo'
|
||||||
|
|
||||||
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||||
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
import MailExample from '@/examples/mail/Example.vue'
|
import MailExample from '@/examples/mail/Example.vue'
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import Logo from './Logo.vue'
|
||||||
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||||
import { Badge } from '@/lib/registry/new-york/ui/badge'
|
|
||||||
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { cn } from '@/lib/utils'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<WrapBalancer :class="cn('max-w-[750px] text-center text-lg text-muted-foreground sm:text-xl', $attrs.class ?? '')" :prefer-native="false">
|
<WrapBalancer :class="cn('max-w-[750px] text-center text-lg font-light text-foreground', $attrs.class ?? '')" :prefer-native="false">
|
||||||
<slot />
|
<slot />
|
||||||
</WrapBalancer>
|
</WrapBalancer>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { cn } from '@/lib/utils'
|
||||||
<template>
|
<template>
|
||||||
<h1
|
<h1
|
||||||
:class="cn(
|
:class="cn(
|
||||||
'text-center text-3xl font-bold leading-tight tracking-tighter md:text-6xl lg:leading-[1.1]',
|
'text-center text-3xl font-bold leading-tight tracking-tighter md:text-5xl lg:leading-[1.1]',
|
||||||
$attrs.class ?? '',
|
$attrs.class ?? '',
|
||||||
)"
|
)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ function getHeadingsWithHierarchy(divId: string) {
|
||||||
const level = Number.parseInt(heading.tagName.charAt(1))
|
const level = Number.parseInt(heading.tagName.charAt(1))
|
||||||
if (!heading.id) {
|
if (!heading.id) {
|
||||||
const newId = heading.textContent
|
const newId = heading.textContent
|
||||||
.replaceAll(/[^a-zA-Z0-9 ]/g, '')
|
.replaceAll(/[^a-z0-9 ]/gi, '')
|
||||||
.replaceAll(' ', '-')
|
.replaceAll(' ', '-')
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
heading.id = `${newId}`
|
heading.id = `${newId}`
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ export const allColors: Color[] = [
|
||||||
'violet',
|
'violet',
|
||||||
]
|
]
|
||||||
|
|
||||||
interface Payment {
|
// interface Payment {
|
||||||
status: string
|
// status: string
|
||||||
email: string
|
// email: string
|
||||||
amount: number
|
// amount: number
|
||||||
}
|
// }
|
||||||
|
|
||||||
interface TeamMember {
|
interface TeamMember {
|
||||||
name: string
|
name: string
|
||||||
|
|
|
||||||
|
|
@ -256,12 +256,17 @@ export const docsConfig: DocsConfig = {
|
||||||
title: 'Navigation Menu',
|
title: 'Navigation Menu',
|
||||||
href: '/docs/components/navigation-menu',
|
href: '/docs/components/navigation-menu',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Number Field',
|
||||||
|
href: '/docs/components/number-field',
|
||||||
|
label: 'New Alpha',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Pagination',
|
title: 'Pagination',
|
||||||
href: '/docs/components/pagination',
|
href: '/docs/components/pagination',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Pin Input',
|
title: 'PIN Input',
|
||||||
href: '/docs/components/pin-input',
|
href: '/docs/components/pin-input',
|
||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import DocsBreadcrumb from '../components/DocsBreadcrumb.vue'
|
||||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||||
import RadixIconsCode from '~icons/radix-icons/code'
|
import RadixIconsCode from '~icons/radix-icons/code'
|
||||||
import RadixIconsExternalLink from '~icons/radix-icons/external-link'
|
import RadixIconsExternalLink from '~icons/radix-icons/external-link'
|
||||||
import ChevronRightIcon from '~icons/lucide/chevron-right'
|
|
||||||
|
|
||||||
const $route = useRoute()
|
const $route = useRoute()
|
||||||
const { frontmatter } = useData()
|
const { frontmatter } = useData()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import ExamplesNav from '../components/ExamplesNav.vue'
|
||||||
import Announcement from '../components/Announcement.vue'
|
import Announcement from '../components/Announcement.vue'
|
||||||
|
|
||||||
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||||
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ watch(() => $route.path, (n) => {
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<DefaultToaster />
|
<DefaultToaster />
|
||||||
<NewYorkSonner :theme="'system'" />
|
<NewYorkSonner class="pointer-events-auto" :theme="'system'" />
|
||||||
<NewYorkToaster />
|
<NewYorkToaster />
|
||||||
</div>
|
</div>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|
|
||||||
|
|
@ -167,12 +167,20 @@ pre code {
|
||||||
@apply relative font-mono text-sm ;
|
@apply relative font-mono text-sm ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line-numbers-wrapper, code {
|
||||||
|
--vp-code-line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-numbers-wrapper {
|
||||||
|
@apply font-mono;
|
||||||
|
}
|
||||||
|
|
||||||
pre code .line {
|
pre code .line {
|
||||||
@apply px-4 min-h-6 !py-0.5 w-full inline-block;
|
@apply px-4 min-h-4 !py-0.5 w-full inline-block leading-[--vp-code-line-height];
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-number {
|
.line-number {
|
||||||
@apply min-h-[1.375rem] !text-sm !inline-block text-muted-foreground;
|
@apply !text-[.75rem] !inline-block text-muted-foreground leading-[--vp-code-line-height];
|
||||||
}
|
}
|
||||||
|
|
||||||
::view-transition-old(root),
|
::view-transition-old(root),
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@apply bg-[hsl(var(--foreground))] dark:bg-[hsl(var(--background)_/_50%)]
|
@apply bg-[hsl(var(--foreground))] dark:bg-[hsl(var(--background)_/_50%)]
|
||||||
}
|
}
|
||||||
hsl(var(--foreground) / 50%)
|
|
||||||
.vp-doc [class*='language-'] code .highlighted.error {
|
.vp-doc [class*='language-'] code .highlighted.error {
|
||||||
background-color: var(--vp-code-line-error-color);
|
background-color: var(--vp-code-line-error-color);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ import { getParameters } from 'codesandbox/lib/api/define'
|
||||||
import sdk from '@stackblitz/sdk'
|
import sdk from '@stackblitz/sdk'
|
||||||
import { dependencies as deps } from '../../../package.json'
|
import { dependencies as deps } from '../../../package.json'
|
||||||
import { Index as demoIndex } from '../../../../www/__registry__'
|
import { Index as demoIndex } from '../../../../www/__registry__'
|
||||||
|
// @ts-expect-error ?raw
|
||||||
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
||||||
|
// @ts-expect-error ?raw
|
||||||
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
||||||
import type { Style } from '@/lib/registry/styles'
|
import type { Style } from '@/lib/registry/styles'
|
||||||
|
|
||||||
|
|
@ -35,7 +37,15 @@ const viteConfig = {
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
import tailwind from 'tailwindcss';
|
||||||
|
import autoprefixer from 'autoprefixer';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
css: {
|
||||||
|
postcss: {
|
||||||
|
plugins: [tailwind(), autoprefixer()],
|
||||||
|
},
|
||||||
|
},
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|
@ -102,7 +112,6 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
||||||
'@vitejs/plugin-vue': 'latest',
|
'@vitejs/plugin-vue': 'latest',
|
||||||
'vue-tsc': 'latest',
|
'vue-tsc': 'latest',
|
||||||
'tailwindcss': 'latest',
|
'tailwindcss': 'latest',
|
||||||
'postcss': 'latest',
|
|
||||||
'autoprefixer': 'latest',
|
'autoprefixer': 'latest',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,15 +154,6 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
||||||
content: tailwindConfigRaw,
|
content: tailwindConfigRaw,
|
||||||
isBinary: false,
|
isBinary: false,
|
||||||
},
|
},
|
||||||
'postcss.config.js': {
|
|
||||||
content: `module.exports = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {},
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
isBinary: false,
|
|
||||||
},
|
|
||||||
'tsconfig.json': {
|
'tsconfig.json': {
|
||||||
content: `{
|
content: `{
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
|
|
||||||
|
|
@ -759,6 +759,48 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/NavigationMenuDemoItem.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/NavigationMenuDemoItem.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/NavigationMenuDemoItem.vue"],
|
files: ["../src/lib/registry/default/example/NavigationMenuDemoItem.vue"],
|
||||||
},
|
},
|
||||||
|
"NumberFieldCurrency": {
|
||||||
|
name: "NumberFieldCurrency",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldCurrency.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldCurrency.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDecimal": {
|
||||||
|
name: "NumberFieldDecimal",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldDecimal.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldDecimal.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDemo": {
|
||||||
|
name: "NumberFieldDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldDemo.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDisabled": {
|
||||||
|
name: "NumberFieldDisabled",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldDisabled.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldDisabled.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldForm": {
|
||||||
|
name: "NumberFieldForm",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","form","number-field","toast"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldForm.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldForm.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldPercentage": {
|
||||||
|
name: "NumberFieldPercentage",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/NumberFieldPercentage.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/NumberFieldPercentage.vue"],
|
||||||
|
},
|
||||||
"PaginationDemo": {
|
"PaginationDemo": {
|
||||||
name: "PaginationDemo",
|
name: "PaginationDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -948,6 +990,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/default/example/SonnerDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/SonnerDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/SonnerDemo.vue"],
|
files: ["../src/lib/registry/default/example/SonnerDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"SonnerWithDialog": {
|
||||||
|
name: "SonnerWithDialog",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","dialog"],
|
||||||
|
component: () => import("../src/lib/registry/default/example/SonnerWithDialog.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/default/example/SonnerWithDialog.vue"],
|
||||||
|
},
|
||||||
"SwitchDemo": {
|
"SwitchDemo": {
|
||||||
name: "SwitchDemo",
|
name: "SwitchDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -1308,7 +1357,7 @@ export const Index = {
|
||||||
"ActivityGoal": {
|
"ActivityGoal": {
|
||||||
name: "ActivityGoal",
|
name: "ActivityGoal",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
registryDependencies: ["button","card","themes","config"],
|
registryDependencies: ["button","card"],
|
||||||
component: () => import("../src/lib/registry/default/example/Cards/ActivityGoal.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/Cards/ActivityGoal.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/Cards/ActivityGoal.vue"],
|
files: ["../src/lib/registry/default/example/Cards/ActivityGoal.vue"],
|
||||||
},
|
},
|
||||||
|
|
@ -1322,7 +1371,7 @@ export const Index = {
|
||||||
"Metric": {
|
"Metric": {
|
||||||
name: "Metric",
|
name: "Metric",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
registryDependencies: ["card","config"],
|
registryDependencies: ["card"],
|
||||||
component: () => import("../src/lib/registry/default/example/Cards/Metric.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/default/example/Cards/Metric.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/default/example/Cards/Metric.vue"],
|
files: ["../src/lib/registry/default/example/Cards/Metric.vue"],
|
||||||
},
|
},
|
||||||
|
|
@ -2160,6 +2209,48 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/NavigationMenuDemoItem.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/NavigationMenuDemoItem.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/NavigationMenuDemoItem.vue"],
|
files: ["../src/lib/registry/new-york/example/NavigationMenuDemoItem.vue"],
|
||||||
},
|
},
|
||||||
|
"NumberFieldCurrency": {
|
||||||
|
name: "NumberFieldCurrency",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldCurrency.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldCurrency.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDecimal": {
|
||||||
|
name: "NumberFieldDecimal",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldDecimal.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldDecimal.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDemo": {
|
||||||
|
name: "NumberFieldDemo",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldDemo.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldDemo.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldDisabled": {
|
||||||
|
name: "NumberFieldDisabled",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldDisabled.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldDisabled.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldForm": {
|
||||||
|
name: "NumberFieldForm",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","form","number-field","toast"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldForm.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldForm.vue"],
|
||||||
|
},
|
||||||
|
"NumberFieldPercentage": {
|
||||||
|
name: "NumberFieldPercentage",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["number-field","label"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/NumberFieldPercentage.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/NumberFieldPercentage.vue"],
|
||||||
|
},
|
||||||
"PaginationDemo": {
|
"PaginationDemo": {
|
||||||
name: "PaginationDemo",
|
name: "PaginationDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -2349,6 +2440,13 @@ export const Index = {
|
||||||
component: () => import("../src/lib/registry/new-york/example/SonnerDemo.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/SonnerDemo.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/SonnerDemo.vue"],
|
files: ["../src/lib/registry/new-york/example/SonnerDemo.vue"],
|
||||||
},
|
},
|
||||||
|
"SonnerWithDialog": {
|
||||||
|
name: "SonnerWithDialog",
|
||||||
|
type: "components:example",
|
||||||
|
registryDependencies: ["button","dialog"],
|
||||||
|
component: () => import("../src/lib/registry/new-york/example/SonnerWithDialog.vue").then((m) => m.default),
|
||||||
|
files: ["../src/lib/registry/new-york/example/SonnerWithDialog.vue"],
|
||||||
|
},
|
||||||
"SwitchDemo": {
|
"SwitchDemo": {
|
||||||
name: "SwitchDemo",
|
name: "SwitchDemo",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
|
|
@ -2709,7 +2807,7 @@ export const Index = {
|
||||||
"ActivityGoal": {
|
"ActivityGoal": {
|
||||||
name: "ActivityGoal",
|
name: "ActivityGoal",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
registryDependencies: ["button","card","themes","config"],
|
registryDependencies: ["button","card"],
|
||||||
component: () => import("../src/lib/registry/new-york/example/Cards/ActivityGoal.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/Cards/ActivityGoal.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/Cards/ActivityGoal.vue"],
|
files: ["../src/lib/registry/new-york/example/Cards/ActivityGoal.vue"],
|
||||||
},
|
},
|
||||||
|
|
@ -2723,7 +2821,7 @@ export const Index = {
|
||||||
"Metric": {
|
"Metric": {
|
||||||
name: "Metric",
|
name: "Metric",
|
||||||
type: "components:example",
|
type: "components:example",
|
||||||
registryDependencies: ["card","config"],
|
registryDependencies: ["card"],
|
||||||
component: () => import("../src/lib/registry/new-york/example/Cards/Metric.vue").then((m) => m.default),
|
component: () => import("../src/lib/registry/new-york/example/Cards/Metric.vue").then((m) => m.default),
|
||||||
files: ["../src/lib/registry/new-york/example/Cards/Metric.vue"],
|
files: ["../src/lib/registry/new-york/example/Cards/Metric.vue"],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "www",
|
"name": "www",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.10.4",
|
"version": "0.10.5",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
|
|
@ -17,66 +17,65 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.2",
|
"@formkit/auto-animate": "^0.8.2",
|
||||||
"@internationalized/date": "^3.5.2",
|
"@internationalized/date": "^3.5.4",
|
||||||
"@radix-icons/vue": "^1.0.0",
|
"@radix-icons/vue": "^1.0.0",
|
||||||
"@stackblitz/sdk": "^1.9.0",
|
"@stackblitz/sdk": "^1.10.0",
|
||||||
"@tanstack/vue-table": "^8.16.0",
|
"@tanstack/vue-table": "^8.17.3",
|
||||||
"@unovis/ts": "^1.4.0",
|
"@unovis/ts": "^1.4.1",
|
||||||
"@unovis/vue": "^1.4.0",
|
"@unovis/vue": "^1.4.1",
|
||||||
"@vee-validate/zod": "^4.12.6",
|
"@vee-validate/zod": "^4.13.1",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.11.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"codesandbox": "^2.2.3",
|
"codesandbox": "^2.2.3",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"embla-carousel": "^8.0.2",
|
"embla-carousel-autoplay": "^8.1.5",
|
||||||
"embla-carousel-autoplay": "^8.0.2",
|
"embla-carousel-vue": "^8.1.5",
|
||||||
"embla-carousel-vue": "^8.0.2",
|
"lucide-vue-next": "^0.383.0",
|
||||||
"lucide-vue-next": "^0.359.0",
|
|
||||||
"magic-string": "^0.30.10",
|
"magic-string": "^0.30.10",
|
||||||
"radix-vue": "^1.7.2",
|
"radix-vue": "^1.8.4",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"vaul-vue": "^0.1.0",
|
"vaul-vue": "^0.2.0",
|
||||||
"vee-validate": "4.12.6",
|
"vee-validate": "4.13.1",
|
||||||
"vue": "^3.4.24",
|
"vue": "^3.4.29",
|
||||||
"vue-sonner": "^1.1.2",
|
"vue-sonner": "^1.1.2",
|
||||||
"vue-wrap-balancer": "^1.1.3",
|
"vue-wrap-balancer": "^1.1.3",
|
||||||
"zod": "^3.23.3"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/traverse": "^7.24.1",
|
"@babel/traverse": "^7.24.7",
|
||||||
"@iconify-json/gravity-ui": "^1.1.2",
|
"@iconify-json/gravity-ui": "^1.1.3",
|
||||||
"@iconify-json/lucide": "^1.1.180",
|
"@iconify-json/lucide": "^1.1.190",
|
||||||
"@iconify-json/ph": "^1.1.12",
|
"@iconify-json/ph": "^1.1.13",
|
||||||
"@iconify-json/radix-icons": "^1.1.14",
|
"@iconify-json/radix-icons": "^1.1.14",
|
||||||
"@iconify-json/ri": "^1.1.18",
|
"@iconify-json/ri": "^1.1.20",
|
||||||
"@iconify-json/simple-icons": "^1.1.94",
|
"@iconify-json/simple-icons": "^1.1.104",
|
||||||
"@iconify-json/tabler": "^1.1.106",
|
"@iconify-json/tabler": "^1.1.113",
|
||||||
"@iconify/vue": "^4.1.2",
|
"@iconify/vue": "^4.1.2",
|
||||||
"@oxc-parser/wasm": "^0.1.0",
|
"@oxc-parser/wasm": "^0.14.0",
|
||||||
"@shikijs/transformers": "^1.3.0",
|
"@shikijs/transformers": "^1.7.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.14.4",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
"@vue/compiler-core": "^3.4.24",
|
"@vue/compiler-core": "^3.4.29",
|
||||||
"@vue/compiler-dom": "^3.4.24",
|
"@vue/compiler-dom": "^3.4.29",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.7",
|
||||||
"shiki": "^1.3.0",
|
"shiki": "^1.7.0",
|
||||||
"tailwind-merge": "^2.3.0",
|
"tailwind-merge": "^2.3.0",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.4",
|
||||||
"tsx": "^4.7.2",
|
"tsx": "^4.15.6",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.19.0",
|
||||||
"vitepress": "^1.1.3",
|
"vitepress": "^1.2.3",
|
||||||
"vue-component-meta": "^2.0.13",
|
"vue-component-meta": "^2.0.21",
|
||||||
"vue-tsc": "^2.0.14"
|
"vue-tsc": "^2.0.21"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ for (const baseColor of ['slate', 'gray', 'zinc', 'neutral', 'stone', 'lime']) {
|
||||||
for (const [key, value] of Object.entries(values)) {
|
for (const [key, value] of Object.entries(values)) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
const resolvedColor = value.replace(
|
const resolvedColor = value.replace(
|
||||||
/{{base}}-/g,
|
/\{\{base\}\}-/g,
|
||||||
`${baseColor}-`,
|
`${baseColor}-`,
|
||||||
)
|
)
|
||||||
base.inlineColors[mode][key] = resolvedColor
|
base.inlineColors[mode][key] = resolvedColor
|
||||||
|
|
|
||||||
10
apps/www/src/components.d.ts
vendored
Normal file
10
apps/www/src/components.d.ts
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
ComponentPreview: typeof import('../.vitepress/theme/components/ComponentPreview.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,139 @@
|
||||||
---
|
---
|
||||||
title: Changelog
|
title: Changelog
|
||||||
|
description: Latest updates and announcements.
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## June 2024
|
||||||
|
|
||||||
|
### New Component - Number Field
|
||||||
|
A new component has been added to the project [`NumberField`](/docs/components/number-field.html).
|
||||||
|
|
||||||
|
A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldDemo" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
## May 2024
|
||||||
|
|
||||||
|
### New Component - Charts
|
||||||
|
Several kinds of chart components has been added to the project.
|
||||||
|
|
||||||
|
Charts are versatile visualization tools, allowing users to represent data using various options for effective analysis.
|
||||||
|
|
||||||
|
1. [`Area Chart`](/docs/charts/area) - An area chart visually represents data over time, displaying trends and patterns through filled-in areas under a line graph.
|
||||||
|
|
||||||
|
<ComponentPreview name="AreaChartDemo" />
|
||||||
|
|
||||||
|
2. [`Bar Chart`](/docs/charts/bar) - A line chart visually represents data using rectangular bars of varying lengths to compare quantities across different categories or groups.
|
||||||
|
|
||||||
|
<ComponentPreview name="BarChartDemo" />
|
||||||
|
|
||||||
|
3. [`Donut Chart`](/docs/charts/donut) - A line chart visually represents data in a circular form, similar to a pie chart but with a central void, emphasizing proportions within categories.
|
||||||
|
|
||||||
|
<ComponentPreview name="DonutChartDemo" />
|
||||||
|
|
||||||
|
4. [`Line Chart`](/docs/charts/line) - A line chart visually displays data points connected by straight lines, illustrating trends or relationships over a continuous axis.
|
||||||
|
|
||||||
|
<ComponentPreview name="LineChartDemo" />
|
||||||
|
|
||||||
|
### New Component - Auto Form
|
||||||
|
|
||||||
|
[`Auto Form`](/docs/components/auto-form.html) is a drop-in form builder for your internal and low-priority forms with existing zod schemas.
|
||||||
|
|
||||||
|
For example, if you already have zod schemas for your API and want to create a simple admin panel to edit user profiles, simply pass the schema to AutoForm and you're done.
|
||||||
|
|
||||||
|
The following form has been created by passing a `zod` schema object to our `AutoForm` component.
|
||||||
|
|
||||||
|
<ComponentPreview name="AutoFormBasic" />
|
||||||
|
|
||||||
|
## April 2024
|
||||||
|
|
||||||
|
### Component Updated - Calendar
|
||||||
|
|
||||||
|
The [`Calendar`](/docs/components/calendar.html) component has been updated and is now built on top of the [RadixVue Calendar](https://www.radix-vue.com/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||||
|
|
||||||
|
If you're looking for a range calendar, check out the [`Range Calendar`](/docs/components/range-calendar.html) component.
|
||||||
|
|
||||||
|
And if you're looking for a date picker input, check out the [`Date Picker`](/docs/components/date-picker.html) component.
|
||||||
|
|
||||||
|
<ComponentPreview name="CalendarDemo" />
|
||||||
|
|
||||||
|
<ComponentPreview name="RangeCalendarDemo" />
|
||||||
|
|
||||||
|
<ComponentPreview name="DatePickerDemo" />
|
||||||
|
|
||||||
|
### Building Blocks for the Web
|
||||||
|
|
||||||
|
[`Blocks`](/blocks) are composed of different components that can be used to build your apps, with each block being a standalone section of your application. These blocks are fully responsive, accessible, and composable, and are built using the same principles as the other components in `shadcn-vue`.
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<image
|
||||||
|
src="/examples/block-dark.png"
|
||||||
|
:width="1280"
|
||||||
|
:height="727"
|
||||||
|
alt="Building Blocks"
|
||||||
|
class="hidden dark:block"
|
||||||
|
/>
|
||||||
|
<image
|
||||||
|
src="/examples/block-light.png"
|
||||||
|
:width="1280"
|
||||||
|
:height="727"
|
||||||
|
alt="Building Blocks"
|
||||||
|
class="block dark:hidden"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## March 2024
|
||||||
|
|
||||||
|
### New Component - Breadcrumb
|
||||||
|
|
||||||
|
[`Breadcrumb`](/docs/components/breadcrumb.html) displays the path to the current resource using a hierarchy of links.
|
||||||
|
|
||||||
|
<ComponentPreview name="BreadcrumbDemo" />
|
||||||
|
|
||||||
|
### New Component - Pin Input (OTP Input)
|
||||||
|
|
||||||
|
[`Pin Input`](/docs/components/pin-input.html) allows users to input a sequence of one-character alphanumeric inputs.
|
||||||
|
|
||||||
|
<ComponentPreview name="PinInputDemo" />
|
||||||
|
|
||||||
|
### New Component - Resizable
|
||||||
|
|
||||||
|
[`Resizable`](/docs/components/resizable.html) - Accessible resizable panel groups and layouts with keyboard support.
|
||||||
|
|
||||||
|
<ComponentPreview name="ResizableDemo" />
|
||||||
|
|
||||||
|
### New Component - Drawer
|
||||||
|
|
||||||
|
[`Drawer`](/docs/components/drawer.html) - A drawer component for vue that is built on top of [Vaul Vue](https://github.com/radix-vue/vaul-vue).
|
||||||
|
|
||||||
|
<ComponentPreview name="DrawerDemo" />
|
||||||
|
|
||||||
|
## February 2024
|
||||||
|
|
||||||
|
### New Component - Tag Inputs
|
||||||
|
|
||||||
|
[`Tag inputs`](/docs/components/tags-input.html) render tags inside an input, followed by an actual text input.
|
||||||
|
|
||||||
|
<ComponentPreview name="TagsInputDemo" />
|
||||||
|
|
||||||
|
## January 2024
|
||||||
|
|
||||||
|
### New Component - Sonner
|
||||||
|
|
||||||
|
[`Sonner`](/docs/components/sonner.html) is an opinionated toast component for Vue.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<ComponentPreview name="SonnerDemo" />
|
||||||
|
|
||||||
|
### New Component - Toggle Group
|
||||||
|
|
||||||
|
[`Toggle Group`](/docs/components/toggle-group.html) - A set of two-state buttons that can be toggled on or off.
|
||||||
|
|
||||||
|
<ComponentPreview name="ToggleGroupDemo" />
|
||||||
|
|
||||||
|
### New Component - Carousel
|
||||||
|
|
||||||
|
[`Carousel`](/docs/components/toggle-group.html) - A carousel with motion and swipe built using [Embla](https://www.embla-carousel.com/) library.
|
||||||
|
|
||||||
|
<ComponentPreview name="CarouselDemo" />
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Bar
|
title: Bar
|
||||||
description: An line chart visually represents data using rectangular bars of varying lengths to compare quantities across different categories or groups.
|
description: A line chart visually represents data using rectangular bars of varying lengths to compare quantities across different categories or groups.
|
||||||
source: apps/www/src/lib/registry/default/ui/chart-bar
|
source: apps/www/src/lib/registry/default/ui/chart-bar
|
||||||
label: Alpha
|
label: Alpha
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Donut
|
title: Donut
|
||||||
description: An line chart visually represents data in a circular form, similar to a pie chart but with a central void, emphasizing proportions within categories.
|
description: A line chart visually represents data in a circular form, similar to a pie chart but with a central void, emphasizing proportions within categories.
|
||||||
source: apps/www/src/lib/registry/default/ui/chart-donut
|
source: apps/www/src/lib/registry/default/ui/chart-donut
|
||||||
label: Alpha
|
label: Alpha
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Line
|
title: Line
|
||||||
description: An line chart visually displays data points connected by straight lines, illustrating trends or relationships over a continuous axis.
|
description: A line chart visually displays data points connected by straight lines, illustrating trends or relationships over a continuous axis.
|
||||||
source: apps/www/src/lib/registry/default/ui/chart-line
|
source: apps/www/src/lib/registry/default/ui/chart-line
|
||||||
label: Alpha
|
label: Alpha
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -414,9 +414,7 @@ const form = useForm({
|
||||||
validationSchema: toTypedSchema(schema),
|
validationSchema: toTypedSchema(schema),
|
||||||
})
|
})
|
||||||
|
|
||||||
form.setValues({
|
form.setFieldValue('username', 'bar')
|
||||||
username: 'foo'
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import {
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
BreadcrumbPage,
|
BreadcrumbPage,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@/lib/components/ui/breadcrumb'
|
} from '@/components/ui/breadcrumb'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -65,7 +65,7 @@ import {
|
||||||
BreadcrumbLink,
|
BreadcrumbLink,
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@/lib/components/ui/breadcrumb'
|
} from '@/components/ui/breadcrumb'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -106,7 +106,7 @@ import {
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/lib/components/ui/dropdown-menu'
|
} from '@/lib/components/ui/dropdown-menu'
|
||||||
|
|
||||||
import { BreadcrumbItem } from '@/lib/components/ui/breadcrumb'
|
import { BreadcrumbItem } from '@/components/ui/breadcrumb'
|
||||||
|
|
||||||
import ChevronDownIcon from '~icons/radix-icons/chevron-down'
|
import ChevronDownIcon from '~icons/radix-icons/chevron-down'
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -143,7 +143,7 @@ import {
|
||||||
BreadcrumbEllipsis,
|
BreadcrumbEllipsis,
|
||||||
BreadcrumbItem,
|
BreadcrumbItem,
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
} from '@/lib/components/ui/breadcrumb'
|
} from '@/components/ui/breadcrumb'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -175,7 +175,7 @@ import {
|
||||||
BreadcrumbItem,
|
BreadcrumbItem,
|
||||||
BreadcrumbLink,
|
BreadcrumbLink,
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
} from '@/lib/components/ui/breadcrumb'
|
} from '@/components/ui/breadcrumb'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import {
|
||||||
const frameworks = [
|
const frameworks = [
|
||||||
{ value: 'next.js', label: 'Next.js' },
|
{ value: 'next.js', label: 'Next.js' },
|
||||||
{ value: 'sveltekit', label: 'SvelteKit' },
|
{ value: 'sveltekit', label: 'SvelteKit' },
|
||||||
{ value: 'nuxt.js', label: 'Nuxt.js' },
|
{ value: 'nuxt', label: 'Nuxt' },
|
||||||
{ value: 'remix', label: 'Remix' },
|
{ value: 'remix', label: 'Remix' },
|
||||||
{ value: 'astro', label: 'Astro' },
|
{ value: 'astro', label: 'Astro' },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ watch(CmdJ, (v) => {
|
||||||
<span class="text-xs">⌘</span>J
|
<span class="text-xs">⌘</span>J
|
||||||
</kbd>
|
</kbd>
|
||||||
</p>
|
</p>
|
||||||
<CommandDialog :open="open" :on-open-change="handleOpenChange">
|
<CommandDialog :open="open" @update:open="handleOpenChange">
|
||||||
<CommandInput placeholder="Type a command or search..." />
|
<CommandInput placeholder="Type a command or search..." />
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
<CommandEmpty>No results found.</CommandEmpty>
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ Start by creating the following file structure:
|
||||||
└── app.vue
|
└── app.vue
|
||||||
```
|
```
|
||||||
|
|
||||||
I'm using a Nuxt.js example here but this works for any other Vue framework.
|
I'm using a Nuxt example here but this works for any other Vue framework.
|
||||||
|
|
||||||
- `columns.ts` It will contain our column definitions.
|
- `columns.ts` It will contain our column definitions.
|
||||||
- `data-table.vue` It will contain our `<DataTable />` component.
|
- `data-table.vue` It will contain our `<DataTable />` component.
|
||||||
|
|
@ -114,7 +114,7 @@ Let's start by building a basic table.
|
||||||
|
|
||||||
First, we'll define our columns in the `columns.ts` file.
|
First, we'll define our columns in the `columns.ts` file.
|
||||||
|
|
||||||
```ts:line-numbers {1,12-27}
|
```ts:line-numbers
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
|
|
||||||
export const columns: ColumnDef<Payment>[] = [
|
export const columns: ColumnDef<Payment>[] = [
|
||||||
|
|
@ -146,14 +146,14 @@ formatted, sorted and filtered.
|
||||||
|
|
||||||
Next, we'll create a `<DataTable />` component to render our table.
|
Next, we'll create a `<DataTable />` component to render our table.
|
||||||
|
|
||||||
```vue:line-numbers
|
```vue
|
||||||
<script setup lang="ts" generic="TData, TValue">
|
<script setup lang="ts" generic="TData, TValue">
|
||||||
import type { ColumnDef } from '@tanstack/vue-table'
|
import type { ColumnDef } from '@tanstack/vue-table'
|
||||||
import {
|
import {
|
||||||
FlexRender,
|
FlexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
useVueTable,
|
useVueTable,
|
||||||
} from "@tanstack/vue-table"
|
} from '@tanstack/vue-table'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
|
@ -162,7 +162,7 @@ import {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table"
|
} from '@/components/ui/table'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
columns: ColumnDef<TData, TValue>[]
|
columns: ColumnDef<TData, TValue>[]
|
||||||
|
|
@ -182,15 +182,19 @@ const table = useVueTable({
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
|
<TableRow v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
|
||||||
<TableHead v-for="header in headerGroup.headers" :key="header.id">
|
<TableHead v-for="header in headerGroup.headers" :key="header.id">
|
||||||
<FlexRender v-if="!header.isPlaceholder" :render="header.column.columnDef.header"
|
<FlexRender
|
||||||
:props="header.getContext()" />
|
v-if="!header.isPlaceholder" :render="header.column.columnDef.header"
|
||||||
|
:props="header.getContext()"
|
||||||
|
/>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<template v-if="table.getRowModel().rows?.length">
|
<template v-if="table.getRowModel().rows?.length">
|
||||||
<TableRow v-for="row in table.getRowModel().rows" :key="row.id"
|
<TableRow
|
||||||
:data-state="row.getIsSelected() ? 'selected' : undefined">
|
v-for="row in table.getRowModel().rows" :key="row.id"
|
||||||
|
:data-state="row.getIsSelected() ? 'selected' : undefined"
|
||||||
|
>
|
||||||
<TableCell v-for="cell in row.getVisibleCells()" :key="cell.id">
|
<TableCell v-for="cell in row.getVisibleCells()" :key="cell.id">
|
||||||
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
|
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
@ -198,7 +202,7 @@ const table = useVueTable({
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell :colSpan="columns.length" class="h-24 text-center">
|
<TableCell :colspan="columns.length" class="h-24 text-center">
|
||||||
No results.
|
No results.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
@ -221,12 +225,12 @@ const table = useVueTable({
|
||||||
|
|
||||||
Finally, we'll render our table in our index component.
|
Finally, we'll render our table in our index component.
|
||||||
|
|
||||||
```vue:line-numbers {28}
|
```vue
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { columns } from "./components/columns"
|
import { columns } from './components/columns'
|
||||||
import type { Payment } from './components/columns';
|
import type { Payment } from './components/columns'
|
||||||
import DataTable from "./components/DataTable.vue"
|
import DataTable from './components/DataTable.vue'
|
||||||
|
|
||||||
const data = ref<Payment[]>([])
|
const data = ref<Payment[]>([])
|
||||||
|
|
||||||
|
|
@ -234,18 +238,18 @@ async function getData(): Promise<Payment[]> {
|
||||||
// Fetch data from your API here.
|
// Fetch data from your API here.
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: "728ed52f",
|
id: '728ed52f',
|
||||||
amount: 100,
|
amount: 100,
|
||||||
status: "pending",
|
status: 'pending',
|
||||||
email: "m@example.com",
|
email: 'm@example.com',
|
||||||
},
|
},
|
||||||
// ...
|
// ...
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
data.value = await getData();
|
data.value = await getData()
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -267,18 +271,18 @@ Let's format the amount cell to display the dollar amount. We'll also align the
|
||||||
|
|
||||||
Update the `header` and `cell` definitions for amount as follows:
|
Update the `header` and `cell` definitions for amount as follows:
|
||||||
|
|
||||||
```ts:line-numbers title="components/payments/columns.ts" {5-17}
|
```ts
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
|
|
||||||
export const columns: ColumnDef<Payment>[] = [
|
export const columns: ColumnDef<Payment>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: "amount",
|
accessorKey: 'amount',
|
||||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const amount = parseFloat(row.getValue("amount"))
|
const amount = Number.parseFloat(row.getValue('amount'))
|
||||||
const formatted = new Intl.NumberFormat("en-US", {
|
const formatted = new Intl.NumberFormat('en-US', {
|
||||||
style: "currency",
|
style: 'currency',
|
||||||
currency: "USD",
|
currency: 'USD',
|
||||||
}).format(amount)
|
}).format(amount)
|
||||||
|
|
||||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||||
|
|
@ -295,10 +299,9 @@ Let's add row actions to our table. We'll use a `<Dropdown />` component for thi
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
|
|
||||||
### Add the following into your `DataTableDropDown.vue` component:
|
### Add the following into your `DataTableDropDown.vue` component
|
||||||
|
|
||||||
```vue:line-numbers
|
```vue
|
||||||
// DataTableDropDown.vue
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { MoreHorizontal } from 'lucide-vue-next'
|
import { MoreHorizontal } from 'lucide-vue-next'
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
||||||
|
|
@ -334,15 +337,14 @@ function copy(id: string) {
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update columns definition
|
### Update columns definition
|
||||||
|
|
||||||
Update our columns definition to add a new `actions` column. The `actions` cell returns a `<Dropdown />` component.
|
Update our columns definition to add a new `actions` column. The `actions` cell returns a `<Dropdown />` component.
|
||||||
|
|
||||||
```ts:line-numbers showLineNumber{2,6-16}
|
```ts
|
||||||
import { ColumnDef } from "@tanstack/vue-table"
|
import { ColumnDef } from '@tanstack/vue-table'
|
||||||
import DropdownAction from '@/components/DataTableDropDown.vue'
|
import DropdownAction from '@/components/DataTableDropDown.vue'
|
||||||
|
|
||||||
export const columns: ColumnDef<Payment>[] = [
|
export const columns: ColumnDef<Payment>[] = [
|
||||||
|
|
@ -359,7 +361,6 @@ export const columns: ColumnDef<Payment>[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can access the row data using `row.original` in the `cell` function. Use this to handle actions for your row eg. use the `id` to make a DELETE call to your API.
|
You can access the row data using `row.original` in the `cell` function. Use this to handle actions for your row eg. use the `id` to make a DELETE call to your API.
|
||||||
|
|
@ -396,9 +397,9 @@ This will automatically paginate your rows into pages of 10. See the [pagination
|
||||||
|
|
||||||
We can add pagination controls to our table using the `<Button />` component and the `table.previousPage()`, `table.nextPage()` API methods.
|
We can add pagination controls to our table using the `<Button />` component and the `table.previousPage()`, `table.nextPage()` API methods.
|
||||||
|
|
||||||
```vue:line-numbers {3,15,21-39}
|
```vue
|
||||||
<script lang="ts" generic="TData, TValue">
|
<script lang="ts" generic="TData, TValue">
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
const table = useVueTable({
|
const table = useVueTable({
|
||||||
get data() { return props.data },
|
get data() { return props.data },
|
||||||
|
|
@ -406,7 +407,6 @@ const table = useVueTable({
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -436,7 +436,6 @@ const table = useVueTable({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Reusable Components](#reusable-components) section for a more advanced pagination component.
|
See [Reusable Components](#reusable-components) section for a more advanced pagination component.
|
||||||
|
|
@ -449,22 +448,21 @@ Let's make the email column sortable.
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
|
|
||||||
### Add the following into your `utils` file:
|
### Add the following into your `utils` file
|
||||||
|
|
||||||
```ts:line-numbers {5,6,12-17}
|
```ts
|
||||||
import { type ClassValue, clsx } from 'clsx'
|
import { type ClassValue, clsx } from 'clsx'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import type { Updater } from '@tanstack/vue-table'
|
import type { Updater } from '@tanstack/vue-table'
|
||||||
import { type Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
export function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
||||||
ref.value
|
ref.value = typeof updaterOrValue === 'function'
|
||||||
= typeof updaterOrValue === 'function'
|
|
||||||
? updaterOrValue(ref.value)
|
? updaterOrValue(ref.value)
|
||||||
: updaterOrValue
|
: updaterOrValue
|
||||||
}
|
}
|
||||||
|
|
@ -474,15 +472,13 @@ The `valueUpdater` function updates a Vue `ref` object's value. It handles both
|
||||||
|
|
||||||
### Update `<DataTable>`
|
### Update `<DataTable>`
|
||||||
|
|
||||||
```vue:line-numbers {4,7,16,34,41-44}
|
```vue:line-numbers {4,14,17,33,40-44}
|
||||||
<script setup lang="ts" generic="TData, TValue">
|
<script setup lang="ts" generic="TData, TValue">
|
||||||
import type {
|
import type {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
SortingState,
|
SortingState,
|
||||||
} from '@tanstack/vue-table'
|
} from '@tanstack/vue-table'
|
||||||
|
|
||||||
import { valueUpdater } from '@/lib/utils'
|
|
||||||
|
|
||||||
import { ArrowUpDown, ChevronDown } from 'lucide-vue-next'
|
import { ArrowUpDown, ChevronDown } from 'lucide-vue-next'
|
||||||
import { h, ref } from 'vue'
|
import { h, ref } from 'vue'
|
||||||
|
|
||||||
|
|
@ -492,7 +488,8 @@ import {
|
||||||
getPaginationRowModel,
|
getPaginationRowModel,
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useVueTable,
|
useVueTable,
|
||||||
} from "@tanstack/vue-table"
|
} from '@tanstack/vue-table'
|
||||||
|
import { valueUpdater } from '@/lib/utils'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
|
@ -501,7 +498,7 @@ import {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table"
|
} from '@/components/ui/table'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
columns: ColumnDef<TData, TValue>[]
|
columns: ColumnDef<TData, TValue>[]
|
||||||
|
|
@ -521,7 +518,6 @@ const table = useVueTable({
|
||||||
get sorting() { return sorting.value },
|
get sorting() { return sorting.value },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import {
|
||||||
|
|
||||||
### Link Component
|
### Link Component
|
||||||
|
|
||||||
When using the Nuxt.js `<NuxtLink />` component, you can use `navigationMenuTriggerStyle()` to apply the correct styles to the trigger.
|
When using the Nuxt `<NuxtLink />` component, you can use `navigationMenuTriggerStyle()` to apply the correct styles to the trigger.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu'
|
import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu'
|
||||||
|
|
|
||||||
71
apps/www/src/content/docs/components/number-field.md
Normal file
71
apps/www/src/content/docs/components/number-field.md
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
title: Number Field
|
||||||
|
description: A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
|
||||||
|
source: apps/www/src/lib/registry/default/ui/number-field
|
||||||
|
primitive: https://www.radix-vue.com/components/number-field.html
|
||||||
|
---
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldDemo" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<TabPreview name="CLI">
|
||||||
|
<template #CLI>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx shadcn-vue@latest add number-field
|
||||||
|
```
|
||||||
|
</template>
|
||||||
|
</TabPreview>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField>
|
||||||
|
<Label>Age</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Default
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldDemo" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
### Disabled
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldDisabled" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
### Decimal
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldDecimal" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
### Percentage
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldPercentage" class="max-w-[180px]" />
|
||||||
|
|
||||||
|
### Currency
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldCurrency" class="max-w-[220px]" />
|
||||||
|
|
||||||
|
### Form
|
||||||
|
|
||||||
|
<ComponentPreview name="NumberFieldForm" class="max-w-xs" />
|
||||||
|
|
@ -44,6 +44,6 @@ import { Separator } from '@/components/ui/separator'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Separator />
|
<Separator label="Or" />
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import {
|
||||||
<SheetTrigger>Open</SheetTrigger>
|
<SheetTrigger>Open</SheetTrigger>
|
||||||
<SheetContent>
|
<SheetContent>
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle>Are you sure absolutely sure?</SheetTitle>
|
<SheetTitle>Are you absolutely sure?</SheetTitle>
|
||||||
<SheetDescription>
|
<SheetDescription>
|
||||||
This action cannot be undone. This will permanently delete your account
|
This action cannot be undone. This will permanently delete your account
|
||||||
and remove your data from our servers.
|
and remove your data from our servers.
|
||||||
|
|
@ -61,7 +61,7 @@ You can adjust the size of the sheet using CSS classes:
|
||||||
<SheetTrigger>Open</SheetTrigger>
|
<SheetTrigger>Open</SheetTrigger>
|
||||||
<SheetContent class="w-[400px] sm:w-[540px]">
|
<SheetContent class="w-[400px] sm:w-[540px]">
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle>Are you sure absolutely sure?</SheetTitle>
|
<SheetTitle>Are you absolutely sure?</SheetTitle>
|
||||||
<SheetDescription>
|
<SheetDescription>
|
||||||
This action cannot be undone. This will permanently delete your account
|
This action cannot be undone. This will permanently delete your account
|
||||||
and remove your data from our servers.
|
and remove your data from our servers.
|
||||||
|
|
|
||||||
|
|
@ -61,3 +61,23 @@ import { Button } from '@/components/ui/button'
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Sonner with Dialog
|
||||||
|
|
||||||
|
Related issue https://github.com/radix-vue/shadcn-vue/issues/462
|
||||||
|
|
||||||
|
Add `pointer-events-auto` class to Toaster component in your `App.vue` file:
|
||||||
|
|
||||||
|
```vue {6}
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Toaster } from '@/components/ui/sonner'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Toaster class="pointer-events-auto" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
<ComponentPreview name="SonnerWithDialog" />
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ Would you like to use TypeScript (recommended)? no / yes
|
||||||
Which framework are you using? Astro
|
Which framework are you using? Astro
|
||||||
Which style would you like to use? › Default
|
Which style would you like to use? › Default
|
||||||
Which color would you like to use as base color? › Slate
|
Which color would you like to use as base color? › Slate
|
||||||
|
Where is your tsconfig.json or jsconfig.json file? › ./tsconfig.json
|
||||||
Where is your global CSS file? › src/styles/globals.css
|
Where is your global CSS file? › src/styles/globals.css
|
||||||
Do you want to use CSS variables for colors? › no / yes
|
Do you want to use CSS variables for colors? › no / yes
|
||||||
Where is your tailwind.config located? › tailwind.config.mjs
|
Where is your tailwind.config located? › tailwind.config.mjs
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,13 @@ Would you like to use TypeScript (recommended)? no / yes
|
||||||
Which framework are you using? Vite / Nuxt / Laravel
|
Which framework are you using? Vite / Nuxt / Laravel
|
||||||
Which style would you like to use? › Default
|
Which style would you like to use? › Default
|
||||||
Which color would you like to use as base color? › Slate
|
Which color would you like to use as base color? › Slate
|
||||||
|
Where is your tsconfig.json or jsconfig.json file? › ./tsconfig.json
|
||||||
Where is your global CSS file? › resources/css/app.css
|
Where is your global CSS file? › resources/css/app.css
|
||||||
Do you want to use CSS variables for colors? › no / yes
|
Do you want to use CSS variables for colors? › no / yes
|
||||||
Where is your tailwind.config.js located? › tailwind.config.js
|
Where is your tailwind.config.js located? › tailwind.config.js
|
||||||
Configure the import alias for components: › @/Components
|
Configure the import alias for components: › @/Components
|
||||||
Configure the import alias for utils: › @/lib/utils
|
Configure the import alias for utils: › @/lib/utils
|
||||||
|
Write configuration to components.json. Proceed? > Y/n
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update tailwind.config.js
|
### Update tailwind.config.js
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ If you encounter the error `ERROR: Cannot read properties of undefined (reading
|
||||||
```bash
|
```bash
|
||||||
npm install -D typescript
|
npm install -D typescript
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install TailwindCSS module
|
### Install TailwindCSS module
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -76,7 +77,7 @@ export default defineNuxtModule<ShadcnVueOptions>({
|
||||||
configKey: 'shadcn',
|
configKey: 'shadcn',
|
||||||
version: '0.0.1',
|
version: '0.0.1',
|
||||||
compatibility: {
|
compatibility: {
|
||||||
nuxt: '^3.9.0',
|
nuxt: '>=3.9.0',
|
||||||
bridge: false,
|
bridge: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -183,11 +184,13 @@ Would you like to use TypeScript (recommended)? no / yes
|
||||||
Which framework are you using? Vite / Nuxt / Laravel
|
Which framework are you using? Vite / Nuxt / Laravel
|
||||||
Which style would you like to use? › Default
|
Which style would you like to use? › Default
|
||||||
Which color would you like to use as base color? › Slate
|
Which color would you like to use as base color? › Slate
|
||||||
|
Where is your tsconfig.json or jsconfig.json file? › ./tsconfig.json
|
||||||
Where is your global CSS file? › › src/index.css
|
Where is your global CSS file? › › src/index.css
|
||||||
Do you want to use CSS variables for colors? › no / yes
|
Do you want to use CSS variables for colors? › no / yes
|
||||||
Where is your tailwind.config.js located? › tailwind.config.js
|
Where is your tailwind.config.js located? › tailwind.config.js
|
||||||
Configure the import alias for components: › @/components
|
Configure the import alias for components: › @/components
|
||||||
Configure the import alias for utils: › @/lib/utils
|
Configure the import alias for utils: › @/lib/utils
|
||||||
|
Write configuration to components.json. Proceed? > Y/n
|
||||||
```
|
```
|
||||||
|
|
||||||
### App structure
|
### App structure
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,12 @@ Install `tailwindcss` and its peer dependencies, then generate your `tailwind.co
|
||||||
#### `vite.config`
|
#### `vite.config`
|
||||||
|
|
||||||
```typescript {5,6,9-13}
|
```typescript {5,6,9-13}
|
||||||
import path from "path"
|
import path from 'node:path'
|
||||||
import { defineConfig } from "vite"
|
import { defineConfig } from 'vite'
|
||||||
import vue from "@vitejs/plugin-vue"
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
import tailwind from "tailwindcss"
|
import tailwind from 'tailwindcss'
|
||||||
import autoprefixer from "autoprefixer"
|
import autoprefixer from 'autoprefixer'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
css: {
|
css: {
|
||||||
|
|
@ -61,7 +61,7 @@ Install `tailwindcss` and its peer dependencies, then generate your `tailwind.co
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
'@': path.resolve(__dirname, './src'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
@ -116,12 +116,12 @@ npm i -D @types/node
|
||||||
```
|
```
|
||||||
|
|
||||||
```typescript {15-19}
|
```typescript {15-19}
|
||||||
import path from "path"
|
import path from 'node:path'
|
||||||
import vue from "@vitejs/plugin-vue"
|
import vue from '@vitejs/plugin-vue'
|
||||||
import { defineConfig } from "vite"
|
import { defineConfig } from 'vite'
|
||||||
|
|
||||||
import tailwind from "tailwindcss"
|
import tailwind from 'tailwindcss'
|
||||||
import autoprefixer from "autoprefixer"
|
import autoprefixer from 'autoprefixer'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
css: {
|
css: {
|
||||||
|
|
@ -132,7 +132,7 @@ export default defineConfig({
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
'@': path.resolve(__dirname, './src'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
@ -159,11 +159,13 @@ Would you like to use TypeScript (recommended)? no / yes
|
||||||
Which framework are you using? Vite / Nuxt / Laravel
|
Which framework are you using? Vite / Nuxt / Laravel
|
||||||
Which style would you like to use? › Default
|
Which style would you like to use? › Default
|
||||||
Which color would you like to use as base color? › Slate
|
Which color would you like to use as base color? › Slate
|
||||||
Where is your global CSS file? › › src/index.css
|
Where is your tsconfig.json or jsconfig.json file? › ./tsconfig.json
|
||||||
|
Where is your global CSS file? › › src/assets/index.css
|
||||||
Do you want to use CSS variables for colors? › no / yes
|
Do you want to use CSS variables for colors? › no / yes
|
||||||
Where is your tailwind.config.js located? › tailwind.config.js
|
Where is your tailwind.config.js located? › tailwind.config.js
|
||||||
Configure the import alias for components: › @/components
|
Configure the import alias for components: › @/components
|
||||||
Configure the import alias for utils: › @/lib/utils
|
Configure the import alias for utils: › @/lib/utils
|
||||||
|
Write configuration to components.json. Proceed? > Y/n
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update main.ts
|
### Update main.ts
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { Label } from '@/lib/registry/new-york/ui/label'
|
||||||
<div class="grid grid-cols-2 gap-6">
|
<div class="grid grid-cols-2 gap-6">
|
||||||
<Button variant="outline">
|
<Button variant="outline">
|
||||||
<GitHubIcon class="mr-2 h-4 w-4" />
|
<GitHubIcon class="mr-2 h-4 w-4" />
|
||||||
Github
|
GitHub
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline">
|
<Button variant="outline">
|
||||||
<svg role="img" viewBox="0 0 24 24" class="mr-2 h-4 w-4">
|
<svg role="img" viewBox="0 0 24 24" class="mr-2 h-4 w-4">
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ async function onSubmit(values: any) {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Form v-slot="{ setValues }" :validation-schema="accountFormSchema" class="space-y-8" @submit="onSubmit">
|
<Form v-slot="{ setFieldValue }" :validation-schema="accountFormSchema" class="space-y-8" @submit="onSubmit">
|
||||||
<FormField v-slot="{ componentField }" name="name">
|
<FormField v-slot="{ componentField }" name="name">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Name</FormLabel>
|
<FormLabel>Name</FormLabel>
|
||||||
|
|
@ -126,15 +126,11 @@ async function onSubmit(values: any) {
|
||||||
@update:model-value="(v) => {
|
@update:model-value="(v) => {
|
||||||
if (v) {
|
if (v) {
|
||||||
dateValue = v
|
dateValue = v
|
||||||
setValues({
|
setFieldValue('dob', toDate(v).toISOString())
|
||||||
dob: toDate(v).toISOString(),
|
|
||||||
}, false)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dateValue = undefined
|
dateValue = undefined
|
||||||
setValues({
|
setFieldValue('dob', undefined)
|
||||||
dob: undefined,
|
|
||||||
}, false)
|
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
|
@ -178,9 +174,7 @@ async function onSubmit(values: any) {
|
||||||
<CommandItem
|
<CommandItem
|
||||||
v-for="language in languages" :key="language.value" :value="language.label"
|
v-for="language in languages" :key="language.value" :value="language.label"
|
||||||
@select="() => {
|
@select="() => {
|
||||||
setValues({
|
setFieldValue('language', language.value)
|
||||||
language: language.value,
|
|
||||||
}, false)
|
|
||||||
open = false
|
open = false
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const onSubmit = handleSubmit((values) => {
|
||||||
<select
|
<select
|
||||||
:class="cn(
|
:class="cn(
|
||||||
buttonVariants({ variant: 'outline' }),
|
buttonVariants({ variant: 'outline' }),
|
||||||
'w-[200px] appearance-none bg-transparent font-normal',
|
'w-[200px] appearance-none font-normal',
|
||||||
)"
|
)"
|
||||||
v-bind="field"
|
v-bind="field"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const { handleSubmit } = useForm({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSubmit = handleSubmit((values, { resetForm }) => {
|
const onSubmit = handleSubmit((values) => {
|
||||||
toast({
|
toast({
|
||||||
title: 'You submitted the following values:',
|
title: 'You submitted the following values:',
|
||||||
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
|
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const $route = useRoute()
|
||||||
const sidebarNavItems: Item[] = [
|
const sidebarNavItems: Item[] = [
|
||||||
{
|
{
|
||||||
title: 'Profile',
|
title: 'Profile',
|
||||||
href: '/examples/forms/forms',
|
href: '/examples/forms',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Account',
|
title: 'Account',
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ const showDeleteDialog = ref(false)
|
||||||
<AlertDialog v-model:open="showDeleteDialog">
|
<AlertDialog v-model:open="showDeleteDialog">
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Are you sure absolutely sure?</AlertDialogTitle>
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
This action cannot be undone. This preset will no longer be
|
This action cannot be undone. This preset will no longer be
|
||||||
accessible by you or others you've shared it with.
|
accessible by you or others you've shared it with.
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export const models: Model<ModelType>[] = [
|
||||||
strengths: 'Moderate classification, semantic search',
|
strengths: 'Moderate classification, semantic search',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: ' be638fb1-973b-4471-a49c-290325085802',
|
id: 'be638fb1-973b-4471-a49c-290325085802',
|
||||||
name: 'text-ada-001',
|
name: 'text-ada-001',
|
||||||
description:
|
description:
|
||||||
'Capable of very simple tasks, usually the fastest model in the GPT-3 series, and lowest cost.',
|
'Capable of very simple tasks, usually the fastest model in the GPT-3 series, and lowest cost.',
|
||||||
|
|
|
||||||
|
|
@ -53,18 +53,18 @@ export const statuses = [
|
||||||
|
|
||||||
export const priorities = [
|
export const priorities = [
|
||||||
{
|
{
|
||||||
label: 'Low',
|
|
||||||
value: 'low',
|
value: 'low',
|
||||||
|
label: 'Low',
|
||||||
icon: h(ArrowDownIcon),
|
icon: h(ArrowDownIcon),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Medium',
|
|
||||||
value: 'medium',
|
value: 'medium',
|
||||||
|
label: 'Medium',
|
||||||
icon: h(ArrowRightIcon),
|
icon: h(ArrowRightIcon),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'High',
|
|
||||||
value: 'high',
|
value: 'high',
|
||||||
|
label: 'High',
|
||||||
icon: h(ArrowUpIcon),
|
icon: h(ArrowUpIcon),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ import { Input } from '@/lib/registry/default/ui/input'
|
||||||
import { Label } from '@/lib/registry/default/ui/label'
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/lib/registry/default/ui/select'
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/lib/registry/default/ui/select'
|
||||||
import { Textarea } from '@/lib/registry/default/ui/textarea'
|
import { Textarea } from '@/lib/registry/default/ui/textarea'
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/ui/tooltip'
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/default/ui/tooltip'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="grid h-screen w-full pl-[53px]">
|
<div class="grid h-screen w-full pl-[56px]">
|
||||||
<aside class="inset-y fixed left-0 z-20 flex h-full flex-col border-r">
|
<aside class="inset-y fixed left-0 z-20 flex h-full flex-col border-r">
|
||||||
<div class="border-b p-2">
|
<div class="border-b p-2">
|
||||||
<Button variant="outline" size="icon" aria-label="Home">
|
<Button variant="outline" size="icon" aria-label="Home">
|
||||||
|
|
@ -26,6 +26,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<nav class="grid gap-1 p-2">
|
<nav class="grid gap-1 p-2">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -41,6 +42,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Playground
|
Playground
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -56,6 +59,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Models
|
Models
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -71,6 +76,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
API
|
API
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -86,6 +93,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Documentation
|
Documentation
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -101,8 +110,10 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Settings
|
Settings
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="mt-auto grid gap-1 p-2">
|
<nav class="mt-auto grid gap-1 p-2">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -118,6 +129,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Help
|
Help
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -133,6 +146,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Account
|
Account
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
|
|
@ -406,6 +420,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
class="min-h-12 resize-none border-0 p-3 shadow-none focus-visible:ring-0"
|
class="min-h-12 resize-none border-0 p-3 shadow-none focus-visible:ring-0"
|
||||||
/>
|
/>
|
||||||
<div class="flex items-center p-3 pt-0">
|
<div class="flex items-center p-3 pt-0">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button variant="ghost" size="icon">
|
<Button variant="ghost" size="icon">
|
||||||
|
|
@ -417,6 +432,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Attach File
|
Attach File
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<Button variant="ghost" size="icon">
|
<Button variant="ghost" size="icon">
|
||||||
|
|
@ -428,6 +445,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/
|
||||||
Use Microphone
|
Use Microphone
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
<Button type="submit" size="sm" class="ml-auto gap-1.5">
|
<Button type="submit" size="sm" class="ml-auto gap-1.5">
|
||||||
Send Message
|
Send Message
|
||||||
<CornerDownLeft class="size-3.5" />
|
<CornerDownLeft class="size-3.5" />
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ export const containerClass = 'w-full h-full'
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
ChevronLeft,
|
|
||||||
ChevronRight,
|
|
||||||
CircleUser,
|
CircleUser,
|
||||||
Copy,
|
Copy,
|
||||||
CreditCard,
|
CreditCard,
|
||||||
|
|
@ -42,11 +40,7 @@ import {
|
||||||
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
||||||
import {
|
import {
|
||||||
Pagination,
|
Pagination,
|
||||||
PaginationEllipsis,
|
|
||||||
PaginationFirst,
|
|
||||||
PaginationLast,
|
|
||||||
PaginationList,
|
PaginationList,
|
||||||
PaginationListItem,
|
|
||||||
PaginationNext,
|
PaginationNext,
|
||||||
PaginationPrev,
|
PaginationPrev,
|
||||||
} from '@/lib/registry/default/ui/pagination'
|
} from '@/lib/registry/default/ui/pagination'
|
||||||
|
|
@ -69,6 +63,7 @@ import {
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/lib/registry/default/ui/tooltip'
|
} from '@/lib/registry/default/ui/tooltip'
|
||||||
import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
|
|
@ -85,6 +80,7 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
||||||
<span class="sr-only">Acme Inc</span>
|
<span class="sr-only">Acme Inc</span>
|
||||||
</a>
|
</a>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -99,6 +95,8 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Dashboard
|
Dashboard
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -113,6 +111,9 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Orders
|
Orders
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -127,6 +128,9 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Products
|
Products
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -141,6 +145,9 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Customers
|
Customers
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -155,8 +162,10 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Analytics
|
Analytics
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
<nav class="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -171,6 +180,7 @@ import { Checkbox } from '@/lib/registry/default/ui/checkbox'
|
||||||
Settings
|
Settings
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ import {
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/lib/registry/default/ui/tooltip'
|
} from '@/lib/registry/default/ui/tooltip'
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -68,6 +69,7 @@ import {
|
||||||
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
||||||
<span class="sr-only">Acme Inc</span>
|
<span class="sr-only">Acme Inc</span>
|
||||||
</a>
|
</a>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -82,6 +84,8 @@ import {
|
||||||
Dashboard
|
Dashboard
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -96,6 +100,8 @@ import {
|
||||||
Orders
|
Orders
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -110,6 +116,8 @@ import {
|
||||||
Products
|
Products
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -124,6 +132,8 @@ import {
|
||||||
Customers
|
Customers
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -138,8 +148,10 @@ import {
|
||||||
Analytics
|
Analytics
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="mt-auto flex flex-col items-center gap-4 px-2 py-4">
|
<nav class="mt-auto flex flex-col items-center gap-4 px-2 py-4">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -154,6 +166,7 @@ import {
|
||||||
Settings
|
Settings
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ import {
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/lib/registry/default/ui/tooltip'
|
} from '@/lib/registry/default/ui/tooltip'
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -71,6 +72,7 @@ import {
|
||||||
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
<Package2 class="h-4 w-4 transition-all group-hover:scale-110" />
|
||||||
<span class="sr-only">Acme Inc</span>
|
<span class="sr-only">Acme Inc</span>
|
||||||
</a>
|
</a>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -85,6 +87,8 @@ import {
|
||||||
Dashboard
|
Dashboard
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -99,6 +103,8 @@ import {
|
||||||
Orders
|
Orders
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -113,6 +119,8 @@ import {
|
||||||
Products
|
Products
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -127,6 +135,8 @@ import {
|
||||||
Customers
|
Customers
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -141,8 +151,10 @@ import {
|
||||||
Analytics
|
Analytics
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
<nav class="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||||
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<a
|
<a
|
||||||
|
|
@ -157,6 +169,7 @@ import {
|
||||||
Settings
|
Settings
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
<div class="flex flex-col sm:gap-4 sm:py-4 sm:pl-14">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
import { h, onMounted, ref, shallowRef } from 'vue'
|
import { h, onMounted, shallowRef } from 'vue'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
import { toast } from '@/lib/registry/default/ui/toast'
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
import { AutoForm } from '@/lib/registry/default/ui/auto-form'
|
import { AutoForm } from '@/lib/registry/default/ui/auto-form'
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
import { h, reactive, ref } from 'vue'
|
import { h } from 'vue'
|
||||||
import { useForm } from 'vee-validate'
|
|
||||||
import { toTypedSchema } from '@vee-validate/zod'
|
|
||||||
import { DependencyType } from '../ui/auto-form/interface'
|
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
import { toast } from '@/lib/registry/default/ui/toast'
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
import type { Config } from '@/lib/registry/default/ui/auto-form'
|
|
||||||
import { AutoForm, AutoFormField } from '@/lib/registry/default/ui/auto-form'
|
import { AutoForm, AutoFormField } from '@/lib/registry/default/ui/auto-form'
|
||||||
|
|
||||||
enum Sports {
|
enum Sports {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import * as z from 'zod'
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
import { toast } from '@/lib/registry/default/ui/toast'
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
import { AutoForm, AutoFormField } from '@/lib/registry/default/ui/auto-form'
|
import { AutoForm } from '@/lib/registry/default/ui/auto-form'
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
subObject: z.object({
|
subObject: z.object({
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const formSchema = toTypedSchema(z.object({
|
||||||
|
|
||||||
const placeholder = ref()
|
const placeholder = ref()
|
||||||
|
|
||||||
const { handleSubmit, setValues, values } = useForm({
|
const { handleSubmit, setFieldValue, values } = useForm({
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -79,14 +79,10 @@ const onSubmit = handleSubmit((values) => {
|
||||||
:max-value="today(getLocalTimeZone())"
|
:max-value="today(getLocalTimeZone())"
|
||||||
@update:model-value="(v) => {
|
@update:model-value="(v) => {
|
||||||
if (v) {
|
if (v) {
|
||||||
setValues({
|
setFieldValue('dob', v.toString())
|
||||||
dob: v.toString(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setValues({
|
setFieldValue('dob', undefined)
|
||||||
dob: '',
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { type HTMLAttributes, type Ref, computed, toRef } from 'vue'
|
import { type HTMLAttributes, type Ref, computed } from 'vue'
|
||||||
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'radix-vue'
|
import { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'radix-vue'
|
||||||
import { createDecade, createYear, toDate } from 'radix-vue/date'
|
import { createDecade, createYear, toDate } from 'radix-vue/date'
|
||||||
import { type DateValue, getLocalTimeZone, today } from '@internationalized/date'
|
import { type DateValue, getLocalTimeZone, today } from '@internationalized/date'
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ import { Button } from '@/lib/registry/default/ui/button'
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent position="popper">
|
<SelectContent position="popper">
|
||||||
<SelectItem value="nuxt">
|
<SelectItem value="nuxt">
|
||||||
Nuxt.js
|
Nuxt
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="next">
|
<SelectItem value="next">
|
||||||
Next.js
|
Next.js
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ import {
|
||||||
Astro
|
Astro
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="nuxt">
|
<SelectItem value="nuxt">
|
||||||
Nuxt.js
|
Nuxt
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { Minus, Plus } from 'lucide-vue-next'
|
import { Minus, Plus } from 'lucide-vue-next'
|
||||||
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
|
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||||
import { useData } from 'vitepress'
|
|
||||||
import { Button } from '@/lib/registry/default/ui/button'
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -13,8 +12,6 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from '@/lib/registry/default/ui/card'
|
} from '@/lib/registry/default/ui/card'
|
||||||
import { themes } from '@/lib/registry/themes'
|
|
||||||
import { useConfigStore } from '@/stores/config'
|
|
||||||
|
|
||||||
const goal = ref(350)
|
const goal = ref(350)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from '@/lib/registry/default/ui/card'
|
} from '@/lib/registry/default/ui/card'
|
||||||
import { useConfigStore } from '@/stores/config'
|
|
||||||
|
|
||||||
type Data = typeof data[number]
|
type Data = typeof data[number]
|
||||||
const data = [
|
const data = [
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import {
|
||||||
const frameworks = [
|
const frameworks = [
|
||||||
{ value: 'next.js', label: 'Next.js' },
|
{ value: 'next.js', label: 'Next.js' },
|
||||||
{ value: 'sveltekit', label: 'SvelteKit' },
|
{ value: 'sveltekit', label: 'SvelteKit' },
|
||||||
{ value: 'nuxt.js', label: 'Nuxt.js' },
|
{ value: 'nuxt', label: 'Nuxt' },
|
||||||
{ value: 'remix', label: 'Remix' },
|
{ value: 'remix', label: 'Remix' },
|
||||||
{ value: 'astro', label: 'Astro' },
|
{ value: 'astro', label: 'Astro' },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const formSchema = toTypedSchema(z.object({
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const { handleSubmit, setValues, values } = useForm({
|
const { handleSubmit, setFieldValue, values } = useForm({
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -91,9 +91,7 @@ const onSubmit = handleSubmit((values) => {
|
||||||
:key="language.value"
|
:key="language.value"
|
||||||
:value="language.label"
|
:value="language.label"
|
||||||
@select="() => {
|
@select="() => {
|
||||||
setValues({
|
setFieldValue('language', language.value)
|
||||||
language: language.value,
|
|
||||||
})
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<Check
|
<Check
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const statuses: Status[] = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const value = ref<typeof statuses[number]>()
|
// const value = ref<typeof statuses[number]>()
|
||||||
|
|
||||||
const selectedStatus = ref<Status>()
|
const selectedStatus = ref<Status>()
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const formSchema = toTypedSchema(z.object({
|
||||||
|
|
||||||
const placeholder = ref()
|
const placeholder = ref()
|
||||||
|
|
||||||
const { handleSubmit, setValues, values } = useForm({
|
const { handleSubmit, setFieldValue, values } = useForm({
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
initialValues: {
|
initialValues: {
|
||||||
|
|
||||||
|
|
@ -82,14 +82,10 @@ const onSubmit = handleSubmit((values) => {
|
||||||
:max-value="today(getLocalTimeZone())"
|
:max-value="today(getLocalTimeZone())"
|
||||||
@update:model-value="(v) => {
|
@update:model-value="(v) => {
|
||||||
if (v) {
|
if (v) {
|
||||||
setValues({
|
setFieldValue('dob', v.toString())
|
||||||
dob: v.toString(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setValues({
|
setFieldValue('dob', undefined)
|
||||||
dob: '',
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}"
|
}"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { DonutChart } from '@/lib/registry/new-york/ui/chart-donut'
|
import { DonutChart } from '@/lib/registry/default/ui/chart-donut'
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{ name: 'Jan', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },
|
{ name: 'Jan', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField
|
||||||
|
id="balance"
|
||||||
|
:default-value="1500"
|
||||||
|
:format-options="{
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'EUR',
|
||||||
|
currencyDisplay: 'code',
|
||||||
|
currencySign: 'accounting',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Label for="balance">Balance</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField
|
||||||
|
id="number"
|
||||||
|
:default-value="5"
|
||||||
|
:format-options="{
|
||||||
|
signDisplay: 'exceptZero',
|
||||||
|
minimumFractionDigits: 1,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Label for="number">Number</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField id="age" :default-value="18" :min="0">
|
||||||
|
<Label for="age">Age</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField id="age-disabled" :default-value="18" disabled>
|
||||||
|
<Label for="age-disabled">Age</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { useForm } from 'vee-validate'
|
||||||
|
import { toTypedSchema } from '@vee-validate/zod'
|
||||||
|
import * as z from 'zod'
|
||||||
|
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/lib/registry/default/ui/form'
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { toast } from '@/lib/registry/default/ui/toast'
|
||||||
|
|
||||||
|
const formSchema = toTypedSchema(z.object({
|
||||||
|
payment: z.number().min(10, 'Min 10 euros to send payment').max(5000, 'Max 5000 euros to send payment'),
|
||||||
|
}))
|
||||||
|
|
||||||
|
const { handleSubmit, setFieldValue } = useForm({
|
||||||
|
validationSchema: formSchema,
|
||||||
|
initialValues: {
|
||||||
|
payment: 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSubmit = handleSubmit((values) => {
|
||||||
|
toast({
|
||||||
|
title: 'You submitted the following values:',
|
||||||
|
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form class="w-2/3 space-y-6" @submit="onSubmit">
|
||||||
|
<FormField name="payment">
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Payment</FormLabel>
|
||||||
|
<NumberField
|
||||||
|
class="gap-2"
|
||||||
|
:min="0"
|
||||||
|
:format-options="{
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'EUR',
|
||||||
|
currencyDisplay: 'code',
|
||||||
|
currencySign: 'accounting',
|
||||||
|
}"
|
||||||
|
@update:model-value="(v) => {
|
||||||
|
if (v) {
|
||||||
|
setFieldValue('payment', v)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setFieldValue('payment', undefined)
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<FormControl>
|
||||||
|
<NumberFieldInput />
|
||||||
|
</FormControl>
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
<FormDescription>
|
||||||
|
Enter value between 10 and 5000.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
</FormField>
|
||||||
|
<Button type="submit">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
NumberField,
|
||||||
|
NumberFieldContent,
|
||||||
|
NumberFieldDecrement,
|
||||||
|
NumberFieldIncrement,
|
||||||
|
NumberFieldInput,
|
||||||
|
} from '@/lib/registry/default/ui/number-field'
|
||||||
|
import { Label } from '@/lib/registry/default/ui/label'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberField
|
||||||
|
id="percent"
|
||||||
|
:default-value="0.05"
|
||||||
|
:step="0.01"
|
||||||
|
:format-options="{
|
||||||
|
style: 'percent',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Label for="percent">Percent</Label>
|
||||||
|
<NumberFieldContent>
|
||||||
|
<NumberFieldDecrement />
|
||||||
|
<NumberFieldInput />
|
||||||
|
<NumberFieldIncrement />
|
||||||
|
</NumberFieldContent>
|
||||||
|
</NumberField>
|
||||||
|
</template>
|
||||||
|
|
@ -23,7 +23,7 @@ const formSchema = toTypedSchema(z.object({
|
||||||
pin: z.array(z.coerce.string()).length(5, { message: 'Invalid input' }),
|
pin: z.array(z.coerce.string()).length(5, { message: 'Invalid input' }),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const { handleSubmit, setValues } = useForm({
|
const { handleSubmit, setFieldValue } = useForm({
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
initialValues: {
|
initialValues: {
|
||||||
pin: ['1', '2', '3'],
|
pin: ['1', '2', '3'],
|
||||||
|
|
@ -56,9 +56,7 @@ const handleComplete = (e: string[]) => console.log(e.join(''))
|
||||||
:name="componentField.name"
|
:name="componentField.name"
|
||||||
@complete="handleComplete"
|
@complete="handleComplete"
|
||||||
@update:model-value="(arrStr) => {
|
@update:model-value="(arrStr) => {
|
||||||
setValues({
|
setFieldValue('pin', arrStr.filter(Boolean))
|
||||||
pin: arrStr.filter(Boolean),
|
|
||||||
})
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<PinInputGroup>
|
<PinInputGroup>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { Separator } from '@/lib/registry/default/ui/separator'
|
||||||
An open-source UI component library.
|
An open-source UI component library.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Separator class="my-4" />
|
<Separator class="my-4" label="Or" />
|
||||||
<div class="flex h-5 items-center space-x-4 text-sm">
|
<div class="flex h-5 items-center space-x-4 text-sm">
|
||||||
<div>Blog</div>
|
<div>Blog</div>
|
||||||
<Separator orientation="vertical" />
|
<Separator orientation="vertical" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { toast } from 'vue-sonner'
|
||||||
|
import { Button } from '@/lib/registry/default/ui/button'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/lib/registry/default/ui/dialog'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger as-child>
|
||||||
|
<Button variant="outline">
|
||||||
|
Dialog with toast
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent
|
||||||
|
class="sm:max-w-md"
|
||||||
|
@interact-outside="event => {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (target?.closest('[data-sonner-toaster]')) return event.preventDefault()
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Vue Sonner Toast</DialogTitle>
|
||||||
|
<DialogDescription> Dialog with toast </DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div class="grid gap-4">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
class="px-3"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
toast('Event has been created', {
|
||||||
|
description: 'Sunday, December 03, 2023 at 9:00 AM',
|
||||||
|
action: {
|
||||||
|
label: 'Undo',
|
||||||
|
onClick: () => console.log('Undo'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Toast
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
@ -7,7 +7,7 @@ import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInpu
|
||||||
const frameworks = [
|
const frameworks = [
|
||||||
{ value: 'next.js', label: 'Next.js' },
|
{ value: 'next.js', label: 'Next.js' },
|
||||||
{ value: 'sveltekit', label: 'SvelteKit' },
|
{ value: 'sveltekit', label: 'SvelteKit' },
|
||||||
{ value: 'nuxt.js', label: 'Nuxt.js' },
|
{ value: 'nuxt', label: 'Nuxt' },
|
||||||
{ value: 'remix', label: 'Remix' },
|
{ value: 'remix', label: 'Remix' },
|
||||||
{ value: 'astro', label: 'Astro' },
|
{ value: 'astro', label: 'Astro' },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { Toggle } from '@/lib/registry/default/ui/toggle'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Toggle aria-label="Toggle italic">
|
<Toggle aria-label="Toggle bold">
|
||||||
<Bold class="h-4 w-4" />
|
<Bold class="h-4 w-4" />
|
||||||
</Toggle>
|
</Toggle>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { Toggle } from '@/lib/registry/default/ui/toggle'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Toggle aria-label="Toggle italic" disabled>
|
<Toggle aria-label="Toggle underline" disabled>
|
||||||
<Underline class="w-4 h-4" />
|
<Underline class="w-4 h-4" />
|
||||||
</Toggle>
|
</Toggle>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="text-lg font-semibold">
|
<div class="text-lg font-semibold">
|
||||||
Are you sure absolutely sure?
|
Are you absolutely sure?
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const date = ref({
|
||||||
id="date"
|
id="date"
|
||||||
:variant="'outline'"
|
:variant="'outline'"
|
||||||
:class="cn(
|
:class="cn(
|
||||||
'w-[300px] justify-start text-left font-normal',
|
'w-[280px] justify-start text-left font-normal',
|
||||||
!date && 'text-muted-foreground',
|
!date && 'text-muted-foreground',
|
||||||
)"
|
)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const date = ref({
|
||||||
id="date"
|
id="date"
|
||||||
:variant="'outline'"
|
:variant="'outline'"
|
||||||
:class="cn(
|
:class="cn(
|
||||||
'w-[300px] justify-start text-left font-normal',
|
'w-[280px] justify-start text-left font-normal',
|
||||||
!date && 'text-muted-foreground',
|
!date && 'text-muted-foreground',
|
||||||
)"
|
)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
|
||||||
import AutoFormLabel from './AutoFormLabel.vue'
|
import AutoFormLabel from './AutoFormLabel.vue'
|
||||||
import { beautifyObjectName } from './utils'
|
import { beautifyObjectName } from './utils'
|
||||||
import type { FieldProps } from './interface'
|
import type { FieldProps } from './interface'
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ const shapes = computed(() => {
|
||||||
return
|
return
|
||||||
Object.keys(shape).forEach((name) => {
|
Object.keys(shape).forEach((name) => {
|
||||||
const item = shape[name] as ZodAny
|
const item = shape[name] as ZodAny
|
||||||
let options = 'values' in item._def ? item._def.values as string[] : undefined
|
const baseItem = getBaseSchema(item) as ZodAny
|
||||||
|
let options = (baseItem && 'values' in baseItem._def) ? baseItem._def.values as string[] : undefined
|
||||||
if (!Array.isArray(options) && typeof options === 'object')
|
if (!Array.isArray(options) && typeof options === 'object')
|
||||||
options = Object.values(options)
|
options = Object.values(options)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Component, InputHTMLAttributes, SelectHTMLAttributes } from 'vue'
|
import type { Component, InputHTMLAttributes } from 'vue'
|
||||||
import type { ZodAny, z } from 'zod'
|
import type { ZodAny, z } from 'zod'
|
||||||
import type { INPUT_COMPONENTS } from './constant'
|
import type { INPUT_COMPONENTS } from './constant'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ type NestedRecord = Record<string, unknown> | { [k: string]: NestedRecord }
|
||||||
* Checks if the path opted out of nested fields using `[fieldName]` syntax
|
* Checks if the path opted out of nested fields using `[fieldName]` syntax
|
||||||
*/
|
*/
|
||||||
export function isNotNestedPath(path: string) {
|
export function isNotNestedPath(path: string) {
|
||||||
return /^\[.+\]$/i.test(path)
|
return /^\[.+\]$/.test(path)
|
||||||
}
|
}
|
||||||
function isObject(obj: unknown): obj is Record<string, unknown> {
|
function isObject(obj: unknown): obj is Record<string, unknown> {
|
||||||
return obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj)
|
return obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj)
|
||||||
|
|
@ -132,7 +132,7 @@ function isContainerValue(value: unknown): value is Record<string, unknown> {
|
||||||
}
|
}
|
||||||
function cleanupNonNestedPath(path: string) {
|
function cleanupNonNestedPath(path: string) {
|
||||||
if (isNotNestedPath(path))
|
if (isNotNestedPath(path))
|
||||||
return path.replace(/\[|\]/gi, '')
|
return path.replace(/\[|\]/g, '')
|
||||||
|
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,8 @@ const { scrollTo, selectedIndex, scrollSnaps, orientation } = useCarousel()
|
||||||
:class="cn('flex gap-2 justify-center relative -translate-x-1/2 left-1/2', { 'top-10': orientation === 'vertical' }, props.class)"
|
:class="cn('flex gap-2 justify-center relative -translate-x-1/2 left-1/2', { 'top-10': orientation === 'vertical' }, props.class)"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(_, index) in scrollSnaps" :key="index" class="border-1 w-4 h-4 rounded-full"
|
v-for="(_, index) in scrollSnaps" :key="index" class="w-2 h-2 rounded-full"
|
||||||
:class="cn(index === selectedIndex ? 'border-transparent bg-primary' : 'bg-border', props.class)"
|
:class="cn(index === selectedIndex ? 'border-transparent bg-primary' : 'bg-border')" @click="scrollTo(index)"
|
||||||
@click="scrollTo(index)"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ const { orientation, canScrollNext, scrollNext } = useCarousel()
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<ArrowRight class="h-4 w-4 text-current" />
|
<ArrowRight class="h-4 w-4 text-current" />
|
||||||
|
<span class="sr-only">Next Slide</span>
|
||||||
</slot>
|
</slot>
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ const { orientation, canScrollPrev, scrollPrev } = useCarousel()
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<ArrowLeft class="h-4 w-4 text-current" />
|
<ArrowLeft class="h-4 w-4 text-current" />
|
||||||
|
<span class="sr-only">Previous Slide</span>
|
||||||
</slot>
|
</slot>
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ export { default as CarouselDotButtons } from './CarouselDotButtons.vue'
|
||||||
export { useCarousel } from './useCarousel'
|
export { useCarousel } from './useCarousel'
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
EmblaCarouselType as CarouselApi,
|
UnwrapRefCarouselApi as CarouselApi,
|
||||||
} from 'embla-carousel'
|
} from './interface'
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,24 @@
|
||||||
|
import type { HTMLAttributes, UnwrapRef } from 'vue'
|
||||||
|
import type useEmblaCarousel from 'embla-carousel-vue'
|
||||||
import type {
|
import type {
|
||||||
EmblaCarouselType as CarouselApi,
|
EmblaCarouselVueType,
|
||||||
EmblaOptionsType as CarouselOptions,
|
} from 'embla-carousel-vue'
|
||||||
EmblaPluginType as CarouselPlugin,
|
|
||||||
} from 'embla-carousel'
|
type CarouselApi = EmblaCarouselVueType[1]
|
||||||
import type { HTMLAttributes, Ref } from 'vue'
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
||||||
|
type CarouselOptions = UseCarouselParameters[0]
|
||||||
|
type CarouselPlugin = UseCarouselParameters[1]
|
||||||
|
|
||||||
|
export type UnwrapRefCarouselApi = UnwrapRef<CarouselApi>
|
||||||
|
|
||||||
export interface CarouselProps {
|
export interface CarouselProps {
|
||||||
opts?: CarouselOptions | Ref<CarouselOptions>
|
opts?: CarouselOptions
|
||||||
plugins?: CarouselPlugin[] | Ref<CarouselPlugin[]>
|
plugins?: CarouselPlugin
|
||||||
orientation?: 'horizontal' | 'vertical'
|
orientation?: 'horizontal' | 'vertical'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CarouselEmits {
|
export interface CarouselEmits {
|
||||||
(e: 'init-api', payload: CarouselApi): void
|
(e: 'init-api', payload: UnwrapRefCarouselApi): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WithClassAsProps {
|
export interface WithClassAsProps {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import { createInjectionState } from '@vueuse/core'
|
import { createInjectionState } from '@vueuse/core'
|
||||||
import emblaCarouselVue from 'embla-carousel-vue'
|
import emblaCarouselVue from 'embla-carousel-vue'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import type {
|
import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from './interface'
|
||||||
EmblaCarouselType as CarouselApi,
|
|
||||||
} from 'embla-carousel'
|
|
||||||
import type { CarouselEmits, CarouselProps } from './interface'
|
|
||||||
|
|
||||||
const [useProvideCarousel, useInjectCarousel] = createInjectionState(
|
const [useProvideCarousel, useInjectCarousel] = createInjectionState(
|
||||||
({
|
({
|
||||||
|
|
@ -27,16 +24,16 @@ const [useProvideCarousel, useInjectCarousel] = createInjectionState(
|
||||||
emblaApi.value?.scrollTo(index)
|
emblaApi.value?.scrollTo(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
const canScrollNext = ref(true)
|
const canScrollNext = ref(false)
|
||||||
const canScrollPrev = ref(true)
|
const canScrollPrev = ref(false)
|
||||||
const selectedIndex = ref(0)
|
const selectedIndex = ref(0)
|
||||||
const scrollSnaps = ref([])
|
const scrollSnaps = ref<number[]>([])
|
||||||
|
|
||||||
function onSelect(api: CarouselApi) {
|
function onSelect(api: CarouselApi) {
|
||||||
canScrollNext.value = api.canScrollNext()
|
canScrollNext.value = api?.canScrollNext() || false
|
||||||
canScrollPrev.value = api.canScrollPrev()
|
canScrollPrev.value = api?.canScrollPrev() || false
|
||||||
selectedIndex.value = api.selectedScrollSnap()
|
selectedIndex.value = api?.selectedScrollSnap() || 0
|
||||||
scrollSnaps.value = api.scrollSnapList()
|
scrollSnaps.value = api?.scrollSnapList() || []
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import { VisArea, VisAxis, VisLine, VisXYContainer } from '@unovis/vue'
|
||||||
import { Area, Axis, Line } from '@unovis/ts'
|
import { Area, Axis, Line } from '@unovis/ts'
|
||||||
import { type Component, computed, ref } from 'vue'
|
import { type Component, computed, ref } from 'vue'
|
||||||
import { useMounted } from '@vueuse/core'
|
import { useMounted } from '@vueuse/core'
|
||||||
import { type BaseChartProps, ChartCrosshair, ChartLegend, defaultColors } from '@/lib/registry/default/ui/chart'
|
import type { BaseChartProps } from '.'
|
||||||
|
import { ChartCrosshair, ChartLegend, defaultColors } from '@/lib/registry/default/ui/chart'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,66 @@
|
||||||
export { default as AreaChart } from './AreaChart.vue'
|
export { default as AreaChart } from './AreaChart.vue'
|
||||||
|
|
||||||
|
import type { Spacing } from '@unovis/ts'
|
||||||
|
|
||||||
|
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>
|
||||||
|
|
||||||
|
export interface BaseChartProps<T extends Record<string, any>> {
|
||||||
|
/**
|
||||||
|
* The source data, in which each entry is a dictionary.
|
||||||
|
*/
|
||||||
|
data: T[]
|
||||||
|
/**
|
||||||
|
* Select the categories from your data. Used to populate the legend and toolip.
|
||||||
|
*/
|
||||||
|
categories: KeyOf<T>[]
|
||||||
|
/**
|
||||||
|
* Sets the key to map the data to the axis.
|
||||||
|
*/
|
||||||
|
index: KeyOf<T>
|
||||||
|
/**
|
||||||
|
* Change the default colors.
|
||||||
|
*/
|
||||||
|
colors?: string[]
|
||||||
|
/**
|
||||||
|
* Margin of each the container
|
||||||
|
*/
|
||||||
|
margin?: Spacing
|
||||||
|
/**
|
||||||
|
* Change the opacity of the non-selected field
|
||||||
|
* @default 0.2
|
||||||
|
*/
|
||||||
|
filterOpacity?: number
|
||||||
|
/**
|
||||||
|
* Function to format X label
|
||||||
|
*/
|
||||||
|
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||||
|
/**
|
||||||
|
* Function to format Y label
|
||||||
|
*/
|
||||||
|
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||||
|
/**
|
||||||
|
* Controls the visibility of the X axis.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
showXAxis?: boolean
|
||||||
|
/**
|
||||||
|
* Controls the visibility of the Y axis.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
showYAxis?: boolean
|
||||||
|
/**
|
||||||
|
* Controls the visibility of tooltip.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
showTooltip?: boolean
|
||||||
|
/**
|
||||||
|
* Controls the visibility of legend.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
showLegend?: boolean
|
||||||
|
/**
|
||||||
|
* Controls the visibility of gridline.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
showGridLine?: boolean
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
<script setup lang="ts" generic="T extends Record<string, any>">
|
<script setup lang="ts" generic="T extends Record<string, any>">
|
||||||
import type { BulletLegendItemInterface, Spacing } from '@unovis/ts'
|
import type { BulletLegendItemInterface } from '@unovis/ts'
|
||||||
import { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'
|
import { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||||
import { Axis, GroupedBar, StackedBar } from '@unovis/ts'
|
import { Axis, GroupedBar, StackedBar } from '@unovis/ts'
|
||||||
import { type Component, computed, ref } from 'vue'
|
import { type Component, computed, ref } from 'vue'
|
||||||
import { useMounted } from '@vueuse/core'
|
import { useMounted } from '@vueuse/core'
|
||||||
import { type BaseChartProps, ChartCrosshair, ChartLegend, defaultColors } from '@/lib/registry/default/ui/chart'
|
import type { BaseChartProps } from '.'
|
||||||
|
import { ChartCrosshair, ChartLegend, defaultColors } from '@/lib/registry/default/ui/chart'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user