refactor(components): [rate] use type-based definitions (#23439)

* refactor(components): [rate] use type-based definitions

* refactor: update

---------

Co-authored-by: rzzf <cszhjh@gmail.com>
This commit is contained in:
lw56777
2026-01-18 17:27:06 +08:00
committed by GitHub
parent 0b8b849f8f
commit e71993c519
2 changed files with 121 additions and 4 deletions

View File

@@ -9,9 +9,100 @@ import {
} from '@element-plus/utils'
import { useAriaProps, useSizeProp } from '@element-plus/hooks'
import type { Component, ExtractPropTypes, ExtractPublicPropTypes } from 'vue'
import type { Component, ExtractPublicPropTypes } from 'vue'
import type { ComponentSize } from '@element-plus/constants'
import type Rate from './rate.vue'
export interface RateProps {
/**
* @description binding value
*/
modelValue?: number
/**
* @description native `id` attribute
*/
id?: string
/**
* @description threshold value between low and medium level. The value itself will be included in low level
*/
lowThreshold?: number
/**
* @description threshold value between medium and high level. The value itself will be included in high level
*/
highThreshold?: number
/**
* @description max rating score
*/
max?: number
/**
* @description colors for icons. If array, it should have 3 elements, each of which corresponds with a score level, else if object, the key should be threshold value between two levels, and the value should be corresponding color
*/
colors?: string[] | Record<number, string>
/**
* @description color of unselected icons
*/
voidColor?: string
/**
* @description color of unselected read-only icons
*/
disabledVoidColor?: string
/**
* @description icon components. If array, it should have 3 elements, each of which corresponds with a score level, else if object, the key should be threshold value between two levels, and the value should be corresponding icon component
*/
icons?: Array<string | Component> | Record<number, string | Component>
/**
* @description component of unselected icons
*/
voidIcon?: string | Component
/**
* @description component of unselected read-only icons
*/
disabledVoidIcon?: string | Component
/**
* @description whether Rate is read-only
*/
disabled?: boolean
/**
* @description whether picking half start is allowed
*/
allowHalf?: boolean
/**
* @description whether to display texts
*/
showText?: boolean
/**
* @description whether to display current score. show-score and show-text cannot be true at the same time
*/
showScore?: boolean
/**
* @description color of texts
*/
textColor?: string
/**
* @description text array
*/
texts?: string[]
/**
* @description score template
*/
scoreTemplate?: string
/**
* @description size of Rate
*/
size?: ComponentSize
/**
* @description whether value can be reset to `0`
*/
clearable?: boolean
/**
* @description native `aria-label` attribute
*/
ariaLabel?: string
}
/**
* @deprecated Removed after 3.0.0, Use `RateProps` instead.
*/
export const rateProps = buildProps({
/**
* @description binding value
@@ -151,7 +242,9 @@ export const rateProps = buildProps({
...useAriaProps(['ariaLabel']),
} as const)
export type RateProps = ExtractPropTypes<typeof rateProps>
/**
* @deprecated Removed after 3.0.0, Use `RateProps` instead.
*/
export type RatePropsPublic = ExtractPublicPropTypes<typeof rateProps>
export const rateEmits = {

View File

@@ -80,11 +80,13 @@ import {
useFormSize,
} from '@element-plus/components/form'
import { ElIcon } from '@element-plus/components/icon'
import { Star, StarFilled } from '@element-plus/icons-vue'
import { useNamespace } from '@element-plus/hooks'
import { rateEmits, rateProps } from './rate'
import { rateEmits } from './rate'
import type { CSSProperties, Component } from 'vue'
import type { IconInstance } from '@element-plus/components/icon'
import type { RateProps } from './rate'
function getValueFromMap<T>(
value: number,
@@ -110,7 +112,29 @@ defineOptions({
name: 'ElRate',
})
const props = defineProps(rateProps)
const props = withDefaults(defineProps<RateProps>(), {
modelValue: 0,
id: undefined,
lowThreshold: 2,
highThreshold: 4,
max: 5,
colors: () => ['', '', ''],
voidColor: '',
disabledVoidColor: '',
icons: () => [StarFilled, StarFilled, StarFilled],
voidIcon: () => Star,
disabledVoidIcon: () => StarFilled,
disabled: undefined,
textColor: '',
texts: () => [
'Extremely bad',
'Disappointed',
'Fair',
'Satisfied',
'Surprise',
],
scoreTemplate: '{value}',
})
const emit = defineEmits(rateEmits)
const formItemContext = inject(formItemContextKey, undefined)