Skip to content

Commit

Permalink
chore(Nav): improve by codereivew
Browse files Browse the repository at this point in the history
  • Loading branch information
fumo.ww authored and eternalsky committed Apr 9, 2024
1 parent 2073475 commit d40e007
Show file tree
Hide file tree
Showing 23 changed files with 241 additions and 262 deletions.
2 changes: 1 addition & 1 deletion components/menu/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export interface MenuProps extends HTMLAttributesWeak, CommonProps {
/**
* 初始选中菜单项的 key 值
*/
defaultSelectedKeys?: string | Array<any>;
defaultSelectedKeys?: string | Array<any> | null;

/**
* 选中或取消选中菜单项触发的回调函数
Expand Down
22 changes: 22 additions & 0 deletions components/nav/__docs__/adaptor/createContents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import { Nav } from '@alifd/next';
import { createMenuItem } from './createMenuItem';
import type { DataSourceOption } from './types';

export function createContents(array: DataSourceOption[] = []) {
return array.map(item => {
if (item.type === 'group' && item.children && item.children.length > 0) {
return (
<Nav.Group key={item.key} label={item.value}>
{item.children.map(it => createMenuItem(it))}
</Nav.Group>
);
}

if (item.type === 'divider') {
return <Nav.Divider key={item.key} />;
}

return createMenuItem(item);
});
}
43 changes: 43 additions & 0 deletions components/nav/__docs__/adaptor/createMenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import { Nav } from '@alifd/next';
import { ContentType } from '@alifd/adaptor-helper';
import { createContents } from './createContents';
import type { DataSourceOption } from './types';

export function createMenuItem(item: DataSourceOption) {
const { value } =
((Array.isArray(item.value) && item.value) || []).find(
item => item && typeof item === 'object' && item.type === ContentType.icon
) || {};
if (item.children && item.children.length > 0) {
return (
// TODO SubNav 并不支持 disabled 属性 (disabled={item.state === 'disabled'})
<Nav.SubNav
key={item.key}
icon={value}
label={
Array.isArray(item.value)
? item.value
.filter(({ type }) => type === ContentType.text)
.map(({ value }) => value)
.join('')
: ''
}
>
{createContents(item.children)}
</Nav.SubNav>
);
}

return (
<Nav.Item
key={item.key}
icon={value}
className={item.state === 'hover' ? 'next-focused' : ''}
disabled={item.state === 'disabled'}
children={(Array.isArray(item.value) ? item.value : ([] as Record<string, any>[])).map(
({ type, value }) => (type === 'icon' ? null : value)
)}
/>
);
}
82 changes: 6 additions & 76 deletions components/nav/__docs__/adaptor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
/* eslint-disable */
import React from 'react';
import { Types, parseData, ContentType } from '@alifd/adaptor-helper';
import { Types, parseData } from '@alifd/adaptor-helper';
import { Nav } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';

type ValueType<T> = T extends keyof typeof ContentType
? { type: keyof typeof ContentType; value: string }[]
: boolean;

interface DataSourceOption {
type: 'node' | 'comment' | 'divider' | 'group' | ContentType.icon | ContentType.text;
key?: string;
value?: ValueType<DataSourceOption['type']>;
children?: DataSourceOption[];
state?: 'active' | 'hover' | 'disabled';
level?: number;
}
import type { NavProps } from '@alifd/next/es/nav';
import { createContents } from './createContents';
import type { DataSourceOption } from './types';

const createDataSource = (
list: DataSourceOption[],
Expand All @@ -32,11 +20,9 @@ const createDataSource = (
let index = 0;

list.forEach(item => {
const key = `${prefix || level}-${index++}`;
switch (item.type) {
// eslint-disable-next-line no-case-declarations
case 'node':
const key = `${prefix || level}-${index++}`;

if (item.children && item.children.length > 0) {
item.children = createDataSource(item.children, keys, level + 1, key);
}
Expand Down Expand Up @@ -108,62 +94,6 @@ const createDataSource = (
return array;
};

const createMenuItem = (item: DataSourceOption) => {
const { value } =
((Array.isArray(item.value) && item.value) || []).find(
item => item && typeof item === 'object' && item.type === ContentType.icon
) || {};
if (item.children && item.children.length > 0) {
return (
// TODO SubNav 并不支持 disabled 属性 (disabled={item.state === 'disabled'})
<Nav.SubNav
key={item.key}
icon={value}
label={
Array.isArray(item.value)
? item.value
.filter(({ type }) => type === ContentType.text)
.map(({ value }) => value)
.join('')
: ''
}
>
{createContents(item.children)}
</Nav.SubNav>
);
}

return (
<Nav.Item
key={item.key}
icon={value}
className={item.state === 'hover' ? 'next-focused' : ''}
disabled={item.state === 'disabled'}
children={(Array.isArray(item.value) ? item.value : ([] as Record<string, any>[])).map(
({ type, value }, index) => (type === 'icon' ? null : value)
)}
/>
);
};

function createContents(array: DataSourceOption[] = []) {
return array.map(item => {
if (item.type === 'group' && item.children && item.children.length > 0) {
return (
<Nav.Group key={item.key} label={item.value}>
{item.children.map(it => createMenuItem(it))}
</Nav.Group>
);
}

if (item.type === 'divider') {
return <Nav.Divider key={item.key} />;
}

return createMenuItem(item);
});
}

export default {
name: 'Nav',
shape: [
Expand Down Expand Up @@ -238,7 +168,7 @@ export default {
level: 'normal' | 'primary' | 'secondary' | 'line';
[key: string]: any;
}) => {
const list = parseData(data, { parseContent: true }) as unknown as DataSourceOption[];
const list = parseData(data, { parseContent: true }) as DataSourceOption[];
const keys = { selected: [], expanded: [] };
const dataSource = createDataSource(list, keys);

Expand Down
20 changes: 20 additions & 0 deletions components/nav/__docs__/adaptor/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { ContentType } from '@alifd/adaptor-helper';

type ValueType<T> = T extends keyof typeof ContentType
? { type: keyof typeof ContentType; value: string }[]
: boolean;

export interface DataSourceOption {
type:
| 'node'
| 'comment'
| 'divider'
| 'group'
| typeof ContentType.icon
| typeof ContentType.text;
key?: string;
value?: ValueType<DataSourceOption['type']>;
children?: DataSourceOption[];
state?: 'active' | 'hover' | 'disabled';
level?: number;
}
2 changes: 1 addition & 1 deletion components/nav/__docs__/demo/custom/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';

type AppState = Pick<NavProps, 'type' | 'mode' | 'direction' | 'activeDirection' | 'triggerType'>;

Expand Down
7 changes: 0 additions & 7 deletions components/nav/__docs__/demo/fixed/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';

const header = <span className="fusion">FUSION</span>;
const footer = (
<a className="login-in" href="javascript:;">
Login in
</a>
);

ReactDOM.render(
<div>
请查看{' '}
Expand Down
2 changes: 1 addition & 1 deletion components/nav/__docs__/demo/icon-only/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';

type AppState = Pick<
NavProps,
Expand Down
2 changes: 1 addition & 1 deletion components/nav/__docs__/demo/open-mode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';

type AppState = Pick<NavProps, 'openMode'>;

Expand Down
2 changes: 1 addition & 1 deletion components/nav/__docs__/demo/popup-align/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';

type AppState = Pick<NavProps, 'popupAlign'>;
const { Item, SubNav } = Nav;
Expand Down
2 changes: 1 addition & 1 deletion components/nav/__docs__/demo/vertical-smart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Switch, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';

const { Item, SubNav } = Nav;

Expand Down
9 changes: 5 additions & 4 deletions components/nav/__docs__/demo/vertical/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Nav, Radio } from '@alifd/next';
import { NavProps } from '@alifd/next/es/nav';
import type { NavProps } from '@alifd/next/es/nav';
import type { GroupProps } from '@alifd/next/es/radio';

type AppState = Pick<NavProps, 'type'>;
const { Item, SubNav } = Nav;
Expand All @@ -11,11 +12,11 @@ class App extends React.Component {
type: 'normal',
};

changeType(type: AppState['type']) {
changeType: GroupProps['onChange'] = type => {
this.setState({
type,
});
}
};

render() {
const { type } = this.state;
Expand All @@ -27,7 +28,7 @@ class App extends React.Component {
shape="button"
size="medium"
value={type}
onChange={this.changeType.bind(this)}
onChange={this.changeType}
>
<Radio value="normal">type="normal"</Radio>
<Radio value="primary">type="primary"</Radio>
Expand Down
Loading

0 comments on commit d40e007

Please sign in to comment.