mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
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:
parent
9bc006c125
commit
e96059cd76
@ -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;
|
@ -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
|
||||
|
@ -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}
|
||||
/>
|
||||
))}
|
||||
|
@ -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} />
|
||||
))}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
|
@ -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,
|
||||
}}
|
||||
|
@ -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%' }} />
|
||||
|
@ -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);
|
||||
}}
|
||||
|
@ -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 />
|
||||
|
@ -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;
|
||||
|
@ -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=""
|
||||
/>
|
||||
|
@ -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>
|
||||
|
@ -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={{
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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 && (
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}),
|
||||
|
@ -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"
|
||||
|
@ -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) => {
|
||||
|
@ -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' }}>
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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 }}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "@emotion/react",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": "../",
|
||||
|
@ -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: {
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user