mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
docs: add direction & theme to url (#26567)
* docs: add direction to localStorage * wip * wip * wip * wip * browserHistory push * add slider menu click query * expand getLocalizedPathname * add logo footer query * fix lint * wip pathname * wip: fix pathname * add hash & theme * remove only component theme * fix theme component change * change var * remove static * change color * chore: optimize code style * fix: exchange theme when router is change * fix: pathname * fix: location pathname * change dark * fix theme * fix router listen theme * remove console Co-authored-by: Kermit <kermitlx@outlook.com>
This commit is contained in:
parent
58a69bc02c
commit
737bd60f23
@ -353,4 +353,13 @@
|
|||||||
.token.strong {
|
.token.strong {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.components-overview {
|
||||||
|
&-img {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
&-search input {
|
||||||
|
color: rgba(255, 255, 255, 0.65);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ const ComponentOverview = ({
|
|||||||
meta: { title },
|
meta: { title },
|
||||||
content,
|
content,
|
||||||
},
|
},
|
||||||
|
location,
|
||||||
utils: { toReactComponent },
|
utils: { toReactComponent },
|
||||||
}) => {
|
}) => {
|
||||||
const { locale, formatMessage } = useIntl();
|
const { locale, formatMessage } = useIntl();
|
||||||
@ -103,7 +104,7 @@ const ComponentOverview = ({
|
|||||||
const url = `${component.filename
|
const url = `${component.filename
|
||||||
.replace(/(\/index)?((\.zh-cn)|(\.en-us))?\.md$/i, '')
|
.replace(/(\/index)?((\.zh-cn)|(\.en-us))?\.md$/i, '')
|
||||||
.toLowerCase()}/`;
|
.toLowerCase()}/`;
|
||||||
const href = getLocalizedPathname(url, locale === 'zh-CN');
|
const href = getLocalizedPathname(url, locale === 'zh-CN', location.query);
|
||||||
return (
|
return (
|
||||||
<Col xs={24} sm={12} lg={8} xl={6} key={component.title}>
|
<Col xs={24} sm={12} lg={8} xl={6} key={component.title}>
|
||||||
<Link to={href} onClick={() => onClickCard(href)}>
|
<Link to={href} onClick={() => onClickCard(href)}>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Link } from 'bisheng/router';
|
import { Link, browserHistory } from 'bisheng/router';
|
||||||
import { Row, Col, Menu, Affix, Tooltip, Avatar, Dropdown } from 'antd';
|
import { Row, Col, Menu, Affix, Tooltip, Avatar, Dropdown } from 'antd';
|
||||||
import { injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
import { LeftOutlined, RightOutlined, ExportOutlined } from '@ant-design/icons';
|
import { LeftOutlined, RightOutlined, ExportOutlined } from '@ant-design/icons';
|
||||||
@ -230,6 +230,7 @@ class MainContent extends Component {
|
|||||||
generateMenuItem(isTop, item, { before = null, after = null }) {
|
generateMenuItem(isTop, item, { before = null, after = null }) {
|
||||||
const {
|
const {
|
||||||
intl: { locale },
|
intl: { locale },
|
||||||
|
location,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const key = fileNameToPath(item.filename);
|
const key = fileNameToPath(item.filename);
|
||||||
if (!item.title) {
|
if (!item.title) {
|
||||||
@ -246,11 +247,13 @@ class MainContent extends Component {
|
|||||||
];
|
];
|
||||||
const { disabled } = item;
|
const { disabled } = item;
|
||||||
const url = item.filename.replace(/(\/index)?((\.zh-cn)|(\.en-us))?\.md$/i, '').toLowerCase();
|
const url = item.filename.replace(/(\/index)?((\.zh-cn)|(\.en-us))?\.md$/i, '').toLowerCase();
|
||||||
|
|
||||||
const child = !item.link ? (
|
const child = !item.link ? (
|
||||||
<Link
|
<Link
|
||||||
to={utils.getLocalizedPathname(
|
to={utils.getLocalizedPathname(
|
||||||
/^components/.test(url) ? `${url}/` : url,
|
/^components/.test(url) ? `${url}/` : url,
|
||||||
locale === 'zh-CN',
|
locale === 'zh-CN',
|
||||||
|
location.query,
|
||||||
)}
|
)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
@ -312,8 +315,19 @@ class MainContent extends Component {
|
|||||||
|
|
||||||
changeThemeMode = theme => {
|
changeThemeMode = theme => {
|
||||||
const { setTheme, theme: selectedTheme } = this.context;
|
const { setTheme, theme: selectedTheme } = this.context;
|
||||||
|
const { pathname, hash, query } = this.props.location;
|
||||||
if (selectedTheme !== theme) {
|
if (selectedTheme !== theme) {
|
||||||
setTheme(theme);
|
setTheme(theme);
|
||||||
|
if (theme === 'default') {
|
||||||
|
delete query.theme;
|
||||||
|
} else {
|
||||||
|
query.theme = theme;
|
||||||
|
}
|
||||||
|
browserHistory.push({
|
||||||
|
pathname: `/${pathname}`,
|
||||||
|
query,
|
||||||
|
hash,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -438,7 +452,7 @@ class MainContent extends Component {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<PrevAndNext prev={prev} next={next} />
|
<PrevAndNext prev={prev} next={next} />
|
||||||
<Footer />
|
<Footer location={location} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,8 @@ import Logo from './Logo';
|
|||||||
import './index.less';
|
import './index.less';
|
||||||
import SiteContext from '../../Layout/SiteContext';
|
import SiteContext from '../../Layout/SiteContext';
|
||||||
|
|
||||||
export default function Banner() {
|
const Banner = (props: { location: any }) => {
|
||||||
|
const { location } = props;
|
||||||
const { isMobile } = React.useContext(SiteContext);
|
const { isMobile } = React.useContext(SiteContext);
|
||||||
const { locale } = useIntl();
|
const { locale } = useIntl();
|
||||||
const isZhCN = locale === 'zh-CN';
|
const isZhCN = locale === 'zh-CN';
|
||||||
@ -74,12 +75,12 @@ export default function Banner() {
|
|||||||
{isZhCN && <div className="banner-qr">{qrNode}</div>}
|
{isZhCN && <div className="banner-qr">{qrNode}</div>}
|
||||||
|
|
||||||
<div className="home-banner-content-operations">
|
<div className="home-banner-content-operations">
|
||||||
<Link to={getLocalizedPathname('/docs/react/introduce', isZhCN)}>
|
<Link to={getLocalizedPathname('/docs/react/introduce', isZhCN, location.query)}>
|
||||||
<Button type="primary" shape="round">
|
<Button type="primary" shape="round">
|
||||||
<FormattedMessage id="app.home.getting-started" />
|
<FormattedMessage id="app.home.getting-started" />
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={getLocalizedPathname('/docs/spec/introduce', isZhCN)}>
|
<Link to={getLocalizedPathname('/docs/spec/introduce', isZhCN, location.query)}>
|
||||||
<Button shape="round" ghost>
|
<Button shape="round" ghost>
|
||||||
<FormattedMessage id="app.home.design-language" />
|
<FormattedMessage id="app.home.design-language" />
|
||||||
</Button>
|
</Button>
|
||||||
@ -89,4 +90,6 @@ export default function Banner() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default Banner;
|
||||||
|
@ -68,7 +68,8 @@ const MiniPanel = ({
|
|||||||
href,
|
href,
|
||||||
link,
|
link,
|
||||||
isZhCN,
|
isZhCN,
|
||||||
}: PanelProps & { isZhCN: boolean }) => {
|
query,
|
||||||
|
}: PanelProps & { isZhCN: boolean } & { query: object }) => {
|
||||||
let content = (
|
let content = (
|
||||||
<Card
|
<Card
|
||||||
hoverable
|
hoverable
|
||||||
@ -86,7 +87,7 @@ const MiniPanel = ({
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else if (link) {
|
} else if (link) {
|
||||||
content = <Link to={getLocalizedPathname(link, isZhCN)}>{content}</Link>;
|
content = <Link to={getLocalizedPathname(link, isZhCN, query)}>{content}</Link>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -96,7 +97,8 @@ const MiniPanel = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DesignPage() {
|
const DesignPage = (props: { location: any }) => {
|
||||||
|
const { location } = props;
|
||||||
const { locale } = useIntl();
|
const { locale } = useIntl();
|
||||||
const isZhCN = locale === 'zh-CN';
|
const isZhCN = locale === 'zh-CN';
|
||||||
const { direction } = React.useContext(SiteContext);
|
const { direction } = React.useContext(SiteContext);
|
||||||
@ -123,7 +125,7 @@ export default function DesignPage() {
|
|||||||
|
|
||||||
<Link
|
<Link
|
||||||
className="design-card-detail"
|
className="design-card-detail"
|
||||||
to={getLocalizedPathname('/docs/spec/values', isZhCN)}
|
to={getLocalizedPathname('/docs/spec/values', isZhCN, location.query)}
|
||||||
>
|
>
|
||||||
<FormattedMessage id="app.home.detail" />
|
<FormattedMessage id="app.home.detail" />
|
||||||
{IconComponent}
|
{IconComponent}
|
||||||
@ -195,13 +197,13 @@ export default function DesignPage() {
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<Link to={getLocalizedPathname('/docs/spec/colors', isZhCN)}>
|
<Link to={getLocalizedPathname('/docs/spec/colors', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.home.global-style" />
|
<FormattedMessage id="app.home.global-style" />
|
||||||
{IconComponent}
|
{IconComponent}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to={getLocalizedPathname('/docs/spec/overview', isZhCN)}>
|
<Link to={getLocalizedPathname('/docs/spec/overview', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.home.design-patterns" />
|
<FormattedMessage id="app.home.design-patterns" />
|
||||||
{IconComponent}
|
{IconComponent}
|
||||||
</Link>
|
</Link>
|
||||||
@ -242,7 +244,9 @@ export default function DesignPage() {
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<Link to={getLocalizedPathname('/docs/react/introduce', isZhCN)}>
|
<Link
|
||||||
|
to={getLocalizedPathname('/docs/react/introduce', isZhCN, location.query)}
|
||||||
|
>
|
||||||
Ant Design of React
|
Ant Design of React
|
||||||
{IconComponent}
|
{IconComponent}
|
||||||
</Link>
|
</Link>
|
||||||
@ -284,9 +288,11 @@ export default function DesignPage() {
|
|||||||
className="design-mini-panels"
|
className="design-mini-panels"
|
||||||
>
|
>
|
||||||
{MINI_LIST.map(panel => (
|
{MINI_LIST.map(panel => (
|
||||||
<MiniPanel key={panel.description} {...panel} isZhCN={isZhCN} />
|
<MiniPanel key={panel.description} {...panel} isZhCN={isZhCN} query={location.query} />
|
||||||
))}
|
))}
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default DesignPage;
|
||||||
|
@ -42,33 +42,42 @@ const BlockContent: React.FC<BlockContentProps> = ({ title, children, extra }) =
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default function Home() {
|
const Home = (props: { location: any }) => {
|
||||||
|
const { location } = props;
|
||||||
const { locale } = useIntl();
|
const { locale } = useIntl();
|
||||||
const isZhCN = locale === 'zh-CN';
|
const isZhCN = locale === 'zh-CN';
|
||||||
|
|
||||||
|
const getLink = () => {
|
||||||
|
const path = getLocalizedPathname('/docs/resources', isZhCN, location.query, {
|
||||||
|
zhCN: '文章',
|
||||||
|
enUS: 'Articles',
|
||||||
|
});
|
||||||
|
const { pathname, query } = path;
|
||||||
|
const pathnames = pathname.split('#');
|
||||||
|
if ('direction' in query) {
|
||||||
|
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="home-container">
|
<div className="home-container">
|
||||||
<style dangerouslySetInnerHTML={{ __html: getStyle() }} />
|
<style dangerouslySetInnerHTML={{ __html: getStyle() }} />
|
||||||
<Banner />
|
<Banner location={location} />
|
||||||
<div style={{ maxWidth: 1256, margin: '0 auto' }}>
|
<div style={{ maxWidth: 1256, margin: '0 auto' }}>
|
||||||
<BlockContent title={<FormattedMessage id="app.home.recommend" />}>
|
<BlockContent title={<FormattedMessage id="app.home.recommend" />}>
|
||||||
<RecommendPage />
|
<RecommendPage />
|
||||||
</BlockContent>
|
</BlockContent>
|
||||||
|
|
||||||
<BlockContent title={<FormattedMessage id="app.home.design-and-framework" />}>
|
<BlockContent title={<FormattedMessage id="app.home.design-and-framework" />}>
|
||||||
<DesignPage />
|
<DesignPage location={location} />
|
||||||
</BlockContent>
|
</BlockContent>
|
||||||
|
|
||||||
{isZhCN ? (
|
{isZhCN ? (
|
||||||
<BlockContent
|
<BlockContent
|
||||||
title={<FormattedMessage id="app.home.more" />}
|
title={<FormattedMessage id="app.home.more" />}
|
||||||
extra={
|
extra={
|
||||||
<Link
|
<Link to={getLink()}>
|
||||||
to={getLocalizedPathname('/docs/resources', isZhCN, {
|
|
||||||
zhCN: '文章',
|
|
||||||
enUS: 'Articles',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<FormattedMessage id="app.home.view-more" />
|
<FormattedMessage id="app.home.view-more" />
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
@ -77,7 +86,9 @@ export default function Home() {
|
|||||||
</BlockContent>
|
</BlockContent>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer location={location} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
import { isLocalStorageNameSupported, loadScript, getLocalizedPathname } from '../utils';
|
import { isLocalStorageNameSupported, loadScript, getLocalizedPathname } from '../utils';
|
||||||
import ColorPicker from '../Color/ColorPicker';
|
import ColorPicker from '../Color/ColorPicker';
|
||||||
|
|
||||||
class Footer extends React.Component<WrappedComponentProps> {
|
class Footer extends React.Component<WrappedComponentProps & { location: any }> {
|
||||||
lessLoaded = false;
|
lessLoaded = false;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -47,9 +47,29 @@ class Footer extends React.Component<WrappedComponentProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getColumns() {
|
getColumns() {
|
||||||
const { intl } = this.props;
|
const { intl, location } = this.props;
|
||||||
|
|
||||||
const isZhCN = intl.locale === 'zh-CN';
|
const isZhCN = intl.locale === 'zh-CN';
|
||||||
|
|
||||||
|
const getLinkHash = (path: string, hash: { zhCN: string; enUS: string }) => {
|
||||||
|
const pathName = getLocalizedPathname(path, isZhCN, location.query, hash);
|
||||||
|
const { pathname, query } = pathName;
|
||||||
|
const pathnames = pathname.split('#');
|
||||||
|
if ('direction' in query) {
|
||||||
|
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
||||||
|
}
|
||||||
|
return pathname;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLink = (path: string) => {
|
||||||
|
const pathName = getLocalizedPathname(path, isZhCN, location.query);
|
||||||
|
const { pathname, query } = pathName;
|
||||||
|
if ('direction' in query) {
|
||||||
|
return `${pathname}?direction=rtl}`;
|
||||||
|
}
|
||||||
|
return pathname;
|
||||||
|
};
|
||||||
|
|
||||||
const col1 = {
|
const col1 = {
|
||||||
title: <FormattedMessage id="app.footer.resources" />,
|
title: <FormattedMessage id="app.footer.resources" />,
|
||||||
items: [
|
items: [
|
||||||
@ -128,7 +148,7 @@ class Footer extends React.Component<WrappedComponentProps> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <FormattedMessage id="app.footer.design-resources" />,
|
title: <FormattedMessage id="app.footer.design-resources" />,
|
||||||
url: getLocalizedPathname('/docs/resources', isZhCN, {
|
url: getLinkHash('/docs/resources', {
|
||||||
zhCN: '设计资源',
|
zhCN: '设计资源',
|
||||||
enUS: 'Design-Resources',
|
enUS: 'Design-Resources',
|
||||||
}),
|
}),
|
||||||
@ -193,7 +213,7 @@ class Footer extends React.Component<WrappedComponentProps> {
|
|||||||
col2.items.push({
|
col2.items.push({
|
||||||
icon: <UsergroupAddOutlined />,
|
icon: <UsergroupAddOutlined />,
|
||||||
title: <FormattedMessage id="app.footer.work_with_us" />,
|
title: <FormattedMessage id="app.footer.work_with_us" />,
|
||||||
url: getLocalizedPathname('/docs/resources', isZhCN, {
|
url: getLinkHash('/docs/resources', {
|
||||||
zhCN: '加入我们',
|
zhCN: '加入我们',
|
||||||
enUS: 'JoinUs',
|
enUS: 'JoinUs',
|
||||||
}),
|
}),
|
||||||
@ -213,13 +233,13 @@ class Footer extends React.Component<WrappedComponentProps> {
|
|||||||
{
|
{
|
||||||
icon: <HistoryOutlined />,
|
icon: <HistoryOutlined />,
|
||||||
title: <FormattedMessage id="app.footer.change-log" />,
|
title: <FormattedMessage id="app.footer.change-log" />,
|
||||||
url: getLocalizedPathname('/changelog', isZhCN),
|
url: getLink('/changelog'),
|
||||||
LinkComponent: Link,
|
LinkComponent: Link,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <ProfileOutlined />,
|
icon: <ProfileOutlined />,
|
||||||
title: <FormattedMessage id="app.footer.faq" />,
|
title: <FormattedMessage id="app.footer.faq" />,
|
||||||
url: getLocalizedPathname('/docs/react/faq', isZhCN),
|
url: getLink('/docs/react/faq'),
|
||||||
LinkComponent: Link,
|
LinkComponent: Link,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Link } from 'bisheng/router';
|
import { Link } from 'bisheng/router';
|
||||||
import * as utils from '../../utils';
|
import * as utils from '../../utils';
|
||||||
import { SharedProps } from './interface';
|
|
||||||
|
|
||||||
import './Logo.less';
|
import './Logo.less';
|
||||||
|
|
||||||
export default ({ isZhCN }: SharedProps) => (
|
export interface LogoProps {
|
||||||
<h1>
|
isZhCN: boolean;
|
||||||
<Link to={utils.getLocalizedPathname('/', isZhCN)} id="logo">
|
location: any;
|
||||||
<img alt="logo" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
}
|
||||||
Ant Design
|
|
||||||
</Link>
|
const Logo = ({ isZhCN, location }: LogoProps) => {
|
||||||
</h1>
|
return (
|
||||||
);
|
<h1>
|
||||||
|
<Link to={utils.getLocalizedPathname('/', isZhCN, location.query)} id="logo">
|
||||||
|
<img alt="logo" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
||||||
|
Ant Design
|
||||||
|
</Link>
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Logo;
|
||||||
|
@ -15,7 +15,7 @@ export interface NavigationProps extends SharedProps {
|
|||||||
isRTL: boolean;
|
isRTL: boolean;
|
||||||
pathname: string;
|
pathname: string;
|
||||||
responsive: null | 'narrow' | 'crowded';
|
responsive: null | 'narrow' | 'crowded';
|
||||||
location: { pathname: string };
|
location: { pathname: string; query: any };
|
||||||
directionText: string;
|
directionText: string;
|
||||||
onLangChange: () => void;
|
onLangChange: () => void;
|
||||||
onDirectionChange: () => void;
|
onDirectionChange: () => void;
|
||||||
@ -81,22 +81,22 @@ export default ({
|
|||||||
id="nav"
|
id="nav"
|
||||||
>
|
>
|
||||||
<Menu.Item key="docs/spec">
|
<Menu.Item key="docs/spec">
|
||||||
<Link to={utils.getLocalizedPathname('/docs/spec/introduce', isZhCN)}>
|
<Link to={utils.getLocalizedPathname('/docs/spec/introduce', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.header.menu.spec" />
|
<FormattedMessage id="app.header.menu.spec" />
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="docs/react">
|
<Menu.Item key="docs/react">
|
||||||
<Link to={utils.getLocalizedPathname('/docs/react/introduce', isZhCN)}>
|
<Link to={utils.getLocalizedPathname('/docs/react/introduce', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.header.menu.documentation" />
|
<FormattedMessage id="app.header.menu.documentation" />
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="components">
|
<Menu.Item key="components">
|
||||||
<Link to={utils.getLocalizedPathname('/components/overview/', isZhCN)}>
|
<Link to={utils.getLocalizedPathname('/components/overview/', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.header.menu.components" />
|
<FormattedMessage id="app.header.menu.components" />
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="docs/resources">
|
<Menu.Item key="docs/resources">
|
||||||
<Link to={utils.getLocalizedPathname('/docs/resources', isZhCN)}>
|
<Link to={utils.getLocalizedPathname('/docs/resources', isZhCN, location.query)}>
|
||||||
<FormattedMessage id="app.header.menu.resource" />
|
<FormattedMessage id="app.header.menu.resource" />
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
@ -51,7 +51,7 @@ export interface HeaderProps {
|
|||||||
intl: {
|
intl: {
|
||||||
locale: string;
|
locale: string;
|
||||||
};
|
};
|
||||||
location: { pathname: string };
|
location: { pathname: string; query: any };
|
||||||
router: any;
|
router: any;
|
||||||
themeConfig: { docVersions: Record<string, string> };
|
themeConfig: { docVersions: Record<string, string> };
|
||||||
changeDirection: (direction: string) => void;
|
changeDirection: (direction: string) => void;
|
||||||
@ -158,7 +158,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
|
|||||||
|
|
||||||
onLangChange = () => {
|
onLangChange = () => {
|
||||||
const {
|
const {
|
||||||
location: { pathname },
|
location: { pathname, query },
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const currentProtocol = `${window.location.protocol}//`;
|
const currentProtocol = `${window.location.protocol}//`;
|
||||||
const currentHref = window.location.href.substr(currentProtocol.length);
|
const currentHref = window.location.href.substr(currentProtocol.length);
|
||||||
@ -171,7 +171,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
|
|||||||
currentProtocol +
|
currentProtocol +
|
||||||
currentHref.replace(
|
currentHref.replace(
|
||||||
window.location.pathname,
|
window.location.pathname,
|
||||||
utils.getLocalizedPathname(pathname, !utils.isZhCN(pathname)),
|
utils.getLocalizedPathname(pathname, !utils.isZhCN(pathname), query).pathname,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,7 +316,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
|
|||||||
)}
|
)}
|
||||||
<Row style={{ flexFlow: 'nowrap', height: 64 }}>
|
<Row style={{ flexFlow: 'nowrap', height: 64 }}>
|
||||||
<Col {...colProps[0]}>
|
<Col {...colProps[0]}>
|
||||||
<Logo {...sharedProps} />
|
<Logo {...sharedProps} location={location} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col {...colProps[1]} className="menu-row">
|
<Col {...colProps[1]} className="menu-row">
|
||||||
{searchBox}
|
{searchBox}
|
||||||
|
@ -10,6 +10,7 @@ import 'moment/locale/zh-cn';
|
|||||||
import { ConfigProvider } from 'antd';
|
import { ConfigProvider } from 'antd';
|
||||||
import LogRocket from 'logrocket';
|
import LogRocket from 'logrocket';
|
||||||
import setupLogRocketReact from 'logrocket-react';
|
import setupLogRocketReact from 'logrocket-react';
|
||||||
|
import { browserHistory } from 'bisheng/router';
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import zhCN from 'antd/es/locale/zh_CN';
|
import zhCN from 'antd/es/locale/zh_CN';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
@ -57,7 +58,6 @@ if (typeof window !== 'undefined') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RESPONSIVE_MOBILE = 768;
|
const RESPONSIVE_MOBILE = 768;
|
||||||
const SITE_THEME_STORE_KEY = 'site-theme';
|
|
||||||
|
|
||||||
// for dark.css timestamp to remove cache
|
// for dark.css timestamp to remove cache
|
||||||
const timestamp = new Date().getTime();
|
const timestamp = new Date().getTime();
|
||||||
@ -73,6 +73,8 @@ const { switcher } = themeSwitcher(themeConfig);
|
|||||||
export default class Layout extends React.Component {
|
export default class Layout extends React.Component {
|
||||||
static contextType = SiteContext;
|
static contextType = SiteContext;
|
||||||
|
|
||||||
|
isBeforeComponent = false;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const { pathname } = props.location;
|
const { pathname } = props.location;
|
||||||
@ -80,10 +82,7 @@ export default class Layout extends React.Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
appLocale,
|
appLocale,
|
||||||
theme:
|
theme: 'default',
|
||||||
typeof localStorage !== 'undefined'
|
|
||||||
? localStorage.getItem(SITE_THEME_STORE_KEY) || 'default'
|
|
||||||
: 'default',
|
|
||||||
setTheme: this.setTheme,
|
setTheme: this.setTheme,
|
||||||
direction: 'ltr',
|
direction: 'ltr',
|
||||||
setIframeTheme: this.setIframeTheme,
|
setIframeTheme: this.setIframeTheme,
|
||||||
@ -91,25 +90,46 @@ export default class Layout extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { theme } = this.state;
|
|
||||||
const { location, router } = this.props;
|
const { location, router } = this.props;
|
||||||
router.listen(loc => {
|
router.listen(({ pathname, search }) => {
|
||||||
|
const { theme } = this.props.location.query;
|
||||||
if (typeof window.ga !== 'undefined') {
|
if (typeof window.ga !== 'undefined') {
|
||||||
window.ga('send', 'pageview', loc.pathname + loc.search);
|
window.ga('send', 'pageview', pathname + search);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
if (typeof window._hmt !== 'undefined') {
|
if (typeof window._hmt !== 'undefined') {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
window._hmt.push(['_trackPageview', loc.pathname + loc.search]);
|
window._hmt.push(['_trackPageview', pathname + search]);
|
||||||
}
|
}
|
||||||
const { pathname } = loc;
|
|
||||||
const componentPage = /^\/?components/.test(pathname);
|
const componentPage = /^\/?components/.test(pathname);
|
||||||
|
|
||||||
// only component page can use `dark` theme
|
// only component page can use `dark` theme
|
||||||
if (!componentPage) {
|
if (!componentPage) {
|
||||||
|
this.isBeforeComponent = false;
|
||||||
this.setTheme('default', false);
|
this.setTheme('default', false);
|
||||||
|
} else if (theme && !this.isBeforeComponent) {
|
||||||
|
this.isBeforeComponent = true;
|
||||||
|
this.setTheme(theme, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.setTheme(/^\/?components/.test(location.pathname) ? theme : 'default');
|
|
||||||
|
if (location.query.theme && /^\/?components/.test(location.pathname)) {
|
||||||
|
this.isBeforeComponent = true;
|
||||||
|
this.setTheme(location.query.theme, false);
|
||||||
|
} else {
|
||||||
|
this.isBeforeComponent = false;
|
||||||
|
this.setTheme('default', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location.query.direction) {
|
||||||
|
this.setState({
|
||||||
|
direction: location.query.direction,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
direction: 'ltr',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
||||||
if (nprogressHiddenStyle) {
|
if (nprogressHiddenStyle) {
|
||||||
@ -180,6 +200,17 @@ export default class Layout extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
direction,
|
direction,
|
||||||
});
|
});
|
||||||
|
const { pathname, hash, query } = this.props.location;
|
||||||
|
if (direction === 'ltr') {
|
||||||
|
delete query.direction;
|
||||||
|
} else {
|
||||||
|
query.direction = 'rtl';
|
||||||
|
}
|
||||||
|
browserHistory.push({
|
||||||
|
pathname: `/${pathname}`,
|
||||||
|
query,
|
||||||
|
hash,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -39,7 +39,7 @@ export default function NotFound(props: NotFoundProps) {
|
|||||||
for (let i = 0; i < directLinks.length; i += 1) {
|
for (let i = 0; i < directLinks.length; i += 1) {
|
||||||
const matchPath = directLinks[i];
|
const matchPath = directLinks[i];
|
||||||
if (pathname.includes(matchPath)) {
|
if (pathname.includes(matchPath)) {
|
||||||
router.replace(utils.getLocalizedPathname(`/${DIRECT_MAP[matchPath]}`, isZhCN));
|
router.replace(utils.getLocalizedPathname(`/${DIRECT_MAP[matchPath]}`, isZhCN).pathname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -30,6 +30,7 @@ interface PagesData {
|
|||||||
interface ResourcesProps {
|
interface ResourcesProps {
|
||||||
location: {
|
location: {
|
||||||
pathname: string;
|
pathname: string;
|
||||||
|
query: object;
|
||||||
};
|
};
|
||||||
data: PagesData;
|
data: PagesData;
|
||||||
localizedPageData: PageData;
|
localizedPageData: PageData;
|
||||||
@ -116,7 +117,7 @@ function injectCards(content: ContentUnit[]): ContentUnit[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Resources = (props: ResourcesProps) => {
|
const Resources = (props: ResourcesProps) => {
|
||||||
const { localizedPageData } = props;
|
const { localizedPageData, location } = props;
|
||||||
const { locale } = useIntl();
|
const { locale } = useIntl();
|
||||||
|
|
||||||
const content = React.useMemo(() => injectCards(localizedPageData.content), [
|
const content = React.useMemo(() => injectCards(localizedPageData.content), [
|
||||||
@ -137,7 +138,7 @@ const Resources = (props: ResourcesProps) => {
|
|||||||
titleRegionClassName="title-region"
|
titleRegionClassName="title-region"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Footer />
|
<Footer location={location} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -118,6 +118,7 @@ export function isZhCN(pathname: string) {
|
|||||||
export function getLocalizedPathname(
|
export function getLocalizedPathname(
|
||||||
path: string,
|
path: string,
|
||||||
zhCN?: boolean,
|
zhCN?: boolean,
|
||||||
|
query = {},
|
||||||
hash?: {
|
hash?: {
|
||||||
zhCN: string;
|
zhCN: string;
|
||||||
enUS: string;
|
enUS: string;
|
||||||
@ -141,7 +142,7 @@ export function getLocalizedPathname(
|
|||||||
fullPath += `#${localHash}`;
|
fullPath += `#${localHash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullPath;
|
return { pathname: fullPath, query };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ping(callback: (status: string) => void) {
|
export function ping(callback: (status: string) => void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user