mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 02:49:18 +08:00
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import React from 'react';
|
||||
import { Col, ConfigProvider, Flex, Row, Tag, theme, Typography } from 'antd';
|
||||
import { Col, ConfigProvider, Flex, Popover, Row, Tag, theme, Typography } from 'antd';
|
||||
import { createStyles, css } from 'antd-style';
|
||||
import classnames from 'classnames';
|
||||
|
||||
@@ -68,6 +69,7 @@ const useStyle = createStyles(({ token }, markPos: [number, number, number, numb
|
||||
}));
|
||||
|
||||
export interface SemanticPreviewProps {
|
||||
componentName?: string;
|
||||
semantics: { name: string; desc: string; version?: string }[];
|
||||
children: React.ReactElement<any>;
|
||||
height?: number;
|
||||
@@ -75,7 +77,7 @@ export interface SemanticPreviewProps {
|
||||
}
|
||||
|
||||
const SemanticPreview: React.FC<SemanticPreviewProps> = (props) => {
|
||||
const { semantics = [], children, height, padding } = props;
|
||||
const { semantics = [], children, height, padding, componentName = 'Component' } = props;
|
||||
const { token } = theme.useToken();
|
||||
|
||||
// ======================= Semantic =======================
|
||||
@@ -162,24 +164,45 @@ const SemanticPreview: React.FC<SemanticPreviewProps> = (props) => {
|
||||
<Col span={8}>
|
||||
<ul className={classnames(styles.listWrap)}>
|
||||
{semantics.map<React.ReactNode>((semantic) => (
|
||||
<li
|
||||
<Popover
|
||||
key={semantic.name}
|
||||
className={classnames(styles.listItem)}
|
||||
onMouseEnter={() => setHoverSemantic(semantic.name)}
|
||||
onMouseLeave={() => setHoverSemantic(null)}
|
||||
content={
|
||||
<Typography style={{ fontSize: 12, minWidth: 300 }}>
|
||||
<pre dir="ltr">
|
||||
<code dir="ltr">
|
||||
{`<${componentName}
|
||||
classNames={{
|
||||
${semantic.name}: 'my-${componentName.toLowerCase()}',
|
||||
}}
|
||||
styles={{
|
||||
${semantic.name}: { color: 'red' },
|
||||
}}
|
||||
>
|
||||
...
|
||||
</${componentName}>`}
|
||||
</code>
|
||||
</pre>
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Flex vertical gap="small">
|
||||
<Flex gap="small" align="center">
|
||||
<Typography.Title level={5} style={{ margin: 0 }}>
|
||||
{semantic.name}
|
||||
</Typography.Title>
|
||||
{semantic.version && <Tag color="blue">{semantic.version}</Tag>}
|
||||
<li
|
||||
className={classnames(styles.listItem)}
|
||||
onMouseEnter={() => setHoverSemantic(semantic.name)}
|
||||
onMouseLeave={() => setHoverSemantic(null)}
|
||||
>
|
||||
<Flex vertical gap="small">
|
||||
<Flex gap="small" align="center">
|
||||
<Typography.Title level={5} style={{ margin: 0 }}>
|
||||
{semantic.name}
|
||||
</Typography.Title>
|
||||
{semantic.version && <Tag color="blue">{semantic.version}</Tag>}
|
||||
</Flex>
|
||||
<Typography.Paragraph style={{ margin: 0, fontSize: token.fontSizeSM }}>
|
||||
{semantic.desc}
|
||||
</Typography.Paragraph>
|
||||
</Flex>
|
||||
<Typography.Paragraph style={{ margin: 0, fontSize: token.fontSizeSM }}>
|
||||
{semantic.desc}
|
||||
</Typography.Paragraph>
|
||||
</Flex>
|
||||
</li>
|
||||
</li>
|
||||
</Popover>
|
||||
))}
|
||||
</ul>
|
||||
</Col>
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export const DarkContext = React.createContext(false);
|
||||
|
||||
export default function useDark() {
|
||||
return React.useContext(DarkContext);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { Badge, Carousel, Flex, Skeleton, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
@@ -110,7 +110,7 @@ const RecommendItem: React.FC<RecommendItemProps> = ({ extra, index, icons, clas
|
||||
};
|
||||
|
||||
export const BannerRecommendsFallback: React.FC = () => {
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const { styles } = useStyle();
|
||||
|
||||
const list = Array.from({ length: 3 });
|
||||
@@ -137,7 +137,7 @@ export const BannerRecommendsFallback: React.FC = () => {
|
||||
const BannerRecommends: React.FC = () => {
|
||||
const { styles } = useStyle();
|
||||
const [, lang] = useLocale();
|
||||
const { isMobile } = React.useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const data = useSiteData();
|
||||
const extras = data?.extras?.[lang];
|
||||
const icons = data?.icons || [];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Alert,
|
||||
@@ -16,9 +16,9 @@ import { createStyles, css } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import useDark from '../../../hooks/useDark';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import { DarkContext } from './../../../hooks/useDark';
|
||||
import { getCarouselStyle } from './util';
|
||||
|
||||
const { _InternalPanelDoNotUseOrYouWillBeFired: ModalDoNotUseOrYouWillBeFired } = Modal;
|
||||
@@ -61,66 +61,62 @@ const locales = {
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => {
|
||||
const isRootDark = useDark();
|
||||
const useStyle = createStyles(({ token }) => {
|
||||
const { carousel } = getCarouselStyle();
|
||||
const isDark = React.use(DarkContext);
|
||||
return {
|
||||
card: css`
|
||||
border-radius: ${token.borderRadius}px;
|
||||
border: 1px solid ${isDark ? token.colorBorder : 'transparent'};
|
||||
background-color: ${isDark ? token.colorBgContainer : '#f5f8ff'};
|
||||
padding: ${token.paddingXL}px;
|
||||
flex: none;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
return createStyles(({ token }) => {
|
||||
const { carousel } = getCarouselStyle();
|
||||
|
||||
return {
|
||||
card: css`
|
||||
border-radius: ${token.borderRadius}px;
|
||||
border: 1px solid ${isRootDark ? token.colorBorder : 'transparent'};
|
||||
background: ${isRootDark ? token.colorBgContainer : '#f5f8ff'};
|
||||
padding: ${token.paddingXL}px;
|
||||
> * {
|
||||
flex: none;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
> * {
|
||||
flex: none;
|
||||
}
|
||||
`,
|
||||
cardCircle: css`
|
||||
position: absolute;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: #1677ff;
|
||||
border-radius: 50%;
|
||||
filter: blur(40px);
|
||||
opacity: 0.1;
|
||||
`,
|
||||
mobileCard: css`
|
||||
height: 395px;
|
||||
`,
|
||||
nodeWrap: css`
|
||||
margin-top: ${token.paddingLG}px;
|
||||
flex: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`,
|
||||
carousel,
|
||||
componentsList: css`
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
`,
|
||||
mobileComponentsList: css`
|
||||
margin: 0 ${token.margin}px;
|
||||
`,
|
||||
};
|
||||
})();
|
||||
};
|
||||
}
|
||||
`,
|
||||
cardCircle: css`
|
||||
position: absolute;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: #1677ff;
|
||||
border-radius: 50%;
|
||||
filter: blur(40px);
|
||||
opacity: 0.1;
|
||||
`,
|
||||
mobileCard: css`
|
||||
height: 395px;
|
||||
`,
|
||||
nodeWrap: css`
|
||||
margin-top: ${token.paddingLG}px;
|
||||
flex: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`,
|
||||
carousel,
|
||||
componentsList: css`
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
`,
|
||||
mobileComponentsList: css`
|
||||
margin: 0 ${token.margin}px;
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
const ComponentItem: React.FC<ComponentItemProps> = ({ title, node, type, index }) => {
|
||||
const tagColor = type === 'new' ? 'processing' : 'warning';
|
||||
const [locale] = useLocale(locales);
|
||||
const tagText = type === 'new' ? locale.new : locale.update;
|
||||
const { styles } = useStyle();
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
return (
|
||||
<div className={classNames(styles.card, isMobile && styles.mobileCard)}>
|
||||
{/* Decorator */}
|
||||
@@ -151,7 +147,7 @@ interface ComponentItemProps {
|
||||
const ComponentsList: React.FC = () => {
|
||||
const { styles } = useStyle();
|
||||
const [locale] = useLocale(locales);
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const COMPONENTS = React.useMemo<Omit<ComponentItemProps, 'index'>[]>(
|
||||
() => [
|
||||
{
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { Col, Row, Typography } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import { useLocation } from 'dumi';
|
||||
|
||||
import useDark from '../../../hooks/useDark';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import Link from '../../../theme/common/Link';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import * as utils from '../../../theme/utils';
|
||||
import { DarkContext } from './../../../hooks/useDark';
|
||||
|
||||
const SECONDARY_LIST = [
|
||||
{
|
||||
@@ -63,14 +63,13 @@ const locales = {
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => {
|
||||
const isRootDark = useDark();
|
||||
|
||||
return createStyles(({ token, css }) => ({
|
||||
const useStyle = createStyles(({ token, css }) => {
|
||||
const isDark = React.use(DarkContext);
|
||||
return {
|
||||
card: css`
|
||||
padding: ${token.paddingSM}px;
|
||||
border-radius: ${token.borderRadius * 2}px;
|
||||
background: ${isRootDark ? 'rgba(0, 0, 0, 0.45)' : token.colorBgElevated};
|
||||
background: ${isDark ? 'rgba(0, 0, 0, 0.45)' : token.colorBgElevated};
|
||||
box-shadow:
|
||||
0 1px 2px rgba(0, 0, 0, 0.03),
|
||||
0 1px 6px -1px rgba(0, 0, 0, 0.02),
|
||||
@@ -87,15 +86,15 @@ const useStyle = () => {
|
||||
display: block;
|
||||
border-radius: ${token.borderRadius * 2}px;
|
||||
padding: ${token.paddingMD}px ${token.paddingLG}px;
|
||||
background: ${isRootDark ? 'rgba(0, 0, 0, 0.25)' : 'rgba(0, 0, 0, 0.02)'};
|
||||
border: 1px solid ${isRootDark ? 'rgba(255, 255, 255, 0.45)' : 'rgba(0, 0, 0, 0.06)'};
|
||||
background: ${isDark ? 'rgba(0, 0, 0, 0.25)' : 'rgba(0, 0, 0, 0.02)'};
|
||||
border: 1px solid ${isDark ? 'rgba(255, 255, 255, 0.45)' : 'rgba(0, 0, 0, 0.06)'};
|
||||
|
||||
img {
|
||||
height: 48px;
|
||||
}
|
||||
`,
|
||||
}))();
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
const DesignFramework: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
@@ -103,7 +102,7 @@ const DesignFramework: React.FC = () => {
|
||||
const { styles } = useStyle();
|
||||
const { pathname, search } = useLocation();
|
||||
const isZhCN = utils.isZhCN(pathname);
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const colSpan = isMobile ? 24 : 8;
|
||||
|
||||
const MAINLY_LIST = [
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { Typography } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
@@ -40,7 +39,7 @@ const Group: React.FC<React.PropsWithChildren<GroupProps>> = (props) => {
|
||||
const { id, title, titleColor, description, children, decoration, background, collapse } = props;
|
||||
const token = useTheme();
|
||||
const { styles } = useStyle();
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const childNode = (
|
||||
<>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
|
||||
@@ -26,101 +26,98 @@ const locales = {
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => {
|
||||
const useStyle = createStyles(({ token, css, cx }) => {
|
||||
const textShadow = `0 0 4px ${token.colorBgContainer}`;
|
||||
const { isMobile, theme } = use(SiteContext);
|
||||
const isDark = theme.includes('dark');
|
||||
return createStyles(({ token, css, cx }) => {
|
||||
const textShadow = `0 0 4px ${token.colorBgContainer}`;
|
||||
const mask = cx(css`
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
backdrop-filter: blur(2px);
|
||||
opacity: 1;
|
||||
background-color: ${isDark ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.2)'};
|
||||
transition: all 1s ease;
|
||||
pointer-events: none;
|
||||
`);
|
||||
|
||||
const mask = cx(css`
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
backdrop-filter: blur(2px);
|
||||
opacity: 1;
|
||||
background-color: ${isDark ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.2)'};
|
||||
transition: all 1s ease;
|
||||
pointer-events: none;
|
||||
`);
|
||||
const block = cx(css`
|
||||
position: absolute;
|
||||
inset-inline-end: -60px;
|
||||
top: -24px;
|
||||
transition: all 1s cubic-bezier(0.03, 0.98, 0.52, 0.99);
|
||||
`);
|
||||
|
||||
const block = cx(css`
|
||||
position: absolute;
|
||||
inset-inline-end: -60px;
|
||||
top: -24px;
|
||||
transition: all 1s cubic-bezier(.03,.98,.52,.99);
|
||||
`);
|
||||
return {
|
||||
holder: css`
|
||||
height: 640px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
perspective: 800px;
|
||||
/* fix safari bug by removing blur style */
|
||||
transform: translateZ(1000px);
|
||||
row-gap: ${token.marginXL}px;
|
||||
|
||||
return {
|
||||
holder: css`
|
||||
height: 640px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
perspective: 800px;
|
||||
/* fix safari bug by removing blur style */
|
||||
transform: translateZ(1000px);
|
||||
row-gap: ${token.marginXL}px;
|
||||
|
||||
&:hover {
|
||||
&:hover {
|
||||
.${mask} {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.${block} {
|
||||
transform: scale(0.96);
|
||||
transform: scale(0.96);
|
||||
}
|
||||
}
|
||||
`,
|
||||
}
|
||||
`,
|
||||
|
||||
mask,
|
||||
mask,
|
||||
|
||||
typography: css`
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-inline: ${token.paddingXL}px;
|
||||
text-shadow: ${Array.from({ length: 5 }, () => textShadow).join(', ')};
|
||||
h1 {
|
||||
font-family: AliPuHui, ${token.fontFamily} !important;
|
||||
font-weight: 900 !important;
|
||||
font-size: ${token.fontSizeHeading2 * 2}px !important;
|
||||
line-height: ${token.lineHeightHeading2} !important;
|
||||
}
|
||||
typography: css`
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-inline: ${token.paddingXL}px;
|
||||
text-shadow: ${Array.from({ length: 5 }, () => textShadow).join(', ')};
|
||||
h1 {
|
||||
font-family: AliPuHui, ${token.fontFamily} !important;
|
||||
font-weight: 900 !important;
|
||||
font-size: ${token.fontSizeHeading2 * 2}px !important;
|
||||
line-height: ${token.lineHeightHeading2} !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: ${token.fontSizeLG}px !important;
|
||||
font-weight: normal !important;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`,
|
||||
block,
|
||||
child: css`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
z-index: 1;
|
||||
`,
|
||||
btnWrap: css`
|
||||
margin-bottom: ${token.marginXL}px;
|
||||
`,
|
||||
bgImg: css`
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
`,
|
||||
bgImgTop: css`
|
||||
top: 0;
|
||||
inset-inline-start: ${isMobile ? '-120px' : 0};
|
||||
`,
|
||||
bgImgBottom: css`
|
||||
bottom: 120px;
|
||||
inset-inline-end: ${isMobile ? 0 : '40%'};
|
||||
`,
|
||||
};
|
||||
})();
|
||||
};
|
||||
p {
|
||||
font-size: ${token.fontSizeLG}px !important;
|
||||
font-weight: normal !important;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`,
|
||||
block,
|
||||
child: css`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
z-index: 1;
|
||||
`,
|
||||
btnWrap: css`
|
||||
margin-bottom: ${token.marginXL}px;
|
||||
`,
|
||||
bgImg: css`
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
`,
|
||||
bgImgTop: css`
|
||||
top: 0;
|
||||
inset-inline-start: ${isMobile ? '-120px' : 0};
|
||||
`,
|
||||
bgImgBottom: css`
|
||||
bottom: 120px;
|
||||
inset-inline-end: ${isMobile ? 0 : '40%'};
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
const PreviewBanner: React.FC<Readonly<React.PropsWithChildren>> = (props) => {
|
||||
const { children } = props;
|
||||
|
||||
@@ -4,8 +4,6 @@ export interface SiteContextProps {
|
||||
isMobile: boolean;
|
||||
}
|
||||
|
||||
const SiteContext = React.createContext<SiteContextProps>({
|
||||
isMobile: false,
|
||||
});
|
||||
const SiteContext = React.createContext<SiteContextProps>({ isMobile: false });
|
||||
|
||||
export default SiteContext;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import * as React from 'react';
|
||||
import { defaultAlgorithm, defaultTheme } from '@ant-design/compatible';
|
||||
import { FastColor } from '@ant-design/fast-color';
|
||||
@@ -25,13 +26,13 @@ import { generateColor } from 'antd/es/color-picker/util';
|
||||
import classNames from 'classnames';
|
||||
import { useLocation } from 'dumi';
|
||||
|
||||
import useDark from '../../../../hooks/useDark';
|
||||
import useLocale from '../../../../hooks/useLocale';
|
||||
import LinkButton from '../../../../theme/common/LinkButton';
|
||||
import SiteContext from '../../../../theme/slots/SiteContext';
|
||||
import { getLocalizedPathname } from '../../../../theme/utils';
|
||||
import Group from '../Group';
|
||||
import { getCarouselStyle } from '../util';
|
||||
import { DarkContext } from './../../../../hooks/useDark';
|
||||
import BackgroundImage from './BackgroundImage';
|
||||
import ColorPicker from './ColorPicker';
|
||||
import { DEFAULT_COLOR, getAvatarURL, getClosetColor, PINK_COLOR } from './colorUtil';
|
||||
@@ -360,7 +361,7 @@ const Theme: React.FC = () => {
|
||||
const { compact, themeType, colorPrimary, ...themeToken } = themeData;
|
||||
const isLight = themeType !== 'dark';
|
||||
const [form] = Form.useForm();
|
||||
const { isMobile } = React.useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const colorPrimaryValue = React.useMemo(
|
||||
() => (typeof colorPrimary === 'string' ? colorPrimary : colorPrimary.toHexString()),
|
||||
[colorPrimary],
|
||||
@@ -393,11 +394,11 @@ const Theme: React.FC = () => {
|
||||
form.setFieldsValue(mergedData);
|
||||
}, [themeType]);
|
||||
|
||||
const isRootDark = useDark();
|
||||
const isDark = React.use(DarkContext);
|
||||
|
||||
React.useEffect(() => {
|
||||
onThemeChange({}, { ...themeData, themeType: isRootDark ? 'dark' : 'default' });
|
||||
}, [isRootDark]);
|
||||
onThemeChange({}, { ...themeData, themeType: isDark ? 'dark' : 'default' });
|
||||
}, [isDark]);
|
||||
|
||||
// ================================ Tokens ================================
|
||||
const closestColor = getClosetColor(colorPrimaryValue);
|
||||
|
||||
@@ -2,8 +2,8 @@ import React, { Suspense } from 'react';
|
||||
import { ConfigProvider, theme } from 'antd';
|
||||
import { createStyles, css } from 'antd-style';
|
||||
|
||||
import useDark from '../../hooks/useDark';
|
||||
import useLocale from '../../hooks/useLocale';
|
||||
import { DarkContext } from './../../hooks/useDark';
|
||||
import BannerRecommends from './components/BannerRecommends';
|
||||
import Group from './components/Group';
|
||||
import PreviewBanner from './components/PreviewBanner';
|
||||
@@ -41,7 +41,7 @@ const Homepage: React.FC = () => {
|
||||
const { styles } = useStyle();
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const isRootDark = useDark();
|
||||
const isDark = React.use(DarkContext);
|
||||
|
||||
return (
|
||||
<section>
|
||||
@@ -78,7 +78,7 @@ const Homepage: React.FC = () => {
|
||||
<Group
|
||||
title={locale.designTitle}
|
||||
description={locale.designDesc}
|
||||
background={isRootDark ? '#393F4A' : '#F5F8FF'}
|
||||
background={isDark ? '#393F4A' : '#F5F8FF'}
|
||||
decoration={
|
||||
<img
|
||||
draggable={false}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import React, { Suspense, useEffect } from 'react';
|
||||
import { Button, App, Skeleton } from 'antd';
|
||||
import { App, Button, Skeleton } from 'antd';
|
||||
import { enUS, zhCN } from 'antd-token-previewer';
|
||||
import type { ThemeConfig } from 'antd/es/config-provider/context';
|
||||
import { Helmet } from 'dumi';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { theme as antdTheme, ConfigProvider } from 'antd';
|
||||
import type { ThemeConfig } from 'antd';
|
||||
import type { ThemeProviderProps } from 'antd-style';
|
||||
@@ -31,10 +31,10 @@ const headerHeight = 64;
|
||||
const bannerHeight = 38;
|
||||
|
||||
const SiteThemeProvider: React.FC<ThemeProviderProps<any>> = ({ children, theme, ...rest }) => {
|
||||
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
|
||||
const { getPrefixCls, iconPrefixCls } = React.use(ConfigProvider.ConfigContext);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const { token } = antdTheme.useToken();
|
||||
const { bannerVisible } = useContext(SiteContext);
|
||||
const { bannerVisible } = React.use(SiteContext);
|
||||
React.useEffect(() => {
|
||||
// 需要注意与 components/config-provider/demo/holderRender.tsx 配置冲突
|
||||
ConfigProvider.config({ theme: theme as ThemeConfig });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { memo, useContext, useMemo, useRef, useState } from 'react';
|
||||
import React, { memo, useMemo, useRef, useState } from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { Affix, Card, Col, Divider, Flex, Input, Row, Tag, Typography } from 'antd';
|
||||
@@ -83,7 +83,7 @@ const { Title } = Typography;
|
||||
|
||||
const Overview: React.FC = () => {
|
||||
const { styles } = useStyle();
|
||||
const { theme } = useContext(SiteContext);
|
||||
const { theme } = React.use(SiteContext);
|
||||
|
||||
const data = useSidebarData();
|
||||
const [searchBarAffixed, setSearchBarAffixed] = useState<boolean>(false);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Suspense, useContext } from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import { BugOutlined, CodeOutlined } from '@ant-design/icons';
|
||||
import { css, Global } from '@emotion/react';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
@@ -9,7 +9,7 @@ import DemoContext from '../../slots/DemoContext';
|
||||
import DemoFallback from '../Previewer/DemoFallback';
|
||||
|
||||
const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
|
||||
const { showDebug, setShowDebug } = useContext(DemoContext);
|
||||
const { showDebug, setShowDebug } = React.use(DemoContext);
|
||||
|
||||
const [expandAll, setExpandAll] = useLayoutState(false);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { LinkOutlined, ThunderboltOutlined, UpOutlined } from '@ant-design/icons';
|
||||
import type { Project } from '@stackblitz/sdk';
|
||||
import stackblitzSdk from '@stackblitz/sdk';
|
||||
@@ -17,7 +18,6 @@ import CodePenIcon from '../../icons/CodePenIcon';
|
||||
import CodeSandboxIcon from '../../icons/CodeSandboxIcon';
|
||||
import ExternalLinkIcon from '../../icons/ExternalLinkIcon';
|
||||
import DemoContext from '../../slots/DemoContext';
|
||||
import type { SiteContextProps } from '../../slots/SiteContext';
|
||||
import SiteContext from '../../slots/SiteContext';
|
||||
import CodeBlockButton from './CodeBlockButton';
|
||||
import type { AntdPreviewerProps } from './Previewer';
|
||||
@@ -86,7 +86,7 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
clientOnly,
|
||||
pkgDependencyList,
|
||||
} = props;
|
||||
const { codeType } = useContext(DemoContext);
|
||||
const { codeType } = React.use(DemoContext);
|
||||
|
||||
const { pkg } = useSiteData();
|
||||
const location = useLocation();
|
||||
@@ -110,7 +110,7 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
const codeSandboxIconRef = useRef<HTMLFormElement>(null);
|
||||
const codepenIconRef = useRef<HTMLFormElement>(null);
|
||||
const [codeExpand, setCodeExpand] = useState<boolean>(false);
|
||||
const { theme } = useContext<SiteContextProps>(SiteContext);
|
||||
const { theme } = React.use(SiteContext);
|
||||
|
||||
const { hash, pathname, search } = location;
|
||||
const docsOnlineUrl = `https://ant.design${pathname}${search}#${asset.id}`;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import type { ComponentProps } from 'react';
|
||||
import React, { useContext, useEffect, useMemo } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { Button, Tabs, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import toReactElement from 'jsonml-to-react-element';
|
||||
@@ -108,7 +109,7 @@ const CodePreview: React.FC<CodePreviewProps> = ({
|
||||
initialCodes.style = '';
|
||||
}
|
||||
const [highlightedCodes, setHighlightedCodes] = React.useState(initialCodes);
|
||||
const { codeType, setCodeType } = useContext(DemoContext);
|
||||
const { codeType, setCodeType } = React.use(DemoContext);
|
||||
const sourceCodes = {
|
||||
// omit trailing line break
|
||||
tsx: sourceCode?.trim(),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ReactElement } from 'react';
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
|
||||
import type { GetProp, MenuProps } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
@@ -7,7 +7,6 @@ import classNames from 'classnames';
|
||||
|
||||
import useMenu from '../../hooks/useMenu';
|
||||
import SiteContext from '../slots/SiteContext';
|
||||
import type { SiteContextProps } from '../slots/SiteContext';
|
||||
|
||||
type MenuItemType = Extract<GetProp<MenuProps, 'items'>[number], { type?: 'item' }>;
|
||||
|
||||
@@ -115,7 +114,7 @@ const PrevAndNext: React.FC<{ rtl?: boolean }> = ({ rtl }) => {
|
||||
|
||||
const [menuItems, selectedKey] = useMenu({ before, after });
|
||||
|
||||
const { isMobile } = useContext<SiteContextProps>(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
|
||||
const [prev, next] = useMemo(() => {
|
||||
const flatMenu = flattenMenu(menuItems);
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import React, { use } from 'react';
|
||||
import { BgColorsOutlined, SmileOutlined, SunOutlined, LinkOutlined } from '@ant-design/icons';
|
||||
import { Dropdown, Button, Badge } from 'antd';
|
||||
import { BgColorsOutlined, LinkOutlined, SmileOutlined, SunOutlined } from '@ant-design/icons';
|
||||
import { Badge, Button, Dropdown } from 'antd';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { CompactTheme, DarkTheme } from 'antd-token-previewer/es/icons';
|
||||
import { FormattedMessage, useLocation } from 'dumi';
|
||||
|
||||
import useThemeAnimation from '../../../hooks/useThemeAnimation';
|
||||
import type { SiteContextProps } from '../../slots/SiteContext';
|
||||
import SiteContext from '../../slots/SiteContext';
|
||||
import useThemeAnimation from '../../../hooks/useThemeAnimation';
|
||||
import { getLocalizedPathname, isZhCN } from '../../utils';
|
||||
import Link from '../Link';
|
||||
import ThemeIcon from './ThemeIcon';
|
||||
|
||||
export type ThemeName = 'light' | 'dark' | 'compact' | 'motion-off' | 'happy-work';
|
||||
|
||||
export interface ThemeSwitchProps {
|
||||
value?: ThemeName[];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import dayjs from 'dayjs';
|
||||
|
||||
import 'dayjs/locale/zh-cn';
|
||||
|
||||
import React, { useContext, useEffect, useLayoutEffect, useRef } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useRef } from 'react';
|
||||
import ConfigProvider from 'antd/es/config-provider';
|
||||
import zhCN from 'antd/es/locale/zh_CN';
|
||||
import { Helmet, useOutlet, useSiteData } from 'dumi';
|
||||
@@ -38,7 +38,7 @@ const DocLayout: React.FC = () => {
|
||||
const { pathname, search, hash } = location;
|
||||
const [locale, lang] = useLocale(locales);
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout>>(null!);
|
||||
const { direction } = useContext(SiteContext);
|
||||
const { direction } = React.use(SiteContext);
|
||||
const { loading } = useSiteData();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
|
||||
@@ -200,20 +200,20 @@ const GlobalLayout: React.FC = () => {
|
||||
));
|
||||
|
||||
return (
|
||||
<DarkContext.Provider value={theme.includes('dark')}>
|
||||
<DarkContext value={theme.includes('dark')}>
|
||||
<StyleProvider
|
||||
cache={styleCache}
|
||||
linters={[legacyNotSelectorLinter, parentSelectorLinter, NaNLinter]}
|
||||
>
|
||||
<SiteContext.Provider value={siteContextValue}>
|
||||
<SiteContext value={siteContextValue}>
|
||||
<SiteThemeProvider theme={themeConfig}>
|
||||
<HappyProvider disabled={!theme.includes('happy-work')}>
|
||||
<App>{outlet}</App>
|
||||
</HappyProvider>
|
||||
</SiteThemeProvider>
|
||||
</SiteContext.Provider>
|
||||
</SiteContext>
|
||||
</StyleProvider>
|
||||
</DarkContext.Provider>
|
||||
</DarkContext>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import { ConfigProvider, Layout, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { FormattedMessage, useRouteMeta } from 'dumi';
|
||||
|
||||
import useDark from '../../../hooks/useDark';
|
||||
import CommonHelmet from '../../common/CommonHelmet';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import Footer from '../../slots/Footer';
|
||||
import { DarkContext } from './../../../hooks/useDark';
|
||||
import AffixTabs from './AffixTabs';
|
||||
|
||||
export type ResourceLayoutProps = PropsWithChildren<NonNullable<any>>;
|
||||
@@ -16,85 +16,77 @@ const resourcePadding = 40;
|
||||
const articleMaxWidth = 1208;
|
||||
const resourcePaddingXS = 24;
|
||||
|
||||
const useStyle = () => {
|
||||
const isRootDark = useDark();
|
||||
|
||||
return createStyles((config) => {
|
||||
const { token, css } = config;
|
||||
const { antCls } = token;
|
||||
|
||||
return {
|
||||
resourcePage: css`
|
||||
footer {
|
||||
margin-top: 176px;
|
||||
|
||||
.rc-footer-container {
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 0 auto;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
}
|
||||
`,
|
||||
resourceContent: css`
|
||||
padding: 0 ${resourcePadding}px;
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 0 auto;
|
||||
box-sizing: content-box;
|
||||
min-height: 100vh;
|
||||
|
||||
@media only screen and (max-width: 767.99px) {
|
||||
& {
|
||||
article {
|
||||
padding: 0 ${resourcePaddingXS}px;
|
||||
}
|
||||
${antCls}-col {
|
||||
padding-top: ${token.padding}px !important;
|
||||
padding-bottom: ${token.padding}px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
banner: css`
|
||||
padding: 0 ${resourcePadding}px;
|
||||
overflow: hidden;
|
||||
${
|
||||
isRootDark
|
||||
? ``
|
||||
: `background: url('https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*y_r7RogIG1wAAAAAAAAAAABkARQnAQ');`
|
||||
}
|
||||
background-size: cover;
|
||||
|
||||
h1 {
|
||||
box-sizing: content-box;
|
||||
const useStyle = createStyles(({ token, css }) => {
|
||||
const isDark = React.use(DarkContext);
|
||||
return {
|
||||
resourcePage: css`
|
||||
footer {
|
||||
margin-top: 176px;
|
||||
.rc-footer-container {
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 56px auto 16px;
|
||||
margin: 0 auto;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
}
|
||||
`,
|
||||
resourceContent: css`
|
||||
padding: 0 ${resourcePadding}px;
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 0 auto;
|
||||
box-sizing: content-box;
|
||||
min-height: 100vh;
|
||||
|
||||
section {
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 0 auto 56px;
|
||||
font-weight: 200;
|
||||
font-size: ${token.fontSizeLG}px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.99px) {
|
||||
& {
|
||||
margin: 0 -${resourcePaddingXS}px;
|
||||
@media only screen and (max-width: 767.99px) {
|
||||
& {
|
||||
article {
|
||||
padding: 0 ${resourcePaddingXS}px;
|
||||
}
|
||||
${token.antCls}-col {
|
||||
padding-top: ${token.padding}px !important;
|
||||
padding-bottom: ${token.padding}px !important;
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
})();
|
||||
};
|
||||
}
|
||||
`,
|
||||
banner: css`
|
||||
padding: 0 ${resourcePadding}px;
|
||||
overflow: hidden;
|
||||
${
|
||||
isDark
|
||||
? ``
|
||||
: `background: url('https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*y_r7RogIG1wAAAAAAAAAAABkARQnAQ');`
|
||||
}
|
||||
background-size: cover;
|
||||
|
||||
h1 {
|
||||
box-sizing: content-box;
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 56px auto 16px;
|
||||
}
|
||||
|
||||
section {
|
||||
max-width: ${articleMaxWidth}px;
|
||||
margin: 0 auto 56px;
|
||||
font-weight: 200;
|
||||
font-size: ${token.fontSizeLG}px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.99px) {
|
||||
& {
|
||||
margin: 0 -${resourcePaddingXS}px;
|
||||
padding: 0 ${resourcePaddingXS}px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
|
||||
const { styles } = useStyle();
|
||||
const meta = useRouteMeta();
|
||||
const isRootDark = useDark();
|
||||
|
||||
const isDark = React.use(DarkContext);
|
||||
const node = (
|
||||
<Layout>
|
||||
<CommonHelmet />
|
||||
@@ -116,7 +108,7 @@ const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
|
||||
</Layout>
|
||||
);
|
||||
|
||||
if (!isRootDark) {
|
||||
if (!isDark) {
|
||||
return <ConfigProvider theme={{ token: { colorBgLayout: '#fff' } }}>{node}</ConfigProvider>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import ContributorsList from '@qixian.cs/github-contributors-list';
|
||||
import { createStyles } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
@@ -40,7 +40,7 @@ interface ContributorsProps {
|
||||
const Contributors: React.FC<ContributorsProps> = ({ filename }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { styles } = useStyle();
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
|
||||
if (!filename) {
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { Col, Flex, Space, Typography, Skeleton } from 'antd';
|
||||
import React, { useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { Col, Flex, Skeleton, Space, Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage, useRouteMeta } from 'dumi';
|
||||
|
||||
@@ -9,8 +9,8 @@ import ComponentMeta from '../../builtins/ComponentMeta';
|
||||
import type { DemoContextProps } from '../DemoContext';
|
||||
import DemoContext from '../DemoContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import InViewSuspense from './InViewSuspense';
|
||||
import { useStyle } from './DocAnchor';
|
||||
import InViewSuspense from './InViewSuspense';
|
||||
|
||||
const Contributors = React.lazy(() => import('./Contributors'));
|
||||
const ColumnCard = React.lazy(() => import('./ColumnCard'));
|
||||
@@ -28,7 +28,7 @@ const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 6 }) =>
|
||||
const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const meta = useRouteMeta();
|
||||
const { pathname, hash } = useLocation();
|
||||
const { direction } = useContext(SiteContext);
|
||||
const { direction } = React.use(SiteContext);
|
||||
const { styles } = useStyle();
|
||||
|
||||
const [showDebug, setShowDebug] = useLayoutState(false);
|
||||
@@ -52,7 +52,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const isRTL = direction === 'rtl';
|
||||
|
||||
return (
|
||||
<DemoContext.Provider value={contextValue}>
|
||||
<DemoContext value={contextValue}>
|
||||
<Col xxl={20} xl={19} lg={18} md={18} sm={24} xs={24}>
|
||||
<InViewSuspense fallback={null}>
|
||||
<DocAnchor showDebug={showDebug} debugDemos={debugDemos} />
|
||||
@@ -110,7 +110,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
</InViewSuspense>
|
||||
<Footer />
|
||||
</Col>
|
||||
</DemoContext.Provider>
|
||||
</DemoContext>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { FastColor } from '@ant-design/fast-color';
|
||||
import {
|
||||
AntDesignOutlined,
|
||||
BgColorsOutlined,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
UsergroupAddOutlined,
|
||||
ZhihuOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { FastColor } from '@ant-design/fast-color';
|
||||
import { createStyles } from 'antd-style';
|
||||
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
|
||||
import { FormattedMessage, Link } from 'dumi';
|
||||
@@ -34,59 +34,52 @@ const locales = {
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => {
|
||||
const { isMobile } = useContext(SiteContext);
|
||||
return createStyles(({ token, css }) => {
|
||||
const background = new FastColor(getAlphaColor('#f0f3fa', '#fff'))
|
||||
.onBackground(token.colorBgContainer)
|
||||
.toHexString();
|
||||
const useStyle = createStyles(({ token, css }) => {
|
||||
const { isMobile } = React.use(SiteContext);
|
||||
const background = new FastColor(getAlphaColor('#f0f3fa', '#fff'))
|
||||
.onBackground(token.colorBgContainer)
|
||||
.toHexString();
|
||||
return {
|
||||
holder: css`
|
||||
background: ${background};
|
||||
`,
|
||||
|
||||
return {
|
||||
holder: css`
|
||||
background: ${background};
|
||||
`,
|
||||
footer: css`
|
||||
background: ${background};
|
||||
color: ${token.colorTextSecondary};
|
||||
box-shadow: inset 0 106px 36px -116px rgba(0, 0, 0, 0.14);
|
||||
|
||||
footer: css`
|
||||
background: ${background};
|
||||
color: ${token.colorTextSecondary};
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h2,
|
||||
a {
|
||||
color: ${token.colorText};
|
||||
}
|
||||
.rc-footer-column {
|
||||
margin-bottom: ${isMobile ? 60 : 0}px;
|
||||
:last-child {
|
||||
margin-bottom: ${isMobile ? 20 : 0}px;
|
||||
}
|
||||
}
|
||||
.rc-footer-item-icon {
|
||||
top: -1.5px;
|
||||
}
|
||||
.rc-footer-container {
|
||||
max-width: 1208px;
|
||||
margin-inline: auto;
|
||||
padding-inline: ${token.marginXXL}px;
|
||||
}
|
||||
.rc-footer-bottom {
|
||||
box-shadow: inset 0 106px 36px -116px rgba(0, 0, 0, 0.14);
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
.rc-footer-bottom-container {
|
||||
font-size: ${token.fontSize}px;
|
||||
}
|
||||
|
||||
h2,
|
||||
a {
|
||||
color: ${token.colorText};
|
||||
}
|
||||
|
||||
.rc-footer-column {
|
||||
margin-bottom: ${isMobile ? 60 : 0}px;
|
||||
:last-child {
|
||||
margin-bottom: ${isMobile ? 20 : 0}px;
|
||||
}
|
||||
}
|
||||
|
||||
.rc-footer-item-icon {
|
||||
top: -1.5px;
|
||||
}
|
||||
|
||||
.rc-footer-container {
|
||||
max-width: 1208px;
|
||||
margin-inline: auto;
|
||||
padding-inline: ${token.marginXXL}px;
|
||||
}
|
||||
|
||||
.rc-footer-bottom {
|
||||
box-shadow: inset 0 106px 36px -116px rgba(0, 0, 0, 0.14);
|
||||
.rc-footer-bottom-container {
|
||||
font-size: ${token.fontSize}px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
})();
|
||||
};
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
const location = useLocation();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
/* eslint-disable react-hooks-extra/no-direct-set-state-in-use-effect */
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
|
||||
import { Alert, Col, ConfigProvider, Popover, Row, Select, Button, Tooltip } from 'antd';
|
||||
import { Alert, Button, Col, ConfigProvider, Popover, Row, Select, Tooltip } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
import dayjs from 'dayjs';
|
||||
@@ -8,17 +9,16 @@ import { useLocation, useSiteData } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import ThemeSwitch from '../../common/ThemeSwitch';
|
||||
import DirectionIcon from '../../icons/DirectionIcon';
|
||||
import { ANT_DESIGN_NOT_SHOW_BANNER } from '../../layouts/GlobalLayout';
|
||||
import * as utils from '../../utils';
|
||||
import { getThemeConfig } from '../../utils';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import type { SharedProps } from './interface';
|
||||
import Logo from './Logo';
|
||||
import Navigation from './Navigation';
|
||||
import SwitchBtn from './SwitchBtn';
|
||||
import ThemeSwitch from '../../common/ThemeSwitch';
|
||||
|
||||
const RESPONSIVE_XS = 1120;
|
||||
const RESPONSIVE_SM = 1200;
|
||||
@@ -169,8 +169,7 @@ const Header: React.FC = () => {
|
||||
windowWidth: 1400,
|
||||
searching: false,
|
||||
});
|
||||
const { direction, isMobile, bannerVisible, updateSiteConfig } =
|
||||
useContext<SiteContextProps>(SiteContext);
|
||||
const { direction, isMobile, bannerVisible, updateSiteConfig } = React.use(SiteContext);
|
||||
const pingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const location = useLocation();
|
||||
const { pathname, search } = location;
|
||||
@@ -339,7 +338,7 @@ const Header: React.FC = () => {
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Tooltip title="GitHub">
|
||||
<Tooltip title="GitHub" destroyTooltipOnHide>
|
||||
<Button type="text" icon={<GithubOutlined />} style={{ fontSize: 16 }} />
|
||||
</Tooltip>
|
||||
</a>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { Col, ConfigProvider, Menu } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import { useSidebarData } from 'dumi';
|
||||
@@ -109,7 +109,7 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
|
||||
const Sidebar: React.FC = () => {
|
||||
const sidebarData = useSidebarData();
|
||||
const { isMobile, theme } = useContext(SiteContext);
|
||||
const { isMobile, theme } = React.use(SiteContext);
|
||||
const { styles } = useStyle();
|
||||
|
||||
const [menuItems, selectedKey] = useMenu();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { waitFakeTimer } from '../../../tests/utils';
|
||||
import { isStyleSupport } from '../styleChecker';
|
||||
import throttleByAnimationFrame from '../throttleByAnimationFrame';
|
||||
import toList from '../toList';
|
||||
|
||||
describe('Test utils function', () => {
|
||||
describe('throttle', () => {
|
||||
@@ -56,4 +57,12 @@ describe('Test utils function', () => {
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
describe('toList', () => {
|
||||
it('toList should work', () => {
|
||||
expect(toList(123)).toEqual([123]);
|
||||
expect(toList([123])).toEqual([123]);
|
||||
expect(toList(null, true)).toEqual([]);
|
||||
expect(toList(undefined, true)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
export default function toList<T>(candidate: T | T[], skipEmpty = false): T[] {
|
||||
if (skipEmpty && (candidate === undefined || candidate === null)) return [];
|
||||
|
||||
const toList = <T>(candidate: T | T[], skipEmpty = false): T[] => {
|
||||
if (skipEmpty && (candidate === undefined || candidate === null)) {
|
||||
return [];
|
||||
}
|
||||
return Array.isArray(candidate) ? candidate : [candidate];
|
||||
}
|
||||
};
|
||||
|
||||
export default toList;
|
||||
|
||||
@@ -19,6 +19,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Badge"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.7.0' },
|
||||
{ name: 'indicator', desc: locale.indicator, version: '5.7.0' },
|
||||
|
||||
@@ -22,6 +22,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Button"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'icon', desc: locale.icon, version: '5.5.0' },
|
||||
|
||||
@@ -58,6 +58,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Card"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'header', desc: locale.header, version: '5.14.0' },
|
||||
|
||||
@@ -43,6 +43,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Collapse"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'header', desc: locale.header, version: '5.21.0' },
|
||||
|
||||
@@ -58,6 +58,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Descriptions"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'header', desc: locale.header, version: '5.23.0' },
|
||||
|
||||
@@ -31,6 +31,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Drawer"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'mask', desc: locale.mask, version: '5.13.0' },
|
||||
|
||||
@@ -23,6 +23,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Empty"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'image', desc: locale.image, version: '5.23.0' },
|
||||
|
||||
@@ -24,6 +24,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Input"
|
||||
semantics={[
|
||||
{ name: 'input', desc: locale.input, version: '5.4.0' },
|
||||
{ name: 'prefix', desc: locale.prefix, version: '5.4.0' },
|
||||
|
||||
@@ -19,6 +19,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="TextArea"
|
||||
semantics={[
|
||||
{ name: 'textarea', desc: locale.textarea, version: '5.4.0' },
|
||||
{ name: 'count', desc: locale.count, version: '5.4.0' },
|
||||
|
||||
@@ -77,6 +77,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="List"
|
||||
height={300}
|
||||
semantics={[
|
||||
{ name: 'extra', desc: locale.extra, version: '5.18.0' },
|
||||
|
||||
@@ -44,7 +44,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| loadMore | Shows a load more content | ReactNode | - | |
|
||||
| locale | The i18n text including empty text | object | {emptyText: `No Data`} | |
|
||||
| pagination | Pagination [config](/components/pagination/), hide it by setting it to false | boolean \| object | false | |
|
||||
| renderItem | Customize list item when using `dataSource` | (item) => ReactNode | - | |
|
||||
| renderItem | Customize list item when using `dataSource` | (item: T, index: number) => ReactNode | - | |
|
||||
| rowKey | Item's unique value, could be an Item's key which holds a unique value of type `React.Key` or function that receives Item and returns a `React.Key` | `keyof` T \| (item: T) => `React.Key` | `"key"` | |
|
||||
| size | Size of list | `default` \| `large` \| `small` | `default` | |
|
||||
| split | Toggles rendering of the split under the list item | boolean | true | |
|
||||
|
||||
@@ -47,7 +47,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*tBzwQ7raKX8AAA
|
||||
| loadMore | 加载更多 | ReactNode | - | |
|
||||
| locale | 默认文案设置,目前包括空数据文案 | object | {emptyText: `暂无数据`} | |
|
||||
| pagination | 对应的 `pagination` 配置,设置 false 不显示 | boolean \| object | false | |
|
||||
| renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项 | (item) => ReactNode | - | |
|
||||
| renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项 | (item: T, index: number) => ReactNode | - | |
|
||||
| rowKey | 当 `renderItem` 自定义渲染列表项有效时,自定义每一行的 `key` 的获取方式 | `keyof` T \| (item: T) => `React.Key` | `"key"` | |
|
||||
| size | list 的尺寸 | `default` \| `large` \| `small` | `default` | |
|
||||
| split | 是否展示分割线 | boolean | true | |
|
||||
|
||||
@@ -61,6 +61,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Modal"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'mask', desc: locale.mask, version: '5.13.0' },
|
||||
|
||||
@@ -36,6 +36,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Popconfirm"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'body', desc: locale.body, version: '5.23.0' },
|
||||
|
||||
@@ -36,6 +36,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Popover"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'body', desc: locale.body, version: '5.23.0' },
|
||||
|
||||
@@ -25,6 +25,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Slider"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'track', desc: locale.track, version: '5.10.0' },
|
||||
|
||||
@@ -19,6 +19,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Space"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.0.0' },
|
||||
{ name: 'item', desc: locale.item, version: '5.6.0' },
|
||||
|
||||
@@ -313,35 +313,25 @@ describe('Theme', () => {
|
||||
});
|
||||
|
||||
it('component token should support algorithm', () => {
|
||||
const Demo = ({ algorithm }: { algorithm?: boolean | typeof theme.darkAlgorithm }) => (
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Input: {
|
||||
colorPrimary: '#00B96B',
|
||||
algorithm,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Input />
|
||||
</ConfigProvider>
|
||||
);
|
||||
const Demo: React.FC<{ algorithm?: boolean | typeof theme.darkAlgorithm }> = (props) => {
|
||||
const { algorithm } = props;
|
||||
return (
|
||||
<ConfigProvider theme={{ components: { Input: { colorPrimary: '#00B96B', algorithm } } }}>
|
||||
<Input />
|
||||
</ConfigProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const { container, rerender } = render(<Demo />);
|
||||
expect(container.querySelector('input')).toHaveStyle({
|
||||
'--ant-input-hover-border-color': '#4096ff',
|
||||
});
|
||||
const inputElement = container.querySelector<HTMLInputElement>('input');
|
||||
|
||||
expect(inputElement).toHaveStyle({ '--ant-input-hover-border-color': '#4096ff' });
|
||||
|
||||
rerender(<Demo algorithm />);
|
||||
expect(container.querySelector('input')).toHaveStyle({
|
||||
'--ant-input-hover-border-color': '#20c77c',
|
||||
});
|
||||
expect(inputElement).toHaveStyle({ '--ant-input-hover-border-color': '#20c77c' });
|
||||
|
||||
rerender(<Demo algorithm={theme.darkAlgorithm} />);
|
||||
expect(container.querySelector('input')).toHaveStyle({
|
||||
'--ant-input-hover-border-color': '#1fb572',
|
||||
});
|
||||
expect(inputElement).toHaveStyle({ '--ant-input-hover-border-color': '#1fb572' });
|
||||
});
|
||||
|
||||
it('get cssVar from useToken', () => {
|
||||
|
||||
@@ -36,6 +36,7 @@ const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Tooltip"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '5.23.0' },
|
||||
{ name: 'body', desc: locale.body, version: '5.23.0' },
|
||||
|
||||
@@ -84,7 +84,7 @@ export interface TransferListProps<RecordType> extends TransferLocale {
|
||||
|
||||
export interface TransferCustomListBodyProps<T> extends TransferListBodyProps<T> {}
|
||||
|
||||
const useShowSearchOption = (showSearch: boolean | TransferSearchOption) => {
|
||||
const getShowSearchOption = (showSearch: boolean | TransferSearchOption) => {
|
||||
if (showSearch && typeof showSearch === 'object') {
|
||||
return {
|
||||
...showSearch,
|
||||
@@ -133,7 +133,7 @@ const TransferList = <RecordType extends KeyWiseTransferItem>(
|
||||
filterOption,
|
||||
render = defaultRender,
|
||||
} = props;
|
||||
const searchOptions = useShowSearchOption(showSearch);
|
||||
const searchOptions = getShowSearchOption(showSearch);
|
||||
const [filterValue, setFilterValue] = useState<string>(searchOptions.defaultValue);
|
||||
const listBodyRef = useRef<ListBodyRef<RecordType>>({});
|
||||
|
||||
|
||||
@@ -196,8 +196,8 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
|
||||
gapY,
|
||||
] as const;
|
||||
|
||||
const result = getClipsCache(params, () => getClips(...params));
|
||||
const [nextClips, clipWidth] = result;
|
||||
const [nextClips, clipWidth] = getClipsCache(params, () => getClips(...params));
|
||||
|
||||
setWatermarkInfo([nextClips, clipWidth]);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { WatermarkProps } from '.';
|
||||
import toList from '../_util/toList';
|
||||
|
||||
export const FontGap = 3;
|
||||
|
||||
function prepareCanvas(
|
||||
const prepareCanvas = (
|
||||
width: number,
|
||||
height: number,
|
||||
ratio = 1,
|
||||
@@ -12,26 +14,31 @@ function prepareCanvas(
|
||||
canvas: HTMLCanvasElement,
|
||||
realWidth: number,
|
||||
realHeight: number,
|
||||
] {
|
||||
] => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
const realWidth = width * ratio;
|
||||
const realHeight = height * ratio;
|
||||
canvas.setAttribute('width', `${realWidth}px`);
|
||||
canvas.setAttribute('height', `${realHeight}px`);
|
||||
ctx.save();
|
||||
|
||||
return [ctx, canvas, realWidth, realHeight];
|
||||
}
|
||||
};
|
||||
|
||||
// Get boundary of rotated text
|
||||
const getRotatePos = (x: number, y: number, angle: number) => {
|
||||
const targetX = x * Math.cos(angle) - y * Math.sin(angle);
|
||||
const targetY = x * Math.sin(angle) + y * Math.cos(angle);
|
||||
return [targetX, targetY] as const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the clips of text content.
|
||||
* This is a lazy hook function since SSR no need this
|
||||
*/
|
||||
export default function useClips() {
|
||||
const useClips = () => {
|
||||
// Get single clips
|
||||
function getClips(
|
||||
const getClips = (
|
||||
content: NonNullable<WatermarkProps['content']> | HTMLImageElement,
|
||||
rotate: number,
|
||||
ratio: number,
|
||||
@@ -40,7 +47,7 @@ export default function useClips() {
|
||||
font: Required<NonNullable<WatermarkProps['font']>>,
|
||||
gapX: number,
|
||||
gapY: number,
|
||||
): [dataURL: string, finalWidth: number, finalHeight: number] {
|
||||
): [dataURL: string, finalWidth: number, finalHeight: number] => {
|
||||
// ================= Text / Image =================
|
||||
const [ctx, canvas, contentWidth, contentHeight] = prepareCanvas(width, height, ratio);
|
||||
|
||||
@@ -74,13 +81,6 @@ export default function useClips() {
|
||||
rCtx.drawImage(canvas, -contentWidth / 2, -contentHeight / 2);
|
||||
}
|
||||
|
||||
// Get boundary of rotated text
|
||||
function getRotatePos(x: number, y: number) {
|
||||
const targetX = x * Math.cos(angle) - y * Math.sin(angle);
|
||||
const targetY = x * Math.sin(angle) + y * Math.cos(angle);
|
||||
return [targetX, targetY];
|
||||
}
|
||||
|
||||
let left = 0;
|
||||
let right = 0;
|
||||
let top = 0;
|
||||
@@ -95,7 +95,7 @@ export default function useClips() {
|
||||
[0 - halfWidth, 0 + halfHeight],
|
||||
];
|
||||
points.forEach(([x, y]) => {
|
||||
const [targetX, targetY] = getRotatePos(x, y);
|
||||
const [targetX, targetY] = getRotatePos(x, y, angle);
|
||||
left = Math.min(left, targetX);
|
||||
right = Math.max(right, targetX);
|
||||
top = Math.min(top, targetY);
|
||||
@@ -115,7 +115,7 @@ export default function useClips() {
|
||||
|
||||
const [fCtx, fCanvas] = prepareCanvas(filledWidth, filledHeight);
|
||||
|
||||
function drawImg(targetX = 0, targetY = 0) {
|
||||
const drawImg = (targetX = 0, targetY = 0) => {
|
||||
fCtx.drawImage(
|
||||
rCanvas,
|
||||
cutLeft,
|
||||
@@ -127,13 +127,15 @@ export default function useClips() {
|
||||
cutWidth,
|
||||
cutHeight,
|
||||
);
|
||||
}
|
||||
};
|
||||
drawImg();
|
||||
drawImg(cutWidth + realGapX, -cutHeight / 2 - realGapY / 2);
|
||||
drawImg(cutWidth + realGapX, +cutHeight / 2 + realGapY / 2);
|
||||
|
||||
return [fCanvas.toDataURL(), filledWidth / ratio, filledHeight / ratio];
|
||||
}
|
||||
};
|
||||
|
||||
return getClips;
|
||||
}
|
||||
return React.useCallback(getClips, []);
|
||||
};
|
||||
|
||||
export default useClips;
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function useSingletonCache<T extends any[], R>(): GetCache<T, R>
|
||||
|
||||
const getCache: GetCache<T, R> = (cacheKeys, callback) => {
|
||||
const filteredKeys = cacheKeys.map((item) =>
|
||||
item instanceof HTMLElement || isNaN(item) ? '' : item,
|
||||
item instanceof HTMLElement || Number.isNaN(item) ? '' : item,
|
||||
);
|
||||
|
||||
if (!isEqual(cacheRef.current[0], filteredKeys)) {
|
||||
|
||||
@@ -66,20 +66,18 @@ import React from 'react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
const useButtonStyle = () => {
|
||||
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
|
||||
const useButtonStyle = createStyles(({ css }) => {
|
||||
const { getPrefixCls } = React.use(ConfigProvider.ConfigContext);
|
||||
const btnPrefixCls = getPrefixCls('btn');
|
||||
|
||||
// Customize styles
|
||||
return createStyles(({ css }) => ({
|
||||
return {
|
||||
btn: css`
|
||||
background: red;
|
||||
.${btnPrefixCls}-icon {
|
||||
color: green;
|
||||
}
|
||||
`,
|
||||
}))();
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
const GeekProvider: React.FC<Readonly<React.PropsWithChildren>> = (props) => {
|
||||
const { styles } = useButtonStyle();
|
||||
|
||||
@@ -66,20 +66,18 @@ import React from 'react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
const useButtonStyle = () => {
|
||||
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
|
||||
const useButtonStyle = createStyles(({ css }) => {
|
||||
const { getPrefixCls } = React.use(ConfigProvider.ConfigContext);
|
||||
const btnPrefixCls = getPrefixCls('btn');
|
||||
|
||||
// Customize styles
|
||||
return createStyles(({ css }) => ({
|
||||
return {
|
||||
btn: css`
|
||||
background: red;
|
||||
.${btnPrefixCls}-icon {
|
||||
color: green;
|
||||
}
|
||||
`,
|
||||
}))();
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
const GeekProvider: React.FC<Readonly<React.PropsWithChildren>> = (props) => {
|
||||
const { styles } = useButtonStyle();
|
||||
|
||||
@@ -64,6 +64,7 @@ export default antfu(
|
||||
/* turn off React 19 only rules */
|
||||
'react/no-forward-ref': 'off',
|
||||
'react/no-context-provider': 'off',
|
||||
'react/no-use-context': 'off',
|
||||
},
|
||||
},
|
||||
compat.configs['flat/recommended'],
|
||||
@@ -125,6 +126,7 @@ export default antfu(
|
||||
'react/no-array-index-key': 'off',
|
||||
'react-dom/no-missing-iframe-sandbox': 'off',
|
||||
'no-restricted-globals': 'off',
|
||||
'react/no-use-context': 'warn',
|
||||
},
|
||||
settings: {
|
||||
polyfills: ['Promise', 'URL', 'URLSearchParams'],
|
||||
|
||||
14
package.json
14
package.json
@@ -240,7 +240,7 @@
|
||||
"dumi": "~2.4.17",
|
||||
"dumi-plugin-color-chunk": "^2.1.0",
|
||||
"env-paths": "^3.0.0",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint": "^9.23.0",
|
||||
"eslint-plugin-compat": "^6.0.1",
|
||||
"eslint-plugin-jest": "^28.9.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
@@ -289,10 +289,10 @@
|
||||
"rc-footer": "^0.6.8",
|
||||
"rc-tween-one": "^3.0.6",
|
||||
"rc-virtual-list": "^3.17.0",
|
||||
"react": "^19.0.0",
|
||||
"react": "^19.1.0",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-countup": "^6.5.3",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-draggable": "^4.4.6",
|
||||
"react-fast-marquee": "^1.6.5",
|
||||
"react-highlight-words": "^0.21.0",
|
||||
@@ -350,17 +350,17 @@
|
||||
"tnpm": {
|
||||
"mode": "npm"
|
||||
},
|
||||
"pnpm":{
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"nwsapi":"2.2.19"
|
||||
"nwsapi": "2.2.20"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"@ant-design/cssinjs": "^2.0.0-alpha.5",
|
||||
"@ant-design/cssinjs-utils": "^2.0.0-alpha.1",
|
||||
"nwsapi": "2.2.19"
|
||||
"nwsapi": "2.2.20"
|
||||
},
|
||||
"resolutions": {
|
||||
"nwsapi": "2.2.19"
|
||||
"nwsapi": "2.2.20"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user