Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(time-select): [time-select] Fix and optimize issues with invalid … #2735

Merged
merged 4 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ test('固定时间范围', async ({ page }) => {
await timeInput.click()
// options 的第一条是 options.first(),时间是 08:30;最后一条(最大时间)是 options.nth(43),时间是 18:30
await expect(options.first()).toContainText('08:30')
await expect(options.nth(43)).toContainText('18:30')
// 起始时间选择 10:00,稍后验证结束时间 10:00 是否 disabled
options.nth(9).click()
await expect(options.nth(44)).toContainText('18:30')
// 起始时间选择10:00,稍后验证结束时间10:00是否disabled
options.nth(10).click()
await expect(page.locator('.tiny-input-suffix .tiny-input__inner').first()).toHaveValue('10:00')

const timeEnd = page.getByRole('textbox', { name: '结束时间' })
const endOptions = page.locator('.tiny-picker-panel').nth(1).locator('div')
await timeEnd.click()
await expect(endOptions.first()).toContainText('08:30')
await expect(endOptions.nth(43)).toContainText('18:30')
// 验证结束时间 10:00 是否 disabled
await expect(endOptions.nth(9)).toHaveClass('tiny-time-select__item disabled')
endOptions.nth(10).click()
await expect(endOptions.nth(44)).toContainText('18:30')
// 验证结束时间10:00是否disabled
await expect(endOptions.nth(10)).toHaveClass('tiny-time-select__item disabled')
endOptions.nth(11).click()
await expect(page.locator('.tiny-input-suffix .tiny-input__inner').last()).toHaveValue('10:15')
})
15 changes: 15 additions & 0 deletions packages/renderless/src/picker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,12 @@ export const handleInput =
const val = event.target.value
state.userInput = val
}

// time-selelt 组件中,输入值开启过滤逻辑,将值传递给生成选项数据的计算属性中生成过滤后的数据面板
if (state.type === 'time-select') {
state.picker.state.isFilter = true
state.picker.state.filterVal = state.userInput
}
}

export const formatInputValue =
Expand Down Expand Up @@ -986,6 +992,11 @@ export const handleKeydown =
// Enter
if (keyCode === 13) {
if (state.userInput === '' || api.isValidValue(api.parseString(state.displayValue))) {
// time-select组件中,对输入的数据进行校验,如果有效则取默认过滤后数据的第一个。
if (state.type === 'time-select') {
state.userInput = state.picker.state.items.length ? state.picker.state.items[0].value : ''
}

api.handleChange()
state.pickerVisible = state.picker.state.visible = false
api.blur()
Expand All @@ -1010,6 +1021,10 @@ export const hidePicker =
({ destroyPopper, state }) =>
() => {
if (state.picker) {
// time-select组件中,选中面板关闭则清除过滤,保证下次面板打开时原始items数据。
if (state.type === 'time-select') {
state.picker.state.isFilter = false
}
state.picker.resetView && state.picker.resetView()
state.pickerVisible = state.picker.visible = state.picker.state.visible = false
destroyPopper()
Expand Down
11 changes: 9 additions & 2 deletions packages/renderless/src/time-panel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,15 @@ export const computItems =
current = api.nextTime(current, step)
}
}

return result
// 生成选项数据时若开启过滤,则进行选项数据过滤,否则返回原始选项数据
if (state.isFilter) {
const newItems = result.filter((item) => {
return item.value.includes(state.filterVal)
})
return newItems
} else {
return result
}
}

export const handleClick = (api) => (item) => !item.disabled && api.emitPick({ value: item.value })
Expand Down
2 changes: 2 additions & 0 deletions packages/renderless/src/time-panel/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const initState = ({ reactive, computed, api }) => {
maxTime: '',
width: 0,
lastEmitValue: '',
isFilter: false,
filterVal: '',
items: computed(() => api.computItems()),
default: computed(() => state.defaultValue || state.defaultTime || ''),
value: computed({
Expand Down
21 changes: 21 additions & 0 deletions packages/theme-saas/src/time-select/index.less
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
@import '../custom.less';

@time-select-prefix-cls: ~'@{css-prefix}time-select';
@picker-panel-prefix-cls: ~'@{css-prefix}picker-panel';
@time-select-scrollbar-cls: ~'@{css-prefix}scrollbar';

.@{time-select-prefix-cls} {

&.not-match-height {
height: 36px;
}
height: 252px;
padding-top: 6px;
border-radius: 8px;
.@{time-select-scrollbar-cls} {
height: 100%;
}

.@{scrollbar-prefix-cls}__wrap {
@apply p-0;
@apply !mb-0;
Expand Down Expand Up @@ -37,4 +50,12 @@
}
}
}

.@{picker-panel-prefix-cls} {
&__content {
.no-match {
text-align: center;
}
}
}
}
12 changes: 9 additions & 3 deletions packages/theme/src/time-select/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@

.@{time-select-prefix-cls} {
.inject-TimeSelect-vars();


&.not-match-height {
height: 36px;
}
height: 242px;
padding-top: var(--tv-TimeSelect-content-padding-top);
.@{time-select-scrollbar-cls} {
height: 242px;
height: 100%;
.@{css-prefix}scrollbar__wrap {
max-height: unset;
}
Expand Down Expand Up @@ -54,7 +58,9 @@
&__content {
padding-left: 0;
padding-right: 0;
padding-top: var(--tv-TimeSelect-content-padding-top);
.no-match {
text-align: center;
}
}
}
}
31 changes: 17 additions & 14 deletions packages/vue/src/time-panel/src/pc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,27 @@
ref="popper"
v-show="state.visible"
:style="{ width: state.width + 'px' }"
:class="state.popperClass"
:class="[state.popperClass, { 'not-match-height': !state.items.length }]"
class="tiny-picker-panel tiny-time-select tiny-popper"
>
<tiny-scrollbar noresize wrap-class="tiny-picker-panel__content">
<div
class="tiny-time-select__item"
v-for="item in state.items"
:class="{
selected: state.value === item.value,
disabled: item.disabled,
default: item.value === state.default
}"
:disabled="item.disabled"
:key="item.value"
@click="handleClick(item)"
>
{{ item.value }}
<div v-if="state.items.length">
<div
class="tiny-time-select__item"
v-for="item in state.items"
:class="{
selected: state.value === item.value,
disabled: item.disabled,
default: item.value === state.default
}"
:disabled="item.disabled"
:key="item.value"
@click="handleClick(item)"
>
{{ item.value }}
</div>
</div>
<div v-else class="no-match">{{ $t('ui.select.noMatch') }}</div>
</tiny-scrollbar>
</div>
</transition>
Expand Down
Loading