mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
refactor(components): [input] use type-based definitions (#23366)
* refactor(components): [input] use type-based props definitions * fix: update * chore: rename evt to eve * refactor: add comments * Update packages/components/input/src/input.vue Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> * fix: import markRaw * chore: change deps * chore: revert catalog comment * refactor: remove generic type * refactor: revert InputInstance * docs: update deprecated * fix: update * chore: remove CSSProperties --------- Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com>
This commit is contained in:
@@ -121,7 +121,7 @@ input/length-limiting
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----------- |
|
||||
| type | type of input, see more in [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types) | ^[string]`'text' \| 'textarea' \| 'number' \| 'password' \| 'email' \| 'search' \| 'tel' \| 'url'` | text |
|
||||
| model-value / v-model | binding value | ^[string] / ^[number] | — |
|
||||
| model-modifiers ^(2.11.5) | v-model modifiers, reference [Vue modifiers](https://vuejs.org/guide/essentials/forms.html#modifiers) | ^[object]`{ lazy?: boolean, number?: boolean, trim?: boolean }` | — |
|
||||
| model-modifiers ^(2.11.5) | v-model modifiers, reference [Vue modifiers](https://vuejs.org/guide/essentials/forms.html#modifiers) | ^[object]`{ lazy?: true, number?: true, trim?: true }` | — |
|
||||
| maxlength | same as `maxlength` in native input | ^[string] / ^[number] | — |
|
||||
| minlength | same as `minlength` in native input | ^[string] / ^[number] | — |
|
||||
| show-word-limit | whether show word count, only works when `type` is 'text' or 'textarea' | ^[boolean] | false |
|
||||
|
||||
@@ -10,16 +10,17 @@ import { useAriaProps, useSizeProp } from '@element-plus/hooks'
|
||||
import { CircleClose } from '@element-plus/icons-vue'
|
||||
|
||||
import type {
|
||||
ExtractPropTypes,
|
||||
Component,
|
||||
ExtractPublicPropTypes,
|
||||
HTMLAttributes,
|
||||
StyleValue,
|
||||
} from 'vue'
|
||||
import type { ComponentSize } from '@element-plus/constants'
|
||||
|
||||
export type InputModelModifiers = {
|
||||
lazy?: boolean
|
||||
number?: boolean
|
||||
trim?: boolean
|
||||
lazy?: true
|
||||
number?: true
|
||||
trim?: true
|
||||
}
|
||||
export type InputAutoSize = { minRows?: number; maxRows?: number } | boolean
|
||||
// Some commonly used values for input type
|
||||
@@ -34,6 +35,141 @@ export type InputType =
|
||||
| 'url'
|
||||
| (string & NonNullable<unknown>)
|
||||
|
||||
export interface InputProps {
|
||||
/**
|
||||
* @description native input id
|
||||
*/
|
||||
id?: string
|
||||
/**
|
||||
* @description input box size
|
||||
*/
|
||||
size?: ComponentSize
|
||||
/**
|
||||
* @description whether to disable
|
||||
*/
|
||||
disabled?: boolean
|
||||
/**
|
||||
* @description binding value
|
||||
*/
|
||||
modelValue?: string | number | null | undefined
|
||||
/**
|
||||
* @description v-model modifiers, reference [Vue modifiers](https://vuejs.org/guide/essentials/forms.html#modifiers)
|
||||
*/
|
||||
modelModifiers?: InputModelModifiers
|
||||
/**
|
||||
* @description same as `maxlength` in native input
|
||||
*/
|
||||
maxlength?: string | number
|
||||
/**
|
||||
* @description same as `minlength` in native input
|
||||
*/
|
||||
minlength?: string | number
|
||||
/**
|
||||
* @description type of input, see more in [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types)
|
||||
*/
|
||||
type?: InputType
|
||||
/**
|
||||
* @description control the resizability
|
||||
*/
|
||||
resize?: 'none' | 'both' | 'horizontal' | 'vertical'
|
||||
/**
|
||||
* @description whether textarea has an adaptive height
|
||||
*/
|
||||
autosize?: InputAutoSize
|
||||
/**
|
||||
* @description native input autocomplete
|
||||
* - When the number of literal types in a union exceeds 315, the TS2590 error occurs. see: https://github.com/vuejs/core/issues/10514
|
||||
*/
|
||||
autocomplete?: string // HTMLInputElement['autocomplete']
|
||||
/**
|
||||
* @description format content
|
||||
*/
|
||||
formatter?: (value: string) => string
|
||||
/**
|
||||
* @description parse content
|
||||
*/
|
||||
parser?: (value: string) => string
|
||||
/**
|
||||
* @description placeholder
|
||||
*/
|
||||
placeholder?: string
|
||||
/**
|
||||
* @description native input form
|
||||
*/
|
||||
form?: string
|
||||
/**
|
||||
* @description native input readonly
|
||||
*/
|
||||
readonly?: boolean
|
||||
/**
|
||||
* @description whether to show clear button
|
||||
*/
|
||||
clearable?: boolean
|
||||
/**
|
||||
* @description custom clear icon component
|
||||
*/
|
||||
clearIcon?: string | Component
|
||||
/**
|
||||
* @description toggleable password input
|
||||
*/
|
||||
showPassword?: boolean
|
||||
/**
|
||||
* @description word count
|
||||
*/
|
||||
showWordLimit?: boolean
|
||||
/**
|
||||
* @description word count position, valid when `show-word-limit` is true
|
||||
*/
|
||||
wordLimitPosition?: 'inside' | 'outside'
|
||||
/**
|
||||
* @description suffix icon
|
||||
*/
|
||||
suffixIcon?: string | Component
|
||||
/**
|
||||
* @description prefix icon
|
||||
*/
|
||||
prefixIcon?: string | Component
|
||||
/**
|
||||
* @description container role, internal properties provided for use by the picker component
|
||||
*/
|
||||
containerRole?: string
|
||||
/**
|
||||
* @description input tabindex
|
||||
*/
|
||||
tabindex?: string | number
|
||||
/**
|
||||
* @description whether to trigger form validation
|
||||
*/
|
||||
validateEvent?: boolean
|
||||
/**
|
||||
* @description input or textarea element style
|
||||
*/
|
||||
inputStyle?: StyleValue
|
||||
/**
|
||||
* @description native input autofocus
|
||||
*/
|
||||
autofocus?: boolean
|
||||
/**
|
||||
* @description number of rows of textarea, only works when `type` is 'textarea'
|
||||
*/
|
||||
rows?: number
|
||||
/**
|
||||
* @description native `aria-label` attribute
|
||||
*/
|
||||
ariaLabel?: string
|
||||
/**
|
||||
* @description native input mode for virtual keyboards
|
||||
*/
|
||||
inputmode?: HTMLAttributes['inputmode']
|
||||
/**
|
||||
* @description same as `name` in native input
|
||||
*/
|
||||
name?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Removed after 3.0.0, Use `InputProps` instead.
|
||||
*/
|
||||
export const inputProps = buildProps({
|
||||
/**
|
||||
* @description native input id
|
||||
@@ -227,7 +363,10 @@ export const inputProps = buildProps({
|
||||
*/
|
||||
name: String,
|
||||
} as const)
|
||||
export type InputProps = ExtractPropTypes<typeof inputProps>
|
||||
|
||||
/**
|
||||
* @deprecated Removed after 3.0.0, Use `InputProps` instead.
|
||||
*/
|
||||
export type InputPropsPublic = ExtractPublicPropTypes<typeof inputProps>
|
||||
|
||||
export const inputEmits = {
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
markRaw,
|
||||
nextTick,
|
||||
onMounted,
|
||||
ref,
|
||||
@@ -175,7 +176,11 @@ import {
|
||||
import { useResizeObserver } from '@vueuse/core'
|
||||
import { isNil } from 'lodash-unified'
|
||||
import { ElIcon } from '@element-plus/components/icon'
|
||||
import { Hide as IconHide, View as IconView } from '@element-plus/icons-vue'
|
||||
import {
|
||||
CircleClose as IconCircleClose,
|
||||
Hide as IconHide,
|
||||
View as IconView,
|
||||
} from '@element-plus/icons-vue'
|
||||
import {
|
||||
useFormDisabled,
|
||||
useFormItem,
|
||||
@@ -202,9 +207,10 @@ import {
|
||||
UPDATE_MODEL_EVENT,
|
||||
} from '@element-plus/constants'
|
||||
import { calcTextareaHeight, looseToNumber } from './utils'
|
||||
import { inputEmits, inputProps } from './input'
|
||||
import { inputEmits } from './input'
|
||||
|
||||
import type { StyleValue } from 'vue'
|
||||
import type { InputProps } from './input'
|
||||
|
||||
type TargetElement = HTMLInputElement | HTMLTextAreaElement
|
||||
|
||||
@@ -213,7 +219,19 @@ defineOptions({
|
||||
name: COMPONENT_NAME,
|
||||
inheritAttrs: false,
|
||||
})
|
||||
const props = defineProps(inputProps)
|
||||
const props = withDefaults(defineProps<InputProps>(), {
|
||||
disabled: undefined,
|
||||
modelValue: '',
|
||||
modelModifiers: () => ({}),
|
||||
type: 'text',
|
||||
autocomplete: 'off',
|
||||
clearIcon: markRaw(IconCircleClose),
|
||||
wordLimitPosition: 'inside',
|
||||
tabindex: 0,
|
||||
validateEvent: true,
|
||||
inputStyle: () => ({}),
|
||||
rows: 2,
|
||||
})
|
||||
const emit = defineEmits(inputEmits)
|
||||
|
||||
const rawAttrs = useRawAttrs()
|
||||
|
||||
Reference in New Issue
Block a user