Skip to content

Commit

Permalink
feat: PinInput with input-otp demos and styles (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
sadeghbarati committed Mar 10, 2024
1 parent 7af3b61 commit 454ecf0
Show file tree
Hide file tree
Showing 24 changed files with 392 additions and 46 deletions.
42 changes: 42 additions & 0 deletions apps/www/__registry__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,20 +549,41 @@ export const Index = {
component: () => import("../src/lib/registry/default/example/PaginationDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PaginationDemo.vue"],
},
"PinInputControlled": {
name: "PinInputControlled",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/default/example/PinInputControlled.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PinInputControlled.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"],
},
"PinInputDisabled": {
name: "PinInputDisabled",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/default/example/PinInputDisabled.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PinInputDisabled.vue"],
},
"PinInputFormDemo": {
name: "PinInputFormDemo",
type: "components:example",
registryDependencies: ["pin-input","button","form","toast"],
component: () => import("../src/lib/registry/default/example/PinInputFormDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PinInputFormDemo.vue"],
},
"PinInputSeparatorDemo": {
name: "PinInputSeparatorDemo",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/default/example/PinInputSeparatorDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PinInputSeparatorDemo.vue"],
},
"PopoverDemo": {
name: "PopoverDemo",
type: "components:example",
Expand Down Expand Up @@ -1586,20 +1607,41 @@ export const Index = {
component: () => import("../src/lib/registry/new-york/example/PaginationDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/PaginationDemo.vue"],
},
"PinInputControlled": {
name: "PinInputControlled",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/new-york/example/PinInputControlled.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/PinInputControlled.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"],
},
"PinInputDisabled": {
name: "PinInputDisabled",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/new-york/example/PinInputDisabled.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/PinInputDisabled.vue"],
},
"PinInputFormDemo": {
name: "PinInputFormDemo",
type: "components:example",
registryDependencies: ["pin-input","button","form","toast"],
component: () => import("../src/lib/registry/new-york/example/PinInputFormDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/PinInputFormDemo.vue"],
},
"PinInputSeparatorDemo": {
name: "PinInputSeparatorDemo",
type: "components:example",
registryDependencies: ["pin-input"],
component: () => import("../src/lib/registry/new-york/example/PinInputSeparatorDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/PinInputSeparatorDemo.vue"],
},
"PopoverDemo": {
name: "PopoverDemo",
type: "components:example",
Expand Down
17 changes: 14 additions & 3 deletions apps/www/src/content/docs/components/pin-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ source: apps/www/src/lib/registry/default/ui/pin-input
primitive: https://www.radix-vue.com/components/pin-input.html
---

<ComponentPreview name="PinInputDemo" />

<ComponentPreview name="PinInputDemo" />

## Installation

Expand All @@ -16,6 +15,18 @@ npx shadcn-vue@latest add pin-input

## Usage

### Controlled

<ComponentPreview name="PinInputControlled" />

### Disabled

<ComponentPreview name="PinInputDisabled" />

### Separator

<ComponentPreview name="PinInputSeparatorDemo" />

### Form

<ComponentPreview name="PinInputFormDemo" />
<ComponentPreview name="PinInputFormDemo" />
30 changes: 30 additions & 0 deletions apps/www/src/lib/registry/default/example/PinInputControlled.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@/lib/registry/default/ui/pin-input'
const value = ref<string[]>(['1', '2', '3'])
const handleComplete = (e: string[]) => alert(e.join(''))
</script>

<template>
<div>
<PinInput
id="pin-input"
v-model="value"
placeholder=""
@complete="handleComplete"
>
<PinInputGroup>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInputGroup>
</PinInput>
</div>
</template>
14 changes: 8 additions & 6 deletions apps/www/src/lib/registry/default/example/PinInputDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { ref } from 'vue'
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@/lib/registry/default/ui/pin-input'
Expand All @@ -15,14 +16,15 @@ const handleComplete = (e: string[]) => alert(e.join(''))
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"
/>
<PinInputGroup>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInputGroup>
</PinInput>
</div>
</template>
29 changes: 29 additions & 0 deletions apps/www/src/lib/registry/default/example/PinInputDisabled.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@/lib/registry/default/ui/pin-input'
const value = ref<string[]>([])
</script>

<template>
<div>
<PinInput
id="pin-input"
v-model="value"
placeholder=""
disabled
>
<PinInputGroup>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInputGroup>
</PinInput>
</div>
</template>
15 changes: 9 additions & 6 deletions apps/www/src/lib/registry/default/example/PinInputFormDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@/lib/registry/default/ui/pin-input'
import { Button } from '@/lib/registry/default/ui/button'
Expand All @@ -25,7 +26,7 @@ const formSchema = toTypedSchema(z.object({
const { handleSubmit, setValues } = useForm({
validationSchema: formSchema,
initialValues: {
pin: [],
pin: ['1', '2', '3'],
},
})
Expand Down Expand Up @@ -59,11 +60,13 @@ const handleComplete = (e: string[]) => console.log(e.join(''))
})
}"
>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
<PinInputGroup>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInputGroup>
</PinInput>
</FormControl>
<FormDescription>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputGroup,
PinInputInput,
PinInputSeparator,
} 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=""
@complete="handleComplete"
>
<PinInputGroup class="gap-1">
<template v-for="(id, index) in 5" :key="id">
<PinInputInput
class="rounded-md border"
:index="index"
/>
<template v-if="index !== 4">
<PinInputSeparator />
</template>
</template>
</PinInputGroup>
</PinInput>
</div>
</template>
18 changes: 18 additions & 0 deletions apps/www/src/lib/registry/default/ui/pin-input/PinInputGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { Primitive, type PrimitiveProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<Primitive v-bind="forwardedProps" :class="cn('flex items-center', props.class)">
<slot />
</primitive>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ const forwardedProps = useForwardProps(delegatedProps)
</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)" />
<PinInputInput v-bind="forwardedProps" :class="cn('relative text-center focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md', props.class)" />
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { Primitive, type PrimitiveProps, useForwardProps } from 'radix-vue'
import { Dot } from 'lucide-vue-next'
const props = defineProps<PrimitiveProps>()
const forwardedProps = useForwardProps(props)
</script>

<template>
<Primitive v-bind="forwardedProps">
<slot>
<Dot />
</slot>
</primitive>
</template>
2 changes: 2 additions & 0 deletions apps/www/src/lib/registry/default/ui/pin-input/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { default as PinInput } from './PinInput.vue'
export { default as PinInputGroup } from './PinInputGroup.vue'
export { default as PinInputSeparator } from './PinInputSeparator.vue'
export { default as PinInputInput } from './PinInputInput.vue'
30 changes: 30 additions & 0 deletions apps/www/src/lib/registry/new-york/example/PinInputControlled.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@/lib/registry/new-york/ui/pin-input'
const value = ref<string[]>(['1', '2', '3'])
const handleComplete = (e: string[]) => alert(e.join(''))
</script>

<template>
<div>
<PinInput
id="pin-input"
v-model="value"
placeholder=""
@complete="handleComplete"
>
<PinInputGroup>
<PinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</PinInputGroup>
</PinInput>
</div>
</template>
Loading

0 comments on commit 454ecf0

Please sign in to comment.