Merge 4.0-prepare into feat-dark-palette

This commit is contained in:
ycjcl868 2019-12-20 16:38:33 +08:00
commit 6a96299010
25 changed files with 511 additions and 173 deletions

View File

@ -607,7 +607,26 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
class="ant-btn ant-btn-primary"
type="button"
>
poweroff
<span
aria-label="poweroff"
class="anticon anticon-poweroff"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="poweroff"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M705.6 124.9a8 8 0 00-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0162.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0127.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 01-76.3 113.3 353.06 353.06 0 01-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 01-113.2-76.4A355.92 355.92 0 01184 650.4a355 355 0 01-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
<span>
Click me!
</span>

View File

@ -15,6 +15,7 @@ A loading indicator can be added to a button by setting the `loading` property o
```jsx
import { Button } from 'antd';
import { PoweroffOutlined } from '@ant-design/icons';
class App extends React.Component {
state = {
@ -45,7 +46,7 @@ class App extends React.Component {
</Button>
<Button
type="primary"
icon="poweroff"
icon={<PoweroffOutlined />}
loading={this.state.iconLoading}
onClick={this.enterIconLoading}
>

View File

@ -986,7 +986,7 @@ exports[`Picker format by locale week 1`] = `
placeholder="请选择周"
readonly=""
size="12"
value="2000-52周"
value="1999-52周"
/>
<span
class="ant-picker-suffix"

View File

