git init
This commit is contained in:
28
resources/js/components/ui/input-otp/InputOTP.vue
Normal file
28
resources/js/components/ui/input-otp/InputOTP.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import type { OTPInputEmits, OTPInputProps } from "vue-input-otp"
|
||||
import { reactiveOmit } from "@vueuse/core"
|
||||
import { useForwardPropsEmits } from "reka-ui"
|
||||
import { OTPInput } from "vue-input-otp"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const props = defineProps<OTPInputProps & { class?: HTMLAttributes["class"] }>()
|
||||
|
||||
const emits = defineEmits<OTPInputEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, "class")
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<OTPInput
|
||||
v-slot="slotProps"
|
||||
v-bind="forwarded"
|
||||
:container-class="cn('flex items-center gap-2 has-disabled:opacity-50', props.class)"
|
||||
data-slot="input-otp"
|
||||
class="disabled:cursor-not-allowed"
|
||||
>
|
||||
<slot v-bind="slotProps" />
|
||||
</OTPInput>
|
||||
</template>
|
||||
22
resources/js/components/ui/input-otp/InputOTPGroup.vue
Normal file
22
resources/js/components/ui/input-otp/InputOTPGroup.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import { reactiveOmit } from "@vueuse/core"
|
||||
import { useForwardProps } from "reka-ui"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, "class")
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
data-slot="input-otp-group"
|
||||
v-bind="forwarded"
|
||||
:class="cn('flex items-center', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
21
resources/js/components/ui/input-otp/InputOTPSeparator.vue
Normal file
21
resources/js/components/ui/input-otp/InputOTPSeparator.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import { MinusIcon } from "lucide-vue-next"
|
||||
import { useForwardProps } from "reka-ui"
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
|
||||
|
||||
const forwarded = useForwardProps(props)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
data-slot="input-otp-separator"
|
||||
role="separator"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot>
|
||||
<MinusIcon />
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
32
resources/js/components/ui/input-otp/InputOTPSlot.vue
Normal file
32
resources/js/components/ui/input-otp/InputOTPSlot.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import { reactiveOmit } from "@vueuse/core"
|
||||
import { useForwardProps } from "reka-ui"
|
||||
import { computed } from "vue"
|
||||
import { useVueOTPContext } from "vue-input-otp"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const props = defineProps<{ index: number, class?: HTMLAttributes["class"] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, "class")
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
|
||||
const context = useVueOTPContext()
|
||||
|
||||
const slot = computed(() => context?.value.slots[props.index])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-bind="forwarded"
|
||||
data-slot="input-otp-slot"
|
||||
:data-active="slot?.isActive"
|
||||
:class="cn('data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]', props.class)"
|
||||
>
|
||||
{{ slot?.char }}
|
||||
<div v-if="slot?.hasFakeCaret" class="pointer-events-none absolute inset-0 flex items-center justify-center">
|
||||
<div class="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
4
resources/js/components/ui/input-otp/index.ts
Normal file
4
resources/js/components/ui/input-otp/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as InputOTP } from "./InputOTP.vue"
|
||||
export { default as InputOTPGroup } from "./InputOTPGroup.vue"
|
||||
export { default as InputOTPSeparator } from "./InputOTPSeparator.vue"
|
||||
export { default as InputOTPSlot } from "./InputOTPSlot.vue"
|
||||
Reference in New Issue
Block a user