mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
fix(components): [time-select] prevent freeze when step is invalid (#23635)
* fix(components): [time-select] prevent freeze when step is 00:00 * test: add test case * fix: handle invalid step value formats "00:" and ":00" * refactor: invalidStep use default value * refactor: step use computed * chore: typo * refactor: step use computed
This commit is contained in:
@@ -269,6 +269,17 @@ describe('TimeSelect', () => {
|
||||
expect(input.attributes('name')).toBe('timeSelectName')
|
||||
})
|
||||
|
||||
it('should fallback to default step when step is 00:00', async () => {
|
||||
const wrapper = mount(() => (
|
||||
<TimeSelect start="09:00" end="10:00" step="00:00" />
|
||||
))
|
||||
const input = wrapper.find('input')
|
||||
await input.trigger('click')
|
||||
const items = document.querySelectorAll('.el-select-dropdown__item>span')
|
||||
expect(items).toHaveLength(3)
|
||||
expect([...items].at(-1)?.textContent).toBe('10:00')
|
||||
})
|
||||
|
||||
describe('form item accessibility integration', () => {
|
||||
it('automatic id attachment', async () => {
|
||||
const wrapper = mount(() => (
|
||||
|
||||
@@ -88,6 +88,8 @@ export interface TimeSelectProps extends UseEmptyValuesProps {
|
||||
popperStyle?: string | CSSProperties
|
||||
}
|
||||
|
||||
export const DEFAULT_STEP = '00:30'
|
||||
|
||||
/**
|
||||
* @deprecated Removed after 3.0.0, Use `TimeSelectProps` instead.
|
||||
*/
|
||||
@@ -160,7 +162,7 @@ export const timeSelectProps = buildProps({
|
||||
*/
|
||||
step: {
|
||||
type: String,
|
||||
default: '00:30',
|
||||
default: DEFAULT_STEP,
|
||||
},
|
||||
/**
|
||||
* @description minimum time, any time before this time will be disabled
|
||||
|
||||
@@ -47,6 +47,8 @@ import { useLocale, useNamespace } from '@element-plus/hooks'
|
||||
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'
|
||||
import { CircleClose, Clock } from '@element-plus/icons-vue'
|
||||
import { compareTime, formatTime, nextTime, parseTime } from './utils'
|
||||
import { debugWarn } from '@element-plus/utils'
|
||||
import { DEFAULT_STEP } from './time-select'
|
||||
|
||||
import type { TimeSelectProps } from './time-select'
|
||||
|
||||
@@ -68,7 +70,7 @@ const props = withDefaults(defineProps<TimeSelectProps>(), {
|
||||
clearable: true,
|
||||
start: '09:00',
|
||||
end: '18:00',
|
||||
step: '00:30',
|
||||
step: DEFAULT_STEP,
|
||||
prefixIcon: () => Clock,
|
||||
clearIcon: () => CircleClose,
|
||||
popperClass: '',
|
||||
@@ -93,11 +95,6 @@ const end = computed(() => {
|
||||
return time ? formatTime(time) : null
|
||||
})
|
||||
|
||||
const step = computed(() => {
|
||||
const time = parseTime(props.step)
|
||||
return time ? formatTime(time) : null
|
||||
})
|
||||
|
||||
const minTime = computed(() => {
|
||||
const time = parseTime(props.minTime || '')
|
||||
return time ? formatTime(time) : null
|
||||
@@ -108,6 +105,24 @@ const maxTime = computed(() => {
|
||||
return time ? formatTime(time) : null
|
||||
})
|
||||
|
||||
const step = computed(() => {
|
||||
const time = parseTime(props.step)
|
||||
const isInvalidStep =
|
||||
!time ||
|
||||
time.hours < 0 ||
|
||||
time.minutes < 0 ||
|
||||
Number.isNaN(time.hours) ||
|
||||
Number.isNaN(time.minutes) ||
|
||||
(time.hours === 0 && time.minutes === 0)
|
||||
if (isInvalidStep) {
|
||||
debugWarn(
|
||||
'ElTimeSelect',
|
||||
`invalid step, fallback to default step (${DEFAULT_STEP}).`
|
||||
)
|
||||
}
|
||||
return !isInvalidStep ? formatTime(time) : DEFAULT_STEP
|
||||
})
|
||||
|
||||
const items = computed(() => {
|
||||
const result: { value: string; rawValue: string; disabled: boolean }[] = []
|
||||
const push = (formattedValue: string, rawValue: string) => {
|
||||
|
||||
Reference in New Issue
Block a user