From cecfc4590db9e0e0d90db01433b2231087ada2e3 Mon Sep 17 00:00:00 2001 From: inottn Date: Fri, 12 Apr 2024 20:30:26 +0800 Subject: [PATCH] feat(DropdownMenu): add disabled for option (#12785) --- .../vant/src/dropdown-item/DropdownItem.tsx | 15 +++++-- packages/vant/src/dropdown-item/index.less | 8 ++++ packages/vant/src/dropdown-item/types.ts | 1 + packages/vant/src/dropdown-menu/README.md | 12 +++--- .../vant/src/dropdown-menu/README.zh-CN.md | 2 + packages/vant/src/dropdown-menu/index.less | 1 + .../src/dropdown-menu/test/index.spec.tsx | 40 +++++++++++++++++++ packages/vant/src/dropdown-menu/types.ts | 1 + 8 files changed, 72 insertions(+), 8 deletions(-) diff --git a/packages/vant/src/dropdown-item/DropdownItem.tsx b/packages/vant/src/dropdown-item/DropdownItem.tsx index 895092542..5e7a61a93 100644 --- a/packages/vant/src/dropdown-item/DropdownItem.tsx +++ b/packages/vant/src/dropdown-item/DropdownItem.tsx @@ -126,9 +126,14 @@ export default defineComponent({ const renderOption = (option: DropdownItemOption) => { const { activeColor } = parent.props; + const { disabled } = option; const active = option.value === props.modelValue; const onClick = () => { + if (disabled) { + return; + } + state.showPopup = false; if (option.value !== props.modelValue) { @@ -140,7 +145,11 @@ export default defineComponent({ const renderIcon = () => { if (active) { return ( - + ); } }; @@ -152,10 +161,10 @@ export default defineComponent({ key={String(option.value)} icon={option.icon} title={option.text} - class={bem('option', { active })} + class={bem('option', { active, disabled })} style={{ color: active ? activeColor : '' }} tabindex={active ? 0 : -1} - clickable + clickable={!disabled} onClick={onClick} /> ); diff --git a/packages/vant/src/dropdown-item/index.less b/packages/vant/src/dropdown-item/index.less index a9bc7c5a3..117decd13 100644 --- a/packages/vant/src/dropdown-item/index.less +++ b/packages/vant/src/dropdown-item/index.less @@ -25,6 +25,14 @@ color: var(--van-dropdown-menu-option-active-color); } } + + &--disabled { + color: var(--van-dropdown-menu-option-disabled-color); + + .van-dropdown-item__icon { + color: var(--van-dropdown-menu-option-disabled-color); + } + } } &--up { diff --git a/packages/vant/src/dropdown-item/types.ts b/packages/vant/src/dropdown-item/types.ts index 00856519f..59c7a8b61 100644 --- a/packages/vant/src/dropdown-item/types.ts +++ b/packages/vant/src/dropdown-item/types.ts @@ -5,6 +5,7 @@ import type { Numeric } from '../utils'; export type DropdownItemOptionValue = Numeric | boolean; export type DropdownItemOption = { + disabled?: boolean; text: string; icon?: string; value: DropdownItemOptionValue; diff --git a/packages/vant/src/dropdown-menu/README.md b/packages/vant/src/dropdown-menu/README.md index d09a46976..2f55c4ddd 100644 --- a/packages/vant/src/dropdown-menu/README.md +++ b/packages/vant/src/dropdown-menu/README.md @@ -249,11 +249,12 @@ dropdownItemRef.value?.toggle(); ### Data Structure of Option -| Key | Description | Type | -| ----- | ----------- | ----------------------------- | -| text | Text | _string_ | -| value | Value | _number \| string \| boolean_ | -| icon | Left icon | _string_ | +| Key | Description | Type | +| -------- | ------------------------- | ----------------------------- | +| text | Text | _string_ | +| value | Value | _number \| string \| boolean_ | +| disabled | Whether to disable option | _boolean_ | +| icon | Left icon | _string_ | ## Theming @@ -273,5 +274,6 @@ The component provides the following CSS variables, which can be used to customi | --van-dropdown-menu-title-padding | _0 var(--van-padding-xs)_ | - | | --van-dropdown-menu-title-line-height | _var(--van-line-height-lg)_ | - | | --van-dropdown-menu-option-active-color | _var(--van-primary-color)_ | - | +| --van-dropdown-menu-option-disabled-color | _var(--van-text-color-3)_ | - | | --van-dropdown-menu-content-max-height | _80%_ | - | | --van-dropdown-item-z-index | _10_ | - | diff --git a/packages/vant/src/dropdown-menu/README.zh-CN.md b/packages/vant/src/dropdown-menu/README.zh-CN.md index 0a9ed3a7e..c59aa63b1 100644 --- a/packages/vant/src/dropdown-menu/README.zh-CN.md +++ b/packages/vant/src/dropdown-menu/README.zh-CN.md @@ -257,6 +257,7 @@ dropdownItemRef.value?.toggle(); | --- | --- | --- | | text | 文字 | _string_ | | value | 标识符 | _number \| string \| boolean_ | +| disabled | 是否禁用选项 | _boolean_ | | icon | 左侧图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props) | _string_ | ## 主题定制 @@ -277,6 +278,7 @@ dropdownItemRef.value?.toggle(); | --van-dropdown-menu-title-padding | _0 var(--van-padding-xs)_ | - | | --van-dropdown-menu-title-line-height | _var(--van-line-height-lg)_ | - | | --van-dropdown-menu-option-active-color | _var(--van-primary-color)_ | - | +| --van-dropdown-menu-option-disabled-color | _var(--van-text-color-3)_ | - | | --van-dropdown-menu-content-max-height | _80%_ | - | | --van-dropdown-item-z-index | _10_ | - | diff --git a/packages/vant/src/dropdown-menu/index.less b/packages/vant/src/dropdown-menu/index.less index e14ba0960..788ebb821 100644 --- a/packages/vant/src/dropdown-menu/index.less +++ b/packages/vant/src/dropdown-menu/index.less @@ -10,6 +10,7 @@ --van-dropdown-menu-title-padding: 0 var(--van-padding-xs); --van-dropdown-menu-title-line-height: var(--van-line-height-lg); --van-dropdown-menu-option-active-color: var(--van-primary-color); + --van-dropdown-menu-option-disabled-color: var(--van-text-color-3); --van-dropdown-menu-content-max-height: 80%; } diff --git a/packages/vant/src/dropdown-menu/test/index.spec.tsx b/packages/vant/src/dropdown-menu/test/index.spec.tsx index db365a940..c91b7fef4 100644 --- a/packages/vant/src/dropdown-menu/test/index.spec.tsx +++ b/packages/vant/src/dropdown-menu/test/index.spec.tsx @@ -367,3 +367,43 @@ test('auto-locate prop', async () => { vi.doUnmock('../../utils/dom'); }); + +test('disable dropdown option', async () => { + const onChange = vi.fn(); + const optionsRef = ref([ + { text: 'A', value: 0 }, + { text: 'B', value: 1, disabled: true }, + { text: 'C', value: 2 }, + ]); + const wrapper = mount({ + setup() { + return () => ( + + + + ); + }, + }); + + await later(); + const title = wrapper.find('.van-dropdown-menu__title'); + await title.trigger('click'); + + const options = wrapper.findAll('.van-dropdown-item .van-cell'); + + await options[1].trigger('click'); + expect(onChange).not.toHaveBeenCalled(); + + await options[2].trigger('click'); + expect(onChange).toHaveBeenCalledTimes(1); + + optionsRef.value[1].disabled = false; + + await later(); + await options[1].trigger('click'); + expect(onChange).toHaveBeenCalledTimes(2); +}); diff --git a/packages/vant/src/dropdown-menu/types.ts b/packages/vant/src/dropdown-menu/types.ts index 661cc2714..c5266dc9f 100644 --- a/packages/vant/src/dropdown-menu/types.ts +++ b/packages/vant/src/dropdown-menu/types.ts @@ -30,5 +30,6 @@ export type DropdownMenuThemeVars = { dropdownMenuTitlePadding?: string; dropdownMenuTitleLineHeight?: number | string; dropdownMenuOptionActiveColor?: string; + dropdownMenuOptionDisabledColor?: string; dropdownMenuContentMaxHeight?: string; };