mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-05 19:41:42 +08:00
feat(Cascader): add option slot (#9036)
* feat(Cascader): add option-text slot * chore: adjust slot
This commit is contained in:
parent
69524def7b
commit
4de5f5ac5a
@ -59,11 +59,7 @@ export default defineComponent({
|
||||
activeTab: 0,
|
||||
});
|
||||
|
||||
const {
|
||||
text: textKey,
|
||||
value: valueKey,
|
||||
children: childrenKey,
|
||||
} = extend(
|
||||
const { text: textKey, value: valueKey, children: childrenKey } = extend(
|
||||
{
|
||||
text: 'text',
|
||||
value: 'value',
|
||||
@ -210,39 +206,52 @@ export default defineComponent({
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderOption = (
|
||||
option: CascaderOption,
|
||||
selectedOption: CascaderOption | null,
|
||||
tabIndex: number
|
||||
) => {
|
||||
const selected =
|
||||
selectedOption && option[valueKey] === selectedOption[valueKey];
|
||||
const color = option.color || (selected ? props.activeColor : undefined);
|
||||
|
||||
const Text = slots.option ? (
|
||||
slots.option({ option, selected })
|
||||
) : (
|
||||
<span>{option[textKey]}</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<li
|
||||
class={[
|
||||
bem('option', {
|
||||
selected,
|
||||
disabled: option.disabled,
|
||||
}),
|
||||
option.className,
|
||||
]}
|
||||
style={{ color }}
|
||||
onClick={() => onSelect(option, tabIndex)}
|
||||
>
|
||||
{Text}
|
||||
{selected ? (
|
||||
<Icon name="success" class={bem('selected-icon')} />
|
||||
) : null}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
const renderOptions = (
|
||||
options: CascaderOption[],
|
||||
selectedOption: CascaderOption | null,
|
||||
tabIndex: number
|
||||
) => {
|
||||
const renderOption = (option: CascaderOption) => {
|
||||
const isSelected =
|
||||
selectedOption && option[valueKey] === selectedOption[valueKey];
|
||||
const color =
|
||||
option.color || (isSelected ? props.activeColor : undefined);
|
||||
|
||||
return (
|
||||
<li
|
||||
class={[
|
||||
bem('option', {
|
||||
selected: isSelected,
|
||||
disabled: option.disabled,
|
||||
}),
|
||||
option.className,
|
||||
]}
|
||||
style={{ color }}
|
||||
onClick={() => onSelect(option, tabIndex)}
|
||||
>
|
||||
<span>{option[textKey]}</span>
|
||||
{isSelected ? (
|
||||
<Icon name="success" class={bem('selected-icon')} />
|
||||
) : null}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
return <ul class={bem('options')}>{options.map(renderOption)}</ul>;
|
||||
};
|
||||
) => (
|
||||
<ul class={bem('options')}>
|
||||
{options.map((option) =>
|
||||
renderOption(option, selectedOption, tabIndex)
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
|
||||
const renderTab = (tab: CascaderTab, tabIndex: number) => {
|
||||
const { options, selectedOption } = tab;
|
||||
|
@ -235,9 +235,10 @@ export default {
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description |
|
||||
| ----- | ------------ |
|
||||
| title | Custom title |
|
||||
| Name | Description | SlotProps |
|
||||
| --- | --- | --- |
|
||||
| title | Custom title | - |
|
||||
| option `v3.1.4` | Custom option text | _{ option: Option, selected: boolean }_ |
|
||||
|
||||
### CSS Variables
|
||||
|
||||
|
@ -247,9 +247,10 @@ export default {
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
| ----- | -------------- |
|
||||
| title | 自定义顶部标题 |
|
||||
| 名称 | 说明 | 参数 |
|
||||
| --------------- | -------------- | --------------------------------------- |
|
||||
| title | 自定义顶部标题 | - |
|
||||
| option `v3.1.4` | 自定义选项文字 | _{ option: Option, selected: boolean }_ |
|
||||
|
||||
### 样式变量
|
||||
|
||||
|
@ -5,6 +5,12 @@ exports[`should change close icon when using close-icon prop 1`] = `
|
||||
</i>
|
||||
`;
|
||||
|
||||
exports[`should render option slot correctly 1`] = `
|
||||
<li class="van-cascader__option">
|
||||
Custom Option foo
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`should render title slot correctly 1`] = `
|
||||
<h2 class="van-cascader__title">
|
||||
Custom Title
|
||||
|
@ -88,6 +88,20 @@ test('should render title slot correctly', () => {
|
||||
expect(wrapper.find('.van-cascader__title').html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render option slot correctly', async () => {
|
||||
const option = { value: '1', text: 'foo' };
|
||||
const wrapper = mount(Cascader, {
|
||||
props: {
|
||||
options: [option],
|
||||
},
|
||||
slots: {
|
||||
option: ({ option }) => `Custom Option ${option.text}`,
|
||||
},
|
||||
});
|
||||
await later();
|
||||
expect(wrapper.find('.van-cascader__option').html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// TODO
|
||||
// test('should select correct option when value changed', async () => {
|
||||
// const wrapper = mount(Cascader, {
|
||||
|
Loading…
x
Reference in New Issue
Block a user