Skip to content

Commit

Permalink
refactor(Cascader): fix comments issue
Browse files Browse the repository at this point in the history
  • Loading branch information
eternalsky committed Feb 21, 2024
1 parent ea76e22 commit 8d4b270
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 77 deletions.
7 changes: 4 additions & 3 deletions components/cascader/__docs__/theme/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import '../../../demo-helper/style';
import '../../style';
import { Demo, DemoGroup, initDemo } from '../../../demo-helper';
import Cascader from '../../index';
import { CascaderDataItem } from '../../types';

const i18nMap = {
'en-us': {
Expand All @@ -14,8 +15,8 @@ const i18nMap = {
},
};

const createDataSource = (label, hasDisabled) => {
const dataSource = [
const createDataSource = (label: unknown, hasDisabled?: boolean) => {
const dataSource: CascaderDataItem[] = [
{
children: [
{
Expand Down Expand Up @@ -6080,7 +6081,7 @@ const createDataSource = (label, hasDisabled) => {
return dataSource;
};

function render(lang = 'en-us') {
function render(lang: keyof typeof i18nMap = 'en-us') {
const i18n = i18nMap[lang];
const dataSource = createDataSource(i18n.option);
const disabledDataSource = createDataSource(i18n.option, true);
Expand Down
139 changes: 77 additions & 62 deletions components/cascader/cascader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component, type ComponentType, type FocusEvent } from 'react';
import React, { Component, type ReactElement, type FocusEvent, type ComponentType } from 'react';
import PropTypes from 'prop-types';
import { polyfill } from 'react-lifecycles-compat';
import cloneDeep from 'lodash.clonedeep';
Expand Down Expand Up @@ -181,7 +181,7 @@ class Cascader extends Component<CascaderProps, CascaderState> {
immutable,
} = props;

const { v2n, p2n } = preHandleData(dataSource, immutable);
const { v2n, p2n } = preHandleData(dataSource!, immutable);

let normalizedValue = normalizeValue(typeof value === 'undefined' ? defaultValue : value);

Expand Down Expand Up @@ -222,7 +222,7 @@ class Cascader extends Component<CascaderProps, CascaderState> {
}

static getDerivedStateFromProps(props: CascaderProps, state: CascaderState) {
const { v2n, p2n } = preHandleData(props.dataSource, props.immutable);
const { v2n, p2n } = preHandleData(props.dataSource!, props.immutable);
const states = {} as CascaderState;

if ('value' in props) {
Expand Down Expand Up @@ -553,7 +553,7 @@ class Cascader extends Component<CascaderProps, CascaderState> {
const { dataSource, searchValue, filteredPaths } = this.props;

return !searchValue
? this.getFirstFocusKeyByDataSource(dataSource)
? this.getFirstFocusKeyByDataSource(dataSource!)
: this.getFirstFocusKeyByFilteredPaths(filteredPaths);
}

Expand Down Expand Up @@ -645,53 +645,64 @@ class Cascader extends Component<CascaderProps, CascaderState> {
onItemFocus={this.handleFocus}
onBlur={this.onBlur}
>
{data
.map(item => {
const disabled = !!item.disabled;
const canExpand =
(!!item.children && !!item.children.length) ||
(!!loadData && !item.isLeaf);
const expanded = expandedValue[level] === item.value;
const props: CascaderItemProps = {
prefix,
disabled,
canExpand,
expanded,
expandTriggerType,
onExpand: this.handleExpand.bind(this, item.value, level, canExpand),
onFold: this.handleFold,
};

if ('title' in item) {
props.title = item.title;
}
{
data!
.map(item => {
const disabled = !!item.disabled;
const canExpand =
(!!item.children && !!item.children.length) ||
(!!loadData && !item.isLeaf);
const expanded = expandedValue[level] === item.value;
const props: CascaderItemProps = {
prefix,
disabled,
canExpand,
expanded,
expandTriggerType,
onExpand: this.handleExpand.bind(
this,
item.value,
level,
canExpand
),
onFold: this.handleFold,
};

if ('title' in item) {
props.title = item.title;
}

if (multiple) {
props.checkable = !(canOnlyCheckLeaf && canExpand);
props.checked = value.indexOf(item.value) > -1 || !!item.checked;
props.indeterminate =
(checkStrictly || canOnlyCheckLeaf
? false
: this.indeterminate.indexOf(item.value) > -1) ||
!!item.indeterminate;
props.checkboxDisabled = !!item.checkboxDisabled;
props.onCheck = this.handleCheck.bind(this, item.value);
} else {
props.selected = value[0] === item.value;
props.onSelect = this.handleSelect.bind(this, item.value, canExpand);
}
if (multiple) {
props.checkable = !(canOnlyCheckLeaf && canExpand);
props.checked = value.indexOf(item.value) > -1 || !!item.checked;
props.indeterminate =
(checkStrictly || canOnlyCheckLeaf
? false
: this.indeterminate.indexOf(item.value) > -1) ||
!!item.indeterminate;
props.checkboxDisabled = !!item.checkboxDisabled;
props.onCheck = this.handleCheck.bind(this, item.value);
} else {
props.selected = value[0] === item.value;
props.onSelect = this.handleSelect.bind(
this,
item.value,
canExpand
);
}

const itemContent = itemRender!(item, props);
if (itemContent === null) {
return null;
}
return (
<CascaderMenuItem key={item.value} {...props}>
{itemContent}
</CascaderMenuItem>
);
})
.filter(v => v)}
const itemContent = itemRender!(item, props);
if (itemContent === null) {
return null;
}
return (
<CascaderMenuItem key={item.value} {...props}>
{itemContent}
</CascaderMenuItem>
);
})
.filter(v => v) as ReactElement[]
}
</CascaderMenu>
);
}
Expand Down Expand Up @@ -728,8 +739,8 @@ class Cascader extends Component<CascaderProps, CascaderState> {
const { value } = this.state;
const lastItem = path[path.length - 1];

let Item: ComponentType;
const props: CheckboxItemProps | ItemProps = {
let Item: ComponentType<CheckboxItemProps | ItemProps>;
let props: CheckboxItemProps | ItemProps = {
className: `${prefix}cascader-filtered-item`,
disabled: path.some(item => item.disabled),
children: resultRender!(searchValue!, path),
Expand All @@ -738,20 +749,24 @@ class Cascader extends Component<CascaderProps, CascaderState> {
if (multiple) {
Item = Menu.CheckboxItem;
const { checkStrictly, canOnlyCheckLeaf } = this.props;
(props as CheckboxItemProps).checked = value.indexOf(lastItem.value) > -1;
(props as CheckboxItemProps).indeterminate =
!checkStrictly &&
!canOnlyCheckLeaf &&
this.indeterminate.indexOf(lastItem.value) > -1;
(props as CheckboxItemProps).checkboxDisabled = lastItem.checkboxDisabled;
props.onChange = this.handleCheck.bind(this, lastItem.value);
props = {
...props,
checked: value.indexOf(lastItem.value) > -1,
indeterminate:
!checkStrictly &&
!canOnlyCheckLeaf &&
this.indeterminate.indexOf(lastItem.value) > -1,
checkboxDisabled: lastItem.checkboxDisabled,
onChange: this.handleCheck.bind(this, lastItem.value),
};
} else {
Item = Menu.Item;
// @ts-expect-error 这里的实现应该是有问题,只有 SelectableItem 才有 selected
(props as ItemProps).selected = value[0] === lastItem.value;
props.onSelect = this.handleSelect.bind(this, lastItem.value, false);
props = {
...props,
selected: value[0] === lastItem.value,
onSelect: this.handleSelect.bind(this, lastItem.value, false),
};
}

return <Item key={lastItem.value} {...props} />;
}

Expand Down
2 changes: 1 addition & 1 deletion components/cascader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ConfigProvider from '../config-provider';
import Cascader from './cascader';

export type { CascaderProps, CascaderDataItem, CascaderDataItemWithPosInfo } from './types';
export type { CascaderProps, CascaderDataItem, CascaderDataItemWithPosInfo, Extra } from './types';

export default ConfigProvider.config(Cascader, {
transform: (props, deprecated) => {
Expand Down
3 changes: 1 addition & 2 deletions components/cascader/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export default class CascaderMenuItem extends Component<ItemProps, ItemState> {
}
}

let Item: ComponentType, title;
let Item: ComponentType<CheckboxItemProps | MenuItemProps>, title;
if (checkable) {
Item = Menu.CheckboxItem;
(itemProps as CheckboxItemProps).checked = checked;
Expand All @@ -143,7 +143,6 @@ export default class CascaderMenuItem extends Component<ItemProps, ItemState> {
(itemProps as CheckboxItemProps).onChange = onCheck;
} else {
Item = Menu.Item;
// @ts-expect-error 这里的实现应该是有问题,只有 SelectableItem 才有 selected
itemProps.selected = selected;
itemProps.onSelect = onSelect;
}
Expand Down
4 changes: 1 addition & 3 deletions components/cascader/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import React, {
Component,
type ReactNode,
type LegacyRef,
type ReactElement,
type ReactNodeArray,
type ComponentElement,
JSXElementConstructor,
} from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
Expand Down Expand Up @@ -34,7 +32,7 @@ export default class CascaderMenu extends Component<CascaderMenuProps> {
if (!children || (children as ReactNodeArray).length === 0) {
return;
}
const selectedIndex = (children as Array<ReactElement>).findIndex(
const selectedIndex = children.findIndex(
item => !!item.props.checked || !!item.props.selected || !!item.props.expanded
);

Expand Down
13 changes: 7 additions & 6 deletions components/cascader/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { type ReactElement } from 'react';
import { CommonProps } from '../util';
import type { CheckboxItemProps, MenuProps, ItemProps as MenuItemProps } from '../menu';

Expand Down Expand Up @@ -38,9 +38,9 @@ export type NormalizeValueReturns<T> = T extends undefined | null
: [T];

/**
* @api extra
* @api Extra
*/
type extra = {
export type Extra = {
/**
* 单选时选中的数据的路径
*/
Expand Down Expand Up @@ -95,6 +95,7 @@ export interface ItemState {

export interface CascaderMenuProps extends CommonProps, MenuProps {
useVirtual?: boolean;
children: Array<ReactElement>;
}

/**
Expand All @@ -108,7 +109,7 @@ export interface CascaderProps
* @en data source
* @defaultValue []
*/
dataSource: Array<CascaderDataItem>;
dataSource?: Array<CascaderDataItem>;

/**
* (非受控)默认值
Expand All @@ -132,7 +133,7 @@ export interface CascaderProps
onChange?: (
value: string | Array<string>,
data: CascaderDataItem | Array<CascaderDataItem>,
extra: extra
extra: Extra
) => void;

/**
Expand All @@ -143,7 +144,7 @@ export interface CascaderProps
* @param data - 选中的数据,包括 value 和 label - selected data, including value and label
* @param extra - 额外参数 - extra parameters
*/
onSelect?: (v: string, data: CascaderDataItemWithPosInfo, extra: extra) => void;
onSelect?: (v: string, data: CascaderDataItemWithPosInfo, extra: Extra) => void;

/**
* (非受控)默认展开值
Expand Down
4 changes: 4 additions & 0 deletions components/menu/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface ItemProps extends React.HTMLAttributes<HTMLElement>, CommonProp
* 菜单项标签内容
*/
children?: React.ReactNode;
/**
* 是否选中
*/
selected?: boolean;
menu?: any;
}

Expand Down

0 comments on commit 8d4b270

Please sign in to comment.