Skip to content

Commit 5c347af

Browse files
authored
fix(Input/InputNumber/Textarea): make modelModifiers generic (#5361)
1 parent eb491e1 commit 5c347af

File tree

4 files changed

+19
-17
lines changed

4 files changed

+19
-17
lines changed

src/runtime/components/Input.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export interface InputProps<T extends InputValue = InputValue> extends UseCompon
4343
highlight?: boolean
4444
modelValue?: T
4545
defaultValue?: T
46-
modelModifiers?: ModelModifiers
46+
modelModifiers?: ModelModifiers<T>
4747
class?: any
4848
ui?: Input['slots']
4949
}

src/runtime/components/InputNumber.vue

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import type { ComponentConfig } from '../types/tv'
88
99
type InputNumber = ComponentConfig<typeof theme, AppConfig, 'inputNumber'>
1010
11-
export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue' | 'defaultValue' | 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly'> {
11+
type InputNumberValue = number | null
12+
13+
export interface InputNumberProps<T extends InputNumberValue = InputNumberValue> extends Pick<NumberFieldRootProps, 'modelValue' | 'defaultValue' | 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly'> {
1214
/**
1315
* The element or component this component should render as.
1416
* @defaultValue 'div'
@@ -54,7 +56,7 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
5456
decrementDisabled?: boolean
5557
autofocus?: boolean
5658
autofocusDelay?: number
57-
modelModifiers?: Pick<ModelModifiers, 'optional'>
59+
modelModifiers?: Pick<ModelModifiers<T>, 'optional'>
5860
/**
5961
* The locale to use for formatting and parsing numbers.
6062
* @defaultValue UApp.locale.code
@@ -64,8 +66,8 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
6466
ui?: InputNumber['slots']
6567
}
6668
67-
export interface InputNumberEmits {
68-
'update:modelValue': [value: number]
69+
export interface InputNumberEmits<T extends InputNumberValue = InputNumberValue> {
70+
'update:modelValue': [value: T]
6971
'blur': [event: FocusEvent]
7072
'change': [event: Event]
7173
}
@@ -76,7 +78,7 @@ export interface InputNumberSlots {
7678
}
7779
</script>
7880

79-
<script setup lang="ts">
81+
<script setup lang="ts" generic="T extends InputNumberValue = InputNumberValue">
8082
import { onMounted, ref, computed } from 'vue'
8183
import { NumberFieldRoot, NumberFieldInput, NumberFieldDecrement, NumberFieldIncrement, useForwardPropsEmits } from 'reka-ui'
8284
import { reactivePick, useVModel } from '@vueuse/core'
@@ -89,23 +91,23 @@ import UButton from './Button.vue'
8991
9092
defineOptions({ inheritAttrs: false })
9193
92-
const props = withDefaults(defineProps<InputNumberProps>(), {
94+
const props = withDefaults(defineProps<InputNumberProps<T>>(), {
9395
orientation: 'horizontal',
9496
increment: true,
9597
decrement: true
9698
})
97-
const emits = defineEmits<InputNumberEmits>()
99+
const emits = defineEmits<InputNumberEmits<T>>()
98100
defineSlots<InputNumberSlots>()
99101
100-
const modelValue = useVModel<InputNumberProps, 'modelValue', 'update:modelValue'>(props, 'modelValue', emits, { defaultValue: props.defaultValue })
102+
const modelValue = useVModel<InputNumberProps<T>, 'modelValue', 'update:modelValue'>(props, 'modelValue', emits, { defaultValue: props.defaultValue })
101103
102104
const { t, code: codeLocale } = useLocale()
103105
const appConfig = useAppConfig() as InputNumber['AppConfig']
104106
105107
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultValue', 'min', 'max', 'step', 'stepSnapping', 'formatOptions', 'disableWheelChange', 'invertWheelChange', 'readonly'), emits)
106108
107-
const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formGroupSize, name, highlight, disabled, ariaAttrs } = useFormField<InputNumberProps>(props)
108-
const { orientation, size: fieldGroupSize } = useFieldGroup<InputNumberProps>(props)
109+
const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formGroupSize, name, highlight, disabled, ariaAttrs } = useFormField<InputNumberProps<T>>(props)
110+
const { orientation, size: fieldGroupSize } = useFieldGroup<InputNumberProps<T>>(props)
109111
110112
const locale = computed(() => props.locale || codeLocale.value)
111113
const inputSize = computed(() => fieldGroupSize.value || formGroupSize.value)

src/runtime/components/Textarea.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export interface TextareaProps<T extends TextareaValue = TextareaValue> extends
4444
highlight?: boolean
4545
modelValue?: T
4646
defaultValue?: T
47-
modelModifiers?: ModelModifiers
47+
modelModifiers?: ModelModifiers<T>
4848
class?: any
4949
ui?: Textarea['slots']
5050
}

src/runtime/types/input.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
export interface ModelModifiers {
2-
string?: boolean
3-
number?: boolean
4-
trim?: boolean
1+
export interface ModelModifiers<T = any> {
2+
string?: string extends T ? boolean : never
3+
number?: number extends T ? boolean : never
4+
trim?: string extends T ? boolean : never
55
lazy?: boolean
6-
nullable?: boolean
6+
nullable?: null extends T ? boolean : never
77
optional?: boolean
88
}

0 commit comments

Comments
 (0)