@ -160,7 +160,7 @@
&-dropdown {
.reset-component;
position: absolute;
z-index: @zindex-picker-panel;
z-index: @zindex-picker;
&-hidden {
display: none;

View File

@ -248,14 +248,14 @@
//select
.@{ant-prefix}-select {
&-selection {
.@{ant-prefix}-select-selector {
border-color: @warning-color;
&:hover {
border-color: @warning-color;
}
}
&-open .@{ant-prefix}-select-selection,
&-focused .@{ant-prefix}-select-selection {
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
.active(@warning-color);
}
}
@ -289,14 +289,14 @@
//select
.@{ant-prefix}-select {
&-selection {
.@{ant-prefix}-select-selector {
border-color: @error-color;
&:hover {
border-color: @error-color;
}
}
&-open .@{ant-prefix}-select-selection,
&-focused .@{ant-prefix}-select-selection {
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
.active(@error-color);
}
}
@ -308,7 +308,7 @@
}
.@{ant-prefix}-input-group-addon .@{ant-prefix}-select {
&-selection {
&-selector {
border-color: transparent;
box-shadow: none;
}

View File

@ -0,0 +1,36 @@
import * as React from 'react';
import omit from 'omit.js';
import classNames from 'classnames';
import Element, { SkeletonElementProps } from './Element';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
interface SkeletonInputProps extends Omit<SkeletonElementProps, 'size' | 'shape'> {
size?: 'large' | 'small' | 'default';
}
// eslint-disable-next-line react/prefer-stateless-function
class SkeletonInput extends React.Component<SkeletonInputProps, any> {
static defaultProps: Partial<SkeletonInputProps> = {
size: 'default',
};
renderSkeletonInput = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, className, active } = this.props;
const prefixCls = getPrefixCls('skeleton', customizePrefixCls);
const otherProps = omit(this.props, ['prefixCls']);
const cls = classNames(prefixCls, className, `${prefixCls}-element`, {
[`${prefixCls}-active`]: active,
});
return (
<div className={cls}>
<Element prefixCls={`${prefixCls}-input`} {...otherProps} />
</div>
);
};
render() {
return <ConfigConsumer>{this.renderSkeletonInput}</ConfigConsumer>;
}
}
export default SkeletonInput;

View File

@ -6,6 +6,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import SkeletonButton from './Button';
import Element from './Element';
import SkeletonAvatar, { AvatarProps } from './Avatar';
import SkeletonInput from './Input';
/* This only for skeleton internal. */
interface SkeletonAvatarProps extends Omit<AvatarProps, 'active'> {}
@ -72,6 +73,8 @@ class Skeleton extends React.Component<SkeletonProps, any> {
static Avatar: typeof SkeletonAvatar;
static Input: typeof SkeletonInput;
static defaultProps: Partial<SkeletonProps> = {
avatar: false,
title: true,

View File

@ -48,7 +48,60 @@ exports[`renders ./components/skeleton/demo/basic.md correctly 1`] = `
</div>
`;
exports[`renders ./components/skeleton/demo/button.md correctly 1`] = `
exports[`renders ./components/skeleton/demo/children.md correctly 1`] = `
<div
class="article"
>
<div>
<h4>
Ant Design, a design language
</h4>
<p>
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
</p>
</div>
<button
class="ant-btn"
type="button"
>
<span>
Show Skeleton
</span>
</button>
</div>
`;
exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = `
<div
class="ant-skeleton ant-skeleton-with-avatar"
>
<div
class="ant-skeleton-header"
>
<span
class="ant-skeleton-avatar ant-skeleton-avatar-lg ant-skeleton-avatar-circle"
/>
</div>
<div
class="ant-skeleton-content"
>
<h3
class="ant-skeleton-title"
style="width:50%"
/>
<ul
class="ant-skeleton-paragraph"
>
<li />
<li />
<li />
<li />
</ul>
</div>
</div>
`;
exports[`renders ./components/skeleton/demo/element.md correctly 1`] = `
<div>
<div>
<form
@ -460,58 +513,137 @@ exports[`renders ./components/skeleton/demo/button.md correctly 1`] = `
/>
</div>
</div>
</div>
`;
exports[`renders ./components/skeleton/demo/children.md correctly 1`] = `
<div
class="article"
>
<br />
<div>
<h4>
Ant Design, a design language
</h4>
<p>
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
</p>
</div>
<button
class="ant-btn"
type="button"
>
<span>
Show Skeleton
</span>
</button>
</div>
`;
exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = `
<div
class="ant-skeleton ant-skeleton-with-avatar"
>
<div
class="ant-skeleton-header"
>
<span
class="ant-skeleton-avatar ant-skeleton-avatar-lg ant-skeleton-avatar-circle"
/>
</div>
<div
class="ant-skeleton-content"
>
<h3
class="ant-skeleton-title"
style="width:50%"
/>
<ul
class="ant-skeleton-paragraph"
<form
class="ant-form ant-form-inline"
style="margin-bottom:16px"
>
<li />
<li />
<li />
<li />
</ul>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
title="InputActive"
>
InputActive
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<button
aria-checked="false"
class="ant-switch"
role="switch"
type="button"
>
<span
class="ant-switch-inner"
/>
</button>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
title="InputSize"
>
InputSize
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-radio-group ant-radio-group-outline"
>
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
>
<span
class="ant-radio-button ant-radio-button-checked"
>
<input
checked=""
class="ant-radio-button-input"
type="radio"
value="default"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Default
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="large"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Large
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="small"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Small
</span>
</label>
</div>
</div>
</div>
</div>
</form>
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input"
style="width:300px"
/>
</div>
</div>
</div>
`;

View File

@ -310,6 +310,46 @@ exports[`Skeleton button element size 3`] = `
</div>
`;
exports[`Skeleton input element active 1`] = `
<div
class="ant-skeleton ant-skeleton-element ant-skeleton-active"
>
<span
class="ant-skeleton-input"
/>
</div>
`;
exports[`Skeleton input element size 1`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input ant-skeleton-input-sm"
/>
</div>
`;
exports[`Skeleton input element size 2`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input"
/>
</div>
`;
exports[`Skeleton input element size 3`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input ant-skeleton-input-lg"
/>
</div>
`;
exports[`Skeleton paragraph rows 1`] = `
<div
class="ant-skeleton"

View File

@ -12,6 +12,7 @@ describe('Skeleton', () => {
);
const genSkeletonButton = props => mount(<Skeleton.Button {...props} />);
const genSkeletonAvatar = props => mount(<Skeleton.Avatar {...props} />);
const genSkeletonInput = props => mount(<Skeleton.Input {...props} />);
mountTest(Skeleton);
@ -112,4 +113,19 @@ describe('Skeleton', () => {
expect(wrapperSquare.render()).toMatchSnapshot();
});
});
describe('input element', () => {
it('active', () => {
const wrapper = genSkeletonInput({ active: true });
expect(wrapper.render()).toMatchSnapshot();
});
it('size', () => {
const wrapperSmall = genSkeletonInput({ size: 'small' });
expect(wrapperSmall.render()).toMatchSnapshot();
const wrapperDefault = genSkeletonInput({ size: 'default' });
expect(wrapperDefault.render()).toMatchSnapshot();
const wrapperLarge = genSkeletonInput({ size: 'large' });
expect(wrapperLarge.render()).toMatchSnapshot();
});
});
});

View File

@ -1,17 +1,17 @@
---
order: 2
title:
zh-CN: 骨架按钮和头像
zh-CN: 骨架按钮、头像和输入框。
en-US: Skeleton button and avatar
---
## zh-CN
骨架按钮和头像
骨架按钮、头像和输入框
## en-US
Skeleton button and avatar.
Skeleton button, avatar and input.
```jsx
import { Skeleton, Switch, Form, Radio } from 'antd';
@ -20,8 +20,10 @@ class Demo extends React.Component {
state = {
buttonActive: false,
avatarActive: false,
inputActive: false,
buttonSize: 'default',
avatarSize: 'default',
inputSize: 'default',
buttonShape: 'default',
avatarShape: 'circle',
};
@ -42,8 +44,10 @@ class Demo extends React.Component {
const {
buttonActive,
avatarActive,
inputActive,
buttonSize,
avatarSize,
inputSize,
buttonShape,
avatarShape,
} = this.state;
@ -93,6 +97,22 @@ class Demo extends React.Component {
</Form>
<Skeleton.Avatar active={avatarActive} size={avatarSize} shape={avatarShape} />
</div>
<br />
<div>
<Form layout="inline" style={{ marginBottom: 16 }}>
<Form.Item label="InputActive">
<Switch checked={inputActive} onChange={this.handleActiveChange('inputActive')} />
</Form.Item>
<Form.Item label="InputSize">
<Radio.Group value={inputSize} onChange={this.handleSizeChange('inputSize')}>
<Radio.Button value="default">Default</Radio.Button>
<Radio.Button value="large">Large</Radio.Button>
<Radio.Button value="small">Small</Radio.Button>
</Radio.Group>
</Form.Item>
</Form>
<Skeleton.Input style ={{width:'300px'}} active={inputActive} size={inputSize}/>
</div>
</div>
);
}

View File

@ -54,3 +54,10 @@ Provide a placeholder while you wait for content to load, or to visualise conten
| active | Show animation effect | boolean | false |
| size | Set the size of button | Enum{ 'large', 'small', 'default' } | - |
| shape | Set the shape of button | Enum{ 'circle', 'round', 'default' } | - |
### SkeletonInputProps
| Property | Description | Type | Default |
| -------- | ---------------------- | ----------------------------------- | ------- |
| active | Show animation effect | boolean | false |
| size | Set the size of button | Enum{ 'large', 'small', 'default' } | - |

View File

@ -1,9 +1,11 @@
import Skeleton from './Skeleton';
import SkeletonButton from './Button';
import SkeletonAvatar from './Avatar';
import SkeletonInput from './Input';
export { SkeletonProps } from './Skeleton';
Skeleton.Button = SkeletonButton;
Skeleton.Avatar = SkeletonAvatar;
Skeleton.Input = SkeletonInput;
export default Skeleton;

View File

@ -55,3 +55,10 @@ cols: 1
| active | 是否展示动画效果 | boolean | false |
| size | 设置按钮的大小 | Enum{ 'large', 'small', 'default' } | - |
| shape | 指定按钮的形状 | Enum{ 'circle', 'round', 'default' } | - |
### SkeletonInputProps
| 属性 | 说明 | 类型 | 默认值 |
| ------ | ---------------- | ----------------------------------- | ------ |
| active | 是否展示动画效果 | boolean | false |
| size | 设置按钮的大小 | Enum{ 'large', 'small', 'default' } | - |

View File

@ -6,6 +6,7 @@
@skeleton-title-prefix-cls: ~'@{skeleton-prefix-cls}-title';
@skeleton-paragraph-prefix-cls: ~'@{skeleton-prefix-cls}-paragraph';
@skeleton-button-prefix-cls: ~'@{skeleton-prefix-cls}-button';
@skeleton-input-prefix-cls: ~'@{skeleton-prefix-cls}-input';
.@{skeleton-prefix-cls} {
display: table;
@ -86,35 +87,45 @@
.@{skeleton-button-prefix-cls} {
.skeleton-color();
}
.@{skeleton-input-prefix-cls} {
.skeleton-color();
}
}
// Skeleton element
&-element {
display: inline-block;
// Button
.@{skeleton-button-prefix-cls} {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
border-radius: @border-radius-base;
.skeleton-element-button-size(@btn-height-base);
&-lg {
.skeleton-element-button-size(@btn-height-lg);
}
&-sm {
.skeleton-element-button-size(@btn-height-sm);
}
.skeleton-element-button();
}
.@{skeleton-avatar-prefix-cls} {
.skeleton-element-avatar();
}
.@{skeleton-input-prefix-cls} {
.skeleton-element-input();
}
}
}
// Button
.skeleton-element-button() {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
border-radius: @border-radius-base;
.skeleton-element-button-size(@btn-height-base);
&-lg {
.skeleton-element-button-size(@btn-height-lg);
}
&-sm {
.skeleton-element-button-size(@btn-height-sm);
}
}
// Avatar
.skeleton-element-avatar() {
display: inline-block;
@ -132,6 +143,23 @@
}
}
// Input
.skeleton-element-input() {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
.skeleton-element-input-size(@input-height-base);
&-lg {
.skeleton-element-input-size(@input-height-lg);
}
&-sm {
.skeleton-element-input-size(@input-height-sm);
}
}
.skeleton-element-avatar-size(@size) {
width: @size;
.skeleton-element-common-size(@size);
@ -155,6 +183,11 @@
}
}
.skeleton-element-input-size(@size) {
width: 100%;
.skeleton-element-common-size(@size);
}
.skeleton-element-common-size(@size) {
height: @size;
line-height: @size;

View File

@ -7,6 +7,7 @@
@dropdown-prefix-cls: ~'@{ant-prefix}-dropdown';
@table-header-icon-color: #bfbfbf;
@table-header-icon-color-hover: darken(@table-header-icon-color, 10%);
@table-header-sort-active-filter-bg: lighten(@table-header-sort-active-bg, 2%);
@table-selection-column-width: 60px;
@ -159,6 +160,10 @@
&:hover {
background: @table-header-sort-active-bg;
.@{table-prefix-cls}-filter-trigger-container {
background: @table-header-sort-active-filter-bg;
}
}
}
@ -226,10 +231,12 @@
flex: none;
align-items: stretch;
align-self: stretch;
cursor: pointer;
transition: background-color 0.3s;
&-open,
&:hover {
&:hover,
thead th.@{table-prefix-cls}-column-has-sorters:hover &:hover {
background: @table-header-filter-active-bg;
}
}

View File

@ -1,5 +1,5 @@
---
order: 1
order: 7
title: V3 to V4
---

View File

@ -1,5 +1,5 @@
---
order: 1
order: 7
title: 从 v3 到 v4
---

View File

@ -165,7 +165,7 @@
"antd-theme-generator": "^1.1.6",
"babel-eslint": "^10.0.1",
"babel-plugin-add-react-displayname": "^0.0.5",
"bisheng": "^1.3.3",
"bisheng": "~1.3.3",
"bisheng-plugin-antd": "^1.3.1",
"bisheng-plugin-description": "^0.1.4",
"bisheng-plugin-react": "^1.1.0",

View File

@ -3,8 +3,7 @@ module.exports = {
messages: {
'app.header.search': 'Search...',
'app.header.menu.home': 'Home',
'app.header.menu.practice': 'Practice',
'app.header.menu.pattern': 'Patterns',
'app.header.menu.documentation': 'Documentation',
'app.header.menu.components': 'Components',
'app.header.menu.spec': 'Guidelines',
'app.header.menu.resource': 'Resources',

View File

@ -38,6 +38,7 @@ a {
z-index: 1;
&-inner {
height: 100%;
max-height: 100vh;
overflow-x: hidden;
overflow-y: hidden;
@ -46,22 +47,56 @@ a {
&:hover &-inner {
overflow-y: auto;
}
> div,
> div > div {
height: 100%;
}
}
.aside-container {
height: 100%;
padding-bottom: 48px;
font-family: Avenir, @font-family, sans-serif;
&.ant-menu-inline .ant-menu-submenu-title h4,
&.ant-menu-inline > .ant-menu-item,
&.ant-menu-inline .ant-menu-item a {
overflow: hidden;
font-size: 14px;
text-overflow: ellipsis;
}
&.ant-menu-inline {
.ant-menu-submenu-title h4,
> .ant-menu-item,
.ant-menu-item a {
overflow: hidden;
font-weight: 500;
font-size: 14px;
text-overflow: ellipsis;
}
&.ant-menu-inline .ant-menu-item-group-title {
padding-left: 56px;
.ant-menu-item-group-title {
margin-top: 16px;
margin-bottom: 16px;
font-size: 13px;
&::after {
position: relative;
top: 12px;
display: block;
width: calc(100% - 20px);
height: 1px;
background: @border-color-split;
content: '';
}
}
> .ant-menu-item,
> .ant-menu-submenu > .ant-menu-submenu-title,
> .ant-menu-item-group > .ant-menu-item-group-title,
> .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item {
padding-left: 40px !important;
}
.ant-menu-item-group:first-child {
.ant-menu-item-group-title {
margin-top: 0;
}
}
}
a[disabled] {
@ -112,12 +147,6 @@ a {
.ant-menu-item > a:hover {
color: @primary-color;
}
.menu-antd-components-count {
margin-left: 0.5em;
color: @disabled-color;
font-size: 12px;
}
}
#react-content {

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'bisheng/router';
import { Row, Col, Menu, Affix, Button } from 'antd';
import { FormattedMessage, injectIntl } from 'react-intl';
import { injectIntl } from 'react-intl';
import classNames from 'classnames';
import get from 'lodash/get';
import MobileMenu from 'rc-drawer';
@ -25,15 +25,18 @@ function getModuleData(props) {
.filter(item => item)
.slice(0, 2)
.join('/');
const moduleData =
moduleName === 'components' ||
moduleName === 'docs/react' ||
moduleName === 'changelog' ||
moduleName === 'changelog-cn'
? [...props.picked.components, ...props.picked['docs/react'], ...props.picked.changelog]
: props.picked[moduleName];
const excludedSuffix = utils.isZhCN(props.location.pathname) ? 'en-US.md' : 'zh-CN.md';
return moduleData.filter(({ meta }) => !meta.filename.endsWith(excludedSuffix));
let data;
switch (moduleName) {
case 'docs/react':
case 'changelog':
case 'changelog-cn':
data = [...props.picked['docs/react'], ...props.picked.changelog];
break;
default:
data = props.picked[moduleName];
}
return data.filter(({ meta }) => !meta.filename.endsWith(excludedSuffix));
}
function fileNameToPath(filename) {
@ -52,24 +55,6 @@ const getSideBarOpenKeys = nextProps => {
return shouldOpenKeys;
};
const getSubMenuTitle = menuItem => {
if (menuItem.title !== 'Components') {
return menuItem.title;
}
let count = 0;
menuItem.children.forEach(item => {
if (item.children) {
count += item.children.length;
}
});
return (
<h4>
<FormattedMessage id="app.header.menu.components" />
<span className="menu-antd-components-count">{count}</span>
</h4>
);
};
class MainContent extends Component {
static contextTypes = {
isMobile: PropTypes.bool.isRequired,
@ -130,21 +115,19 @@ class MainContent extends Component {
themeConfig.typeOrder,
);
return menuItems.map(menuItem => {
if (menuItem.type === 'type') {
return (
<Menu.ItemGroup title={menuItem.title} key={menuItem.title}>
{menuItem.children
.sort((a, b) => a.title.charCodeAt(0) - b.title.charCodeAt(0))
.map(leaf => this.generateMenuItem(false, leaf, footerNavIcons))}
</Menu.ItemGroup>
);
}
if (menuItem.children) {
return (
<SubMenu title={getSubMenuTitle(menuItem)} key={menuItem.title}>
{menuItem.children.map(child => {
if (child.type === 'type') {
return (
<Menu.ItemGroup title={child.title} key={child.title}>
{child.children
.sort((a, b) => a.title.charCodeAt(0) - b.title.charCodeAt(0))
.map(leaf => this.generateMenuItem(false, leaf, footerNavIcons))}
</Menu.ItemGroup>
);
}
return this.generateMenuItem(false, child, footerNavIcons);
})}
<SubMenu title={menuItem.title} key={menuItem.title}>
{menuItem.children.map(child => this.generateMenuItem(false, child, footerNavIcons))}
</SubMenu>
);
}
@ -305,7 +288,7 @@ class MainContent extends Component {
});
const menuChild = (
<Menu
inlineIndent={40}
inlineIndent={30}
className="aside-container menu-site"
mode="inline"
openKeys={openKeys}

View File

@ -127,7 +127,7 @@ class Header extends React.Component {
.slice(0, -1)
.join('/');
let activeMenuItem = module || 'home';
if (activeMenuItem === 'components' || location.pathname === 'changelog') {
if (location.pathname === 'changelog') {
activeMenuItem = 'docs/react';
}
const isZhCN = locale === 'zh-CN';
@ -176,6 +176,11 @@ class Header extends React.Component {
</Menu.Item>
<Menu.Item key="docs/react">
<Link to={utils.getLocalizedPathname('/docs/react/introduce', isZhCN)}>
<FormattedMessage id="app.header.menu.documentation" />
</Link>
</Menu.Item>
<Menu.Item key="components">
<Link to={utils.getLocalizedPathname('/components/button/', isZhCN)}>
<FormattedMessage id="app.header.menu.components" />
</Link>
</Menu.Item>

View File

@ -9,34 +9,34 @@ export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
menuMeta.sort(sortFn).forEach(meta => {
if (!meta.category) {
menuItems.push(meta);
} else {
const category = meta.category[locale] || meta.category;
let group = menuItems.filter(i => i.title === category)[0];
if (!group) {
group = {
type: 'category',
title: category,
children: [],
order: categoryOrder[category],
};
menuItems.push(group);
}
if (meta.type) {
let type = group.children.filter(i => i.title === meta.type)[0];
if (!type) {
type = {
type: 'type',
title: meta.type,
children: [],
order: typeOrder[meta.type],
};
group.children.push(type);
}
type.children.push(meta);
} else {
group.children.push(meta);
}
return;
}
if (meta.category === 'Components' && meta.type) {
let type = menuItems.find(i => i.title === meta.type);
if (!type) {
type = {
type: 'type',
title: meta.type,
children: [],
order: typeOrder[meta.type],
};
menuItems.push(type);
}
type.children.push(meta);
return;
}
const category = meta.category[locale] || meta.category;
let group = menuItems.find(i => i.title === category);
if (!group) {
group = {
type: 'category',
title: category,
children: [],
order: categoryOrder[category],
};
menuItems.push(group);
}
group.children.push(meta);
});
return menuItems
.map(i => {

View File

@ -3,10 +3,9 @@ module.exports = {
messages: {
'app.header.search': '全文本搜索...',
'app.header.menu.home': '首页',
'app.header.menu.practice': '实践',
'app.header.menu.pattern': '模式',
'app.header.menu.documentation': '文档',
'app.header.menu.components': '组件',
'app.header.menu.spec': '设计语言',
'app.header.menu.spec': '设计',
'app.header.menu.resource': '资源',
'app.header.menu.mobile': '移动版',
'app.header.menu.pro.v4': 'Ant Design Pro v4',