feat: add number-field component (#571)

This commit is contained in:
Roman Slonov 2024-06-03 17:29:39 +08:00 committed by GitHub
parent f48d1d4f4c
commit ce6eb79a3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 2151 additions and 1421 deletions

View File

@ -256,6 +256,11 @@ export const docsConfig: DocsConfig = {
title: 'Navigation Menu',
href: '/docs/components/navigation-menu',
},
{
title: 'Number Field',
href: '/docs/components/number-field',
label: 'New Alpha',
},
{
title: 'Pagination',
href: '/docs/components/pagination',

View File

@ -759,6 +759,48 @@ export const Index = {
component: () => import("../src/lib/registry/default/example/NavigationMenuDemoItem.vue").then((m) => m.default),
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": {
name: "PaginationDemo",
type: "components:example",
@ -2167,6 +2209,48 @@ export const Index = {
component: () => import("../src/lib/registry/new-york/example/NavigationMenuDemoItem.vue").then((m) => m.default),
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": {
name: "PaginationDemo",
type: "components:example",

View File

@ -23,8 +23,8 @@
"@tanstack/vue-table": "^8.17.3",
"@unovis/ts": "^1.4.1",
"@unovis/vue": "^1.4.1",
"@vee-validate/zod": "^4.12.8",
"@vueuse/core": "^10.9.0",
"@vee-validate/zod": "^4.13.0",
"@vueuse/core": "^10.10.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"codesandbox": "^2.2.3",
@ -32,9 +32,9 @@
"embla-carousel": "^8.1.3",
"embla-carousel-autoplay": "^8.1.3",
"embla-carousel-vue": "^8.1.3",
"lucide-vue-next": "^0.378.0",
"lucide-vue-next": "^0.383.0",
"magic-string": "^0.30.10",
"radix-vue": "^1.8.2",
"radix-vue": "^1.8.3",
"tailwindcss-animate": "^1.0.7",
"v-calendar": "^3.1.2",
"vaul-vue": "^0.1.2",
@ -45,21 +45,21 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@babel/traverse": "^7.24.5",
"@iconify-json/gravity-ui": "^1.1.2",
"@iconify-json/lucide": "^1.1.187",
"@babel/traverse": "^7.24.6",
"@iconify-json/gravity-ui": "^1.1.3",
"@iconify-json/lucide": "^1.1.189",
"@iconify-json/ph": "^1.1.13",
"@iconify-json/radix-icons": "^1.1.14",
"@iconify-json/ri": "^1.1.20",
"@iconify-json/simple-icons": "^1.1.102",
"@iconify-json/tabler": "^1.1.112",
"@iconify-json/simple-icons": "^1.1.104",
"@iconify-json/tabler": "^1.1.113",
"@iconify/vue": "^4.1.2",
"@oxc-parser/wasm": "^0.1.0",
"@shikijs/transformers": "^1.6.0",
"@shikijs/transformers": "^1.6.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.12.12",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@types/node": "^20.14.0",
"@vitejs/plugin-vue": "^5.0.5",
"@vitejs/plugin-vue-jsx": "^4.0.0",
"@vue/compiler-core": "^3.4.27",
"@vue/compiler-dom": "^3.4.27",
"@vue/tsconfig": "^0.5.1",
@ -69,10 +69,10 @@
"markdown-it": "^14.1.0",
"pathe": "^1.1.2",
"rimraf": "^5.0.7",
"shiki": "^1.6.0",
"shiki": "^1.6.2",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.3",
"tsx": "^4.10.5",
"tsx": "^4.11.2",
"typescript": "^5.4.5",
"unplugin-icons": "^0.19.0",
"vitepress": "^1.2.2",

View 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" />

View File

@ -1,5 +1,5 @@
<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 = [
{ name: 'Jan', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue'
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<NumberFieldRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
<slot />
</NumberFieldRoot>
</template>

View File

@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn('relative', props.class)">
<slot />
</div>
</template>

View File

@ -0,0 +1,25 @@
<script setup lang="ts">
import type { NumberFieldDecrementProps } from 'radix-vue'
import { NumberFieldDecrement, useForwardProps } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { Minus } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardProps(delegatedProps)
</script>
<template>
<NumberFieldDecrement v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)">
<slot>
<Minus class="h-4 w-4" />
</slot>
</NumberFieldDecrement>
</template>

View File

@ -0,0 +1,25 @@
<script setup lang="ts">
import type { NumberFieldIncrementProps } from 'radix-vue'
import { NumberFieldIncrement, useForwardProps } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { Plus } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardProps(delegatedProps)
</script>
<template>
<NumberFieldIncrement v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)">
<slot>
<Plus class="h-4 w-4" />
</slot>
</NumberFieldIncrement>
</template>

View File

@ -0,0 +1,8 @@
<script setup lang="ts">
import { NumberFieldInput } from 'radix-vue'
import { cn } from '@/lib/utils'
</script>
<template>
<NumberFieldInput :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-10 py-2 text-sm text-center ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50')" />
</template>

View File

@ -0,0 +1,5 @@
export { default as NumberField } from './NumberField.vue'
export { default as NumberFieldInput } from './NumberFieldInput.vue'
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'
export { default as NumberFieldContent } from './NumberFieldContent.vue'

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { Card, CardContent } from '@/lib/registry/default/ui/card'
import { Card, CardContent } from '@/lib/registry/new-york/ui/card'
defineProps<{
title?: string

View File

@ -2,10 +2,10 @@
import { type Ref, ref, watch } from 'vue'
import {
Calendar as CalendarIcon,
ChevronLeft,
ChevronRight,
} from 'lucide-vue-next'
CalendarIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from '@radix-icons/vue'
import {
CalendarDate,
type DateValue,
@ -153,7 +153,7 @@ watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
"
@click="updateMonth('first', -1)"
>
<ChevronLeft class="h-4 w-4" />
<ChevronLeftIcon class="h-4 w-4" />
</button>
<div :class="cn('text-sm font-medium')">
{{
@ -171,7 +171,7 @@ watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
"
@click="updateMonth('first', 1)"
>
<ChevronRight class="h-4 w-4" />
<ChevronRightIcon class="h-4 w-4" />
</button>
</div>
<RangeCalendarGrid>
@ -219,7 +219,7 @@ watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
"
@click="updateMonth('second', -1)"
>
<ChevronLeft class="h-4 w-4" />
<ChevronLeftIcon class="h-4 w-4" />
</button>
<div :class="cn('text-sm font-medium')">
{{
@ -238,7 +238,7 @@ watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
"
@click="updateMonth('second', 1)"
>
<ChevronRight class="h-4 w-4" />
<ChevronRightIcon class="h-4 w-4" />
</button>
</div>
<RangeCalendarGrid>

View File

@ -0,0 +1,30 @@
<script setup lang="ts">
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { Label } from '@/lib/registry/new-york/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>

View File

@ -0,0 +1,28 @@
<script setup lang="ts">
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { Label } from '@/lib/registry/new-york/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>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { Label } from '@/lib/registry/new-york/ui/label'
</script>
<template>
<NumberField id="age" :default-value="18" :min="0">
<Label for="age">Age</Label>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { Label } from '@/lib/registry/new-york/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>

View File

@ -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/new-york/ui/button'
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/lib/registry/new-york/ui/form'
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { toast } from '@/lib/registry/new-york/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>

View File

@ -0,0 +1,28 @@
<script setup lang="ts">
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from '@/lib/registry/new-york/ui/number-field'
import { Label } from '@/lib/registry/new-york/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>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { type HTMLAttributes, computed } from 'vue'
import { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'radix-vue'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
import { cn } from '@/lib/utils'
const props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import { type HTMLAttributes, computed } from 'vue'
import { CalendarNext, type CalendarNextProps, useForwardProps } from 'radix-vue'
import { ChevronRightIcon } from '@radix-icons/vue'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
const props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import { type HTMLAttributes, computed } from 'vue'
import { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'radix-vue'
import { ChevronLeftIcon } from '@radix-icons/vue'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
const props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue'
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<NumberFieldRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
<slot />
</NumberFieldRoot>
</template>

View File

@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn('relative', props.class)">
<slot />
</div>
</template>

View File

@ -0,0 +1,25 @@
<script setup lang="ts">
import type { NumberFieldDecrementProps } from 'radix-vue'
import { NumberFieldDecrement, useForwardProps } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { Minus } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardProps(delegatedProps)
</script>
<template>
<NumberFieldDecrement v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)">
<slot>
<Minus class="h-4 w-4" />
</slot>
</NumberFieldDecrement>
</template>

View File

@ -0,0 +1,25 @@
<script setup lang="ts">
import type { NumberFieldIncrementProps } from 'radix-vue'
import { NumberFieldIncrement, useForwardProps } from 'radix-vue'
import { type HTMLAttributes, computed } from 'vue'
import { Plus } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
const props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardProps(delegatedProps)
</script>
<template>
<NumberFieldIncrement v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)">
<slot>
<Plus class="h-4 w-4" />
</slot>
</NumberFieldIncrement>
</template>

View File

@ -0,0 +1,8 @@
<script setup lang="ts">
import { NumberFieldInput } from 'radix-vue'
import { cn } from '@/lib/utils'
</script>
<template>
<NumberFieldInput :class="cn('flex h-9 w-full rounded-md border border-input bg-transparent px-10 py-1 text-sm text-center shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50')" />
</template>

View File

@ -0,0 +1,5 @@
export { default as NumberField } from './NumberField.vue'
export { default as NumberFieldInput } from './NumberFieldInput.vue'
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'
export { default as NumberFieldContent } from './NumberFieldContent.vue'

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { type HTMLAttributes, computed } from 'vue'
import { RangeCalendarCellTrigger, type RangeCalendarCellTriggerProps, useForwardProps } from 'radix-vue'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
import { cn } from '@/lib/utils'
const props = defineProps<RangeCalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import { type HTMLAttributes, computed } from 'vue'
import { RangeCalendarNext, type RangeCalendarNextProps, useForwardProps } from 'radix-vue'
import { ChevronRightIcon } from '@radix-icons/vue'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
const props = defineProps<RangeCalendarNextProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import { type HTMLAttributes, computed } from 'vue'
import { RangeCalendarPrev, type RangeCalendarPrevProps, useForwardProps } from 'radix-vue'
import { ChevronLeftIcon } from '@radix-icons/vue'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
const props = defineProps<RangeCalendarPrevProps & { class?: HTMLAttributes['class'] }>()

View File

@ -554,6 +554,22 @@
],
"type": "components:ui"
},
{
"name": "number-field",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/number-field/NumberField.vue",
"ui/number-field/NumberFieldContent.vue",
"ui/number-field/NumberFieldDecrement.vue",
"ui/number-field/NumberFieldIncrement.vue",
"ui/number-field/NumberFieldInput.vue",
"ui/number-field/index.ts"
],
"type": "components:ui"
},
{
"name": "pagination",
"dependencies": [],

View File

@ -0,0 +1,34 @@
{
"name": "number-field",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "NumberField.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue'\nimport { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<NumberFieldRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NumberFieldRoot v-bind=\"forwarded\" :class=\"cn('grid gap-1.5', props.class)\">\n <slot />\n </NumberFieldRoot>\n</template>\n"
},
{
"name": "NumberFieldContent.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('relative', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "NumberFieldDecrement.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldDecrementProps } from 'radix-vue'\nimport { NumberFieldDecrement, useForwardProps } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { Minus } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldDecrement v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)\">\n <slot>\n <Minus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldDecrement>\n</template>\n"
},
{
"name": "NumberFieldIncrement.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldIncrementProps } from 'radix-vue'\nimport { NumberFieldIncrement, useForwardProps } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { Plus } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldIncrement v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)\">\n <slot>\n <Plus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldIncrement>\n</template>\n"
},
{
"name": "NumberFieldInput.vue",
"content": "<script setup lang=\"ts\">\nimport { NumberFieldInput } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <NumberFieldInput :class=\"cn('flex h-10 w-full rounded-md border border-input bg-background px-10 py-2 text-sm text-center ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50')\" />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as NumberField } from './NumberField.vue'\nexport { default as NumberFieldInput } from './NumberFieldInput.vue'\nexport { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'\nexport { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'\nexport { default as NumberFieldContent } from './NumberFieldContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -16,7 +16,7 @@
},
{
"name": "CalendarCellTrigger.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'radix-vue'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-8 w-8 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'radix-vue'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-8 w-8 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n"
},
{
"name": "CalendarGrid.vue",
@ -48,11 +48,11 @@
},
{
"name": "CalendarNextButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'radix-vue'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'radix-vue'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n"
},
{
"name": "CalendarPrevButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'radix-vue'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'radix-vue'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n"
},
{
"name": "index.ts",

View File

@ -0,0 +1,34 @@
{
"name": "number-field",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "NumberField.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue'\nimport { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<NumberFieldRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NumberFieldRoot v-bind=\"forwarded\" :class=\"cn('grid gap-1.5', props.class)\">\n <slot />\n </NumberFieldRoot>\n</template>\n"
},
{
"name": "NumberFieldContent.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('relative', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "NumberFieldDecrement.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldDecrementProps } from 'radix-vue'\nimport { NumberFieldDecrement, useForwardProps } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { Minus } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldDecrement v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)\">\n <slot>\n <Minus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldDecrement>\n</template>\n"
},
{
"name": "NumberFieldIncrement.vue",
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldIncrementProps } from 'radix-vue'\nimport { NumberFieldIncrement, useForwardProps } from 'radix-vue'\nimport { type HTMLAttributes, computed } from 'vue'\nimport { Plus } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldIncrement v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)\">\n <slot>\n <Plus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldIncrement>\n</template>\n"
},
{
"name": "NumberFieldInput.vue",
"content": "<script setup lang=\"ts\">\nimport { NumberFieldInput } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <NumberFieldInput :class=\"cn('flex h-9 w-full rounded-md border border-input bg-transparent px-10 py-1 text-sm text-center shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50')\" />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as NumberField } from './NumberField.vue'\nexport { default as NumberFieldInput } from './NumberFieldInput.vue'\nexport { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'\nexport { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'\nexport { default as NumberFieldContent } from './NumberFieldContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -16,7 +16,7 @@
},
{
"name": "RangeCalendarCellTrigger.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarCellTrigger, type RangeCalendarCellTriggerProps, useForwardProps } from 'radix-vue'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<RangeCalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal data-[selected]:opacity-100',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selection Start\n 'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground data-[selection-start]:hover:bg-primary data-[selection-start]:hover:text-primary-foreground data-[selection-start]:focus:bg-primary data-[selection-start]:focus:text-primary-foreground',\n // Selection End\n 'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground data-[selection-end]:hover:bg-primary data-[selection-end]:hover:text-primary-foreground data-[selection-end]:focus:bg-primary data-[selection-end]:focus:text-primary-foreground',\n // Outside months\n 'data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCellTrigger>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarCellTrigger, type RangeCalendarCellTriggerProps, useForwardProps } from 'radix-vue'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<RangeCalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal data-[selected]:opacity-100',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selection Start\n 'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground data-[selection-start]:hover:bg-primary data-[selection-start]:hover:text-primary-foreground data-[selection-start]:focus:bg-primary data-[selection-start]:focus:text-primary-foreground',\n // Selection End\n 'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground data-[selection-end]:hover:bg-primary data-[selection-end]:hover:text-primary-foreground data-[selection-end]:focus:bg-primary data-[selection-end]:focus:text-primary-foreground',\n // Outside months\n 'data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCellTrigger>\n</template>\n"
},
{
"name": "RangeCalendarGrid.vue",
@ -48,11 +48,11 @@
},
{
"name": "RangeCalendarNextButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarNext, type RangeCalendarNextProps, useForwardProps } from 'radix-vue'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<RangeCalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarNext>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarNext, type RangeCalendarNextProps, useForwardProps } from 'radix-vue'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\n\nconst props = defineProps<RangeCalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarNext>\n</template>\n"
},
{
"name": "RangeCalendarPrevButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarPrev, type RangeCalendarPrevProps, useForwardProps } from 'radix-vue'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<RangeCalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarPrev>\n</template>\n"
"content": "<script lang=\"ts\" setup>\nimport { type HTMLAttributes, computed } from 'vue'\nimport { RangeCalendarPrev, type RangeCalendarPrevProps, useForwardProps } from 'radix-vue'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/new-york/ui/button'\n\nconst props = defineProps<RangeCalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarPrev>\n</template>\n"
},
{
"name": "index.ts",

View File

@ -34,7 +34,7 @@
"@vitest/ui": "^1.6.0",
"bumpp": "^9.4.1",
"eslint": "^9.3.0",
"lint-staged": "^15.2.2",
"lint-staged": "^15.2.5",
"simple-git-hooks": "^2.11.1",
"taze": "^0.13.8",
"typescript": "^5.4.5",

File diff suppressed because it is too large Load Diff