docs: migrate to antd-style (#43623)

* docs: migrate to antd-style

* [CodeFactor] Apply fixes

* chore: code clean

* chore: lint

* chore: try cache

* chore: try

* fix: ssr

* chore: code clean

---------

Co-authored-by: codefactor-io <support@codefactor.io>
This commit is contained in:
MadCcc 2023-07-20 19:27:33 +08:00 committed by GitHub
parent 9bc006c125
commit e96059cd76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 475 additions and 520 deletions

View File

@ -1,35 +0,0 @@
import { theme } from 'antd';
import { useContext } from 'react';
import { ConfigContext } from 'antd/es/config-provider';
const { useToken } = theme;
const useSiteToken = () => {
const result = useToken();
const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext);
const rootPrefixCls = getPrefixCls();
const { token } = result;
const siteMarkdownCodeBg = token.colorFillTertiary;
return {
...result,
token: {
...token,
headerHeight: 64,
menuItemBorder: 2,
mobileMaxWidth: 767.99,
siteMarkdownCodeBg,
antCls: `.${rootPrefixCls}`,
iconCls: `.${iconPrefixCls}`,
/** 56 */
marginFarXS: (token.marginXXL / 6) * 7,
/** 80 */
marginFarSM: (token.marginXXL / 3) * 5,
/** 96 */
marginFar: token.marginXXL * 2,
codeFamily: `'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace`,
},
};
};
export default useSiteToken;

View File

