diff --git a/components/cascader-select/__docs__/index.en-us.md b/components/cascader-select/__docs__/index.en-us.md index 7181b1f8ad..2fdf285860 100644 --- a/components/cascader-select/__docs__/index.en-us.md +++ b/components/cascader-select/__docs__/index.en-us.md @@ -21,34 +21,34 @@ Inherits partial props from Cascader, support passing props to Cascader: dataSou checkStrictly, resultRender, expandedValue, defaultExpandedValue, expandTriggerType, onExpand, listStyle, listClassName, loadData, i temRender, immutable. Support passing props to Select: other Select props except those listed above and those listed below. -| Param | Description | Type | Default Value | Required | Supported Version | -| -------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------- | ----------------- | -| size | Size | 'small' \| 'medium' \| 'large' | 'medium' | | - | -| disabled | Disabled | boolean | false | | - | -| hasArrow | HasArrow | boolean | true | | - | -| hasBorder | HasBorder | boolean | true | | - | -| hasClear | HasClear | boolean | false | | - | -| readOnly | ReadOnly, popup layer can be expanded but cannot be selected in read | boolean | - | | - | -| defaultValue | Default value(not controlled) | string \| Array\ | - | | - | -| value | Current value(controlled) | string \| Array\ | - | | - | -| onChange | Callback when selected value changes | (
value: string \| Array\ \| null,
data: CascaderDataItem \| Array\ \| null,
extra?: Extra
) => void | - | | - | -| changeOnSelect | Whether to call onChange as soon as selected, this property only works in single selection mode | boolean | false | | - | -| displayRender | Custom render function of selected result | (
label: Array\,
data: CascaderSelectDataItem
) => React.ReactNode | - | | - | -| showSearch | Show search box | boolean | false | | - | -| filter | Custom search function | (searchValue: string, path: CascaderSelectDataItem[]) => boolean | - | | - | -| onSearch | Callback when search value changes | (value: string) => void | - | | 1.23 | -| resultAutoWidth | Whether the search result list is the same width as the selection box | boolean | true | | - | -| notFoundContent | Content when no data | React.ReactNode | - | | - | -| header | Custom dropdown header | React.ReactNode | - | | - | -| footer | Custom dropdown footer | React.ReactNode | - | | - | -| defaultVisible | Visible by default | boolean | false | | - | -| visible | Current visible | boolean | - | | - | -| onVisibleChange | - | (visible: boolean, type?: CascaderSelectVisibleChangeType) => void | - | | - | -| popupProps | Props object passed to Popup | React.ComponentPropsWithRef\ | - | | - | -| isPreview | Whether it is in preview mode | boolean | false | | - | -| renderPreview | Custom preview | (
value: CascaderSelectDataItem \| CascaderSelectDataItem[],
props: CascaderSelectProps
) => React.ReactNode | - | | - | -| menuProps | Props object passed to Cascader | Omit\ | - | | - | -| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when multiple is true | boolean | false | | - | +| Param | Description | Type | Default Value | Required | Supported Version | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------- | ----------------- | +| size | Size | 'small' \| 'medium' \| 'large' | 'medium' | | - | +| disabled | Disabled | boolean | false | | - | +| hasArrow | HasArrow | boolean | true | | - | +| hasBorder | HasBorder | boolean | true | | - | +| hasClear | HasClear | boolean | false | | - | +| readOnly | ReadOnly, popup layer can be expanded but cannot be selected in read | boolean | - | | - | +| defaultValue | Default value(not controlled) | string \| Array\ | - | | - | +| value | Current value(controlled) | string \| Array\ | - | | - | +| onChange | Callback when selected value changes | (
value: string \| Array\ \| null,
data: CascaderDataItem \| Array\ \| null,
extra?: Extra
) => void | - | | - | +| changeOnSelect | Whether to call onChange as soon as selected, this property only works in single selection mode | boolean | false | | - | +| displayRender | Custom render function of selected result | (
label: Array\,
data: CascaderSelectDataItem
) => React.ReactNode | - | | - | +| showSearch | Show search box | boolean | false | | - | +| filter | Custom search function | (searchValue: string, path: CascaderSelectDataItem[]) => boolean | - | | - | +| onSearch | Callback when search value changes | (value: string) => void | - | | 1.23 | +| resultAutoWidth | Whether the search result list is the same width as the selection box | boolean | true | | - | +| notFoundContent | Content when no data | React.ReactNode | - | | - | +| header | Custom dropdown header | React.ReactNode | - | | - | +| footer | Custom dropdown footer | React.ReactNode | - | | - | +| defaultVisible | Visible by default | boolean | false | | - | +| visible | Current visible | boolean | - | | - | +| onVisibleChange | - | (visible: boolean, type?: CascaderSelectVisibleChangeType) => void | - | | - | +| popupProps | Props object passed to Popup | React.ComponentPropsWithRef\ | - | | - | +| isPreview | Whether it is in preview mode | boolean | false | | - | +| renderPreview | Custom preview | (
value: CascaderSelectDataItem \| CascaderSelectDataItem[],
props: CascaderSelectProps
) => React.ReactNode | - | | - | +| menuProps | Props object passed to Cascader:The parameters focusedKey, onItemFocus, className, style, focusable, and isSelectIconRight are invalid. Additionally, onBlur is invalid when passed under the filter | Omit\ | - | | - | +| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when multiple is true | boolean | false | | - | diff --git a/components/cascader-select/__docs__/index.md b/components/cascader-select/__docs__/index.md index dea6676207..960a60f7d9 100644 --- a/components/cascader-select/__docs__/index.md +++ b/components/cascader-select/__docs__/index.md @@ -21,34 +21,34 @@ checkStrictly, resultRender, expandedValue, defaultExpandedValue, expandTriggerType, onExpand, listStyle, listClassName, loadData, itemRender, immutable。支持透传给 Select 的包括除上面传给 Cascader 和下方单独列出的属性以外的其他全部属性。 -| 参数 | 说明 | 类型 | 默认值 | 是否必填 | 支持版本 | -| -------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------- | -------- | -| size | 选择框大小 | 'small' \| 'medium' \| 'large' | 'medium' | | - | -| disabled | 是否禁用 | boolean | false | | - | -| hasArrow | 是否有下拉箭头 | boolean | true | | - | -| hasBorder | 是否有边框 | boolean | true | | - | -| hasClear | 是否有清除按钮 | boolean | false | | - | -| readOnly | 是否只读,只读模式下可以展开弹层但不能选 | boolean | - | | - | -| defaultValue | (非受控)默认值 | string \| Array\ | - | | - | -| value | (受控)当前值 | string \| Array\ | - | | - | -| onChange | 选中值改变时触发的回调函数 | (
value: string \| Array\ \| null,
data: CascaderDataItem \| Array\ \| null,
extra?: Extra
) => void | - | | - | -| changeOnSelect | 是否选中即发生改变,该属性仅在单选模式下有效 | boolean | false | | - | -| displayRender | 选择框单选时展示结果的自定义渲染函数 | (
label: Array\,
data: CascaderSelectDataItem
) => React.ReactNode | - | | - | -| showSearch | 是否显示搜索框 | boolean | false | | - | -| filter | 自定义搜索函数 | (searchValue: string, path: CascaderSelectDataItem[]) => boolean | - | | - | -| onSearch | 当搜索框值变化时回调 | (value: string) => void | - | | 1.23 | -| resultAutoWidth | 搜索结果列表是否和选择框等宽 | boolean | true | | - | -| notFoundContent | 无数据时显示内容 | React.ReactNode | - | | - | -| header | 自定义下拉框头部 | React.ReactNode | - | | - | -| footer | 自定义下拉框底部 | React.ReactNode | - | | - | -| defaultVisible | 初始下拉框是否显示 | boolean | false | | - | -| visible | 当前下拉框是否显示 | boolean | - | | - | -| onVisibleChange | 下拉框显示或关闭时触发事件的回调函数 | (visible: boolean, type?: CascaderSelectVisibleChangeType) => void | - | | - | -| popupProps | 透传到 Popup 的属性对象 | React.ComponentPropsWithRef\ | - | | - | -| isPreview | 是否为预览态 | boolean | false | | - | -| renderPreview | 自定义预览态 | (
value: CascaderSelectDataItem \| CascaderSelectDataItem[],
props: CascaderSelectProps
) => React.ReactNode | - | | - | -| menuProps | 透传到 Cascader 的属性对象 | Omit\ | - | | - | -| autoClearSearchValue | 是否在选中项后清空搜索框,只在 multiple 为 true 时有效 | boolean | false | | - | +| 参数 | 说明 | 类型 | 默认值 | 是否必填 | 支持版本 | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------- | -------- | +| size | 选择框大小 | 'small' \| 'medium' \| 'large' | 'medium' | | - | +| disabled | 是否禁用 | boolean | false | | - | +| hasArrow | 是否有下拉箭头 | boolean | true | | - | +| hasBorder | 是否有边框 | boolean | true | | - | +| hasClear | 是否有清除按钮 | boolean | false | | - | +| readOnly | 是否只读,只读模式下可以展开弹层但不能选 | boolean | - | | - | +| defaultValue | (非受控)默认值 | string \| Array\ | - | | - | +| value | (受控)当前值 | string \| Array\ | - | | - | +| onChange | 选中值改变时触发的回调函数 | (
value: string \| Array\ \| null,
data: CascaderDataItem \| Array\ \| null,
extra?: Extra
) => void | - | | - | +| changeOnSelect | 是否选中即发生改变,该属性仅在单选模式下有效 | boolean | false | | - | +| displayRender | 选择框单选时展示结果的自定义渲染函数 | (
label: Array\,
data: CascaderSelectDataItem
) => React.ReactNode | - | | - | +| showSearch | 是否显示搜索框 | boolean | false | | - | +| filter | 自定义搜索函数 | (searchValue: string, path: CascaderSelectDataItem[]) => boolean | - | | - | +| onSearch | 当搜索框值变化时回调 | (value: string) => void | - | | 1.23 | +| resultAutoWidth | 搜索结果列表是否和选择框等宽 | boolean | true | | - | +| notFoundContent | 无数据时显示内容 | React.ReactNode | - | | - | +| header | 自定义下拉框头部 | React.ReactNode | - | | - | +| footer | 自定义下拉框底部 | React.ReactNode | - | | - | +| defaultVisible | 初始下拉框是否显示 | boolean | false | | - | +| visible | 当前下拉框是否显示 | boolean | - | | - | +| onVisibleChange | 下拉框显示或关闭时触发事件的回调函数 | (visible: boolean, type?: CascaderSelectVisibleChangeType) => void | - | | - | +| popupProps | 透传到 Popup 的属性对象 | React.ComponentPropsWithRef\ | - | | - | +| isPreview | 是否为预览态 | boolean | false | | - | +| renderPreview | 自定义预览态 | (
value: CascaderSelectDataItem \| CascaderSelectDataItem[],
props: CascaderSelectProps
) => React.ReactNode | - | | - | +| menuProps | 透传到 Cascader 的属性对象;focusedKey、onItemFocus、className、style、focusable、isSelectIconRight 传入无效,其中 onBlur 在 filter 下传入无效 | Omit\ | - | | - | +| autoClearSearchValue | 是否在选中项后清空搜索框,只在 multiple 为 true 时有效 | boolean | false | | - | diff --git a/components/cascader-select/__tests__/index-spec.tsx b/components/cascader-select/__tests__/index-spec.tsx index a80851ea2e..0ace606759 100644 --- a/components/cascader-select/__tests__/index-spec.tsx +++ b/components/cascader-select/__tests__/index-spec.tsx @@ -558,4 +558,12 @@ describe('CascaderSelect', () => { cy.get('.next-tag').invoke('text').should('eq', '西安'); cy.get('.next-select-trigger-search input').should('have.text', ''); }); + + it('should support The value of the menuProps attribute is passed by props, close #3852', () => { + cy.mount( + + ); + cy.get('.next-select').click(); + cy.get('.next-menu-item').first().should('have.class', 'test-list-cls'); + }); }); diff --git a/components/cascader-select/types.ts b/components/cascader-select/types.ts index 21ff107ece..4a8691e7fc 100644 --- a/components/cascader-select/types.ts +++ b/components/cascader-select/types.ts @@ -244,8 +244,8 @@ export interface CascaderSelectProps */ treeCheckable?: boolean; /** - * 透传到 Cascader 的属性对象 - * @en props object passed to Cascader + * 透传到 Cascader 的属性对象;focusedKey、onItemFocus、className、style、focusable、isSelectIconRight 传入无效,其中 onBlur 在 filter 下传入无效 + * @en props object passed to Cascader:The parameters focusedKey, onItemFocus, className, style, focusable, and isSelectIconRight are invalid. Additionally, onBlur is invalid when passed under the filter */ menuProps?: Omit; /** diff --git a/components/cascader/__docs__/index.en-us.md b/components/cascader/__docs__/index.en-us.md index ff0eaf2629..02ebf3ad11 100644 --- a/components/cascader/__docs__/index.en-us.md +++ b/components/cascader/__docs__/index.en-us.md @@ -47,7 +47,7 @@ ```typescript export type CascaderDataItem = { value: string; - label?: string; + label?: React.ReactNode; disabled?: boolean; checkboxDisabled?: boolean; children?: Array; @@ -64,7 +64,7 @@ export type CascaderDataItemWithPosInfo = CascaderDataItem & { * 位置信息 */ pos: string; - _source: CascaderDataItem; + _source?: CascaderDataItem; }; ``` diff --git a/components/cascader/__docs__/index.md b/components/cascader/__docs__/index.md index a86d4e3a43..329af9ba52 100644 --- a/components/cascader/__docs__/index.md +++ b/components/cascader/__docs__/index.md @@ -20,6 +20,8 @@ ### Cascader +Cascader 支持属性透传给 Menu,但会忽略 onSelect、value、onChange、defaultValue、focusedKey、onItemFocus、focusable、isSelectIconRight、onBlur 等和 Cascader 同名的属性 + | 参数 | 说明 | 类型 | 默认值 | 是否必填 | 支持版本 | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------- | -------- | | dataSource | 数据源 | Array\ | [] | | - | @@ -47,7 +49,7 @@ ```typescript export type CascaderDataItem = { value: string; - label?: string; + label?: React.ReactNode; disabled?: boolean; checkboxDisabled?: boolean; children?: Array; @@ -64,7 +66,7 @@ export type CascaderDataItemWithPosInfo = CascaderDataItem & { * 位置信息 */ pos: string; - _source: CascaderDataItem; + _source?: CascaderDataItem; }; ``` diff --git a/components/cascader/__tests__/index-spec.tsx b/components/cascader/__tests__/index-spec.tsx index b4f5ebe45c..32de243987 100644 --- a/components/cascader/__tests__/index-spec.tsx +++ b/components/cascader/__tests__/index-spec.tsx @@ -8,6 +8,7 @@ import React, { import cloneDeep from 'lodash.clonedeep'; import type { SinonSpy } from 'cypress/types/sinon'; import Cascader, { type CascaderDataItem, type CascaderProps } from '../index'; +import ConfigProvider from '../../config-provider'; import '../style'; function freeze(dataSource: NonNullable) { @@ -739,4 +740,64 @@ describe('Cascader', () => { 'rgb(255, 255, 255)' ); }); + + // Fix https://github.com/alibaba-fusion/next/issues/3852 + it('The Cascader component enforces isSelectIconRight to be false to prevent potential style conflicts that may arise when isSelectIconRight is set to true', () => { + const dataSource = [ + { + value: '2973', + label: '陕西', + children: [ + { + value: '2974', + label: '西安', + children: [ + { value: '2975', label: '西安市' }, + { value: '2976', label: '高陵县' }, + ], + }, + { + value: '2980', + label: '铜川', + children: [ + { value: '2981', label: '铜川市' }, + { value: '2982', label: '宜君县' }, + ], + }, + ], + }, + { + value: '3371', + label: '新疆', + children: [ + { + value: '3430', + label: '巴音郭楞蒙古自治州', + children: [ + { value: '3431', label: '库尔勒市' }, + { value: '3432', label: '和静县' }, + ], + }, + ], + }, + ]; + cy.mount( + + + + ); + findItem(0, 0) + .click({ force: true }) + .then(() => { + findItem(0, 0) + .find('.next-menu-icon-selected') + .should('not.have.class', 'next-menu-icon-right'); + }); + }); }); diff --git a/components/cascader/cascader.tsx b/components/cascader/cascader.tsx index 950dbec4f1..11ca70a267 100644 --- a/components/cascader/cascader.tsx +++ b/components/cascader/cascader.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { polyfill } from 'react-lifecycles-compat'; import cloneDeep from 'lodash.clonedeep'; import cx from 'classnames'; -import Menu, { type ItemProps, type CheckboxItemProps } from '../menu'; +import Menu, { type ItemProps, type CheckboxItemProps, type MenuProps } from '../menu'; import { func, obj, dom } from '../util'; import CascaderMenu from './menu'; import CascaderMenuItem from './item'; @@ -25,9 +25,11 @@ import type { P2n, V2n, } from './types'; +import { Menu as ViewMenu } from '../menu/view/menu'; +import ConfigProvider from '../config-provider'; const { bindCtx } = func; -const { pickOthers } = obj; +const { pickOthers, pickProps } = obj; const { addClass, removeClass, setStyle, getStyle } = dom; // 数据打平 @@ -109,6 +111,27 @@ const normalizeValue = (value: T): NormalizeValueReturns => { return [] as NormalizeValueReturns; }; +const getFormatMenuProps = (others: Record) => { + const targetProps = pickProps(ViewMenu.propTypes, others); + const targetMenuProps = pickOthers( + { + value: false, + onChange: false, + defaultValue: false, + focusedKey: false, + onItemFocus: false, + focusable: false, + onBlur: false, + ...ConfigProvider.propTypes, + }, + targetProps + ); + return { + ...targetMenuProps, + isSelectIconRight: false, + } as MenuProps; +}; + /** * Cascader */ @@ -631,11 +654,13 @@ class Cascader extends Component { listClassName, listStyle, itemRender, + ...others } = this.props; const { value, expandedValue, focusedValue } = this.state; return ( { } renderFilteredList() { - const { prefix, filteredListStyle, filteredPaths, focusable = false } = this.props; + const { + prefix, + filteredListStyle, + filteredPaths, + focusable = false, + ...others + } = this.props; const { focusedValue } = this.state; + return ( { searchValue, } = this.props; // FIXME 这样做风险比较大,propTypes 如果不全,就会出现一些 div 接收不了的参数传导到 div - const others = pickOthers(Cascader.propTypes, this.props); + const others = pickOthers({ ...Cascader.propTypes, ...ViewMenu.propTypes }, this.props); const { value } = this.state; if (rtl) { diff --git a/components/cascader/types.ts b/components/cascader/types.ts index 6b96cdef55..72f7b1f590 100644 --- a/components/cascader/types.ts +++ b/components/cascader/types.ts @@ -99,10 +99,26 @@ export interface CascaderMenuProps extends CommonProps, MenuProps { /** * @api Cascader + * @remarks + * Cascader 支持除 onSelect、value、onChange、defaultValue、focusedKey、onItemFocus、focusable、isSelectIconRight、onBlur 等和 Cascader 同名的属性透传给 Menu + * - + * Cascader supports passing through properties with the same names to Menu, such as onSelect, value, onChange, defaultValue, focusedKey, onItemFocus, focusable, isSelectIconRight, onBlur, etc. */ export interface CascaderProps extends Omit, - CommonProps { + CommonProps, + Omit< + MenuProps, + | 'value' + | 'onChange' + | 'onSelect' + | 'defaultValue' + | 'focusedKey' + | 'onItemFocus' + | 'focusable' + | 'isSelectIconRight' + | 'onBlur' + > { /** * 数据源 * @en data source