mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-19 06:43:16 +08:00
Merge pull request #18161 from ant-design/migrate-react-intl
refactor: Migrate to react-intl@3
This commit is contained in:
commit
e4fb528cd5
@ -97,7 +97,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/colors": "^3.1.0",
|
||||
"@ant-design/tools": "^8.0.0",
|
||||
"@ant-design/tools": "^8.0.4",
|
||||
"@packtracker/webpack-plugin": "^2.0.1",
|
||||
"@sentry/browser": "^5.4.0",
|
||||
"@types/classnames": "^2.2.8",
|
||||
@ -168,7 +168,7 @@
|
||||
"react-github-button": "^0.1.11",
|
||||
"react-highlight-words": "^0.16.0",
|
||||
"react-infinite-scroller": "^1.2.4",
|
||||
"react-intl": "^2.9.0",
|
||||
"react-intl": "^3.1.1",
|
||||
"react-resizable": "^1.8.0",
|
||||
"react-router": "^3.2.3",
|
||||
"react-router-dom": "^5.0.1",
|
||||
@ -214,7 +214,7 @@
|
||||
"tsc": "tsc",
|
||||
"start": "rimraf _site && mkdir _site && node ./scripts/generateColorLess.js && cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js",
|
||||
"start:preact": "node ./scripts/generateColorLess.js && cross-env NODE_ENV=development REACT_ENV=preact bisheng start -c ./site/bisheng.config.js",
|
||||
"site": "cross-env NODE_ENV=production bisheng build --ssr -c ./site/bisheng.config.js && node ./scripts/generateColorLess.js",
|
||||
"site": "bisheng build --ssr -c ./site/bisheng.config.js && node ./scripts/generateColorLess.js",
|
||||
"predeploy": "antd-tools run clean && npm run site && cp netlify.toml CNAME _site && cp .circleci/config.yml _site",
|
||||
"deploy": "bisheng gh-pages --push-only",
|
||||
"deploy:china-mirror": "git checkout gh-pages && git pull origin gh-pages && git push git@gitee.com:ant-design/ant-design.git gh-pages",
|
||||
@ -242,4 +242,4 @@
|
||||
"> 1%",
|
||||
"ie >= 9"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,12 @@ module.exports = {
|
||||
|
||||
alertBabelConfig(config.module.rules);
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.mjs$/,
|
||||
include: /node_modules/,
|
||||
type: 'javascript/auto',
|
||||
});
|
||||
|
||||
config.plugins.push(new CSSSplitWebpackPlugin({ size: 4000 }));
|
||||
|
||||
return config;
|
||||
|
@ -1,8 +1,5 @@
|
||||
const appLocaleData = require('react-intl/locale-data/en');
|
||||
|
||||
module.exports = {
|
||||
locale: 'en-US',
|
||||
data: appLocaleData,
|
||||
messages: {
|
||||
'app.header.search': 'Search...',
|
||||
'app.header.menu.home': 'Home',
|
||||
|
@ -2,7 +2,6 @@ const path = require('path');
|
||||
|
||||
const homeTmpl = './template/Home/index';
|
||||
const contentTmpl = './template/Content/index';
|
||||
const redirectTmpl = './template/Redirect';
|
||||
const appShellTmpl = './template/AppShell';
|
||||
|
||||
function pickerGenerator(module) {
|
||||
@ -43,9 +42,7 @@ module.exports = {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
'docs/pattern': pickerGenerator('pattern'),
|
||||
'docs/react': pickerGenerator('react'),
|
||||
'docs/resource': pickerGenerator('resource'),
|
||||
'docs/spec': pickerGenerator('spec'),
|
||||
},
|
||||
plugins: [
|
||||
@ -67,10 +64,6 @@ module.exports = {
|
||||
path: 'index-cn',
|
||||
component: homeTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/pattern/:children',
|
||||
component: redirectTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/react/:children',
|
||||
component: contentTmpl,
|
||||
@ -87,22 +80,10 @@ module.exports = {
|
||||
path: 'components/:children/',
|
||||
component: contentTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/spec/feature',
|
||||
component: redirectTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/spec/feature-cn',
|
||||
component: redirectTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/spec/:children',
|
||||
component: contentTmpl,
|
||||
},
|
||||
{
|
||||
path: 'docs/resource/:children',
|
||||
component: redirectTmpl,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -23,7 +23,7 @@
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet/less" type="text/css" href="{{ root }}color.less" />
|
||||
<script src="https://polyfill.alicdn.com/polyfill.min.js?features=default,es2015,matchMedia"></script>
|
||||
<script src="https://polyfill.alicdn.com/polyfill.min.js?features=default,es2015,matchMedia,Intl"></script>
|
||||
<script>
|
||||
(function() {
|
||||
function isLocalStorageNameSupported() {
|
||||
|
@ -1,16 +1,11 @@
|
||||
import React, { Children, cloneElement } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import DocumentTitle from 'react-document-title';
|
||||
import { getChildren } from 'jsonml.js/lib/utils';
|
||||
import { Timeline, Alert, Affix } from 'antd';
|
||||
import EditButton from './EditButton';
|
||||
|
||||
export default class Article extends React.Component {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
class Article extends React.Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { location } = this.props;
|
||||
const { location: nextLocation } = nextProps;
|
||||
@ -69,13 +64,9 @@ export default class Article extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
const { content } = props;
|
||||
const { content, intl: { locale }, utils } = this.props;
|
||||
const { meta, description } = content;
|
||||
const { title, subtitle, filename } = meta;
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const isNotTranslated = locale === 'en-US' && typeof title === 'object';
|
||||
return (
|
||||
<DocumentTitle title={`${title[locale] || title} - Ant Design`}>
|
||||
@ -104,22 +95,22 @@ export default class Article extends React.Component {
|
||||
</h1>
|
||||
{!description
|
||||
? null
|
||||
: props.utils.toReactComponent(
|
||||
: utils.toReactComponent(
|
||||
['section', { className: 'markdown' }].concat(getChildren(description)),
|
||||
)}
|
||||
{!content.toc || content.toc.length <= 1 || meta.toc === false ? null : (
|
||||
<Affix className="toc-affix" offsetTop={16}>
|
||||
{props.utils.toReactComponent(
|
||||
{utils.toReactComponent(
|
||||
['ul', { className: 'toc' }].concat(getChildren(content.toc)),
|
||||
)}
|
||||
</Affix>
|
||||
)}
|
||||
{this.getArticle(
|
||||
props.utils.toReactComponent(
|
||||
utils.toReactComponent(
|
||||
['section', { className: 'markdown' }].concat(getChildren(content.content)),
|
||||
),
|
||||
)}
|
||||
{props.utils.toReactComponent(
|
||||
{utils.toReactComponent(
|
||||
[
|
||||
'section',
|
||||
{
|
||||
@ -132,3 +123,5 @@ export default class Article extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(Article);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import DocumentTitle from 'react-document-title';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { Row, Col, Icon, Affix, Tooltip } from 'antd';
|
||||
import { getChildren } from 'jsonml.js/lib/utils';
|
||||
@ -9,11 +8,7 @@ import Demo from './Demo';
|
||||
import EditButton from './EditButton';
|
||||
import { ping } from '../utils';
|
||||
|
||||
export default class ComponentDoc extends React.Component {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object,
|
||||
};
|
||||
|
||||
class ComponentDoc extends React.Component {
|
||||
state = {
|
||||
expandAll: false,
|
||||
showRiddleButton: false,
|
||||
@ -57,21 +52,17 @@ export default class ComponentDoc extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
const { doc, location } = props;
|
||||
const { doc, location, intl: { locale }, utils, demos } = this.props;
|
||||
const { content, meta } = doc;
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const demos = Object.keys(props.demos).map(key => props.demos[key]);
|
||||
const demoValues = Object.keys(demos).map(key => demos[key]);
|
||||
const { expandAll, showRiddleButton } = this.state;
|
||||
|
||||
const isSingleCol = meta.cols === 1;
|
||||
const leftChildren = [];
|
||||
const rightChildren = [];
|
||||
const showedDemo = demos.some(demo => demo.meta.only)
|
||||
? demos.filter(demo => demo.meta.only)
|
||||
: demos.filter(demo => demo.preview);
|
||||
const showedDemo = demoValues.some(demo => demo.meta.only)
|
||||
? demoValues.filter(demo => demo.meta.only)
|
||||
: demoValues.filter(demo => demo.preview);
|
||||
showedDemo
|
||||
.sort((a, b) => a.meta.order - b.meta.order)
|
||||
.forEach((demoData, index) => {
|
||||
@ -79,7 +70,7 @@ export default class ComponentDoc extends React.Component {
|
||||
<Demo
|
||||
{...demoData}
|
||||
key={demoData.meta.filename}
|
||||
utils={props.utils}
|
||||
utils={utils}
|
||||
expand={expandAll}
|
||||
location={location}
|
||||
/>
|
||||
@ -126,7 +117,7 @@ export default class ComponentDoc extends React.Component {
|
||||
filename={filename}
|
||||
/>
|
||||
</h1>
|
||||
{props.utils.toReactComponent(
|
||||
{utils.toReactComponent(
|
||||
['section', { className: 'markdown' }].concat(getChildren(content)),
|
||||
)}
|
||||
<h2>
|
||||
@ -159,7 +150,7 @@ export default class ComponentDoc extends React.Component {
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
{props.utils.toReactComponent(
|
||||
{utils.toReactComponent(
|
||||
[
|
||||
'section',
|
||||
{
|
||||
@ -172,3 +163,5 @@ export default class ComponentDoc extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(ComponentDoc);
|
||||
|
@ -1,8 +1,7 @@
|
||||
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import classNames from 'classnames';
|
||||
import LZString from 'lz-string';
|
||||
@ -18,11 +17,7 @@ function compress(string) {
|
||||
.replace(/=+$/, ''); // Remove ending '='
|
||||
}
|
||||
|
||||
export default class Demo extends React.Component {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object,
|
||||
};
|
||||
|
||||
class Demo extends React.Component {
|
||||
state = {
|
||||
codeExpand: false,
|
||||
copied: false,
|
||||
@ -102,10 +97,11 @@ export default class Demo extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { state } = this;
|
||||
const { props } = this;
|
||||
const { meta, src, content, preview, highlightedCode, style, highlightedStyle, expand } = props;
|
||||
const { copied } = state;
|
||||
const {
|
||||
meta, src, content, preview, highlightedCode, style,
|
||||
highlightedStyle, expand, utils, intl: { locale },
|
||||
} = this.props;
|
||||
const { copied, copyTooltipVisible } = this.state;
|
||||
if (!this.liveDemo) {
|
||||
this.liveDemo = meta.iframe ? (
|
||||
<BrowserFrame>
|
||||
@ -115,17 +111,14 @@ export default class Demo extends React.Component {
|
||||
preview(React, ReactDOM)
|
||||
);
|
||||
}
|
||||
const codeExpand = state.codeExpand || expand;
|
||||
const codeExpand = this.state.codeExpand || expand;
|
||||
const codeBoxClass = classNames('code-box', {
|
||||
expand: codeExpand,
|
||||
'code-box-debug': meta.debug,
|
||||
});
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const localizedTitle = meta.title[locale] || meta.title;
|
||||
const localizeIntro = content[locale] || content;
|
||||
const introChildren = props.utils.toReactComponent(['div'].concat(localizeIntro));
|
||||
const introChildren = utils.toReactComponent(['div'].concat(localizeIntro));
|
||||
|
||||
const highlightClass = classNames({
|
||||
'highlight-wrapper': true,
|
||||
@ -285,12 +278,12 @@ ${sourceCode.replace('mountNode', "document.getElementById('container')")}
|
||||
</form>
|
||||
<CopyToClipboard text={sourceCode} onCopy={() => this.handleCodeCopied(meta.id)}>
|
||||
<Tooltip
|
||||
visible={state.copyTooltipVisible}
|
||||
visible={copyTooltipVisible}
|
||||
onVisibleChange={this.onCopyTooltipVisibleChange}
|
||||
title={<FormattedMessage id={`app.demo.${copied ? 'copied' : 'copy'}`} />}
|
||||
>
|
||||
<Icon
|
||||
type={state.copied && state.copyTooltipVisible ? 'check' : 'snippets'}
|
||||
type={copied && copyTooltipVisible ? 'check' : 'snippets'}
|
||||
className="code-box-code-copy"
|
||||
/>
|
||||
</Tooltip>
|
||||
@ -316,7 +309,7 @@ ${sourceCode.replace('mountNode', "document.getElementById('container')")}
|
||||
</div>
|
||||
</section>
|
||||
<section className={highlightClass} key="code">
|
||||
<div className="highlight">{props.utils.toReactComponent(highlightedCode)}</div>
|
||||
<div className="highlight">{utils.toReactComponent(highlightedCode)}</div>
|
||||
{highlightedStyle ? (
|
||||
<div key="style" className="highlight">
|
||||
<pre>
|
||||
@ -329,3 +322,5 @@ ${sourceCode.replace('mountNode', "document.getElementById('container')")}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(Demo);
|
||||
|
@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'bisheng/router';
|
||||
import { Row, Col, Menu, Icon, Affix } from 'antd';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import get from 'lodash/get';
|
||||
import MobileMenu from 'rc-drawer';
|
||||
@ -14,13 +14,6 @@ import * as utils from '../utils';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
|
||||
function getActiveMenuItem(props) {
|
||||
const { children } = props.params;
|
||||
return (
|
||||
(children && children.replace('-cn', '')) || props.location.pathname.replace(/(^\/|-cn$)/g, '')
|
||||
);
|
||||
}
|
||||
|
||||
function getModuleData(props) {
|
||||
const { pathname } = props.location;
|
||||
const moduleName = /^\/?components/.test(pathname)
|
||||
@ -69,19 +62,14 @@ const getSubMenuTitle = menuItem => {
|
||||
});
|
||||
return (
|
||||
<h4>
|
||||
{menuItem.title === 'Components' ? (
|
||||
<FormattedMessage id="app.header.menu.components" />
|
||||
) : (
|
||||
menuItem.title
|
||||
)}
|
||||
<FormattedMessage id="app.header.menu.components" />
|
||||
<span className="menu-antd-components-count">{count}</span>
|
||||
</h4>
|
||||
);
|
||||
};
|
||||
|
||||
export default class MainContent extends Component {
|
||||
class MainContent extends Component {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
isMobile: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
@ -126,10 +114,7 @@ export default class MainContent extends Component {
|
||||
}
|
||||
|
||||
getMenuItems(footerNavIcons = {}) {
|
||||
const { themeConfig } = this.props;
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const { themeConfig, intl: { locale } } = this.props;
|
||||
const moduleData = getModuleData(this.props);
|
||||
const menuItems = utils.getMenuItems(
|
||||
moduleData,
|
||||
@ -173,6 +158,13 @@ export default class MainContent extends Component {
|
||||
return { prev, next };
|
||||
}
|
||||
|
||||
getActiveMenuItem() {
|
||||
const { params: { children }, location } = this.props;
|
||||
return (
|
||||
(children && children.replace('-cn', '')) || location.pathname.replace(/(^\/|-cn$)/g, '')
|
||||
);
|
||||
}
|
||||
|
||||
handleMenuOpenChange = openKeys => {
|
||||
this.setState({ openKeys });
|
||||
};
|
||||
@ -195,6 +187,9 @@ export default class MainContent extends Component {
|
||||
if (this.scroller) {
|
||||
this.scroller.destroy();
|
||||
}
|
||||
if (!document.querySelector('.markdown > h2, .code-box')) {
|
||||
return;
|
||||
}
|
||||
require('intersection-observer'); // eslint-disable-line
|
||||
const scrollama = require('scrollama'); // eslint-disable-line
|
||||
this.scroller = scrollama();
|
||||
@ -217,7 +212,7 @@ export default class MainContent extends Component {
|
||||
generateMenuItem(isTop, item, { before = null, after = null }) {
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
} = this.props;
|
||||
const key = fileNameToPath(item.filename);
|
||||
if (!item.title) {
|
||||
return null;
|
||||
@ -280,19 +275,18 @@ export default class MainContent extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
const { isMobile } = this.context;
|
||||
const { openKeys } = this.state;
|
||||
const activeMenuItem = getActiveMenuItem(props);
|
||||
const { localizedPageData, demos } = this.props;
|
||||
const activeMenuItem = this.getActiveMenuItem();
|
||||
const menuItems = this.getMenuItems();
|
||||
const menuItemsForFooterNav = this.getMenuItems({
|
||||
before: <Icon className="footer-nav-icon-before" type="left" />,
|
||||
after: <Icon className="footer-nav-icon-after" type="right" />,
|
||||
});
|
||||
const { prev, next } = this.getFooterNav(menuItemsForFooterNav, activeMenuItem);
|
||||
const { localizedPageData } = props;
|
||||
const mainContainerClass = classNames('main-container', {
|
||||
'main-container-component': !!props.demos,
|
||||
'main-container-component': !!demos,
|
||||
});
|
||||
const menuChild = (
|
||||
<Menu
|
||||
@ -329,10 +323,10 @@ export default class MainContent extends Component {
|
||||
)}
|
||||
<Col xxl={20} xl={19} lg={18} md={24} sm={24} xs={24}>
|
||||
<section className={mainContainerClass}>
|
||||
{props.demos ? (
|
||||
<ComponentDoc {...props} doc={localizedPageData} demos={props.demos} />
|
||||
{demos ? (
|
||||
<ComponentDoc {...this.props} doc={localizedPageData} demos={demos} />
|
||||
) : (
|
||||
<Article {...props} content={localizedPageData} />
|
||||
<Article {...this.props} content={localizedPageData} />
|
||||
)}
|
||||
</section>
|
||||
<PrevAndNext prev={prev} next={next} />
|
||||
@ -343,3 +337,5 @@ export default class MainContent extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(MainContent);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import TweenOne from 'rc-tween-one';
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
import ScrollParallax from 'rc-scroll-anim/lib/ScrollParallax';
|
||||
import { Link } from 'bisheng/router';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
import GitHubButton from 'react-github-button';
|
||||
import { Button } from 'antd';
|
||||
import BannerImage from './BannerImage';
|
||||
@ -16,96 +15,79 @@ const loop = {
|
||||
repeat: -1,
|
||||
};
|
||||
|
||||
class Banner extends React.PureComponent {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
className: 'banner',
|
||||
};
|
||||
|
||||
render() {
|
||||
const { className, isMobile } = this.props;
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const isZhCN = locale === 'zh-CN';
|
||||
return (
|
||||
<div className="home-page-wrapper banner-wrapper" id="banner">
|
||||
<div className="banner-bg-wrapper">
|
||||
<svg width="400px" height="576px" viewBox="0 0 400 576" fill="none">
|
||||
<TweenOne component="g" animation={[{ opacity: 0, type: 'from' }, { ...loop, y: 15 }]}>
|
||||
<ellipse cx="100" cy="100" rx="6" ry="6" stroke="#2F54EB" strokeWidth="1.6" />
|
||||
</TweenOne>
|
||||
<TweenOne component="g" animation={[{ opacity: 0, type: 'from' }, { ...loop, y: -15 }]}>
|
||||
<g transform="translate(200 450)">
|
||||
<g style={{ transformOrigin: '50% 50%', transform: 'rotate(-340deg)' }}>
|
||||
<rect stroke="#FADB14" strokeWidth="1.6" width="9" height="9" />
|
||||
</g>
|
||||
const Banner = ({ isMobile }) => {
|
||||
const { locale } = useIntl();
|
||||
const isZhCN = locale === 'zh-CN';
|
||||
return (
|
||||
<div className="home-page-wrapper banner-wrapper" id="banner">
|
||||
<div className="banner-bg-wrapper">
|
||||
<svg width="400px" height="576px" viewBox="0 0 400 576" fill="none">
|
||||
<TweenOne component="g" animation={[{ opacity: 0, type: 'from' }, { ...loop, y: 15 }]}>
|
||||
<ellipse cx="100" cy="100" rx="6" ry="6" stroke="#2F54EB" strokeWidth="1.6" />
|
||||
</TweenOne>
|
||||
<TweenOne component="g" animation={[{ opacity: 0, type: 'from' }, { ...loop, y: -15 }]}>
|
||||
<g transform="translate(200 450)">
|
||||
<g style={{ transformOrigin: '50% 50%', transform: 'rotate(-340deg)' }}>
|
||||
<rect stroke="#FADB14" strokeWidth="1.6" width="9" height="9" />
|
||||
</g>
|
||||
</TweenOne>
|
||||
</svg>
|
||||
<ScrollParallax
|
||||
location="banner"
|
||||
className="banner-bg"
|
||||
animation={{ playScale: [1, 1.5], rotate: 0 }}
|
||||
/>
|
||||
</div>
|
||||
<QueueAnim className={`${className} page`} type="alpha" delay={150}>
|
||||
{isMobile && (
|
||||
<div className="img-wrapper" key="image">
|
||||
<BannerImage />
|
||||
</div>
|
||||
)}
|
||||
<QueueAnim className="text-wrapper" key="text" type="bottom">
|
||||
<h1 key="h1">Ant Design</h1>
|
||||
<p key="p">
|
||||
<FormattedMessage id="app.home.introduce" />
|
||||
</p>
|
||||
<div className="banner-btns" key="buttons">
|
||||
<Link to={utils.getLocalizedPathname('/docs/react/introduce', isZhCN)}>
|
||||
<Button type="primary" className="banner-btn components">
|
||||
<FormattedMessage id="app.home.getting-started" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Link
|
||||
to={utils.getLocalizedPathname('/docs/spec/introduce', isZhCN)}
|
||||
style={{ marginLeft: 16 }}
|
||||
>
|
||||
<Button className="banner-btn language">
|
||||
<FormattedMessage id="app.home.design-language" />
|
||||
</Button>
|
||||
</Link>
|
||||
{!isMobile && (
|
||||
<GitHubButton
|
||||
style={{ marginLeft: 16 }}
|
||||
key="github-button"
|
||||
size="large"
|
||||
type="stargazers"
|
||||
namespace="ant-design"
|
||||
repo="ant-design"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</QueueAnim>
|
||||
{!isMobile && (
|
||||
<div className="img-wrapper" key="image">
|
||||
<ScrollParallax
|
||||
location="banner"
|
||||
component={BannerImage}
|
||||
animation={{ playScale: [1, 1.5], y: 80 }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</QueueAnim>
|
||||
</g>
|
||||
</TweenOne>
|
||||
</svg>
|
||||
<ScrollParallax
|
||||
location="banner"
|
||||
className="banner-bg"
|
||||
animation={{ playScale: [1, 1.5], rotate: 0 }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
<QueueAnim className="banner page" type="alpha" delay={150}>
|
||||
{isMobile && (
|
||||
<div className="img-wrapper" key="image">
|
||||
<BannerImage />
|
||||
</div>
|
||||
)}
|
||||
<QueueAnim className="text-wrapper" key="text" type="bottom">
|
||||
<h1 key="h1">Ant Design</h1>
|
||||
<p key="p">
|
||||
<FormattedMessage id="app.home.introduce" />
|
||||
</p>
|
||||
<div className="banner-btns" key="buttons">
|
||||
<Link to={utils.getLocalizedPathname('/docs/react/introduce', isZhCN)}>
|
||||
<Button type="primary" className="banner-btn components">
|
||||
<FormattedMessage id="app.home.getting-started" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Link
|
||||
to={utils.getLocalizedPathname('/docs/spec/introduce', isZhCN)}
|
||||
style={{ marginLeft: 16 }}
|
||||
>
|
||||
<Button className="banner-btn language">
|
||||
<FormattedMessage id="app.home.design-language" />
|
||||
</Button>
|
||||
</Link>
|
||||
{!isMobile && (
|
||||
<GitHubButton
|
||||
style={{ marginLeft: 16 }}
|
||||
key="github-button"
|
||||
size="large"
|
||||
type="stargazers"
|
||||
namespace="ant-design"
|
||||
repo="ant-design"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</QueueAnim>
|
||||
{!isMobile && (
|
||||
<div className="img-wrapper" key="image">
|
||||
<ScrollParallax
|
||||
location="banner"
|
||||
component={BannerImage}
|
||||
animation={{ playScale: [1, 1.5], y: 80 }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Banner;
|
||||
|
@ -61,12 +61,12 @@ function getStyle() {
|
||||
// eslint-disable-next-line react/prefer-stateless-function
|
||||
class Home extends React.Component {
|
||||
static contextTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
isMobile: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isMobile, intl } = this.context;
|
||||
const { intl } = this.props;
|
||||
const { isMobile } = this.context;
|
||||
const childProps = { ...this.props, isMobile, locale: intl.locale };
|
||||
return (
|
||||
<DocumentTitle title={`Ant Design - ${intl.formatMessage({ id: 'app.home.slogan' })}`}>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'bisheng/router';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { Select, Menu, Row, Col, Icon, Popover, Input, Button, Badge } from 'antd';
|
||||
import Santa from './Santa';
|
||||
@ -36,10 +36,9 @@ function initDocSearch(locale) {
|
||||
});
|
||||
}
|
||||
|
||||
export default class Header extends React.Component {
|
||||
class Header extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
isMobile: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
@ -48,7 +47,8 @@ export default class Header extends React.Component {
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { intl, router } = this.context;
|
||||
const { intl } = this.props;
|
||||
const { router } = this.context;
|
||||
router.listen(this.handleHideMenu);
|
||||
const { searchInput } = this;
|
||||
document.addEventListener('keyup', event => {
|
||||
@ -108,7 +108,7 @@ export default class Header extends React.Component {
|
||||
const { menuVisible } = this.state;
|
||||
const { isMobile } = this.context;
|
||||
const menuMode = isMobile ? 'inline' : 'horizontal';
|
||||
const { location, themeConfig } = this.props;
|
||||
const { location, themeConfig, intl: { locale } } = this.props;
|
||||
const docVersions = { ...themeConfig.docVersions, [antdVersion]: antdVersion };
|
||||
const versionOptions = Object.keys(docVersions).map(version => (
|
||||
<Option value={docVersions[version]} key={version}>
|
||||
@ -124,9 +124,6 @@ export default class Header extends React.Component {
|
||||
if (activeMenuItem === 'components' || location.pathname === 'changelog') {
|
||||
activeMenuItem = 'docs/react';
|
||||
}
|
||||
const {
|
||||
intl: { locale },
|
||||
} = this.context;
|
||||
const isZhCN = locale === 'zh-CN';
|
||||
|
||||
const headerClassName = classNames({
|
||||
@ -280,3 +277,5 @@ export default class Header extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(Header);
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { enquireScreen } from 'enquire-js';
|
||||
import { addLocaleData, IntlProvider } from 'react-intl';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import 'moment/locale/zh-cn';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import LogRocket from 'logrocket';
|
||||
@ -63,7 +63,6 @@ export default class Layout extends React.Component {
|
||||
super(props);
|
||||
const { pathname } = props.location;
|
||||
const appLocale = utils.isZhCN(pathname) ? cnLocale : enLocale;
|
||||
addLocaleData(appLocale.data);
|
||||
|
||||
this.state = {
|
||||
appLocale,
|
||||
@ -110,10 +109,12 @@ export default class Layout extends React.Component {
|
||||
render() {
|
||||
const { children, ...restProps } = this.props;
|
||||
const { appLocale } = this.state;
|
||||
|
||||
// Temp remove SentryBoundary
|
||||
return (
|
||||
<IntlProvider locale={appLocale.locale} messages={appLocale.messages}>
|
||||
<IntlProvider
|
||||
locale={appLocale.locale}
|
||||
messages={appLocale.messages}
|
||||
defaultLocale="en-US"
|
||||
>
|
||||
<ConfigProvider locale={appLocale.locale === 'zh-CN' ? zhCN : null}>
|
||||
<div className="page-wrapper">
|
||||
<Header {...restProps} />
|
||||
|
@ -1,38 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const redirect = {
|
||||
'/docs/resource/download': '/docs/spec/download',
|
||||
'/docs/resource/download-cn': '/docs/spec/download-cn',
|
||||
'/docs/resource/reference': '/docs/spec/reference',
|
||||
'/docs/resource/reference-cn': '/docs/spec/reference-cn',
|
||||
'/docs/spec/feature': '/docs/spec/values',
|
||||
'/docs/spec/feature-cn': '/docs/spec/values-cn',
|
||||
'/docs/pattern/advanced-search': '/docs/spec/overview',
|
||||
'/docs/pattern/advanced-search-cn': '/docs/spec/overview-cn',
|
||||
'/docs/pattern/complex-table': '/docs/spec/overview',
|
||||
'/docs/pattern/complex-table-cn': '/docs/spec/overview-cn',
|
||||
'/docs/pattern/form': '/docs/spec/overview',
|
||||
'/docs/pattern/form-cn': '/docs/spec/overview-cn',
|
||||
'/docs/pattern/list': '/docs/spec/overview',
|
||||
'/docs/pattern/list-cn': '/docs/spec/overview-cn',
|
||||
'/docs/pattern/navigation': '/docs/spec/navigation',
|
||||
'/docs/pattern/navigation-cn': '/docs/spec/navigation-cn',
|
||||
'/docs/pattern/table': '/docs/spec/overview',
|
||||
'/docs/pattern/table-cn': '/docs/spec/overview-cn',
|
||||
};
|
||||
|
||||
export default class Redirect extends React.Component {
|
||||
componentDidMount() {
|
||||
const { location } = this.props;
|
||||
const pathname = `/${location.pathname}`;
|
||||
Object.keys(redirect).forEach(from => {
|
||||
if (pathname.indexOf(from) === 0) {
|
||||
window.location.href = redirect[from];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
const appLocaleData = require('react-intl/locale-data/zh');
|
||||
|
||||
module.exports = {
|
||||
locale: 'zh-CN',
|
||||
data: appLocaleData,
|
||||
messages: {
|
||||
'app.header.search': '全文本搜索...',
|
||||
'app.header.menu.home': '首页',
|
||||
|
Loading…
Reference in New Issue
Block a user