feat: pin input

This commit is contained in:
Sadegh Barati 2024-01-16 20:52:40 +03:30
parent 5409b33992
commit a387bc501e
10 changed files with 163 additions and 0 deletions

View File

@ -478,6 +478,13 @@ export const Index = {
component: () => import('../src/lib/registry/default/example/PaginationDemo.vue').then(m => m.default), component: () => import('../src/lib/registry/default/example/PaginationDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/PaginationDemo.vue'], files: ['../src/lib/registry/default/example/PaginationDemo.vue'],
}, },
PinInputDemo: {
name: 'PinInputDemo',
type: 'components:example',
registryDependencies: ['pin-input'],
component: () => import('../src/lib/registry/default/example/PinInputDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/PinInputDemo.vue'],
},
PopoverDemo: { PopoverDemo: {
name: 'PopoverDemo', name: 'PopoverDemo',
type: 'components:example', type: 'components:example',
@ -1362,6 +1369,13 @@ export const Index = {
component: () => import('../src/lib/registry/new-york/example/PaginationDemo.vue').then(m => m.default), component: () => import('../src/lib/registry/new-york/example/PaginationDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/PaginationDemo.vue'], files: ['../src/lib/registry/new-york/example/PaginationDemo.vue'],
}, },
PinInputDemo: {
name: 'PinInputDemo',
type: 'components:example',
registryDependencies: ['pin-input'],
component: () => import('../src/lib/registry/new-york/example/PinInputDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/PinInputDemo.vue'],
},
PopoverDemo: { PopoverDemo: {
name: 'PopoverDemo', name: 'PopoverDemo',
type: 'components:example', type: 'components:example',

View File

@ -0,0 +1,9 @@
---
title: PIN Input
description: Allows users to input a sequence of one-character alphanumeric inputs.
source: apps/www/src/lib/registry/default/ui/pin-input
primitive: https://www.radix-vue.com/components/pin-input.html
---
<ComponentPreview name="PinInputDemo" />

View File

@ -0,0 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputInput,
} from '@/lib/registry/default/ui/pin-input'
const value = ref<string[]>([])
const handleComplete = (e: string[]) => alert(e.join(''))
</script>
<template>
<div>
<PinInput
id="pin-input"
v-model="value"
placeholder="○"
class="flex gap-2 items-center mt-1"
@complete="handleComplete"
>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInput>
</div>
{{ value }}
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { PinInputRoot, type PinInputRootEmits, type PinInputRootProps, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<PinInputRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<PinInputRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps.value, emits)
</script>
<template>
<PinInputRoot v-bind="forwarded" :class="cn('flex gap-2 items-center', props.class)">
<slot />
</PinInputRoot>
</template>

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { PinInputInput, type PinInputInputProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<PinInputInputProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps.value)
</script>
<template>
<PinInputInput v-bind="forwardedProps" :class="cn('flex w-10 h-10 text-center rounded-md border border-input bg-background text-sm 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', props.class)" />
</template>

View File

@ -0,0 +1,2 @@
export { default as PinInput } from './PinInput.vue'
export { default as PinInputInput } from './PinInputInput.vue'

View File

@ -0,0 +1,28 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputInput,
} from '@/lib/registry/new-york/ui/pin-input'
const value = ref<string[]>([])
function handleComplete() {
console.log('212121')
}
</script>
<template>
<PinInput
id="pin-input"
v-model="value"
placeholder="○"
class="flex gap-2 items-center mt-1"
@complete="handleComplete"
>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInput>
</template>

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { PinInputRoot, type PinInputRootEmits, type PinInputRootProps, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<PinInputRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<PinInputRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps.value, emits)
</script>
<template>
<PinInputRoot v-bind="forwarded" :class="cn('flex gap-2 items-center', props.class)">
<slot />
</PinInputRoot>
</template>

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { PinInputInput, type PinInputInputProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<PinInputInputProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps.value)
</script>
<template>
<PinInputInput v-bind="forwardedProps" :class="cn('flex w-10 h-10 text-center rounded-md border border-input bg-background text-sm 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', props.class)" />
</template>

View File

@ -0,0 +1,2 @@
export { default as PinInput } from './PinInput.vue'
export { default as PinInputInput } from './PinInputInput.vue'