mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-28 05:05:48 +08:00
site style code optimization (#40524)
* site style code optimization * site style code optimization * del trigger * revert
This commit is contained in:
parent
619814c005
commit
286a42b4e5
@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { Button, Space, Typography } from 'antd';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import * as React from 'react';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import { GroupMask } from './Group';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import * as utils from '../../../theme/utils';
|
||||
import { GroupMask } from './Group';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import React, { useMemo } from 'react';
|
||||
import useSiteToken from '../../../../hooks/useSiteToken';
|
||||
import { COLOR_IMAGES, getClosetColor } from './colorUtil';
|
||||
|
||||
@ -7,49 +8,40 @@ export interface BackgroundImageProps {
|
||||
isLight?: boolean;
|
||||
}
|
||||
|
||||
export default function BackgroundImage({ colorPrimary, isLight }: BackgroundImageProps) {
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const activeColor = React.useMemo(() => getClosetColor(colorPrimary), [colorPrimary]);
|
||||
|
||||
const sharedStyle: React.CSSProperties = {
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
return {
|
||||
image: css`
|
||||
transition: all ${token.motionDurationSlow};
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
object-position: right top;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
const BackgroundImage: React.FC<BackgroundImageProps> = ({ colorPrimary, isLight }) => {
|
||||
const activeColor = useMemo(() => getClosetColor(colorPrimary), [colorPrimary]);
|
||||
|
||||
const { image } = useStyle();
|
||||
|
||||
return (
|
||||
<>
|
||||
{COLOR_IMAGES.map(({ color, url }) => {
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
key={color}
|
||||
style={{
|
||||
...sharedStyle,
|
||||
opacity: isLight && activeColor === color ? 1 : 0,
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'right top',
|
||||
}}
|
||||
src={url}
|
||||
alt=""
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* <div
|
||||
style={{
|
||||
...sharedStyle,
|
||||
opacity: isLight || !activeColor || activeColor === DEFAULT_COLOR ? 0 : 1,
|
||||
background: 'rgba(0,0,0,0.79)',
|
||||
}}
|
||||
/> */}
|
||||
{COLOR_IMAGES.filter(({ url }) => url).map(({ color, url }) => (
|
||||
<img
|
||||
css={image}
|
||||
style={{ opacity: isLight && activeColor === color ? 1 : 0 }}
|
||||
key={color}
|
||||
src={url}
|
||||
alt=""
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default BackgroundImage;
|
||||
|
@ -1,27 +1,35 @@
|
||||
import React from 'react';
|
||||
import { useLocale as useDumiLocale } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import { useLocale as useDumiLocale } from 'dumi';
|
||||
import React from 'react';
|
||||
import useLocale from '../../hooks/useLocale';
|
||||
import Banner from './components/Banner';
|
||||
import Group from './components/Group';
|
||||
import { useSiteData } from './components/util';
|
||||
import Theme from './components/Theme';
|
||||
import BannerRecommends from './components/BannerRecommends';
|
||||
import ComponentsList from './components/ComponentsList';
|
||||
import DesignFramework from './components/DesignFramework';
|
||||
import Group from './components/Group';
|
||||
import Theme from './components/Theme';
|
||||
import { useSiteData } from './components/util';
|
||||
|
||||
const useStyle = () => ({
|
||||
image: css`
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -50px;
|
||||
height: 160px;
|
||||
`,
|
||||
});
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
assetsTitle: '组件丰富,选用自如',
|
||||
assetsDesc: '大量实用组件满足你的需求,灵活定制与拓展',
|
||||
|
||||
designTitle: '设计语言与研发框架',
|
||||
designDesc: '配套生态,让你快速搭建网站应用',
|
||||
},
|
||||
en: {
|
||||
assetsTitle: 'Rich components',
|
||||
assetsDesc: 'Practical components to meet your needs, flexible customization and expansion',
|
||||
|
||||
designTitle: 'Design and framework',
|
||||
designDesc: 'Supporting ecology, allowing you to quickly build website applications',
|
||||
},
|
||||
@ -31,7 +39,7 @@ const Homepage: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
const { id: localeId } = useDumiLocale();
|
||||
const localeStr = localeId === 'zh-CN' ? 'cn' : 'en';
|
||||
|
||||
const { image } = useStyle();
|
||||
const [siteData] = useSiteData();
|
||||
|
||||
return (
|
||||
@ -40,7 +48,6 @@ const Homepage: React.FC = () => {
|
||||
<Banner>
|
||||
<BannerRecommends extras={siteData?.extras?.[localeStr]} icons={siteData?.icons} />
|
||||
</Banner>
|
||||
|
||||
<div>
|
||||
<Theme />
|
||||
<Group
|
||||
@ -57,14 +64,11 @@ const Homepage: React.FC = () => {
|
||||
description={locale.designDesc}
|
||||
background="#F5F8FF"
|
||||
decoration={
|
||||
<>
|
||||
{/* Image Left Top */}
|
||||
<img
|
||||
style={{ position: 'absolute', left: 0, top: -50, height: 160 }}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
|
||||
alt=""
|
||||
/>
|
||||
</>
|
||||
<img
|
||||
css={image}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
|
||||
alt=""
|
||||
/>
|
||||
}
|
||||
>
|
||||
<DesignFramework />
|
||||
|
@ -1,9 +1,8 @@
|
||||
import type { AlertProps } from 'antd';
|
||||
import { Alert } from 'antd';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
const MdAlert: FC<AlertProps> = ({ style, ...props }) => (
|
||||
const MdAlert: React.FC<AlertProps> = ({ style, ...props }) => (
|
||||
<Alert {...props} style={{ margin: '24px 0', ...style }} />
|
||||
);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { Tabs } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import { Tabs } from 'antd';
|
||||
import throttle from 'lodash/throttle';
|
||||
import * as React from 'react';
|
||||
import scrollTo from '../../../../components/_util/scrollTo';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
@ -45,18 +45,21 @@ const useStyle = () => {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
`,
|
||||
span: css`
|
||||
text-transform: capitalize;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
const VIEW_BALANCE = 32;
|
||||
|
||||
export default () => {
|
||||
const AffixTabs: React.FC = () => {
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
const idsRef = React.useRef<string[]>([]);
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
const [fixedId, setFixedId] = React.useState<string | null>(null);
|
||||
|
||||
const styles = useStyle();
|
||||
const { affixTabs, affixTabsFixed, span } = useStyle();
|
||||
|
||||
function scrollToId(id: string) {
|
||||
const targetNode = document.getElementById(id);
|
||||
@ -113,17 +116,17 @@ export default () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div css={[styles.affixTabs, fixedId && styles.affixTabsFixed]} ref={containerRef}>
|
||||
<div css={[affixTabs, fixedId && affixTabsFixed]} ref={containerRef}>
|
||||
<Tabs
|
||||
activeKey={fixedId}
|
||||
onChange={(key) => {
|
||||
scrollToId(key);
|
||||
}}
|
||||
onChange={scrollToId}
|
||||
items={idsRef.current.map((id) => ({
|
||||
key: id,
|
||||
label: <span style={{ textTransform: 'capitalize' }}>{id.replace(/-/g, ' ')}</span>,
|
||||
label: <span css={span}>{id.replace(/-/g, ' ')}</span>,
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AffixTabs;
|
||||
|
@ -1,24 +1,23 @@
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import { useRouteMeta, FormattedMessage } from 'dumi';
|
||||
import { Layout, Typography, ConfigProvider } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import Footer from '../../slots/Footer';
|
||||
import AffixTabs from './AffixTabs';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import { ConfigProvider, Layout, Typography } from 'antd';
|
||||
import { FormattedMessage, useRouteMeta } from 'dumi';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import CommonHelmet from '../../common/CommonHelmet';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import Footer from '../../slots/Footer';
|
||||
import AffixTabs from './AffixTabs';
|
||||
|
||||
export type ResourceLayoutProps = PropsWithChildren<{}>;
|
||||
|
||||
const resourcePadding = 40;
|
||||
const articleMaxWidth = 1208;
|
||||
const resourcePaddingXS = 24;
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
const { antCls } = token;
|
||||
|
||||
const resourcePadding = 40;
|
||||
const articleMaxWidth = 1208;
|
||||
const resourcePaddingXS = 24;
|
||||
|
||||
return {
|
||||
resourcePage: css`
|
||||
footer {
|
||||
@ -110,10 +109,9 @@ const useStyle = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const ResourceLayout: FC<ResourceLayoutProps> = ({ children }) => {
|
||||
const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
|
||||
const styles = useStyle();
|
||||
const meta = useRouteMeta();
|
||||
|
||||
return (
|
||||
<ConfigProvider theme={{ token: { colorBgLayout: '#fff' } }}>
|
||||
<Layout>
|
||||
|
@ -1,15 +1,26 @@
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import Sidebar from '../../slots/Sidebar';
|
||||
import Content from '../../slots/Content';
|
||||
import CommonHelmet from '../../common/CommonHelmet';
|
||||
import Content from '../../slots/Content';
|
||||
import Sidebar from '../../slots/Sidebar';
|
||||
|
||||
const SidebarLayout: FC<PropsWithChildren<{}>> = ({ children }) => (
|
||||
<main style={{ display: 'flex', marginTop: 40 }}>
|
||||
<CommonHelmet />
|
||||
<Sidebar />
|
||||
<Content>{children}</Content>
|
||||
</main>
|
||||
);
|
||||
const useStyle = () => ({
|
||||
main: css`
|
||||
display: flex;
|
||||
margintop: 40;
|
||||
`,
|
||||
});
|
||||
|
||||
const SidebarLayout: React.FC<PropsWithChildren<{}>> = ({ children }) => {
|
||||
const { main } = useStyle();
|
||||
return (
|
||||
<main css={main}>
|
||||
<CommonHelmet />
|
||||
<Sidebar />
|
||||
<Content>{children}</Content>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidebarLayout;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { removeCSS, updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
import * as React from 'react';
|
||||
import { updateCSS, removeCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
|
||||
const whereCls = 'ant-where-checker';
|
||||
|
@ -1,7 +1,3 @@
|
||||
import React, { useContext } from 'react';
|
||||
import RcFooter from 'rc-footer';
|
||||
import { Link, FormattedMessage } from 'dumi';
|
||||
import type { FooterColumn } from 'rc-footer/lib/column';
|
||||
import {
|
||||
AntDesignOutlined,
|
||||
BgColorsOutlined,
|
||||
@ -10,20 +6,24 @@ import {
|
||||
HistoryOutlined,
|
||||
IssuesCloseOutlined,
|
||||
MediumOutlined,
|
||||
MessageOutlined,
|
||||
QuestionCircleOutlined,
|
||||
TwitterOutlined,
|
||||
UsergroupAddOutlined,
|
||||
ZhihuOutlined,
|
||||
MessageOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { css } from '@emotion/react';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { css } from '@emotion/react';
|
||||
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
|
||||
import useLocation from '../../../hooks/useLocation';
|
||||
import { FormattedMessage, Link } from 'dumi';
|
||||
import RcFooter from 'rc-footer';
|
||||
import type { FooterColumn } from 'rc-footer/lib/column';
|
||||
import React, { useContext } from 'react';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import useLocation from '../../../hooks/useLocation';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import AdditionalInfo from './AdditionalInfo';
|
||||
import SiteContext from '../SiteContext';
|
||||
import AdditionalInfo from './AdditionalInfo';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
@ -87,7 +87,7 @@ const useStyle = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const Footer = () => {
|
||||
const Footer: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const [locale, lang] = useLocale(locales);
|
||||
const style = useStyle();
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import * as utils from '../../utils';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import * as React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import * as utils from '../../utils';
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
@ -31,8 +31,8 @@ const useStyle = () => {
|
||||
|
||||
img {
|
||||
height: 32px;
|
||||
margin-inline-end: 12px;
|
||||
vertical-align: middle;
|
||||
margin-inline-end: 12px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: ${mobileMaxWidth}px) {
|
||||
@ -40,6 +40,9 @@ const useStyle = () => {
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
`,
|
||||
title: css`
|
||||
line-height: 32px;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
@ -48,15 +51,14 @@ export interface LogoProps {
|
||||
location: any;
|
||||
}
|
||||
|
||||
const Logo = ({ isZhCN }: LogoProps) => {
|
||||
const Logo: React.FC<LogoProps> = ({ isZhCN }) => {
|
||||
const { search } = useLocation();
|
||||
const { logo } = useStyle();
|
||||
|
||||
const { logo, title } = useStyle();
|
||||
return (
|
||||
<h1>
|
||||
<Link to={utils.getLocalizedPathname('/', isZhCN, search)} css={logo}>
|
||||
<img alt="logo" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
||||
<span style={{ lineHeight: '32px' }}>Ant Design</span>
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" alt="logo" />
|
||||
<span css={title}>Ant Design</span>
|
||||
</Link>
|
||||
</h1>
|
||||
);
|
||||
|
@ -1,79 +1,88 @@
|
||||
import * as React from 'react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { css } from '@emotion/react';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import { FormattedMessage } from 'dumi';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import type { SharedProps } from './interface';
|
||||
|
||||
const smallStyle = { fontSize: 12, color: '#777', marginLeft: '0.3em' };
|
||||
const useStyle = (rtl?: boolean) => ({
|
||||
smallStyle: css`
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
margin-left: 0.3em;
|
||||
`,
|
||||
downOutlined: css`
|
||||
font-size: 9px;
|
||||
margin: ${rtl ? '-1px 2px 0 0' : '-1px 0 0 2px'};
|
||||
vertical-align: middle;
|
||||
`,
|
||||
});
|
||||
|
||||
export function getEcosystemGroup(): Exclude<MenuProps['items'], undefined> {
|
||||
return [
|
||||
{
|
||||
label: (
|
||||
<a href="https://charts.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.charts" />
|
||||
</a>
|
||||
),
|
||||
key: 'charts',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://pro.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.v4" />
|
||||
</a>
|
||||
),
|
||||
key: 'pro',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://procomponents.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.components" />
|
||||
</a>
|
||||
),
|
||||
key: 'procomponents',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://ng.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Angular
|
||||
<span style={smallStyle}>
|
||||
(
|
||||
<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
</a>
|
||||
),
|
||||
key: 'ng',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://antdv.com" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Vue
|
||||
<span style={smallStyle}>
|
||||
(
|
||||
<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
</a>
|
||||
),
|
||||
key: 'vue',
|
||||
},
|
||||
];
|
||||
}
|
||||
const Community: React.FC = () => {
|
||||
const { smallStyle } = useStyle();
|
||||
return (
|
||||
<span css={smallStyle}>
|
||||
(<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default (props: SharedProps) => {
|
||||
const downStyle = props.isRTL ? '-1px 2px 0 0' : '-1px 0 0 2px';
|
||||
export const getEcosystemGroup = (): MenuProps['items'] => [
|
||||
{
|
||||
label: (
|
||||
<a href="https://charts.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.charts" />
|
||||
</a>
|
||||
),
|
||||
key: 'charts',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://pro.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.v4" />
|
||||
</a>
|
||||
),
|
||||
key: 'pro',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://procomponents.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.components" />
|
||||
</a>
|
||||
),
|
||||
key: 'procomponents',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://ng.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Angular
|
||||
<Community />
|
||||
</a>
|
||||
),
|
||||
key: 'ng',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://antdv.com" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Vue
|
||||
<Community />
|
||||
</a>
|
||||
),
|
||||
key: 'vue',
|
||||
},
|
||||
];
|
||||
|
||||
const More: React.FC<SharedProps> = ({ isRTL }) => {
|
||||
const { downOutlined } = useStyle(isRTL);
|
||||
return (
|
||||
<Dropdown menu={{ items: getEcosystemGroup() }} placement="bottomRight">
|
||||
<Button size="small">
|
||||
<FormattedMessage id="app.header.menu.more" />
|
||||
<DownOutlined
|
||||
style={{
|
||||
fontSize: '9px',
|
||||
margin: downStyle,
|
||||
verticalAlign: 'middle',
|
||||
}}
|
||||
/>
|
||||
<DownOutlined css={downOutlined} />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default More;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import { Tooltip } from 'antd';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export interface LangBtnProps {
|
||||
@ -17,12 +17,21 @@ const BASE_SIZE = '1.2em';
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
const { controlHeight, motionDurationMid } = token;
|
||||
|
||||
const {
|
||||
colorText,
|
||||
colorBorder,
|
||||
colorBgContainer,
|
||||
colorBgTextHover,
|
||||
borderRadius,
|
||||
controlHeight,
|
||||
motionDurationMid,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
btn: css`
|
||||
color: ${token.colorText};
|
||||
border-color: ${token.colorBorder};
|
||||
color: ${colorText};
|
||||
border-color: ${colorBorder};
|
||||
padding: 0 !important;
|
||||
width: ${controlHeight}px;
|
||||
height: ${controlHeight}px;
|
||||
@ -31,100 +40,67 @@ const useStyle = () => {
|
||||
justify-content: center;
|
||||
border: none;
|
||||
background: transparent;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
border-radius: ${borderRadius}px;
|
||||
transition: all ${motionDurationMid};
|
||||
cursor: pointer;
|
||||
|
||||
.btn-inner {
|
||||
transition: all ${motionDurationMid};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorBgTextHover};
|
||||
background: ${colorBgTextHover};
|
||||
}
|
||||
|
||||
img {
|
||||
width: ${BASE_SIZE};
|
||||
height: ${BASE_SIZE};
|
||||
}
|
||||
|
||||
.anticon {
|
||||
font-size: ${BASE_SIZE};
|
||||
}
|
||||
`,
|
||||
innerDiv: css`
|
||||
position: relative;
|
||||
width: ${BASE_SIZE};
|
||||
height: ${BASE_SIZE};
|
||||
`,
|
||||
labelStyle: css`
|
||||
position: absolute;
|
||||
font-size: ${BASE_SIZE};
|
||||
line-height: 1;
|
||||
border: 1px solid ${colorText};
|
||||
color: ${colorText};
|
||||
`,
|
||||
label1Style: css`
|
||||
left: -5%;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background-color: ${colorText};
|
||||
color: ${colorBgContainer};
|
||||
transform: scale(0.7);
|
||||
transform-origin: 0 0;
|
||||
`,
|
||||
label2Style: css`
|
||||
right: -5%;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
transform: scale(0.5);
|
||||
transform-origin: 100% 100%;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
export default function LangBtn({
|
||||
label1,
|
||||
label2,
|
||||
tooltip1,
|
||||
tooltip2,
|
||||
value,
|
||||
pure,
|
||||
onClick,
|
||||
}: LangBtnProps) {
|
||||
const { token } = useSiteToken();
|
||||
const style = useStyle();
|
||||
const LangBtn: React.FC<LangBtnProps> = (props) => {
|
||||
const { label1, label2, tooltip1, tooltip2, value, pure, onClick } = props;
|
||||
|
||||
let label1Style: React.CSSProperties;
|
||||
let label2Style: React.CSSProperties;
|
||||
const { btn, innerDiv, labelStyle, label1Style, label2Style } = useStyle();
|
||||
|
||||
const iconStyle: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
fontSize: BASE_SIZE,
|
||||
lineHeight: 1,
|
||||
border: `1px solid ${token.colorText}`,
|
||||
color: token.colorText,
|
||||
};
|
||||
|
||||
const fontStyle: React.CSSProperties = {
|
||||
left: '-5%',
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
background: token.colorText,
|
||||
color: token.colorBgContainer,
|
||||
transformOrigin: '0 0',
|
||||
transform: `scale(0.7)`,
|
||||
};
|
||||
const backStyle: React.CSSProperties = {
|
||||
right: '-5%',
|
||||
bottom: 0,
|
||||
zIndex: 0,
|
||||
transformOrigin: '100% 100%',
|
||||
transform: `scale(0.5)`,
|
||||
};
|
||||
|
||||
if (value === 1) {
|
||||
label1Style = fontStyle;
|
||||
label2Style = backStyle;
|
||||
} else {
|
||||
label1Style = backStyle;
|
||||
label2Style = fontStyle;
|
||||
}
|
||||
|
||||
let node = (
|
||||
<button onClick={onClick} css={[style.btn]} key="lang-button">
|
||||
const node = (
|
||||
<button onClick={onClick} css={btn} key="lang-button">
|
||||
<div className="btn-inner">
|
||||
{pure && (value === 1 ? label1 : label2)}
|
||||
{!pure && (
|
||||
<div style={{ position: 'relative', width: BASE_SIZE, height: BASE_SIZE }}>
|
||||
<span
|
||||
style={{
|
||||
...iconStyle,
|
||||
...label1Style,
|
||||
}}
|
||||
>
|
||||
{label1}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
...iconStyle,
|
||||
...label2Style,
|
||||
}}
|
||||
>
|
||||
{label2}
|
||||
</span>
|
||||
<div css={innerDiv}>
|
||||
<span css={[labelStyle, value === 1 ? label1Style : label2Style]}>{label1}</span>
|
||||
<span css={[labelStyle, value === 1 ? label2Style : label1Style]}>{label2}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -132,8 +108,10 @@ export default function LangBtn({
|
||||
);
|
||||
|
||||
if (tooltip1 || tooltip2) {
|
||||
node = <Tooltip title={value === 1 ? tooltip1 : tooltip2}>{node}</Tooltip>;
|
||||
return <Tooltip title={value === 1 ? tooltip1 : tooltip2}>{node}</Tooltip>;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
export default LangBtn;
|
||||
|
@ -1,20 +1,21 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
import classNames from 'classnames';
|
||||
import { Col, Modal, Popover, Row, Select } from 'antd';
|
||||
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
|
||||
import { ClassNames, css } from '@emotion/react';
|
||||
import { Col, Modal, Popover, Row, Select } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useLocation } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import packageJson from '../../../../package.json';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import * as utils from '../../utils';
|
||||
import { getThemeConfig, ping } from '../../utils';
|
||||
import packageJson from '../../../../package.json';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import type { SharedProps } from './interface';
|
||||
import Logo from './Logo';
|
||||
import More from './More';
|
||||
import Navigation from './Navigation';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SwitchBtn from './SwitchBtn';
|
||||
|
||||
const RESPONSIVE_XS = 1120;
|
||||
@ -262,7 +263,7 @@ const Header: React.FC = () => {
|
||||
'home-header': isHome,
|
||||
});
|
||||
|
||||
const sharedProps = {
|
||||
const sharedProps: SharedProps = {
|
||||
isZhCN,
|
||||
isRTL,
|
||||
isClient,
|
||||
|
Loading…
Reference in New Issue
Block a user