@ -1,9 +1,9 @@
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import { Button, Space, Typography } from 'antd';
import { Link, useLocation } from 'dumi';
import * as React from 'react';
import classNames from 'classnames';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import SiteContext from '../../../theme/slots/SiteContext';
import * as utils from '../../../theme/utils';
import { GroupMask } from './Group';
@ -23,10 +23,8 @@ const locales = {
};
const useStyle = () => {
const { token } = useSiteToken();
const { isMobile } = React.useContext(SiteContext);
return {
return createStyles(({ token }) => ({
titleBase: css`
h1& {
font-family: AliPuHui, ${token.fontFamily};
@ -48,7 +46,7 @@ const useStyle = () => {
font-size: 68px;
}
`,
};
}))();
};
export interface BannerProps {
@ -58,8 +56,8 @@ export interface BannerProps {
export default function Banner({ children }: BannerProps) {
const [locale] = useLocale(locales);
const { pathname, search } = useLocation();
const { token } = useSiteToken();
const styles = useStyle();
const token = useTheme();
const { styles } = useStyle();
const { isMobile } = React.useContext(SiteContext);
const isZhCN = utils.isZhCN(pathname);
@ -146,7 +144,7 @@ export default function Banner({ children }: BannerProps) {
alt="bg"
/>
<Typography.Title level={1} css={[styles.titleBase, styles.title]}>
<Typography.Title level={1} className={classNames(styles.titleBase, styles.title)}>
Ant Design 5.0
</Typography.Title>
<Typography.Paragraph

View File

@ -1,15 +1,13 @@
import * as React from 'react';
import { Typography, Skeleton, Carousel } from 'antd';
import type { SerializedStyles } from '@emotion/react';
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import classNames from 'classnames';
import type { Extra, Icon } from './util';
import useSiteToken from '../../../hooks/useSiteToken';
import SiteContext from '../../../theme/slots/SiteContext';
import { useCarouselStyle } from './util';
import { getCarouselStyle } from './util';
const useStyle = () => {
const { token } = useSiteToken();
const { carousel } = useCarouselStyle();
const useStyle = createStyles(({ token }) => {
const { carousel } = getCarouselStyle();
return {
itemBase: css`
@ -47,17 +45,17 @@ const useStyle = () => {
`,
carousel,
};
};
});
interface RecommendItemProps {
extra: Extra;
index: number;
icons: Icon[];
itemCss: SerializedStyles;
className?: string;
}
const RecommendItem = ({ extra, index, icons, itemCss }: RecommendItemProps) => {
const style = useStyle();
const { token } = useSiteToken();
const RecommendItem = ({ extra, index, icons, className }: RecommendItemProps) => {
const token = useTheme();
const { styles } = useStyle();
if (!extra) {
return <Skeleton key={index} />;
@ -69,7 +67,7 @@ const RecommendItem = ({ extra, index, icons, itemCss }: RecommendItemProps) =>
key={extra?.title}
href={extra.href}
target="_blank"
css={[style.itemBase, itemCss]}
className={classNames(styles.itemBase, className)}
rel="noreferrer"
>
<Typography.Title level={5}>{extra?.title}</Typography.Title>
@ -90,33 +88,33 @@ export interface BannerRecommendsProps {
}
export default function BannerRecommends({ extras = [], icons = [] }: BannerRecommendsProps) {
const styles = useStyle();
const { styles } = useStyle();
const { isMobile } = React.useContext(SiteContext);
const first3 = extras.length === 0 ? Array(3).fill(null) : extras.slice(0, 3);
return (
<div>
{isMobile ? (
<Carousel css={styles.carousel}>
<Carousel className={styles.carousel}>
{first3.map((extra, index) => (
<div key={index}>
<RecommendItem
extra={extra}
index={index}
icons={icons}
itemCss={styles.sliderItem}
className={styles.sliderItem}
/>
</div>
))}
</Carousel>
) : (
<div css={styles.container}>
<div className={styles.container}>
{first3.map((extra, index) => (
<RecommendItem
extra={extra}
index={index}
icons={icons}
itemCss={styles.cardItem}
className={styles.cardItem}
key={index}
/>
))}

View File

@ -14,11 +14,11 @@ import {
} from 'antd';
import dayjs from 'dayjs';
import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
import { createStyles, css, useTheme } from 'antd-style';
import classNames from 'classnames';
import useLocale from '../../../hooks/useLocale';
import SiteContext from '../../../theme/slots/SiteContext';
import { useCarouselStyle } from './util';
import { getCarouselStyle } from './util';
const SAMPLE_CONTENT_EN =
'Ant Design 5.0 use CSS-in-JS technology to provide dynamic & mix theme ability. And which use component level CSS-in-JS solution get your application a better performance.';
@ -55,9 +55,8 @@ const locales = {
},
};
const useStyle = () => {
const { token } = useSiteToken();
const { carousel } = useCarouselStyle();
const useStyle = createStyles(({ token }) => {
const { carousel } = getCarouselStyle();
return {
card: css`
@ -89,7 +88,7 @@ const useStyle = () => {
`,
carousel,
};
};
});
interface ComponentItemProps {
title: React.ReactNode;
@ -99,8 +98,8 @@ interface ComponentItemProps {
}
export default function ComponentsList() {
const { token } = useSiteToken();
const styles = useStyle();
const token = useTheme();
const { styles } = useStyle();
const [locale] = useLocale(locales);
const { isMobile } = useContext(SiteContext);
@ -239,10 +238,10 @@ export default function ComponentsList() {
const tagText = type === 'new' ? locale.new : locale.update;
return (
<div key={index} css={[styles.card, isMobile && styles.mobileCard]}>
<div key={index} className={classNames(styles.card, isMobile && styles.mobileCard)}>
{/* Decorator */}
<div
css={styles.cardCircle}
className={styles.cardCircle}
style={{
right: (index % 2) * -20 - 20,
bottom: (index % 3) * -40 - 20,
@ -274,7 +273,7 @@ export default function ComponentsList() {
return isMobile ? (
<div style={{ margin: '0 16px' }}>
<Carousel css={styles.carousel}>
<Carousel className={styles.carousel}>
{COMPONENTS.map(({ title, node, type }, index) => (
<ComponentItem title={title} node={node} type={type} index={index} key={index} />
))}

View File

@ -1,9 +1,8 @@
import { Col, Row, Typography } from 'antd';
import React, { useContext } from 'react';
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import { Link, useLocation } from 'dumi';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import * as utils from '../../../theme/utils';
import SiteContext from '../../../theme/slots/SiteContext';
@ -61,11 +60,8 @@ const locales = {
},
};
const useStyle = () => {
const { token } = useSiteToken();
return {
card: css`
const useStyle = createStyles(({ token, css }) => ({
card: css`
padding: ${token.paddingSM}px;
border-radius: ${token.borderRadius * 2}px;
background: #fff;
@ -79,7 +75,7 @@ const useStyle = () => {
}
`,
cardMini: css`
cardMini: css`
display: block;
border-radius: ${token.borderRadius * 2}px;
padding: ${token.paddingMD}px ${token.paddingLG}px;
@ -90,13 +86,12 @@ const useStyle = () => {
height: 48px;
}
`,
};
};
}));
export default function DesignFramework() {
const [locale] = useLocale(locales);
const { token } = useSiteToken();
const style = useStyle();
const token = useTheme();
const { styles } = useStyle();
const { pathname, search } = useLocation();
const isZhCN = utils.isZhCN(pathname);
const { isMobile } = useContext(SiteContext);
@ -129,7 +124,7 @@ export default function DesignFramework() {
return (
<Col key={index} span={colSpan}>
<Link to={path}>
<div css={style.card}>
<div className={styles.card}>
<img alt={title} src={img} />
<Typography.Title
@ -153,7 +148,7 @@ export default function DesignFramework() {
return (
<Col key={index} span={colSpan}>
<a css={style.cardMini} target="_blank" href={url} rel="noreferrer">
<a className={styles.cardMini} target="_blank" href={url} rel="noreferrer">
<img alt={title} src={img} style={{ transform: `scale(${imgScale})` }} />
<Typography.Title

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import { useContext } from 'react';
import { Typography } from 'antd';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
import SiteContext from '../../../theme/slots/SiteContext';
export interface GroupMaskProps {
@ -50,7 +50,7 @@ export interface GroupProps {
export default function Group(props: GroupProps) {
const { id, title, titleColor, description, children, decoration, background, collapse } = props;
const { token } = useSiteToken();
const token = useTheme();
const { isMobile } = useContext(SiteContext);
const marginStyle: React.CSSProperties = collapse

View File

@ -1,14 +1,10 @@
import * as React from 'react';
import { Row, Col, Typography } from 'antd';
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import type { Recommendation } from './util';
import useSiteToken from '../../../hooks/useSiteToken';
const useStyle = () => {
const { token } = useSiteToken();
return {
card: css`
const useStyle = createStyles(({ token }) => ({
card: css`
height: 300px;
background-size: 100% 100%;
background-position: center;
@ -70,16 +66,15 @@ const useStyle = () => {
}
}
`,
};
};
}));
export interface RecommendsProps {
recommendations?: Recommendation[];
}
export default function Recommends({ recommendations = [] }: RecommendsProps) {
const { token } = useSiteToken();
const style = useStyle();
const token = useTheme();
const { styles } = useStyle();
return (
<Row gutter={token.marginLG}>
@ -89,7 +84,7 @@ export default function Recommends({ recommendations = [] }: RecommendsProps) {
return (
<Col key={index} span={8}>
{data ? (
<div css={style.card} style={{ backgroundImage: `url(${data.img})` }}>
<div className={styles.card} style={{ backgroundImage: `url(${data.img})` }}>
<div className="intro">
<Typography.Title level={4}>{data?.title}</Typography.Title>
<Typography.Paragraph>{data.description}</Typography.Paragraph>

View File

@ -1,6 +1,5 @@
import { css } from '@emotion/react';
import { createStyles, css } from 'antd-style';
import React, { useMemo } from 'react';
import useSiteToken from '../../../../hooks/useSiteToken';
import { COLOR_IMAGES, getClosetColor } from './colorUtil';
export interface BackgroundImageProps {
@ -8,10 +7,8 @@ export interface BackgroundImageProps {
isLight?: boolean;
}
const useStyle = () => {
const { token } = useSiteToken();
return {
image: css`
const useStyle = createStyles(({ token }) => ({
image: css`
transition: all ${token.motionDurationSlow};
position: absolute;
left: 0;
@ -21,19 +18,18 @@ const useStyle = () => {
object-fit: cover;
object-position: right top;
`,
};
};
}));
const BackgroundImage: React.FC<BackgroundImageProps> = ({ colorPrimary, isLight }) => {
const activeColor = useMemo(() => getClosetColor(colorPrimary), [colorPrimary]);
const { image } = useStyle();
const { styles } = useStyle();
return (
<>
{COLOR_IMAGES.filter(({ url }) => url).map(({ color, url }) => (
<img
css={image}
className={styles.image}
style={{ opacity: isLight && activeColor === color ? 1 : 0 }}
key={color}
src={url}

View File

@ -1,17 +1,14 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { ColorPicker, Input, Space } from 'antd';
import type { Color, ColorPickerProps } from 'antd/es/color-picker';
import { generateColor } from 'antd/es/color-picker/util';
import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import useSiteToken from '../../../../hooks/useSiteToken';
import classNames from 'classnames';
import { PRESET_COLORS } from './colorUtil';
const useStyle = () => {
const { token } = useSiteToken();
return {
color: css`
const useStyle = createStyles(({ token, css }) => ({
color: css`
width: ${token.controlHeightLG / 2}px;
height: ${token.controlHeightLG / 2}px;
border-radius: 100%;
@ -30,12 +27,11 @@ const useStyle = () => {
}
`,
colorActive: css`
colorActive: css`
box-shadow: 0 0 0 1px ${token.colorBgContainer},
0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary};
`,
};
};
}));
const DebouncedColorPicker: FC<ColorPickerProps> = ({ value: color, onChange, children }) => {
const [value, setValue] = useState(color);
@ -73,7 +69,7 @@ export interface RadiusPickerProps {
}
export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps) {
const style = useStyle();
const { styles } = useStyle();
const matchColors = React.useMemo(() => {
const valueStr = generateColor(value).toRgbString();
@ -117,7 +113,7 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps)
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label
key={color}
css={[style.color, active && style.colorActive]}
className={classNames(styles.color, active && styles.colorActive)}
style={{
background: color,
}}

View File

@ -1,12 +1,11 @@
import * as React from 'react';
import { useState } from 'react';
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import { Typography, Carousel } from 'antd';
import { useCarouselStyle } from '../util';
import useSiteToken from '../../../../hooks/useSiteToken';
import { getCarouselStyle } from '../util';
const useStyle = () => {
const { carousel } = useCarouselStyle();
const useStyle = createStyles(() => {
const { carousel } = getCarouselStyle();
return {
carousel,
container: css`
@ -20,7 +19,7 @@ const useStyle = () => {
text-align: center;
`,
};
};
});
const mobileImageConfigList = [
{
@ -77,14 +76,14 @@ export interface MobileCarouselProps {
}
export default function MobileCarousel(props: MobileCarouselProps) {
const styles = useStyle();
const { styles } = useStyle();
const { id, title, description } = props;
const { token } = useSiteToken();
const token = useTheme();
const [currentSlider, setCurrentSlider] = useState<number>(0);
return (
<div css={styles.container}>
<div css={styles.title}>
<div className={styles.container}>
<div className={styles.title}>
<Typography.Title
id={id}
level={1}
@ -107,7 +106,7 @@ export default function MobileCarousel(props: MobileCarouselProps) {
{description}
</Typography.Paragraph>
</div>
<Carousel css={styles.carousel} afterChange={setCurrentSlider}>
<Carousel className={styles.carousel} afterChange={setCurrentSlider}>
{mobileImageConfigList.map((item, index) => (
<div key={index}>
<img src={item.imageSrc} alt="" style={{ width: '100%' }} />

View File

@ -1,7 +1,7 @@
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import { Space } from 'antd';
import * as React from 'react';
import useSiteToken from '../../../../hooks/useSiteToken';
import classNames from 'classnames';
import useLocale from '../../../../hooks/useLocale';
export const THEMES = {
@ -28,11 +28,8 @@ const locales = {
},
};
const useStyle = () => {
const { token } = useSiteToken();
return {
themeCard: css`
const useStyle = createStyles(({ token, css }) => ({
themeCard: css`
border-radius: ${token.borderRadius}px;
cursor: pointer;
transition: all ${token.motionDurationSlow};
@ -57,7 +54,7 @@ const useStyle = () => {
}
`,
themeCardActive: css`
themeCardActive: css`
box-shadow: 0 0 0 1px ${token.colorBgContainer},
0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary};
@ -66,8 +63,7 @@ const useStyle = () => {
transform: scale(1);
}
`,
};
};
}));
export interface ThemePickerProps {
value?: string;
@ -75,8 +71,8 @@ export interface ThemePickerProps {
}
export default function ThemePicker({ value, onChange }: ThemePickerProps) {
const { token } = useSiteToken();
const style = useStyle();
const token = useTheme();
const { styles } = useStyle();
const [locale] = useLocale(locales);
@ -89,7 +85,7 @@ export default function ThemePicker({ value, onChange }: ThemePickerProps) {
<Space key={theme} direction="vertical" align="center">
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label
css={[style.themeCard, value === theme && style.themeCardActive]}
className={classNames(styles.themeCard, value === theme && styles.themeCardActive)}
onClick={() => {
onChange?.(theme);
}}

View File

@ -4,7 +4,7 @@ import {
HomeOutlined,
QuestionCircleOutlined,
} from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import type { MenuProps } from 'antd';
import {
Breadcrumb,
@ -22,11 +22,11 @@ import {
import type { Color } from 'antd/es/color-picker';
import { generateColor } from 'antd/es/color-picker/util';
import * as React from 'react';
import classNames from 'classnames';
import useLocale from '../../../../hooks/useLocale';
import useSiteToken from '../../../../hooks/useSiteToken';
import SiteContext from '../../../../theme/slots/SiteContext';
import Group from '../Group';
import { useCarouselStyle } from '../util';
import { getCarouselStyle } from '../util';
import BackgroundImage from './BackgroundImage';
import ColorPicker from './ColorPicker';
import MobileCarousel from './MobileCarousel';
@ -83,35 +83,44 @@ const locales = {
};
// ============================= Style =============================
const useStyle = () => {
const { token } = useSiteToken();
const { carousel } = useCarouselStyle();
const useStyle = createStyles(({ token, cx }) => {
const { carousel } = getCarouselStyle();
return {
demo: css`
const demo = css`
overflow: hidden;
background: rgba(240, 242, 245, 0.25);
backdrop-filter: blur(50px);
box-shadow: 0 2px 10px 2px rgba(0, 0, 0, 0.1);
transition: all ${token.motionDurationSlow};
`,
`;
return {
demo,
otherDemo: css`
backdrop-filter: blur(10px);
background: rgba(247, 247, 247, 0.5);
&.${cx(demo)} {
backdrop-filter: blur(10px);
background: rgba(247, 247, 247, 0.5);
}
`,
darkDemo: css`
background: #000;
&.${cx(demo)} {
background: #000;
}
`,
larkDemo: css`
// background: #f7f7f7;
background: rgba(240, 242, 245, 0.65);
&.${cx(demo)} {
// background: #f7f7f7;
background: rgba(240, 242, 245, 0.65);
}
`,
comicDemo: css`
// background: #ffe4e6;
background: rgba(240, 242, 245, 0.65);
&.${cx(demo)} {
// background: #ffe4e6;
background: rgba(240, 242, 245, 0.65);
}
`,
menu: css`
@ -184,7 +193,7 @@ const useStyle = () => {
`,
carousel,
};
};
});
// ========================== Menu Config ==========================
const subMenuItems: MenuProps['items'] = [
@ -271,8 +280,8 @@ const ThemesInfo: Record<THEME, Partial<ThemeData>> = {
};
export default function Theme() {
const style = useStyle();
const { token } = useSiteToken();
const { styles } = useStyle();
const token = useTheme();
const [locale] = useLocale(locales);
const [themeData, setThemeData] = React.useState<ThemeData>(ThemeDefault);
@ -348,25 +357,11 @@ export default function Theme() {
theme={{
token: {
...themeToken,
...(isLight
? {}
: {
// colorBgContainer: '#474C56',
// colorBorderSecondary: 'rgba(255,255,255,0.06)',
}),
colorPrimary: colorPrimaryValue,
},
hashed: true,
algorithm: algorithmFn,
components: {
Slider: {
// 1677FF
},
Card: isLight
? {}
: {
// colorBgContainer: '#474C56',
},
Layout: isLight
? {
colorBgHeader: 'transparent',
@ -379,7 +374,7 @@ export default function Theme() {
? {
itemBg: 'transparent',
subMenuItemBg: 'transparent',
colorActiveBarWidth: 0,
activeBarBorderWidth: 0,
}
: {
// colorItemBg: 'transparent',
@ -392,18 +387,24 @@ export default function Theme() {
>
<TokenChecker />
<div
css={[
style.demo,
isLight && closestColor !== DEFAULT_COLOR && style.otherDemo,
!isLight && style.darkDemo,
]}
className={classNames(styles.demo, {
[styles.otherDemo]: isLight && closestColor !== DEFAULT_COLOR && styles.otherDemo,
[styles.darkDemo]: !isLight,
})}
style={{ borderRadius: themeData.borderRadius }}
>
<Layout css={style.transBg}>
<Header css={[style.header, style.transBg, !isLight && style.headerDark]}>
<Layout className={styles.transBg}>
<Header
className={classNames(styles.header, styles.transBg, !isLight && styles.headerDark)}
>
{/* Logo */}
<div css={style.logo}>
<div css={[style.logoImg, closestColor !== DEFAULT_COLOR && style.logoImgPureColor]}>
<div className={styles.logo}>
<div
className={classNames(
styles.logoImg,
closestColor !== DEFAULT_COLOR && styles.logoImgPureColor,
)}
>
<img
src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
style={{
@ -418,11 +419,11 @@ export default function Theme() {
<h1>Ant Design 5.0</h1>
</div>
<Space css={style.menu} size="middle">
<Space className={styles.menu} size="middle">
<BellOutlined />
<QuestionCircleOutlined />
<div
css={[style.avatar, themeType === 'dark' && style.avatarDark]}
className={classNames(styles.avatar, themeType === 'dark' && styles.avatarDark)}
style={{
backgroundColor: avatarColor,
backgroundImage: `url(${getAvatarURL(closestColor)})`,
@ -432,23 +433,23 @@ export default function Theme() {
/>
</Space>
</Header>
<Layout css={style.transBg} hasSider>
<Sider css={style.transBg} width={200} className="site-layout-background">
<Layout className={styles.transBg} hasSider>
<Sider className={classNames(styles.transBg, 'site-layout-background')} width={200}>
<Menu
mode="inline"
css={[style.transBg, !isLight && style.darkSideMenu]}
className={classNames(styles.transBg, !isLight && styles.darkSideMenu)}
selectedKeys={['Themes']}
openKeys={['Design']}
style={{ height: '100%', borderRight: 0 }}
items={sideMenuItems}
/>
</Sider>
<Layout css={style.transBg} style={{ padding: '0 24px 24px' }}>
<Layout className={styles.transBg} style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>
<HomeOutlined />
</Breadcrumb.Item>
<Breadcrumb.Item overlay={<Menu items={subMenuItems} />}>Design</Breadcrumb.Item>
<Breadcrumb.Item menu={{ items: subMenuItems }}>Design</Breadcrumb.Item>
<Breadcrumb.Item>Themes</Breadcrumb.Item>
</Breadcrumb>
<Content>
@ -468,7 +469,7 @@ export default function Theme() {
onValuesChange={onThemeChange}
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
css={style.form}
className={styles.form}
>
<Form.Item label={locale.titleTheme} name="themeType">
<ThemePicker />

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import { css } from '@emotion/react';
import { css } from 'antd-style';
export interface Author {
avatar: string;
@ -99,7 +99,7 @@ export function useSiteData(): [Partial<SiteData>, boolean] {
return [data, loading];
}
export const useCarouselStyle = () => ({
export const getCarouselStyle = () => ({
carousel: css`
.slick-dots.slick-dots-bottom {
bottom: -22px;

View File

@ -1,4 +1,4 @@
import { css } from '@emotion/react';
import { createStyles, css } from 'antd-style';
import { ConfigProvider } from 'antd';
import { useLocale as useDumiLocale } from 'dumi';
import React from 'react';
@ -11,14 +11,14 @@ import Group from './components/Group';
import Theme from './components/Theme';
import { useSiteData } from './components/util';
const useStyle = () => ({
const useStyle = createStyles(() => ({
image: css`
position: absolute;
left: 0;
top: -50px;
height: 160px;
`,
});
}));
const locales = {
cn: {
@ -39,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 { styles } = useStyle();
const [siteData] = useSiteData();
return (
@ -65,7 +65,7 @@ const Homepage: React.FC = () => {
background="#F5F8FF"
decoration={
<img
css={image}
className={styles.image}
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
alt=""
/>

View File

@ -1,4 +1,4 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { Button, ConfigProvider, Modal, Spin, Typography, message } from 'antd';
import { ThemeEditor, enUS, zhCN } from 'antd-token-previewer';
import type { ThemeConfig } from 'antd/es/config-provider/context';
@ -38,7 +38,7 @@ const locales = {
},
};
const useStyle = () => ({
const useStyle = createStyles(({ css }) => ({
header: css({
display: 'flex',
height: 56,
@ -47,7 +47,7 @@ const useStyle = () => ({
justifyContent: 'space-between',
borderBottom: '1px solid #F0F0F0',
}),
});
}));
const ANT_DESIGN_V5_THEME_EDITOR_THEME = 'ant-design-v5-theme-editor-theme';
@ -77,7 +77,7 @@ const CustomTheme = () => {
}
}, []);
const styles = useStyle();
const { styles } = useStyle();
const handleSave = () => {
localStorage.setItem(ANT_DESIGN_V5_THEME_EDITOR_THEME, JSON.stringify(theme));
@ -140,7 +140,7 @@ const CustomTheme = () => {
</Helmet>
{contextHolder}
<ConfigProvider theme={{ inherit: false }}>
<div css={styles.header}>
<div className={styles.header}>
<Typography.Title level={5} style={{ margin: 0 }}>
{locale.title}
</Typography.Title>

View File

@ -4,6 +4,25 @@ import { ThemeProvider } from 'antd-style';
import type { FC } from 'react';
import React, { useContext } from 'react';
interface NewToken {
headerHeight: number;
menuItemBorder: number;
mobileMaxWidth: number;
siteMarkdownCodeBg: string;
antCls: string;
iconCls: string;
marginFarXS: number;
marginFarSM: number;
marginFar: number;
codeFamily: string;
}
// 通过给 antd-style 扩展 CustomToken 对象类型定义,可以为 useTheme 中增加相应的 token 对象
declare module 'antd-style' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CustomToken extends NewToken {}
}
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, theme, ...rest }) => {
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
const rootPrefixCls = getPrefixCls();
@ -16,7 +35,7 @@ const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, theme, ...rest })
}, [theme]);
return (
<ThemeProvider
<ThemeProvider<NewToken>
{...rest}
theme={theme}
customToken={{

View File

@ -1,25 +1,21 @@
import { TinyColor, type ColorInput } from '@ctrl/tinycolor';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import * as React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
interface ColorChunkProps {
children?: React.ReactNode;
color?: ColorInput;
}
const useStyle = () => {
const { token } = useSiteToken();
return {
codeSpan: css`
const useStyle = createStyles(({ token, css }) => ({
codeSpan: css`
padding: 0.2em 0.4em;
font-size: 0.9em;
background: ${token.siteMarkdownCodeBg};
border-radius: ${token.borderRadius}px;
font-family: monospace;
`,
dot: css`
dot: css`
display: inline-block;
width: 6px;
height: 6px;
@ -27,11 +23,10 @@ const useStyle = () => {
margin-inline-end: 4px;
border: 1px solid ${token.colorSplit};
`,
};
};
}));
const ColorChunk: React.FC<ColorChunkProps> = (props) => {
const styles = useStyle();
const { styles } = useStyle();
const { color, children } = props;
const dotColor = React.useMemo(() => {
@ -40,8 +35,8 @@ const ColorChunk: React.FC<ColorChunkProps> = (props) => {
}, [color]);
return (
<span css={styles.codeSpan}>
<span css={styles.dot} style={{ backgroundColor: dotColor }} />
<span className={styles.codeSpan}>
<span className={styles.dot} style={{ backgroundColor: dotColor }} />
{children ?? dotColor}
</span>
);

View File

@ -1,51 +1,48 @@
import React, { memo, useContext, useMemo, useRef, useState } from 'react';
import type { CSSProperties } from 'react';
import { Link, useIntl, useSidebarData, useLocation } from 'dumi';
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import debounce from 'lodash/debounce';
import { Card, Col, Divider, Input, Row, Space, Tag, Typography, Affix } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import type { Component } from './ProComponentsList';
import proComponentsList from './ProComponentsList';
import useSiteToken from '../../../hooks/useSiteToken';
import SiteContext from '../../slots/SiteContext';
const useStyle = () => {
const { token } = useSiteToken();
return {
componentsOverviewGroupTitle: css`
const useStyle = createStyles(({ token, css }) => ({
componentsOverviewGroupTitle: css`
margin-bottom: 24px !important;
`,
componentsOverviewTitle: css`
componentsOverviewTitle: css`
overflow: hidden;
color: ${token.colorTextHeading};
text-overflow: ellipsis;
`,
componentsOverviewImg: css`
componentsOverviewImg: css`
display: flex;
align-items: center;
justify-content: center;
height: 152px;
`,
componentsOverviewCard: css`
componentsOverviewCard: css`
cursor: pointer;
transition: all 0.5s;
&:hover {
box-shadow: 0 6px 16px -8px #00000014, 0 9px 28px #0000000d, 0 12px 48px 16px #00000008;
}
`,
componentsOverviewAffix: css`
componentsOverviewAffix: css`
display: flex;
transition: all 0.3s;
justify-content: space-between;
`,
componentsOverviewSearch: css`
componentsOverviewSearch: css`
padding: 0;
.anticon-search {
color: ${token.colorTextDisabled};
}
`,
componentsOverviewContent: css`
componentsOverviewContent: css`
&:empty:after {
display: block;
padding: 16px 0 40px;
@ -55,8 +52,7 @@ const useStyle = () => {
content: 'Not Found';
}
`,
};
};
}));
const onClickCard = (pathname: string) => {
if (window.gtag) {
@ -79,13 +75,13 @@ const reportSearch = debounce<(value: string) => void>((value) => {
const { Title } = Typography;
const Overview: React.FC = () => {
const style = useStyle();
const { styles } = useStyle();
const { theme } = useContext(SiteContext);
const data = useSidebarData();
const [searchBarAffixed, setSearchBarAffixed] = useState<boolean>(false);
const { token } = useSiteToken();
const token = useTheme();
const { borderRadius, colorBgContainer, fontSizeXL } = token;
const affixedStyle: CSSProperties = {
@ -144,12 +140,15 @@ const Overview: React.FC = () => {
<section className="markdown" ref={sectionRef}>
<Divider />
<Affix offsetTop={24} onChange={setSearchBarAffixed}>
<div css={style.componentsOverviewAffix} style={searchBarAffixed ? affixedStyle : {}}>
<div
className={styles.componentsOverviewAffix}
style={searchBarAffixed ? affixedStyle : {}}
>
<Input
autoFocus
value={search}
placeholder={formatMessage({ id: 'app.components.overview.search' })}
css={style.componentsOverviewSearch}
className={styles.componentsOverviewSearch}
onChange={(e) => {
setSearch(e.target.value);
reportSearch(e.target.value);
@ -162,7 +161,7 @@ const Overview: React.FC = () => {
</div>
</Affix>
<Divider />
<div css={style.componentsOverviewContent}>
<div className={styles.componentsOverviewContent}>
{groups
.filter((i) => i?.title)
.map((group) => {
@ -174,7 +173,7 @@ const Overview: React.FC = () => {
);
return components?.length ? (
<div key={group?.title}>
<Title level={2} css={style.componentsOverviewGroupTitle}>
<Title level={2} className={styles.componentsOverviewGroupTitle}>
<Space align="center">
<span style={{ fontSize: 24 }}>{group?.title}</span>
<Tag style={{ display: 'block' }}>{components.length}</Tag>
@ -203,14 +202,14 @@ const Overview: React.FC = () => {
backgroundImage: `url(${component?.tag || ''})`,
}}
size="small"
css={style.componentsOverviewCard}
className={styles.componentsOverviewCard}
title={
<div css={style.componentsOverviewTitle}>
<div className={styles.componentsOverviewTitle}>
{component?.title} {component.subtitle}
</div>
}
>
<div css={style.componentsOverviewImg}>
<div className={styles.componentsOverviewImg}>
<img
src={
theme.includes('dark') && component.coverDark

View File

@ -1,12 +1,11 @@
import { RightOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles, css, useTheme } from 'antd-style';
import { ConfigProvider, Table } from 'antd';
import { getDesignToken } from 'antd-token-previewer';
import tokenMeta from 'antd/es/version/token-meta.json';
import tokenData from 'antd/es/version/token.json';
import React, { useMemo, useState } from 'react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import { useColumns } from '../TokenTable';
const defaultToken = getDesignToken();
@ -30,7 +29,7 @@ const locales = {
},
};
const useStyle = () => ({
const useStyle = createStyles(() => ({
tableTitle: css`
cursor: pointer;
position: relative;
@ -46,7 +45,7 @@ const useStyle = () => ({
transition: all 0.3s;
}
`,
});
}));
interface SubTokenTableProps {
defaultOpen?: boolean;
@ -57,12 +56,12 @@ interface SubTokenTableProps {
const SubTokenTable: React.FC<SubTokenTableProps> = ({ defaultOpen, tokens, title, component }) => {
const [, lang] = useLocale(locales);
const { token } = useSiteToken();
const token = useTheme();
const columns = useColumns();
const [open, setOpen] = useState<boolean>(defaultOpen || process.env.NODE_ENV !== 'production');
const { tableTitle, arrowIcon } = useStyle();
const { styles } = useStyle();
if (!tokens.length) {
return null;
@ -107,8 +106,8 @@ const SubTokenTable: React.FC<SubTokenTableProps> = ({ defaultOpen, tokens, titl
return (
<div>
<div css={tableTitle} onClick={() => setOpen(!open)}>
<RightOutlined css={arrowIcon} rotate={open ? 90 : 0} />
<div className={styles.tableTitle} onClick={() => setOpen(!open)}>
<RightOutlined className={styles.arrowIcon} rotate={open ? 90 : 0} />
<h3>{title}</h3>
</div>
{open && (

View File

@ -4,14 +4,13 @@ import Icon, * as AntdIcons from '@ant-design/icons';
import type { SegmentedProps } from 'antd';
import type { IntlShape } from 'react-intl';
import { Segmented, Input, Empty, Affix } from 'antd';
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import { useIntl } from 'dumi';
import debounce from 'lodash/debounce';
import Category from './Category';
import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons';
import type { CategoriesKeys } from './fields';
import { categories } from './fields';
import useSiteToken from '../../../hooks/useSiteToken';
export enum ThemeType {
Filled = 'Filled',
@ -21,13 +20,13 @@ export enum ThemeType {
const allIcons: { [key: string]: any } = AntdIcons;
const useStyle = () => ({
const useStyle = createStyles(({ css }) => ({
iconSearchAffix: css`
display: flex;
transition: all 0.3s;
justify-content: space-between;
`,
});
}));
const options = (intl: IntlShape): SegmentedProps['options'] => [
{
@ -54,7 +53,7 @@ interface IconSearchState {
const IconSearch: React.FC = () => {
const intl = useIntl();
const { iconSearchAffix } = useStyle();
const { styles } = useStyle();
const [displayState, setDisplayState] = useState<IconSearchState>({
searchKey: '',
theme: ThemeType.Outlined,
@ -112,7 +111,7 @@ const IconSearch: React.FC = () => {
}, [displayState.searchKey, displayState.theme]);
const [searchBarAffixed, setSearchBarAffixed] = useState<boolean>(false);
const { token } = useSiteToken();
const token = useTheme();
const { borderRadius, colorBgContainer } = token;
const affixedStyle: CSSProperties = {
@ -124,11 +123,11 @@ const IconSearch: React.FC = () => {
};
return (
<div className='markdown'>
<div className="markdown">
<Affix offsetTop={24} onChange={setSearchBarAffixed}>
<div css={iconSearchAffix} style={searchBarAffixed ? affixedStyle : {}}>
<div className={styles.iconSearchAffix} style={searchBarAffixed ? affixedStyle : {}}>
<Segmented
size='large'
size="large"
value={displayState.theme}
options={options(intl)}
onChange={handleChangeTheme}
@ -138,7 +137,7 @@ const IconSearch: React.FC = () => {
style={{ flex: 1, marginInlineStart: 16 }}
allowClear
autoFocus
size='large'
size="large"
onChange={handleSearchIcon}
/>
</div>

View File

@ -1,13 +1,13 @@
import type { FC } from 'react';
import React, { useRef } from 'react';
import { createStyles, css } from 'antd-style';
import { createStyles } from 'antd-style';
import { CheckOutlined, SketchOutlined } from '@ant-design/icons';
import { nodeToGroup } from 'html2sketch';
import copy from 'copy-to-clipboard';
import { App } from 'antd';
import type { AntdPreviewerProps } from '.';
const useStyle = createStyles(({ token }) => ({
const useStyle = createStyles(({ token, css }) => ({
wrapper: css`
border: 1px solid ${token.colorBorderSecondary};
border-radius: ${token.borderRadius}px;

View File

@ -2,14 +2,12 @@
import * as React from 'react';
import dayjs from 'dayjs';
import { FormattedMessage, useIntl } from 'dumi';
import { Tabs, Skeleton, Avatar, Divider, Empty } from 'antd';
import { css } from '@emotion/react';
import { useSiteData } from '../../../pages/index/components/util';
import { Avatar, Divider, Empty, Skeleton, Tabs } from 'antd';
import { createStyles } from 'antd-style';
import type { Article, Authors } from '../../../pages/index/components/util';
import useSiteToken from '../../../hooks/useSiteToken';
import { useSiteData } from '../../../pages/index/components/util';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
@ -58,7 +56,7 @@ const useStyle = () => {
}
`,
};
};
});
interface ArticleListProps {
name: React.ReactNode;
@ -67,11 +65,11 @@ interface ArticleListProps {
}
const ArticleList: React.FC<ArticleListProps> = ({ name, data = [], authors = [] }) => {
const { articleList } = useStyle();
const { styles } = useStyle();
return (
<td>
<h4>{name}</h4>
<ul css={articleList}>
<ul className={styles.articleList}>
{data.length === 0 ? (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
) : (
@ -100,7 +98,7 @@ export default () => {
const isZhCN = locale === 'zh-CN';
const [{ articles = { cn: [], en: [] }, authors = [] }, loading] = useSiteData();
const styles = useStyle();
const { styles } = useStyle();
// ========================== Data ==========================
const mergedData = React.useMemo(() => {
@ -147,7 +145,7 @@ export default () => {
}
return (
<div id="articles" css={styles.articles}>
<div id="articles" className={styles.articles}>
{content}
</div>
);

View File

@ -1,12 +1,10 @@
import React from 'react';
import { Col, Row, Tooltip } from 'antd';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import useSiteToken from '../../../hooks/useSiteToken';
import useLocale from '../../../hooks/useLocale';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { boxShadowSecondary } = token;
return {
@ -60,7 +58,7 @@ const useStyle = () => {
line-height: 22px;
`,
};
};
});
export type Resource = {
title: string;
@ -88,7 +86,7 @@ export type ResourceCardProps = {
};
const ResourceCard: React.FC<ResourceCardProps> = ({ resource }) => {
const styles = useStyle();
const { styles } = useStyle();
const [locale] = useLocale(locales);
const { title: titleStr, description, cover, src, official } = resource;
@ -104,25 +102,25 @@ const ResourceCard: React.FC<ResourceCardProps> = ({ resource }) => {
return (
<Col xs={24} sm={12} md={8} lg={6} style={{ padding: 12 }}>
<a css={styles.card} target="_blank" href={src} rel="noreferrer">
<a className={styles.card} target="_blank" href={src} rel="noreferrer">
<img
css={styles.image}
className={styles.image}
src={cover}
alt={title}
style={coverColor ? { backgroundColor: coverColor } : {}}
/>
{official ? (
<div css={styles.badge}>{locale.official}</div>
<div className={styles.badge}>{locale.official}</div>
) : (
<Tooltip title={locale.thirdPartDesc}>
<div css={styles.badge}>
<div className={styles.badge}>
<ExclamationCircleOutlined />
{locale.thirdPart}
</div>
</Tooltip>
)}
<p css={styles?.title}>{title}</p>
<p css={styles.description}>{description}</p>
<p className={styles?.title}>{title}</p>
<p className={styles.description}>{description}</p>
</a>
</Col>
);

View File

@ -1,13 +1,11 @@
import type { FC } from 'react';
import * as React from 'react';
/* eslint import/no-unresolved: 0 */
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import type { TableProps } from 'antd';
import { Table } from 'antd';
import { getDesignToken } from 'antd-token-previewer';
import tokenMeta from 'antd/es/version/token-meta.json';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import ColorChunk from '../ColorChunk';
type TokenTableProps = {
@ -39,11 +37,8 @@ const locales = {
},
};
const useStyle = () => {
const { token } = useSiteToken();
return {
codeSpan: css`
const useStyle = createStyles(({ token, css }) => ({
codeSpan: css`
margin: 0 1px;
padding: 0.2em 0.4em;
font-size: 0.9em;
@ -52,12 +47,11 @@ const useStyle = () => {
border-radius: 3px;
font-family: monospace;
`,
};
};
}));
export function useColumns(): Exclude<TableProps<TokenData>['columns'], undefined> {
const [locale] = useLocale(locales);
const styles = useStyle();
const { styles } = useStyle();
return [
{
@ -74,7 +68,7 @@ export function useColumns(): Exclude<TableProps<TokenData>['columns'], undefine
title: locale.type,
key: 'type',
dataIndex: 'type',
render: (_, record) => <span css={styles.codeSpan}>{record.type}</span>,
render: (_, record) => <span className={styles.codeSpan}>{record.type}</span>,
},
{
title: locale.value,

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Global, css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
const gray = {
1: '#fff',
@ -19,7 +19,7 @@ const gray = {
};
const ColorStyle = () => {
const { token } = useSiteToken();
const token = useTheme();
const makePalette = (color: string, index: number = 1): string => {
if (index <= 10) {

View File

@ -1,8 +1,7 @@
import React from 'react';
import { Tooltip } from 'antd';
import { EditOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import useSiteToken from '../../hooks/useSiteToken';
import { createStyles } from 'antd-style';
const branchUrl = 'https://github.com/ant-design/ant-design/edit/master/';
@ -11,9 +10,7 @@ export interface EditButtonProps {
filename?: string;
}
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { colorIcon, colorText, iconCls } = token;
return {
@ -39,15 +36,15 @@ const useStyle = () => {
}
`,
};
};
});
export default function EditButton({ title, filename }: EditButtonProps) {
const styles = useStyle();
const { styles } = useStyle();
return (
<Tooltip title={title}>
<a
css={styles.editButton}
className={styles.editButton}
href={`${branchUrl}${filename}`}
target="_blank"
rel="noopener noreferrer"

View File

@ -1,14 +1,13 @@
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import type { MenuProps } from 'antd';
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
import type { ReactElement } from 'react';
import React, { useMemo } from 'react';
import classNames from 'classnames';
import useMenu from '../../hooks/useMenu';
import useSiteToken from '../../hooks/useSiteToken';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { colorSplit, iconCls, fontSizeIcon } = token;
return {
@ -85,7 +84,7 @@ const useStyle = () => {
}
`,
};
};
});
const flattenMenu = (menuItems: MenuProps['items']): MenuProps['items'] | null => {
if (Array.isArray(menuItems)) {
@ -103,7 +102,7 @@ const flattenMenu = (menuItems: MenuProps['items']): MenuProps['items'] | null =
};
const PrevAndNext: React.FC<{ rtl?: boolean }> = ({ rtl }) => {
const styles = useStyle();
const { styles } = useStyle();
const beforeProps = { className: 'footer-nav-icon-before' };
const afterProps = { className: 'footer-nav-icon-after' };
@ -130,14 +129,14 @@ const PrevAndNext: React.FC<{ rtl?: boolean }> = ({ rtl }) => {
}, [menuItems, selectedKey]);
return (
<section css={styles.prevNextNav}>
<section className={styles.prevNextNav}>
{prev &&
React.cloneElement(prev.label as ReactElement, {
css: [styles.pageNav, styles.prevNav],
className: classNames(styles.pageNav, styles.prevNav, prev.className),
})}
{next &&
React.cloneElement(next.label as ReactElement, {
css: [styles.pageNav, styles.nextNav],
className: classNames(styles.pageNav, styles.nextNav, next.className),
})}
</section>
);

View File

@ -3,7 +3,7 @@ import { FloatButton } from 'antd';
import { CompactTheme, DarkTheme, Motion } from 'antd-token-previewer/es/icons';
import { FormattedMessage, Link, useLocation } from 'dumi';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
import { getLocalizedPathname, isZhCN } from '../../utils';
import ThemeIcon from './ThemeIcon';
@ -16,7 +16,7 @@ export type ThemeSwitchProps = {
const ThemeSwitch: React.FC<ThemeSwitchProps> = (props) => {
const { value = ['light'], onChange } = props;
const { token } = useSiteToken();
const token = useTheme();
const { pathname, search } = useLocation();
const isMotionOff = value.includes('motion-off');

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
const GlobalDemoStyles: React.FC = () => {
const { token } = useSiteToken();
const token = useTheme();
const { antCls, iconCls } = token;

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
const { antCls, iconCls } = token;

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
const { iconCls } = token;

View File

@ -1,10 +1,10 @@
import { TinyColor } from '@ctrl/tinycolor';
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
const GlobalStyle: React.FC = () => {
const { token } = useSiteToken();
const token = useTheme();
const { antCls } = token;

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global
styles={css`

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global

View File

@ -1,9 +1,9 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global

View File

@ -1,11 +1,11 @@
import React from 'react';
import { css, Global } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
import { useTheme } from 'antd-style';
const THEME_PREFIX = 'dumi-default-';
export default () => {
const { token } = useSiteToken();
const token = useTheme();
return (
<Global

View File

@ -1,15 +1,13 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { Tabs } from 'antd';
import throttle from 'lodash/throttle';
import * as React from 'react';
import classNames from 'classnames';
import scrollTo from '../../../../components/_util/scrollTo';
import useSiteToken from '../../../hooks/useSiteToken';
const listenerEvents = ['scroll', 'resize'] as const;
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { boxShadowSecondary, antCls } = token;
return {
@ -51,7 +49,7 @@ const useStyle = () => {
text-transform: capitalize;
`,
};
};
});
const VIEW_BALANCE = 32;
@ -61,7 +59,9 @@ const AffixTabs: React.FC = () => {
const [loaded, setLoaded] = React.useState(false);
const [fixedId, setFixedId] = React.useState<string | null>(null);
const { affixTabs, affixTabsFixed, span } = useStyle();
const {
styles: { affixTabs, affixTabsFixed, span },
} = useStyle();
function scrollToId(id: string) {
const targetNode = document.getElementById(id);
@ -115,13 +115,13 @@ const AffixTabs: React.FC = () => {
}, []);
return (
<div css={[affixTabs, fixedId && affixTabsFixed]} ref={containerRef}>
<div className={classNames(affixTabs, fixedId && affixTabsFixed)} ref={containerRef}>
<Tabs
activeKey={fixedId}
onChange={scrollToId}
items={idsRef.current.map((id) => ({
key: id,
label: <span css={span}>{id.replace(/-/g, ' ')}</span>,
label: <span className={span}>{id.replace(/-/g, ' ')}</span>,
}))}
/>
</div>

View File

@ -1,9 +1,8 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
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';
@ -15,8 +14,7 @@ const resourcePadding = 40;
const articleMaxWidth = 1208;
const resourcePaddingXS = 24;
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
resourcePage: css`
@ -107,18 +105,18 @@ const useStyle = () => {
}
`,
};
};
});
const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
const styles = useStyle();
const { styles } = useStyle();
const meta = useRouteMeta();
return (
<ConfigProvider theme={{ token: { colorBgLayout: '#fff' } }}>
<Layout>
<CommonHelmet />
<div id="resources-page" css={styles.resourcePage}>
<div id="resources-page" className={styles.resourcePage}>
<AffixTabs />
<div css={styles.banner}>
<div className={styles.banner}>
<Typography.Title style={{ fontSize: 30 }}>
{meta.frontmatter?.title}
<EditButton
@ -128,7 +126,7 @@ const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
</Typography.Title>
<section>{meta.frontmatter.description}</section>
</div>
<div css={styles.resourceContent}>{children}</div>
<div className={styles.resourceContent}>{children}</div>
<Footer />
</div>
</Layout>

View File

@ -1,21 +1,21 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import type { PropsWithChildren } from 'react';
import React from 'react';
import CommonHelmet from '../../common/CommonHelmet';
import Content from '../../slots/Content';
import Sidebar from '../../slots/Sidebar';
const useStyle = () => ({
const useStyle = createStyles(({ css }) => ({
main: css`
display: flex;
margin-top: 40px;
`,
});
}));
const SidebarLayout: React.FC<PropsWithChildren<{}>> = ({ children }) => {
const { main } = useStyle();
const { styles } = useStyle();
return (
<main css={main}>
<main className={styles.main}>
<CommonHelmet />
<Sidebar />
<Content>{children}</Content>

View File

@ -2,9 +2,16 @@ import { extractStyle } from '@ant-design/cssinjs';
import type { IApi, IRoute } from 'dumi';
import ReactTechStack from 'dumi/dist/techStacks/react';
import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import sylvanas from 'sylvanas';
import { extractStaticStyle } from 'antd-style';
import { createHash } from 'crypto';
import localPackage from '../../package.json';
export const getHash = (str: string, length = 8) =>
createHash('md5').update(str).digest('hex').slice(0, length);
/**
* extends dumi internal tech stack, for customize previewer props
*/
@ -40,11 +47,29 @@ class AntdReactTechStack extends ReactTechStack {
}
}
const resolve = (path: string): string => require.resolve(path);
const resolve = (p: string): string => require.resolve(p);
const RoutesPlugin = (api: IApi) => {
const ssrCssFileName = `ssr-${Date.now()}.css`;
const writeCSSFile = (key: string, hashKey: string, cssString: string) => {
const fileName = `emotion-${key}.${getHash(hashKey)}.css`;
const filePath = path.join(api.paths.absOutputPath, fileName);
if (!fs.existsSync(filePath)) {
api.logger.event(chalk.grey(`write to: ${filePath}`));
fs.writeFileSync(filePath, cssString, 'utf8');
}
return fileName;
};
const addLinkStyle = (html: string, cssFile: string) => {
const prefix = api.userConfig.publicPath || api.config.publicPath;
return html.replace('</head>', `<link rel="stylesheet" href="${prefix + cssFile}"></head>`);
};
api.registerTechStack(() => new AntdReactTechStack());
api.modifyRoutes((routes) => {
@ -78,20 +103,34 @@ const RoutesPlugin = (api: IApi) => {
files
// exclude dynamic route path, to avoid deploy failed by `:id` directory
.filter((f) => !f.path.includes(':'))
// FIXME: workaround to make emotion support react 18 pipeableStream
// ref: https://github.com/emotion-js/emotion/issues/2800#issuecomment-1221296308
.map((file) => {
let styles = '';
let globalStyles = '';
// extract all emotion style tags from body
file.content = file.content.replace(/<style data-emotion[\S\s]+?<\/style>/g, (s) => {
styles += s;
globalStyles += s;
return '';
});
// insert emotion style tags to head
file.content = file.content.replace('</head>', `${styles}</head>`);
file.content = file.content.replace('</head>', `${globalStyles}</head>`);
// 1. 提取 antd-style 样式
const styles = extractStaticStyle(file.content, { includeAntd: false });
// 2. 提取每个样式到独立 css 文件
styles.forEach((result) => {
api.logger.event(
`${chalk.yellow(file.path)} include ${chalk.blue`[${result.key}]`} ${chalk.yellow(
result.ids.length,
)} styles`,
);
const cssFile = writeCSSFile(result.key, result.ids.join(''), result.css);
file.content = addLinkStyle(file.content, cssFile);
});
return file;
}),

View File

@ -1,35 +1,32 @@
import { RightOutlined, YuqueOutlined, ZhihuOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { Button, Card, Divider } from 'antd';
import React from 'react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import JuejinLogo from './JuejinLogo';
const ANTD_IMG_URL =
'https://picx.zhimg.com/v2-3b2bca09c2771e7a82a81562e806be4d.jpg?source=d16d100b';
const useStyle = () => {
const { token } = useSiteToken();
return {
card: css`
const useStyle = createStyles(({ token, css }) => ({
card: css`
width: 100%;
margin: 40px 0;
transition: all 0.2s;
background-color: ${token.colorFillQuaternary};
`,
bigTitle: css`
bigTitle: css`
font-size: 16px;
color: #121212;
margin-bottom: 24px;
font-weight: 600;
`,
cardBody: css`
cardBody: css`
display: flex;
justify-content: space-between;
align-items: center;
`,
left: css`
left: css`
display: flex;
justify-content: flex-start;
align-items: center;
@ -40,12 +37,12 @@ const useStyle = () => {
border-radius: 8px;
}
`,
title: css`
title: css`
color: #444;
font-size: 16px;
font-weight: 600;
`,
subTitle: css`
subTitle: css`
display: flex;
justify-content: flex-start;
align-items: center;
@ -83,13 +80,12 @@ const useStyle = () => {
color: #646464;
}
`,
btn: css`
btn: css`
display: flex;
justify-content: center;
align-items: center;
`,
};
};
}));
const locales = {
cn: {
@ -116,20 +112,22 @@ interface Props {
const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
const [locale] = useLocale(locales);
const { card, bigTitle, cardBody, left, title, subTitle, btn } = useStyle();
const {
styles: { card, bigTitle, cardBody, left, title, subTitle, btn },
} = useStyle();
if (!zhihuLink && !yuqueLink && !juejinLink) {
return null;
}
return (
<Card css={card} bordered={false}>
<h3 css={bigTitle}>{locale.bigTitle}</h3>
<Card className={card} bordered={false}>
<h3 className={bigTitle}>{locale.bigTitle}</h3>
{zhihuLink && (
<div css={cardBody}>
<div css={left}>
<div className={cardBody}>
<div className={left}>
<img src={ANTD_IMG_URL} alt="antd" />
<div>
<p css={title}>Ant Design</p>
<div css={subTitle}>
<p className={title}>Ant Design</p>
<div className={subTitle}>
<ZhihuOutlined className="logo zhihu-logo" />
<RightOutlined className="arrowIcon" />
<Button
@ -145,7 +143,7 @@ const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
</div>
<Button
type="primary"
css={btn}
className={btn}
icon={<ZhihuOutlined style={{ fontSize: 16 }} />}
ghost
target="_blank"
@ -158,12 +156,12 @@ const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
{yuqueLink && (
<>
<Divider />
<div css={cardBody}>
<div css={left}>
<div className={cardBody}>
<div className={left}>
<img src={ANTD_IMG_URL} alt="antd" />
<div>
<p css={title}>Ant Design</p>
<div css={subTitle}>
<p className={title}>Ant Design</p>
<div className={subTitle}>
<YuqueOutlined className="logo yuque-logo" />
<RightOutlined className="arrowIcon" />
<Button
@ -179,7 +177,7 @@ const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
</div>
<Button
type="primary"
css={btn}
className={btn}
icon={<YuqueOutlined style={{ fontSize: 16 }} />}
ghost
target="_blank"
@ -193,12 +191,12 @@ const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
{juejinLink && (
<>
<Divider />
<div css={cardBody}>
<div css={left}>
<div className={cardBody}>
<div className={left}>
<img src={ANTD_IMG_URL} alt="antd" />
<div>
<p css={title}>Ant Design</p>
<div css={subTitle}>
<p className={title}>Ant Design</p>
<div className={subTitle}>
<JuejinLogo className="logo juejin-logo" />
<RightOutlined className="arrowIcon" />
<Button
@ -214,7 +212,7 @@ const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink, juejinLink }) => {
</div>
<Button
type="primary"
css={btn}
className={btn}
icon={<JuejinLogo style={{ fontSize: 16, width: 16, height: 16 }} />}
ghost
target="_blank"

View File

@ -1,5 +1,5 @@
import { CalendarOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import ContributorsList from '@qixian.cs/github-contributors-list';
import { Affix, Anchor, Avatar, Col, Skeleton, Space, Tooltip, Typography } from 'antd';
import classNames from 'classnames';
@ -9,7 +9,6 @@ import type { ReactNode } from 'react';
import React, { useContext, useLayoutEffect, useMemo, useState } from 'react';
import useLayoutState from '../../../hooks/useLayoutState';
import useLocation from '../../../hooks/useLocation';
import useSiteToken from '../../../hooks/useSiteToken';
import EditButton from '../../common/EditButton';
import PrevAndNext from '../../common/PrevAndNext';
import type { DemoContextProps } from '../DemoContext';
@ -18,9 +17,7 @@ import Footer from '../Footer';
import SiteContext from '../SiteContext';
import ColumnCard from './ColumnCard';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
@ -96,7 +93,7 @@ const useStyle = () => {
}
`,
};
};
});
type AnchorItem = {
id: string;
@ -136,8 +133,8 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
const tab = useTabMeta();
const { pathname, hash } = useLocation();
const { formatMessage } = useIntl();
const styles = useStyle();
const { token } = useSiteToken();
const { styles } = useStyle();
const token = useTheme();
const { direction } = useContext(SiteContext);
const [showDebug, setShowDebug] = useLayoutState(false);
@ -206,9 +203,9 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
<DemoContext.Provider value={contextValue}>
<Col xxl={20} xl={19} lg={18} md={18} sm={24} xs={24}>
<Affix>
<section css={styles.tocWrapper}>
<section className={styles.tocWrapper}>
<Anchor
css={styles.toc}
className={styles.toc}
affix={false}
targetOffset={token.marginXXL}
showInkInFixed
@ -231,7 +228,7 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
/>
</section>
</Affix>
<article css={styles.articleWrapper} className={classNames({ rtl: isRTL })}>
<article className={classNames(styles.articleWrapper, { rtl: isRTL })}>
{meta.frontmatter?.title ? (
<Typography.Title style={{ fontSize: 30 }}>
{meta.frontmatter?.title}
@ -286,7 +283,7 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
<ContributorsList
repo="ant-design"
owner="ant-design"
css={styles.contributorsList}
className={styles.contributorsList}
cache
fileName={meta.frontmatter.filename}
renderItem={(item, loading) => {

View File

@ -13,7 +13,7 @@ import {
ZhihuOutlined,
} from '@ant-design/icons';
import { TinyColor } from '@ctrl/tinycolor';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
import { FormattedMessage, Link } from 'dumi';
import RcFooter from 'rc-footer';
@ -21,7 +21,6 @@ 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 SiteContext from '../SiteContext';
import AdditionalInfo from './AdditionalInfo';
@ -35,18 +34,18 @@ const locales = {
};
const useStyle = () => {
const { token } = useSiteToken();
const { isMobile } = useContext(SiteContext);
const background = new TinyColor(getAlphaColor('#f0f3fa', '#fff'))
.onBackground(token.colorBgContainer)
.toHexString();
return createStyles(({ token, css }) => {
const background = new TinyColor(getAlphaColor('#f0f3fa', '#fff'))
.onBackground(token.colorBgContainer)
.toHexString();
return {
holder: css`
return {
holder: css`
background: ${background};
`,
footer: css`
footer: css`
background: ${background};
color: ${token.colorTextSecondary};
box-shadow: inset 0 106px 36px -116px rgba(0, 0, 0, 0.14);
@ -84,13 +83,14 @@ const useStyle = () => {
}
}
`,
};
};
})();
};
const Footer: React.FC = () => {
const location = useLocation();
const [locale, lang] = useLocale(locales);
const style = useStyle();
const { styles } = useStyle();
const { getLink } = location;
@ -377,7 +377,7 @@ const Footer: React.FC = () => {
<>
<RcFooter
columns={getColumns}
css={style.footer}
className={styles.footer}
bottom={
<>
<div style={{ opacity: '0.4' }}>

View File

@ -1,12 +1,9 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
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();
const useStyle = createStyles(({ token, css }) => {
const { headerHeight, colorTextHeading, fontFamily, mobileMaxWidth } = token;
return {
@ -44,7 +41,7 @@ const useStyle = () => {
line-height: 32px;
`,
};
};
});
export interface LogoProps {
isZhCN: boolean;
@ -53,12 +50,12 @@ export interface LogoProps {
const Logo: React.FC<LogoProps> = ({ isZhCN }) => {
const { search } = useLocation();
const { logo, title } = useStyle();
const { styles } = useStyle();
return (
<h1>
<Link to={utils.getLocalizedPathname('/', isZhCN, search)} css={logo}>
<Link to={utils.getLocalizedPathname('/', isZhCN, search)} className={styles.logo}>
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" alt="logo" />
<span css={title}>Ant Design</span>
<span className={styles.title}>Ant Design</span>
</Link>
</h1>
);

View File

@ -1,12 +1,12 @@
import { DownOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import type { MenuProps } from 'antd';
import { Button, Dropdown } from 'antd';
import { FormattedMessage } from 'dumi';
import React from 'react';
import type { SharedProps } from './interface';
const useStyle = (rtl?: boolean) => ({
const useStyle = createStyles(({ css }) => ({
smallStyle: css`
font-size: 12px;
color: #777;
@ -14,15 +14,20 @@ const useStyle = (rtl?: boolean) => ({
`,
downOutlined: css`
font-size: 9px;
margin: ${rtl ? '-1px 2px 0 0' : '-1px 0 0 2px'};
margin: -1px 0 0 2px;
vertical-align: middle;
`,
});
downOutlinedRTL: css`
font-size: 9px;
margin: -1px 2px 0 0;
vertical-align: middle;
`,
}));
const Community: React.FC = () => {
const { smallStyle } = useStyle();
const { styles } = useStyle();
return (
<span css={smallStyle}>
<span className={styles.smallStyle}>
(<FormattedMessage id="app.implementation.community" />)
</span>
);
@ -74,12 +79,12 @@ export const getEcosystemGroup = (): MenuProps['items'] => [
];
const More: React.FC<SharedProps> = ({ isRTL }) => {
const { downOutlined } = useStyle(isRTL);
const { styles } = useStyle();
return (
<Dropdown menu={{ items: getEcosystemGroup() }} placement="bottomRight">
<Button size="small">
<FormattedMessage id="app.header.menu.more" />
<DownOutlined css={downOutlined} />
<DownOutlined className={isRTL ? styles.downOutlinedRTL : styles.downOutlined} />
</Button>
</Dropdown>
);

View File

@ -3,11 +3,10 @@ import { FormattedMessage, Link, useFullSidebarData, useLocation } from 'dumi';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import { MenuOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { createStyles, css } from 'antd-style';
import { getEcosystemGroup } from './More';
import * as utils from '../../utils';
import type { SharedProps } from './interface';
import useSiteToken from '../../../hooks/useSiteToken';
import useLocale from '../../../hooks/useLocale';
// ============================= Theme =============================
@ -29,9 +28,7 @@ const locales = {
};
// ============================= Style =============================
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token }) => {
const { antCls, iconCls, fontFamily, headerHeight, menuItemBorder, colorPrimary } = token;
return {
@ -95,7 +92,7 @@ const useStyle = () => {
}
`,
};
};
});
export interface NavigationProps extends SharedProps {
isMobile: boolean;
@ -121,7 +118,7 @@ export default ({
const sidebarData = useFullSidebarData();
const blogList = sidebarData['/docs/blog']?.[0]?.children || [];
const style = useStyle();
const { styles } = useStyle();
const menuMode = isMobile ? 'inline' : 'horizontal';
@ -268,7 +265,7 @@ export default ({
<Menu
mode={menuMode}
selectedKeys={[activeMenuItem]}
css={style.nav}
className={styles.nav}
disabledOverflow
items={items}
style={{ borderRight: 0 }}

View File

@ -1,7 +1,7 @@
import { css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { Tooltip } from 'antd';
import React from 'react';
import useSiteToken from '../../../hooks/useSiteToken';
import classNames from 'classnames';
export interface LangBtnProps {
label1: React.ReactNode;
@ -15,9 +15,7 @@ export interface LangBtnProps {
const BASE_SIZE = '1.2em';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const {
colorText,
colorBorder,
@ -86,21 +84,27 @@ const useStyle = () => {
transform-origin: 100% 100%;
`,
};
};
});
const LangBtn: React.FC<LangBtnProps> = (props) => {
const { label1, label2, tooltip1, tooltip2, value, pure, onClick } = props;
const { btn, innerDiv, labelStyle, label1Style, label2Style } = useStyle();
const {
styles: { btn, innerDiv, labelStyle, label1Style, label2Style },
} = useStyle();
const node = (
<button onClick={onClick} css={btn} key="lang-button">
<button onClick={onClick} className={btn} key="lang-button">
<div className="btn-inner">
{pure && (value === 1 ? label1 : label2)}
{!pure && (
<div css={innerDiv}>
<span css={[labelStyle, value === 1 ? label1Style : label2Style]}>{label1}</span>
<span css={[labelStyle, value === 1 ? label2Style : label1Style]}>{label2}</span>
<div className={innerDiv}>
<span className={classNames(labelStyle, value === 1 ? label1Style : label2Style)}>
{label1}
</span>
<span className={classNames(labelStyle, value === 1 ? label2Style : label1Style)}>
{label2}
</span>
</div>
)}
</div>

View File

@ -1,12 +1,11 @@
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
import { ClassNames, css } from '@emotion/react';
import { createStyles } from 'antd-style';
import { Col, Modal, Popover, Row, Select } from 'antd';
import classNames from 'classnames';
import { useLocation, useSiteData } from 'dumi';
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import DirectionIcon from '../../common/DirectionIcon';
import * as utils from '../../utils';
import { getThemeConfig, ping } from '../../utils';
@ -21,8 +20,7 @@ import type { SharedProps } from './interface';
const RESPONSIVE_XS = 1120;
const RESPONSIVE_SM = 1200;
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const searchIconColor = '#ced4d9';
return {
@ -107,7 +105,7 @@ const useStyle = () => {
},
},
};
};
});
const SHOULD_OPEN_ANT_DESIGN_MIRROR_MODAL = 'ANT_DESIGN_DO_NOT_OPEN_MIRROR_MODAL';
@ -143,7 +141,7 @@ const Header: React.FC = () => {
const location = useLocation();
const { pathname, search } = location;
const style = useStyle();
const { styles } = useStyle();
const handleHideMenu = useCallback(() => {
setHeaderState((prev) => ({ ...prev, menuVisible: false }));
@ -266,8 +264,7 @@ const Header: React.FC = () => {
responsive = 'narrow';
}
const headerClassName = classNames({
clearfix: true,
const headerClassName = classNames(styles.header, 'clearfix', {
'home-header': isHome,
});
@ -316,9 +313,9 @@ const Header: React.FC = () => {
key="direction"
onClick={onDirectionChange}
value={direction === 'rtl' ? 2 : 1}
label1={<DirectionIcon css={style.dataDirectionIcon} direction="ltr" />}
label1={<DirectionIcon className={styles.dataDirectionIcon} direction="ltr" />}
tooltip1="LTR"
label2={<DirectionIcon css={style.dataDirectionIcon} direction="rtl" />}
label2={<DirectionIcon className={styles.dataDirectionIcon} direction="rtl" />}
tooltip2="RTL"
pure
/>,
@ -346,29 +343,25 @@ const Header: React.FC = () => {
];
return (
<header css={style.header} className={headerClassName}>
<header className={headerClassName}>
{isMobile && (
<ClassNames>
{({ css: cssFn }) => (
<Popover
overlayClassName={cssFn(style.popoverMenu)}
placement="bottomRight"
content={menu}
trigger="click"
open={menuVisible}
arrow={{ arrowPointAtCenter: true }}
onOpenChange={onMenuVisibleChange}
>
<MenuOutlined className="nav-phone-icon" onClick={handleShowMenu} />
</Popover>
)}
</ClassNames>
<Popover
overlayClassName={styles.popoverMenu}
placement="bottomRight"
content={menu}
trigger="click"
open={menuVisible}
arrow={{ arrowPointAtCenter: true }}
onOpenChange={onMenuVisibleChange}
>
<MenuOutlined className="nav-phone-icon" onClick={handleShowMenu} />
</Popover>
)}
<Row style={{ flexFlow: 'nowrap', height: 64 }}>
<Col {...colProps[0]}>
<Logo {...sharedProps} location={location} />
</Col>
<Col {...colProps[1]} css={style.menuRow}>
<Col {...colProps[1]} className={styles.menuRow}>
<div className="nav-search-wrapper">
<DumiSearchBar />
</div>

View File

@ -1,15 +1,12 @@
import { css } from '@emotion/react';
import { createStyles, useTheme } from 'antd-style';
import { Col, ConfigProvider, Menu } from 'antd';
import { useSidebarData } from 'dumi';
import MobileMenu from 'rc-drawer';
import React, { useContext } from 'react';
import useMenu from '../../../hooks/useMenu';
import useSiteToken from '../../../hooks/useSiteToken';
import SiteContext from '../SiteContext';
const useStyle = () => {
const { token } = useSiteToken();
const useStyle = createStyles(({ token, css }) => {
const { antCls, fontFamily, colorSplit } = token;
return {
@ -44,17 +41,17 @@ const useStyle = () => {
}
> ${antCls}-menu-item,
> ${antCls}-menu-submenu
> ${antCls}-menu-submenu-title,
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-title,
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-list
> ${antCls}-menu-item,
&${antCls}-menu-inline
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-list
> ${antCls}-menu-item {
> ${antCls}-menu-submenu
> ${antCls}-menu-submenu-title,
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-title,
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-list
> ${antCls}-menu-item,
&${antCls}-menu-inline
> ${antCls}-menu-item-group
> ${antCls}-menu-item-group-list
> ${antCls}-menu-item {
padding-left: 40px !important;
${antCls}-row-rtl & {
@ -120,18 +117,16 @@ const useStyle = () => {
}
`,
};
};
});
const Sidebar: React.FC = () => {
const sidebarData = useSidebarData();
const { isMobile, theme } = useContext(SiteContext);
const styles = useStyle();
const { styles } = useStyle();
const [menuItems, selectedKey] = useMenu();
const isDark = theme.includes('dark');
const {
token: { colorBgContainer },
} = useSiteToken();
const { colorBgContainer } = useTheme();
const menuChild = (
<ConfigProvider
@ -140,7 +135,7 @@ const Sidebar: React.FC = () => {
<Menu
items={menuItems}
inlineIndent={30}
css={styles.asideContainer}
className={styles.asideContainer}
mode="inline"
theme={isDark ? 'dark' : 'light'}
selectedKeys={[selectedKey]}
@ -152,7 +147,7 @@ const Sidebar: React.FC = () => {
return isMobile ? (
<MobileMenu key="Mobile-menu">{menuChild}</MobileMenu>
) : (
<Col xxl={4} xl={5} lg={6} md={6} sm={24} xs={24} css={styles.mainMenu}>
<Col xxl={4} xl={5} lg={6} md={6} sm={24} xs={24} className={styles.mainMenu}>
<section className="main-menu-inner">{menuChild}</section>
</Col>
);

View File

@ -1,7 +1,6 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"esModuleInterop": true,
"resolveJsonModule": true,
"baseUrl": "../",

View File

@ -35,7 +35,6 @@ export default defineConfig({
},
extraRehypePlugins: [rehypeAntd],
extraRemarkPlugins: [remarkAntd],
extraBabelPresets: [require.resolve('@emotion/babel-preset-css-prop')],
mfsu: false,
metas: [{ name: 'theme-color', content: '#1677ff' }],
analytics: {

View File

@ -166,8 +166,6 @@
"@dnd-kit/modifiers": "^6.0.1",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
"@emotion/babel-preset-css-prop": "^11.10.0",
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.4",
"@emotion/server": "^11.4.0",
"@qixian.cs/github-contributors-list": "^1.1.0",
@ -207,12 +205,13 @@
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"antd-img-crop": "^4.9.0",
"antd-style": "^3.0.0",
"antd-style": "^3.4.2-beta.1",
"antd-token-previewer": "^1.1.0-21",
"chalk": "^4.0.0",
"cheerio": "1.0.0-rc.12",
"circular-dependency-plugin": "^5.2.2",
"cross-env": "^7.0.0",
"crypto": "^1.0.1",
"dekko": "^0.2.1",
"dumi": "^2.1.17",
"duplicate-package-checker-webpack-plugin": "^3.0.0",