chore: docs stuff (#400)
This commit is contained in:
parent
f530e3e4a7
commit
f2f5641b33
|
|
@ -15,7 +15,7 @@ const { copy, copied } = useClipboard()
|
|||
|
||||
const codeRef = ref<HTMLElement>()
|
||||
async function copyCode() {
|
||||
await copy(codeRef.value?.innerText.replace(/\u00A0/g, " ") ?? '')
|
||||
await copy(codeRef.value?.textContent?.replace(/\u00A0/g, ' ') ?? '')
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<a href="/" class="mr-6 flex items-center space-x-2">
|
||||
<a href="/" class="mr-4 md:mr-2 xl:mr-6 flex items-center lg:space-x1 xl:space-x-2">
|
||||
<svg class="h-6 w-6" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_102_1338)">
|
||||
<path d="M208 128L128 208" stroke="#41B883" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" />
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
</defs>
|
||||
</svg>
|
||||
|
||||
<span class="font-bold ">
|
||||
<span class="font-bold">
|
||||
shadcn-vue
|
||||
</span>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import Logo from './Logo.vue'
|
|||
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||
import ViewVerticalIcon from '~icons/radix-icons/view-vertical'
|
||||
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
|
@ -17,7 +16,35 @@ const open = ref(false)
|
|||
variant="ghost"
|
||||
class="mr-2 px-2 text-base flex-shrink-0 hover:bg-transparent focus-visible:bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 md:hidden"
|
||||
>
|
||||
<ViewVerticalIcon class="h-5 w-5" />
|
||||
<svg
|
||||
strokeWidth="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
>
|
||||
<path
|
||||
d="M3 5H11"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M3 12H16"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M3 19H21"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<span class="sr-only">Toggle Menu</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
|
|
|
|||
|
|
@ -14,15 +14,13 @@ import CardChat from '@/lib/registry/new-york/example/CardChat.vue'
|
|||
import ActivityGoal from '@/lib/registry/new-york/example/Cards/ActivityGoal.vue'
|
||||
import Metric from '@/lib/registry/new-york/example/Cards/Metric.vue'
|
||||
import DataTable from '@/lib/registry/new-york/example/Cards/DataTable.vue'
|
||||
import CardStats from '@/lib/registry/default/example/CardStats.vue'
|
||||
import CardStats from '@/lib/registry/new-york/example/CardStats.vue'
|
||||
|
||||
import {
|
||||
Card,
|
||||
} from '@/lib/registry/new-york/ui/card'
|
||||
import { Calendar } from '@/lib/registry/new-york/ui/calendar'
|
||||
|
||||
const goal = ref(350)
|
||||
|
||||
const range = ref({
|
||||
start: startOfToday(),
|
||||
end: addDays(startOfToday(), 8),
|
||||
|
|
|
|||
|
|
@ -87,11 +87,9 @@ watch(() => $route.path, (n) => {
|
|||
<div vaul-drawer-wrapper class="flex min-h-screen flex-col bg-background">
|
||||
<header class="sticky z-40 top-0 bg-background/80 backdrop-blur-lg border-b border-border">
|
||||
<div
|
||||
class="container flex justify-between h-14 max-w-screen-2xl items-center"
|
||||
class="container flex h-14 max-w-screen-2xl items-center"
|
||||
>
|
||||
<MobileNav />
|
||||
|
||||
<div class="mr-4 hidden md:flex">
|
||||
<div class="mr-4 md:mr-1 hidden md:flex">
|
||||
<Logo />
|
||||
|
||||
<nav
|
||||
|
|
@ -105,29 +103,31 @@ watch(() => $route.path, (n) => {
|
|||
class="transition-colors hover:text-foreground/80 text-foreground/60"
|
||||
:class="{
|
||||
'font-semibold !text-foreground': $route.path === `${route.href}.html`,
|
||||
'hidden lg:block': route?.href?.includes('github'),
|
||||
}"
|
||||
>
|
||||
{{ route.title }}
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<MobileNav />
|
||||
|
||||
<div class=" flex items-center justify-end space-x-4 ">
|
||||
<div class="flex flex-1 items-center justify-between space-x-2 md:justify-end">
|
||||
<div class="w-full flex-1 md:w-auto md:flex-none">
|
||||
<Button
|
||||
variant="outline"
|
||||
class="w-72 h-8 px-3 hidden lg:flex lg:justify-between lg:items-center"
|
||||
class="relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64"
|
||||
@click="isOpen = true"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<SearchIcon class="w-4 h-4 mr-2 text-muted-foreground" />
|
||||
<span class="text-muted-foreground"> Search documentation... </span>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-1">
|
||||
<Kbd> <span>⌘</span>K </Kbd>
|
||||
</div>
|
||||
<span className="hidden lg:inline-flex">Search documentation...</span>
|
||||
<span className="inline-flex lg:hidden">Search...</span>
|
||||
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
|
||||
<span className="text-xs">⌘</span>K
|
||||
</kbd>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-x-1">
|
||||
<nav class="flex items-center gap-x-1">
|
||||
<Button
|
||||
v-for="link in links"
|
||||
:key="link.name"
|
||||
|
|
@ -151,7 +151,7 @@ watch(() => $route.path, (n) => {
|
|||
/>
|
||||
</Button>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@
|
|||
}
|
||||
body {
|
||||
@apply bg-background text-foreground min-h-screen antialiased font-sans;
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
/* font-feature-settings: "rlig" 1, "calt" 1; */
|
||||
font-synthesis-weight: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
/* Mobile tap highlight */
|
||||
|
|
|
|||
|
|
@ -227,6 +227,13 @@ export const Index = {
|
|||
component: () => import("../src/lib/registry/default/example/CarouselSpacing.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/CarouselSpacing.vue"],
|
||||
},
|
||||
"CarouselThumbnails": {
|
||||
name: "CarouselThumbnails",
|
||||
type: "components:example",
|
||||
registryDependencies: ["carousel","card"],
|
||||
component: () => import("../src/lib/registry/default/example/CarouselThumbnails.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/CarouselThumbnails.vue"],
|
||||
},
|
||||
"CheckboxDemo": {
|
||||
name: "CheckboxDemo",
|
||||
type: "components:example",
|
||||
|
|
@ -1257,6 +1264,13 @@ export const Index = {
|
|||
component: () => import("../src/lib/registry/new-york/example/CarouselSpacing.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/CarouselSpacing.vue"],
|
||||
},
|
||||
"CarouselThumbnails": {
|
||||
name: "CarouselThumbnails",
|
||||
type: "components:example",
|
||||
registryDependencies: ["carousel","card"],
|
||||
component: () => import("../src/lib/registry/new-york/example/CarouselThumbnails.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/CarouselThumbnails.vue"],
|
||||
},
|
||||
"CheckboxDemo": {
|
||||
name: "CheckboxDemo",
|
||||
type: "components:example",
|
||||
|
|
|
|||
|
|
@ -5,17 +5,14 @@ source: apps/www/src/lib/registry/default/ui/carousel
|
|||
primitive: https://www.embla-carousel.com/api
|
||||
---
|
||||
|
||||
|
||||
<ComponentPreview name="CarouselDemo" />
|
||||
|
||||
|
||||
## About
|
||||
|
||||
The carousel component is built using the [Embla Carousel](https://www.embla-carousel.com/) library.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
```bash
|
||||
npx shadcn-vue@latest add carousel
|
||||
```
|
||||
|
|
@ -54,7 +51,6 @@ To set the size of the items, you can use the `basis` utility class on the `<Car
|
|||
|
||||
<ComponentPreview name="CarouselSize" />
|
||||
|
||||
|
||||
Example
|
||||
|
||||
```vue:line-numbers title="Example" {4-6}
|
||||
|
|
@ -68,7 +64,6 @@ Example
|
|||
</Carousel>
|
||||
```
|
||||
|
||||
|
||||
Responsive
|
||||
|
||||
```vue:line-numbers title="Responsive" {4-6}
|
||||
|
|
@ -151,6 +146,10 @@ Use the `orientation` prop to set the orientation of the carousel.
|
|||
</Carousel>
|
||||
```
|
||||
|
||||
### Thumbnails
|
||||
|
||||
<ComponentPreview name="CarouselThumbnails" />
|
||||
|
||||
## Options
|
||||
|
||||
You can pass options to the carousel using the `opts` prop. See the [Embla Carousel docs](https://www.embla-carousel.com/api/options/) for more information.
|
||||
|
|
@ -259,7 +258,6 @@ You can use the `plugins` prop to add plugins to the carousel.
|
|||
npm i embla-carousel-autoplay
|
||||
```
|
||||
|
||||
|
||||
```vue:line-numbers {2,8-10}
|
||||
<script setup lang="ts">
|
||||
import Autoplay from 'embla-carousel-autoplay'
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ const onSubmit = handleSubmit((values) => {
|
|||
</option>
|
||||
</select>
|
||||
</FormControl>
|
||||
<ChevronDownIcon class="absolute right-3 top-2.5 h-4 w-4 opacity-50" />
|
||||
<ChevronDownIcon class="pointer-events-none absolute right-3 top-2.5 h-4 w-4 opacity-50" />
|
||||
</div>
|
||||
<FormDescription>
|
||||
Set the font you want to use in the dashboard.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from '@tanstack/vue-table'
|
||||
|
||||
import { ref } from 'vue'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Task } from '../data/schema'
|
||||
import DataTablePagination from './DataTablePagination.vue'
|
||||
import DataTableToolbar from './DataTableToolbar.vue'
|
||||
import { valueUpdater } from '@/lib/utils'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { Column } from '@tanstack/vue-table'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Task } from '../data/schema'
|
||||
import ArrowDownIcon from '~icons/radix-icons/arrow-down'
|
||||
import ArrowUpIcon from '~icons/radix-icons/arrow-up'
|
||||
import CaretSortIcon from '~icons/radix-icons/caret-sort'
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ const selectedValues = computed(() => new Set(props.column?.getFilterValue() as
|
|||
>
|
||||
<CheckIcon :class="cn('h-4 w-4')" />
|
||||
</div>
|
||||
<option.icon v-if="option.icon" class="mr-2 h-4 w-4 text-muted-foreground" />
|
||||
<component :is="option.icon" v-if="option.icon" class="mr-2 h-4 w-4 text-muted-foreground" />
|
||||
<span>{{ option.label }}</span>
|
||||
<span v-if="facets?.get(option.value)" class="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs">
|
||||
{{ facets.get(option.value) }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { type Table } from '@tanstack/vue-table'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Table } from '@tanstack/vue-table'
|
||||
import type { Task } from '../data/schema'
|
||||
import ChevronLeftIcon from '~icons/radix-icons/chevron-left'
|
||||
import ChevronRightIcon from '~icons/radix-icons/chevron-right'
|
||||
import DoubleArrowLeftIcon from '~icons/radix-icons/double-arrow-left'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Row } from '@tanstack/vue-table'
|
|||
import { computed } from 'vue'
|
||||
import { labels } from '../data/data'
|
||||
import { taskSchema } from '../data/schema'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Task } from '../data/schema'
|
||||
import DotsHorizontalIcon from '~icons/radix-icons/dots-horizontal'
|
||||
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { type Table } from '@tanstack/vue-table'
|
||||
import type { Table } from '@tanstack/vue-table'
|
||||
import { computed } from 'vue'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Task } from '../data/schema'
|
||||
|
||||
import { priorities, statuses } from '../data/data'
|
||||
import DataTableFacetedFilter from './DataTableFacetedFilter.vue'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import type { Table } from '@tanstack/vue-table'
|
||||
import { computed } from 'vue'
|
||||
import { type Task } from '../data/schema'
|
||||
import type { Task } from '../data/schema'
|
||||
import MixerHorizontalIcon from '~icons/radix-icons/mixer-horizontal'
|
||||
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
|
|
|
|||
|
|
@ -11,10 +11,13 @@ import { Badge } from '@/lib/registry/new-york/ui/badge'
|
|||
export const columns: ColumnDef<Task>[] = [
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox,
|
||||
{ 'checked': table.getIsAllPageRowsSelected(), 'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value), 'ariaLabel': 'Select all', 'class': 'translate-y-0.5' }),
|
||||
cell: ({ row }) => h(Checkbox,
|
||||
{ 'checked': row.getIsSelected(), 'onUpdate:checked': value => row.toggleSelected(!!value), 'ariaLabel': 'Select row', 'class': 'translate-y-0.5' }),
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
'class': 'translate-y-0.5',
|
||||
}),
|
||||
cell: ({ row }) => h(Checkbox, { 'checked': row.getIsSelected(), 'onUpdate:checked': value => row.toggleSelected(!!value), 'ariaLabel': 'Select row', 'class': 'translate-y-0.5' }),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
|
|
@ -33,7 +36,7 @@ export const columns: ColumnDef<Task>[] = [
|
|||
const label = labels.find(label => label.value === row.original.label)
|
||||
|
||||
return h('div', { class: 'flex space-x-2' }, [
|
||||
label && h(Badge, { variant: 'outline' }, label.label),
|
||||
label ? h(Badge, { variant: 'outline' }, () => label.label) : null,
|
||||
h('span', { class: 'max-w-[500px] truncate font-medium' }, row.getValue('title')),
|
||||
])
|
||||
},
|
||||
|
|
@ -72,7 +75,7 @@ export const columns: ColumnDef<Task>[] = [
|
|||
|
||||
return h('div', { class: 'flex items-center' }, [
|
||||
priority.icon && h(priority.icon, { class: 'mr-2 h-4 w-4 text-muted-foreground' }),
|
||||
h('span', priority.label),
|
||||
h('span', {}, priority.label),
|
||||
])
|
||||
},
|
||||
filterFn: (row, id, value) => {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const columns: ColumnDef<Payment>[] = [
|
|||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { watchOnce } from '@vueuse/core'
|
||||
import { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/lib/registry/default/ui/carousel'
|
||||
import { Card, CardContent } from '@/lib/registry/default/ui/card'
|
||||
|
||||
const emblaMainApi = ref<CarouselApi>()
|
||||
const emblaThumbnailApi = ref<CarouselApi>()
|
||||
const selectedIndex = ref(0)
|
||||
|
||||
function onSelect() {
|
||||
if (!emblaMainApi.value || !emblaThumbnailApi.value)
|
||||
return
|
||||
selectedIndex.value = emblaMainApi.value.selectedScrollSnap()
|
||||
emblaThumbnailApi.value.scrollTo(emblaMainApi.value.selectedScrollSnap())
|
||||
}
|
||||
|
||||
function onThumbClick(index: number) {
|
||||
if (!emblaMainApi.value || !emblaThumbnailApi.value)
|
||||
return
|
||||
emblaMainApi.value.scrollTo(index)
|
||||
}
|
||||
|
||||
watchOnce(emblaMainApi, (emblaMainApi) => {
|
||||
if (!emblaMainApi)
|
||||
return
|
||||
|
||||
onSelect()
|
||||
emblaMainApi.on('select', onSelect)
|
||||
emblaMainApi.on('reInit', onSelect)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full sm:w-auto">
|
||||
<Carousel
|
||||
class="relative w-full max-w-xs"
|
||||
@init-api="(val) => emblaMainApi = val"
|
||||
>
|
||||
<CarouselContent>
|
||||
<CarouselItem v-for="(_, index) in 10" :key="index">
|
||||
<div class="p-1">
|
||||
<Card>
|
||||
<CardContent class="flex aspect-square items-center justify-center p-6">
|
||||
<span class="text-4xl font-semibold">{{ index + 1 }}</span>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
|
||||
<Carousel
|
||||
class="relative w-full max-w-xs"
|
||||
@init-api="(val) => emblaThumbnailApi = val"
|
||||
>
|
||||
<CarouselContent class="flex gap-1 ml-0">
|
||||
<CarouselItem v-for="(_, index) in 10" :key="index" class="pl-0 basis-1/4 cursor-pointer" @click="onThumbClick(index)">
|
||||
<div class="p-1" :class="index === selectedIndex ? '' : 'opacity-50'">
|
||||
<Card>
|
||||
<CardContent class="flex aspect-square items-center justify-center p-6">
|
||||
<span class="text-4xl font-semibold">{{ index + 1 }}</span>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -84,11 +84,11 @@ const columns = [
|
|||
columnHelper.display({
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
cell: ({ row, column }) => {
|
||||
cell: ({ row }) => {
|
||||
return h(Checkbox, {
|
||||
'checked': row.getIsSelected(),
|
||||
'onUpdate:checked': value => row.toggleSelected(!!value),
|
||||
|
|
@ -165,8 +165,6 @@ const table = useVueTable({
|
|||
},
|
||||
},
|
||||
})
|
||||
|
||||
const getState = table.getState()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const columns: ColumnDef<Payment>[] = [
|
|||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import * as z from 'zod'
|
|||
import {
|
||||
PinInput,
|
||||
PinInputInput,
|
||||
} from '@/lib/registry/new-york/ui/pin-input'
|
||||
} from '@/lib/registry/default/ui/pin-input'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import {
|
||||
FormControl,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ const formSchema = toTypedSchema(z.object({
|
|||
|
||||
const { handleSubmit } = useForm({
|
||||
validationSchema: formSchema,
|
||||
initialValues: {
|
||||
duration: [30],
|
||||
},
|
||||
})
|
||||
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
|
|
@ -36,20 +39,20 @@ const onSubmit = handleSubmit((values) => {
|
|||
|
||||
<template>
|
||||
<form class="w-2/3 space-y-6" @submit="onSubmit">
|
||||
<FormField v-slot="{ componentField }" name="duration">
|
||||
<FormField v-slot="{ componentField, value }" name="duration">
|
||||
<FormItem>
|
||||
<FormLabel>Duration</FormLabel>
|
||||
<FormControl>
|
||||
<Slider
|
||||
v-bind="componentField"
|
||||
:default-value="[30]"
|
||||
:max="60"
|
||||
:min="5"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:step="5"
|
||||
/>
|
||||
<FormDescription class="flex justify-between">
|
||||
<span>How many minutes are you available?</span>
|
||||
<span>{{ componentField.modelValue?.[0] ?? "30" }} min</span>
|
||||
<span>{{ value?.[0] }} min</span>
|
||||
</FormDescription>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const columns: ColumnDef<Payment>[] = [
|
|||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
|
|
@ -104,7 +104,7 @@ const columns: ColumnDef<Payment>[] = [
|
|||
return h(Button, {
|
||||
variant: 'ghost',
|
||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
|
||||
}, ['Email', h(CaretSortIcon, { class: 'ml-2 h-4 w-4' })])
|
||||
}, () => ['Email', h(CaretSortIcon, { class: 'ml-2 h-4 w-4' })])
|
||||
},
|
||||
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { watchOnce } from '@vueuse/core'
|
||||
import { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/lib/registry/new-york/ui/carousel'
|
||||
import { Card, CardContent } from '@/lib/registry/new-york/ui/card'
|
||||
|
||||
const emblaMainApi = ref<CarouselApi>()
|
||||
const emblaThumbnailApi = ref<CarouselApi>()
|
||||
const selectedIndex = ref(0)
|
||||
|
||||
function onSelect() {
|
||||
if (!emblaMainApi.value || !emblaThumbnailApi.value)
|
||||
return
|
||||
selectedIndex.value = emblaMainApi.value.selectedScrollSnap()
|
||||
emblaThumbnailApi.value.scrollTo(emblaMainApi.value.selectedScrollSnap())
|
||||
}
|
||||
|
||||
function onThumbClick(index: number) {
|
||||
if (!emblaMainApi.value || !emblaThumbnailApi.value)
|
||||
return
|
||||
emblaMainApi.value.scrollTo(index)
|
||||
}
|
||||
|
||||
watchOnce(emblaMainApi, (emblaMainApi) => {
|
||||
if (!emblaMainApi)
|
||||
return
|
||||
|
||||
onSelect()
|
||||
emblaMainApi.on('select', onSelect)
|
||||
emblaMainApi.on('reInit', onSelect)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full sm:w-auto">
|
||||
<Carousel
|
||||
class="relative w-full max-w-xs"
|
||||
@init-api="(val) => emblaMainApi = val"
|
||||
>
|
||||
<CarouselContent>
|
||||
<CarouselItem v-for="(_, index) in 10" :key="index">
|
||||
<div class="p-1">
|
||||
<Card>
|
||||
<CardContent class="flex aspect-square items-center justify-center p-6">
|
||||
<span class="text-4xl font-semibold">{{ index + 1 }}</span>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
|
||||
<Carousel
|
||||
class="relative w-full max-w-xs"
|
||||
@init-api="(val) => emblaThumbnailApi = val"
|
||||
>
|
||||
<CarouselContent class="flex gap-1 ml-0">
|
||||
<CarouselItem v-for="(_, index) in 10" :key="index" class="pl-0 basis-1/4 cursor-pointer" @click="onThumbClick(index)">
|
||||
<div class="p-1" :class="index === selectedIndex ? '' : 'opacity-50'">
|
||||
<Card>
|
||||
<CardContent class="flex aspect-square items-center justify-center p-6">
|
||||
<span class="text-4xl font-semibold">{{ index + 1 }}</span>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -84,11 +84,11 @@ const columns = [
|
|||
columnHelper.display({
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
cell: ({ row, column }) => {
|
||||
cell: ({ row }) => {
|
||||
return h(Checkbox, {
|
||||
'checked': row.getIsSelected(),
|
||||
'onUpdate:checked': value => row.toggleSelected(!!value),
|
||||
|
|
@ -165,8 +165,6 @@ const table = useVueTable({
|
|||
},
|
||||
},
|
||||
})
|
||||
|
||||
const getState = table.getState()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const columns: ColumnDef<Payment>[] = [
|
|||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
|
||||
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref } from 'vue'
|
||||
import { Minus, Plus } from 'lucide-vue-next'
|
||||
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
|
|
@ -12,7 +12,7 @@ import {
|
|||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@/lib/registry/default/ui/drawer'
|
||||
} from '@/lib/registry/new-york/ui/drawer'
|
||||
|
||||
const goal = ref(350)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
|
|
@ -9,7 +9,7 @@ import {
|
|||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@/lib/registry/default/ui/dialog'
|
||||
} from '@/lib/registry/new-york/ui/dialog'
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
|
|
@ -19,9 +19,9 @@ import {
|
|||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@/lib/registry/default/ui/drawer'
|
||||
import { Label } from '@/lib/registry/default/ui/label'
|
||||
import { Input } from '@/lib/registry/default/ui/input'
|
||||
} from '@/lib/registry/new-york/ui/drawer'
|
||||
import { Label } from '@/lib/registry/new-york/ui/label'
|
||||
import { Input } from '@/lib/registry/new-york/ui/input'
|
||||
|
||||
// Reuse `form` section
|
||||
const [UseTemplate, GridForm] = createReusableTemplate()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ const formSchema = toTypedSchema(z.object({
|
|||
|
||||
const { handleSubmit } = useForm({
|
||||
validationSchema: formSchema,
|
||||
initialValues: {
|
||||
duration: [30],
|
||||
},
|
||||
})
|
||||
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
|
|
@ -36,20 +39,20 @@ const onSubmit = handleSubmit((values) => {
|
|||
|
||||
<template>
|
||||
<form class="w-2/3 space-y-6" @submit="onSubmit">
|
||||
<FormField v-slot="{ componentField }" name="duration">
|
||||
<FormField v-slot="{ componentField, value }" name="duration">
|
||||
<FormItem>
|
||||
<FormLabel>Duration</FormLabel>
|
||||
<FormControl>
|
||||
<Slider
|
||||
v-bind="componentField"
|
||||
:default-value="[30]"
|
||||
:max="60"
|
||||
:min="5"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:step="5"
|
||||
/>
|
||||
<FormDescription class="flex justify-between">
|
||||
<span>How many minutes are you available?</span>
|
||||
<span>{{ componentField.modelValue?.[0] ?? "30" }} min</span>
|
||||
<span>{{ value?.[0] }} min</span>
|
||||
</FormDescription>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
|
|
|
|||
|
|
@ -103,11 +103,11 @@ const vCalendarSlots = computed(() => {
|
|||
</template>
|
||||
|
||||
<template #nav-prev-button>
|
||||
<ChevronLeft />
|
||||
<ChevronLeftIcon />
|
||||
</template>
|
||||
|
||||
<template #nav-next-button>
|
||||
<ChevronRight />
|
||||
<ChevronRightIcon />
|
||||
</template>
|
||||
</DatePicker>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -5,7 +5,7 @@ import { type Theme, themes } from './../lib/registry/themes'
|
|||
import { type Style, styles } from '@/lib/registry/styles'
|
||||
|
||||
interface Config {
|
||||
theme: Theme['name']
|
||||
theme?: Theme['name']
|
||||
radius: number
|
||||
style: Style
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ export const RADII = [0, 0.25, 0.5, 0.75, 1]
|
|||
export function useConfigStore() {
|
||||
const { isDark } = useData()
|
||||
const config = useSessionStorage<Config>('config', {
|
||||
theme: 'zinc',
|
||||
radius: 0.5,
|
||||
style: styles[0].name,
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user