@@ -7,7 +7,9 @@ import type { ComponentConfig } from '../types/utils'
77
88type PinInput = ComponentConfig <typeof theme , AppConfig , ' pinInput' >
99
10- export interface PinInputProps extends Pick <PinInputRootProps , ' defaultValue' | ' disabled' | ' id' | ' mask' | ' modelValue' | ' name' | ' otp' | ' placeholder' | ' required' | ' type' > {
10+ type PinInputType = ' text' | ' number'
11+
12+ export interface PinInputProps <T extends PinInputType = ' text' > extends Pick <PinInputRootProps <T >, ' defaultValue' | ' disabled' | ' id' | ' mask' | ' modelValue' | ' name' | ' otp' | ' placeholder' | ' required' | ' type' > {
1113 /**
1214 * The element or component this component should render as.
1315 * @defaultValue 'div'
@@ -37,14 +39,14 @@ export interface PinInputProps extends Pick<PinInputRootProps, 'defaultValue' |
3739 ui? : PinInput [' slots' ]
3840}
3941
40- export type PinInputEmits = PinInputRootEmits & {
42+ export type PinInputEmits < T extends PinInputType = ' text ' > = PinInputRootEmits < T > & {
4143 change: [payload : Event ]
4244 blur: [payload : Event ]
4345}
4446
4547 </script >
4648
47- <script setup lang="ts">
49+ <script setup lang="ts" generic = " T extends PinInputType = ' text ' " >
4850import type { ComponentPublicInstance } from ' vue'
4951import { ref , computed , onMounted } from ' vue'
5052import { PinInputInput , PinInputRoot , useForwardPropsEmits } from ' reka-ui'
@@ -54,16 +56,16 @@ import { useFormField } from '../composables/useFormField'
5456import { looseToNumber } from ' ../utils'
5557import { tv } from ' ../utils/tv'
5658
57- const props = withDefaults (defineProps <PinInputProps >(), {
58- type: ' text' ,
59+ const props = withDefaults (defineProps <PinInputProps < T > >(), {
60+ type: ' text' as never ,
5961 length: 5 ,
6062 autofocusDelay: 0
6163})
62- const emits = defineEmits <PinInputEmits >()
64+ const emits = defineEmits <PinInputEmits < T > >()
6365
6466const appConfig = useAppConfig () as PinInput [' AppConfig' ]
6567
66- const rootProps = useForwardPropsEmits (reactivePick (props , ' defaultValue' , ' disabled' , ' id' , ' mask' , ' modelValue' , ' name' , ' otp' , ' placeholder ' , ' required' , ' type' ), emits )
68+ const rootProps = useForwardPropsEmits (reactivePick (props , ' defaultValue' , ' disabled' , ' id' , ' mask' , ' modelValue' , ' name' , ' otp' , ' required' , ' type' ), emits )
6769
6870const { emitFormInput, emitFormFocus, emitFormChange, emitFormBlur, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField <PinInputProps >(props )
6971
@@ -77,7 +79,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.pinInput ||
7779const inputsRef = ref <ComponentPublicInstance []>([])
7880
7981const completed = ref (false )
80- function onComplete(value : string []) {
82+ function onComplete(value : string [] | number [] ) {
8183 // @ts-expect-error - 'target' does not exist in type 'EventInit'
8284 const event = new Event (' change' , { target: { value } })
8385 emits (' change' , event )
@@ -113,6 +115,7 @@ defineExpose({
113115 v-bind =" { ...rootProps, ...ariaAttrs }"
114116 :id =" id"
115117 :name =" name"
118+ :placeholder =" placeholder"
116119 :class =" ui.root({ class: [props.ui?.root, props.class] })"
117120 @update:model-value =" emitFormInput()"
118121 @complete =" onComplete"
0 commit comments