Merge remote-tracking branch 'origin/feature' into flex

This commit is contained in:
二货机器人 2024-01-23 17:55:13 +08:00
commit 4e12c3eca9
363 changed files with 10012 additions and 8298 deletions

View File

@ -9,7 +9,7 @@ function useLocale<Key extends string>(
localeMap?: LocaleMap<Key>,
): [Record<Key, string>, 'cn' | 'en'] {
const { id } = useDumiLocale();
const localeType = id === 'zh-CN' ? ('cn' as const) : ('en' as const);
const localeType = id === 'zh-CN' ? 'cn' : 'en';
return [localeMap?.[localeType]!, localeType];
}

View File

@ -39,8 +39,8 @@
.mirror-modal-mask {
position: fixed;
inset: 0;
height: '100vh';
width: '100vw';
height: 100vh;
width: 100vw;
background: rgba(0, 0, 0, 0.3);
z-index: 9999;
animation: mirror-fade-in 0.3s forwards;
@ -48,12 +48,12 @@
.mirror-modal-dialog {
position: fixed;
inset: 0;
top: 120px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
width: 400px;
height: 120px;
width: 420px;
display: flex;
align-items: center;
flex-direction: column;
@ -63,6 +63,9 @@
padding: 20px 24px;
box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
animation: mirror-zoom-in 0.3s forwards;
box-sizing: border-box;
max-width: 100vw;
z-index: 9999;
}
.mirror-modal-title {
@ -75,7 +78,7 @@
.mirror-modal-content {
font-size: 14px;
align-self: flex-start;
margin-bottom: 16px;
margin-bottom: 24px;
}
.mirror-modal-btns {
@ -143,7 +146,7 @@
const content = document.createElement('div');
content.className = 'mirror-modal-content';
content.innerText = '国内用户推荐访问国内镜像以获得极速体验~';
content.innerText = '🚀 国内用户推荐访问国内镜像以获得极速体验~';
dialog.append(content);
const btnWrapper = document.createElement('div');

View File

@ -1,8 +1,9 @@
import { createStyles, css, useTheme } from 'antd-style';
import { Link, useLocation } from 'dumi';
import * as React from 'react';
import { Button, Flex, Typography } from 'antd';
import { createStyles, css, useTheme } from 'antd-style';
import classNames from 'classnames';
import { Button, Space, Typography } from 'antd';
import { Link, useLocation } from 'dumi';
import useLocale from '../../../hooks/useLocale';
import SiteContext from '../../../theme/slots/SiteContext';
import * as utils from '../../../theme/utils';
@ -46,22 +47,19 @@ const useStyle = () => {
font-size: 68px;
}
`,
btnWrap: css`
margin-bottom: ${token.marginXL}px;
`,
}))();
};
export interface BannerProps {
children?: React.ReactNode;
}
export default function Banner({ children }: BannerProps) {
const Banner: React.FC<React.PropsWithChildren> = ({ children }) => {
const [locale] = useLocale(locales);
const { pathname, search } = useLocation();
const token = useTheme();
const { styles } = useStyle();
const { isMobile } = React.useContext(SiteContext);
const isZhCN = utils.isZhCN(pathname);
return (
<>
{/* Banner Placeholder Motion */}
@ -157,8 +155,7 @@ export default function Banner({ children }: BannerProps) {
>
<div>{locale.slogan}</div>
</Typography.Paragraph>
<Space size="middle" style={{ marginBottom: token.marginFar }}>
<Flex gap="middle" className={styles.btnWrap}>
<Link to={utils.getLocalizedPathname('/components/overview/', isZhCN, search)}>
<Button size="large" type="primary">
{locale.start}
@ -167,11 +164,12 @@ export default function Banner({ children }: BannerProps) {
<Link to={utils.getLocalizedPathname('/docs/spec/introduce/', isZhCN, search)}>
<Button size="large">{locale.designLanguage}</Button>
</Link>
</Space>
</Flex>
{children}
</GroupMask>
</div>
</>
);
}
};
export default Banner;

View File

@ -1,14 +1,13 @@
/* eslint-disable react/jsx-pascal-case */
import React, { useContext } from 'react';
import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons';
import {
Alert,
Carousel,
DatePicker,
Flex,
FloatButton,
Modal,
Progress,
Space,
Tag,
Tour,
Typography,
@ -22,6 +21,11 @@ import useLocale from '../../../hooks/useLocale';
import SiteContext from '../../../theme/slots/SiteContext';
import { getCarouselStyle } from './util';
const { _InternalPanelDoNotUseOrYouWillBeFired: ModalDoNotUseOrYouWillBeFired } = Modal;
const { _InternalPanelDoNotUseOrYouWillBeFired: DatePickerDoNotUseOrYouWillBeFired } = DatePicker;
const { _InternalPanelDoNotUseOrYouWillBeFired: TourDoNotUseOrYouWillBeFired } = Tour;
const { _InternalPanelDoNotUseOrYouWillBeFired: FloatButtonDoNotUseOrYouWillBeFired } = FloatButton;
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.';
@ -110,19 +114,16 @@ const ComponentItem: React.FC<ComponentItemProps> = ({ title, node, type, index
{/* Decorator */}
<div
className={styles.cardCircle}
style={{
right: (index % 2) * -20 - 20,
bottom: (index % 3) * -40 - 20,
}}
style={{ right: (index % 2) * -20 - 20, bottom: (index % 3) * -40 - 20 }}
/>
{/* Title */}
<Space>
<Flex align="center" gap="small">
<Typography.Title level={4} style={{ fontWeight: 'normal', margin: 0 }}>
{title}
</Typography.Title>
<Tag color={tagColor}>{tagText}</Tag>
</Space>
</Flex>
<div
style={{
@ -146,25 +147,20 @@ interface ComponentItemProps {
index: number;
}
export default function ComponentsList() {
const ComponentsList: React.FC = () => {
const token = useTheme();
const { styles } = useStyle();
const [locale] = useLocale(locales);
const { isMobile } = useContext(SiteContext);
const COMPONENTS: {
title: React.ReactNode;
type: 'new' | 'update';
node: React.ReactNode;
}[] = React.useMemo(
const COMPONENTS = React.useMemo<Omit<ComponentItemProps, 'index'>[]>(
() => [
{
title: 'Modal',
type: 'update',
node: (
<Modal._InternalPanelDoNotUseOrYouWillBeFired title="Ant Design 5.0" width={300}>
<ModalDoNotUseOrYouWillBeFired title="Ant Design 5.0" width={300}>
{locale.sampleContent}
</Modal._InternalPanelDoNotUseOrYouWillBeFired>
</ModalDoNotUseOrYouWillBeFired>
),
},
@ -172,7 +168,8 @@ export default function ComponentsList() {
title: 'DatePicker',
type: 'update',
node: (
<DatePicker._InternalPanelDoNotUseOrYouWillBeFired
<DatePickerDoNotUseOrYouWillBeFired
value={dayjs('2022-11-18 14:00:00')}
showToday={false}
presets={
isMobile
@ -184,7 +181,6 @@ export default function ComponentsList() {
{ label: locale.lastYear, value: dayjs().add(-1, 'year') },
]
}
value={dayjs('2022-11-18 14:00:00')}
/>
),
},
@ -193,28 +189,27 @@ export default function ComponentsList() {
title: 'Progress',
type: 'update',
node: (
<Space direction="vertical">
<Space>
<Flex gap="small" vertical>
<Flex gap="small" align="center">
<Progress type="circle" trailColor="#e6f4ff" percent={60} size={14} />
{locale.inProgress}
</Space>
<Space>
</Flex>
<Flex gap="small" align="center">
<Progress type="circle" percent={100} size={14} />
{locale.success}
</Space>
<Space>
</Flex>
<Flex gap="small" align="center">
<Progress type="circle" status="exception" percent={88} size={14} />
{locale.taskFailed}
</Space>
</Space>
</Flex>
</Flex>
),
},
{
title: 'Tour',
type: 'new',
node: (
<Tour._InternalPanelDoNotUseOrYouWillBeFired
<TourDoNotUseOrYouWillBeFired
title="Ant Design 5.0"
description={locale.tour}
style={{ width: isMobile ? 'auto' : 350 }}
@ -227,36 +222,24 @@ export default function ComponentsList() {
title: 'FloatButton',
type: 'new',
node: (
<Space size="large">
<FloatButton._InternalPanelDoNotUseOrYouWillBeFired
<Flex align="center" gap="large">
<FloatButtonDoNotUseOrYouWillBeFired
shape="square"
items={[
{
icon: <QuestionCircleOutlined />,
},
{
icon: <CustomerServiceOutlined />,
},
{
icon: <SyncOutlined />,
},
{ icon: <QuestionCircleOutlined /> },
{ icon: <CustomerServiceOutlined /> },
{ icon: <SyncOutlined /> },
]}
/>
<FloatButton._InternalPanelDoNotUseOrYouWillBeFired backTop />
<FloatButton._InternalPanelDoNotUseOrYouWillBeFired
<FloatButtonDoNotUseOrYouWillBeFired backTop />
<FloatButtonDoNotUseOrYouWillBeFired
items={[
{
icon: <QuestionCircleOutlined />,
},
{
icon: <CustomerServiceOutlined />,
},
{
icon: <SyncOutlined />,
},
{ icon: <QuestionCircleOutlined /> },
{ icon: <CustomerServiceOutlined /> },
{ icon: <SyncOutlined /> },
]}
/>
</Space>
</Flex>
),
},
@ -285,7 +268,7 @@ export default function ComponentsList() {
return isMobile ? (
<div style={{ margin: '0 16px' }}>
<Carousel className={styles.carousel}>
{COMPONENTS.map(({ title, node, type }, index) => (
{COMPONENTS.map<React.ReactNode>(({ title, node, type }, index) => (
<ComponentItem title={title} node={node} type={type} index={index} key={index} />
))}
</Carousel>
@ -293,10 +276,12 @@ export default function ComponentsList() {
) : (
<div style={{ width: '100%', overflow: 'hidden', display: 'flex', justifyContent: 'center' }}>
<div style={{ display: 'flex', alignItems: 'stretch', columnGap: token.paddingLG }}>
{COMPONENTS.map(({ title, node, type }, index) => (
{COMPONENTS.map<React.ReactNode>(({ title, node, type }, index) => (
<ComponentItem title={title} node={node} type={type} index={index} key={index} />
))}
</div>
</div>
);
}
};
export default ComponentsList;

View File

@ -1,6 +1,6 @@
import React, { Suspense } from 'react';
import { Button, ConfigProvider, Space, Typography } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import { Button, ConfigProvider, Flex, Typography } from 'antd';
import { createStyles } from 'antd-style';
import { Link, useLocation } from 'dumi';
import useLocale from '../../../../hooks/useLocale';
@ -97,21 +97,18 @@ const useStyle = () => {
width: 100%;
z-index: 1;
`,
btnWrap: css`
margin-bottom: ${token.marginXL}px;
`,
};
})();
};
export interface PreviewBannerProps {
children?: React.ReactNode;
}
const PreviewBanner: React.FC<PreviewBannerProps> = (props) => {
const PreviewBanner: React.FC<React.PropsWithChildren> = (props) => {
const { children } = props;
const [locale] = useLocale(locales);
const { styles } = useStyle();
const { isMobile } = React.useContext(SiteContext);
const token = useTheme();
const { pathname, search } = useLocation();
const isZhCN = utils.isZhCN(pathname);
@ -140,13 +137,11 @@ const PreviewBanner: React.FC<PreviewBannerProps> = (props) => {
)}
</Suspense>
<div className={styles.mask} />
<Typography className={styles.typography}>
<h1>Ant Design 5.0</h1>
<p>{locale.slogan}</p>
</Typography>
<Space size="middle" style={{ marginBottom: token.marginXL }}>
<Flex gap="middle" className={styles.btnWrap}>
<Link to={utils.getLocalizedPathname('/components/overview/', isZhCN, search)}>
<Button size="large" type="primary">
{locale.start}
@ -155,7 +150,7 @@ const PreviewBanner: React.FC<PreviewBannerProps> = (props) => {
<Link to={utils.getLocalizedPathname('/docs/spec/introduce/', isZhCN, search)}>
<Button size="large">{locale.designLanguage}</Button>
</Link>
</Space>
</Flex>
<div className={styles.child}>{children}</div>
</div>
</GroupMask>

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { ColorPicker, Input, Space } from 'antd';
import { ColorPicker, Flex, Input } from 'antd';
import { createStyles } from 'antd-style';
import type { Color } from 'antd/es/color-picker';
import { generateColor } from 'antd/es/color-picker/util';
@ -91,21 +91,20 @@ const ThemeColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, id }) =
}, [value]);
return (
<Space size="large">
<Flex gap="large" align="center" wrap="wrap">
<Input
value={typeof value === 'string' ? value : value?.toHexString()}
onChange={(event) => onChange?.(event.target.value)}
style={{ width: 120 }}
id={id}
/>
<Space size="middle">
{matchColors.map(({ color, active, picker }) => {
let colorNode = (
<Flex gap="middle">
{matchColors.map<React.ReactNode>(({ color, active, picker }) => {
const colorNode = (
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label
key={color}
className={classNames(styles.color, active && styles.colorActive)}
className={classNames(styles.color, { [styles.colorActive]: active })}
style={{ background: color }}
onClick={() => {
if (!picker) {
@ -121,23 +120,20 @@ const ThemeColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, id }) =
/>
</label>
);
if (picker) {
colorNode = (
<DebouncedColorPicker
key={`colorpicker-${value}`}
value={value || ''}
onChange={onChange}
>
{colorNode}
</DebouncedColorPicker>
);
}
return colorNode;
return picker ? (
<DebouncedColorPicker
key={`colorpicker-${value}`}
value={value || ''}
onChange={onChange}
>
{colorNode}
</DebouncedColorPicker>
) : (
colorNode
);
})}
</Space>
</Space>
</Flex>
</Flex>
);
};

View File

@ -1,5 +1,5 @@
import React from 'react';
import { InputNumber, Slider, Space } from 'antd';
import { Flex, InputNumber, Slider } from 'antd';
export interface RadiusPickerProps {
id?: string;
@ -7,27 +7,26 @@ export interface RadiusPickerProps {
onChange?: (value: number | null) => void;
}
export default function RadiusPicker({ value, onChange, id }: RadiusPickerProps) {
return (
<Space size="large">
<InputNumber
value={value}
onChange={onChange}
style={{ width: 120 }}
min={0}
formatter={(val) => `${val}px`}
parser={(str) => (str ? parseFloat(str) : (str as any))}
id={id}
/>
const RadiusPicker: React.FC<RadiusPickerProps> = ({ id, value, onChange }) => (
<Flex gap="large">
<InputNumber
value={value}
onChange={onChange}
style={{ width: 120 }}
min={0}
formatter={(val) => `${val}px`}
parser={(str) => (str ? parseFloat(str) : (str as any))}
id={id}
/>
<Slider
tooltip={{ open: false }}
style={{ width: 128 }}
min={0}
value={value}
max={20}
onChange={onChange}
/>
</Flex>
);
<Slider
tooltip={{ open: false }}
style={{ width: 128 }}
min={0}
value={value}
max={20}
onChange={onChange}
/>
</Space>
);
}
export default RadiusPicker;

View File

@ -1,6 +1,7 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import * as React from 'react';
import { Space } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import { Flex } from 'antd';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import useLocale from '../../../../hooks/useLocale';
@ -65,7 +66,6 @@ const useStyle = createStyles(({ token, css }) => ({
box-shadow:
0 0 0 1px ${token.colorBgContainer},
0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary};
&,
&:hover:not(:focus-within) {
transform: scale(1);
@ -79,35 +79,28 @@ export interface ThemePickerProps {
onChange?: (value: string) => void;
}
export default function ThemePicker(props: ThemePickerProps) {
const { value, onChange, id } = props;
const token = useTheme();
const ThemePicker: React.FC<ThemePickerProps> = (props) => {
const { value, id, onChange } = props;
const { styles } = useStyle();
const [locale] = useLocale(locales);
return (
<Space size={token.paddingLG}>
{Object.keys(THEMES).map((theme, index) => {
const url = THEMES[theme as THEME];
return (
<Space key={theme} direction="vertical" align="center">
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label
className={classNames(styles.themeCard, value === theme && styles.themeCardActive)}
onClick={() => {
onChange?.(theme);
}}
>
<input type="radio" name="theme" id={index === 0 ? id : undefined} />
<img src={url} alt={theme} />
</label>
<span>{locale[theme as keyof typeof locale]}</span>
</Space>
);
})}
</Space>
<Flex gap="large" wrap="wrap">
{Object.keys(THEMES).map<React.ReactNode>((theme: THEME, index) => (
<Flex vertical gap="small" justify="center" align="center" key={theme}>
<label
onClick={() => onChange?.(theme)}
className={classNames(styles.themeCard, {
[styles.themeCardActive]: value === theme,
})}
>
<input type="radio" name="theme" id={index === 0 ? id : undefined} />
<img src={THEMES[theme]} alt={theme} />
</label>
<span>{locale[theme]}</span>
</Flex>
))}
</Flex>
);
}
};
export default ThemePicker;

View File

@ -13,11 +13,11 @@ import {
Button,
Card,
ConfigProvider,
Flex,
Form,
Layout,
Menu,
Radio,
Space,
theme,
Typography,
} from 'antd';
@ -31,7 +31,7 @@ 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 { getLocalizedPathname } from '../../../../theme/utils';
import Group from '../Group';
import { getCarouselStyle } from '../util';
import BackgroundImage from './BackgroundImage';
@ -154,6 +154,8 @@ const useStyle = createStyles(({ token, cx }) => {
height: ${token.controlHeight}px;
border-radius: 100%;
background: rgba(240, 240, 240, 0.75);
background-size: cover;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
`,
avatarDark: css`
@ -189,7 +191,7 @@ const useStyle = createStyles(({ token, cx }) => {
`,
form: css`
width: 800px;
width: 100%;
margin: 0 auto;
`,
carousel,
@ -458,8 +460,7 @@ export default function Theme() {
</div>
<h1>Ant Design 5.0</h1>
</div>
<Space className={styles.menu} size="middle">
<Flex className={styles.menu} gap="middle">
<BellOutlined />
<QuestionCircleOutlined />
<div
@ -467,11 +468,9 @@ export default function Theme() {
style={{
backgroundColor: avatarColor,
backgroundImage: `url(${getAvatarURL(closestColor)})`,
backgroundSize: 'cover',
boxShadow: `0 0 2px rgba(0, 0, 0, 0.2)`,
}}
/>
</Space>
</Flex>
</Header>
<Layout className={styles.transBg} hasSider>
<Sider className={classNames(styles.transBg, 'site-layout-background')} width={200}>
@ -499,20 +498,16 @@ export default function Theme() {
<Card
title={locale.myTheme}
extra={
<Space>
<Link to={utils.getLocalizedPathname('/theme-editor', isZhCN, search)}>
<Flex gap="small">
<Link to={getLocalizedPathname('/theme-editor', isZhCN, search)}>
<Button type="default">{locale.toDef}</Button>
</Link>
<Link
to={utils.getLocalizedPathname(
'/docs/react/customize-theme',
isZhCN,
search,
)}
to={getLocalizedPathname('/docs/react/customize-theme', isZhCN, search)}
>
<Button type="primary">{locale.toUse}</Button>
</Link>
</Space>
</Flex>
}
>
<Form
@ -536,15 +531,8 @@ export default function Theme() {
<Form.Item label={locale.titleCompact} name="compact" htmlFor="compact_default">
<Radio.Group
options={[
{
label: locale.default,
value: 'default',
id: 'compact_default',
},
{
label: locale.compact,
value: 'compact',
},
{ label: locale.default, value: 'default', id: 'compact_default' },
{ label: locale.compact, value: 'compact' },
]}
/>
</Form.Item>

View File

@ -1,9 +0,0 @@
import React from 'react';
import type { AlertProps } from 'antd';
import { Alert } from 'antd';
const MdAlert: React.FC<AlertProps> = ({ style, ...props }) => (
<Alert {...props} style={{ margin: '24px 0', ...style }} />
);
export default MdAlert;

View File

@ -1,7 +1,7 @@
import React, { memo, useContext, useMemo, useRef, useState } from 'react';
import type { CSSProperties } from 'react';
import { SearchOutlined } from '@ant-design/icons';
import { Affix, Card, Col, Divider, Input, Row, Space, Tag, Typography } from 'antd';
import { Affix, Card, Col, Divider, Flex, Input, Row, Tag, Typography } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import { useIntl, useLocation, useSidebarData } from 'dumi';
import debounce from 'lodash/debounce';
@ -191,10 +191,10 @@ const Overview: React.FC = () => {
return components?.length ? (
<div key={group?.title}>
<Title level={2} className={styles.componentsOverviewGroupTitle}>
<Space align="center">
<Flex gap="small" align="center">
<span style={{ fontSize: 24 }}>{group?.title}</span>
<Tag style={{ display: 'block' }}>{components.length}</Tag>
</Space>
</Flex>
</Title>
<Row gutter={[24, 24]}>
{components.map((component) => {

View File

@ -2,13 +2,11 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
import { LinkOutlined, ThunderboltOutlined, UpOutlined } from '@ant-design/icons';
import type { Project } from '@stackblitz/sdk';
import stackblitzSdk from '@stackblitz/sdk';
import { Alert, Badge, Space, Tooltip } from 'antd';
import { Alert, Badge, Flex, Tooltip } from 'antd';
import { createStyles, css } from 'antd-style';
import classNames from 'classnames';
import { FormattedMessage, LiveContext, useSiteData } from 'dumi';
import { FormattedMessage, useSiteData, useLiveDemo } from 'dumi';
import LZString from 'lz-string';
import type { AntdPreviewerProps } from './Previewer';
import useLocation from '../../../hooks/useLocation';
import BrowserFrame from '../../common/BrowserFrame';
import ClientOnly from '../../common/ClientOnly';
@ -21,7 +19,7 @@ import RiddleIcon from '../../common/RiddleIcon';
import type { SiteContextProps } from '../../slots/SiteContext';
import SiteContext from '../../slots/SiteContext';
import { ping } from '../../utils';
import LiveDemo from 'dumi/theme-default/slots/LiveDemo';
import type { AntdPreviewerProps } from './Previewer';
const { ErrorBoundary } = Alert;
@ -108,14 +106,22 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
const { pkg } = useSiteData();
const location = useLocation();
const { enabled: liveEnabled } = useContext(LiveContext);
const { styles } = useStyle();
const entryCode = asset.dependencies['index.tsx'].value;
const entryName = 'index.tsx';
const entryCode = asset.dependencies[entryName].value;
const showRiddleButton = useShowRiddleButton();
const liveDemo = useRef<React.ReactNode>(null);
const previewDemo = useRef<React.ReactNode>(null);
const demoContainer = useRef<HTMLElement>(null);
const {
node: liveDemoNode,
error: liveDemoError,
setSource: setLiveDemoSource,
} = useLiveDemo(asset.id, {
iframe: Boolean(iframe),
containerRef: demoContainer,
});
const anchorRef = useRef<HTMLAnchorElement>(null);
const codeSandboxIconRef = useRef<HTMLFormElement>(null);
const riddleIconRef = useRef<HTMLFormElement>(null);
@ -153,8 +159,8 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
const mergedChildren = !iframe && clientOnly ? <ClientOnly>{children}</ClientOnly> : children;
if (!liveDemo.current) {
liveDemo.current = iframe ? (
if (!previewDemo.current) {
previewDemo.current = iframe ? (
<BrowserFrame>
<iframe
src={demoUrl}
@ -365,13 +371,11 @@ createRoot(document.getElementById('container')).render(<Demo />);
const codeBox: React.ReactNode = (
<section className={codeBoxClass} id={asset.id}>
<section className="code-box-demo" style={codeBoxDemoStyle}>
{!liveEnabled ? (
<section className="code-box-demo" style={codeBoxDemoStyle} ref={demoContainer}>
{liveDemoNode || (
<ErrorBoundary>
<React.StrictMode>{liveDemo.current}</React.StrictMode>
<React.StrictMode>{previewDemo.current}</React.StrictMode>
</ErrorBoundary>
) : (
<LiveDemo />
)}
</section>
<section className="code-box-meta markdown">
@ -386,7 +390,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
{description && (
<div className="code-box-description" dangerouslySetInnerHTML={{ __html: description }} />
)}
<Space wrap size="middle" className="code-box-actions">
<Flex wrap="wrap" gap="middle" className="code-box-actions">
{showOnlineUrl && (
<Tooltip title={<FormattedMessage id="app.demo.online" />}>
<a
@ -505,7 +509,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
/>
</div>
</Tooltip>
</Space>
</Flex>
</section>
{codeExpand && (
<section className={highlightClass} key="code">
@ -513,7 +517,10 @@ createRoot(document.getElementById('container')).render(<Demo />);
sourceCode={entryCode}
jsxCode={jsx}
styleCode={style}
error={liveDemoError}
entryName={entryName}
onCodeTypeChange={setCodeType}
onSourceChange={setLiveDemoSource}
/>
<div
tabIndex={0}

View File

@ -1,6 +1,6 @@
import React from 'react';
import type { IPreviewerProps } from 'dumi';
import { LiveProvider, useTabMeta } from 'dumi';
import { useTabMeta } from 'dumi';
import CodePreviewer from './CodePreviewer';
import DesignPreviewer from './DesignPreviewer';
@ -16,23 +16,7 @@ const Previewer: React.FC<AntdPreviewerProps> = (props) => {
return <DesignPreviewer {...props} />;
}
const codePreviewer = <CodePreviewer {...props} />;
if (props.live === false || props.iframe) {
return codePreviewer;
}
return (
<LiveProvider
initialCode={
Object.entries(props.asset.dependencies).filter(([, { type }]) => type === 'FILE')[0][1]
.value
}
demoId={props.asset.id}
>
{codePreviewer}
</LiveProvider>
);
return <CodePreviewer {...props} />;
};
export default Previewer;

View File

@ -76,7 +76,7 @@ const locales = {
},
en: {
official: 'Official',
thirdPart: 'Third Part',
thirdPart: 'Third Party',
thirdPartDesc: 'Unofficial product, please take care confirm availability',
},
};

View File

@ -1,10 +1,11 @@
// 用于 color.md 中的颜色对比
import React from 'react';
import classNames from 'classnames';
import { TinyColor } from '@ctrl/tinycolor';
import { Flex, theme } from 'antd';
import { createStyles } from 'antd-style';
import tokenMeta from 'antd/es/version/token-meta.json';
import { Space, theme } from 'antd';
import classNames from 'classnames';
import useLocale from '../../../hooks/useLocale';
const useStyle = createStyles(({ token, css }) => {
@ -29,7 +30,7 @@ const useStyle = createStyles(({ token, css }) => {
display: flex;
align-items: center;
justify-content: center;
color: rgba(0,0,0,0.88);
color: rgba(0, 0, 0, 0.88);
border-right: 1px solid rgba(0, 0, 0, 0.1);
`,
@ -61,33 +62,30 @@ interface ColorCircleProps {
color?: string;
}
function ColorCircle({ color }: ColorCircleProps) {
const ColorCircle: React.FC<ColorCircleProps> = ({ color }) => {
const { styles } = useStyle();
return (
<Space size={4}>
<Flex align="center" gap={4}>
<div className={styles.dot} style={{ background: color }} />
<div className={styles.dotColor}>{color}</div>
</Space>
</Flex>
);
}
};
export interface TokenCompareProps {
tokenNames?: string;
}
export default function TokenCompare(props: TokenCompareProps) {
const TokenCompare: React.FC<TokenCompareProps> = (props) => {
const { tokenNames = '' } = props;
const [, lang] = useLocale({});
const [, lang] = useLocale();
const { styles } = useStyle();
const tokenList = React.useMemo(() => {
const list = tokenNames.split('|');
const lightTokens = theme.getDesignToken();
const darkTokens = theme.getDesignToken({
algorithm: theme.darkAlgorithm,
});
const darkTokens = theme.getDesignToken({ algorithm: theme.darkAlgorithm });
return list.map((tokenName) => {
const meta = tokenMeta.global[tokenName];
@ -116,4 +114,6 @@ export default function TokenCompare(props: TokenCompareProps) {
))}
</div>
);
}
};
export default TokenCompare;

View File

@ -10,7 +10,7 @@ const useStyle = createStyles(({ token, css }) => ({
fallback: css`
width: 100%;
> * {
width: 100%;
width: 100% !important;
border-radius: 8px;
}
`,

View File

@ -1,10 +1,10 @@
import React, { type ComponentProps, useEffect, useMemo } from 'react';
import { Button, Tabs, Typography } from 'antd';
import { createStyles } from 'antd-style';
import { LiveContext } from 'dumi';
import toReactElement from 'jsonml-to-react-element';
import JsonML from 'jsonml.js/lib/utils';
import Prism from 'prismjs';
import React, { useContext, useEffect, useMemo } from 'react';
import LiveCode from './LiveCode';
const useStyle = createStyles(({ token, css }) => {
@ -19,6 +19,7 @@ const useStyle = createStyles(({ token, css }) => {
copyButton: css`
color: ${colorIcon};
position: absolute;
z-index: 2;
top: 16px;
inset-inline-end: 16px;
width: 32px;
@ -29,7 +30,19 @@ const useStyle = createStyles(({ token, css }) => {
copyIcon: css`
${antCls}-typography-copy {
position: relative;
margin-inline-start: 0;
// expand clickable area
&::before {
content: '';
display: block;
position: absolute;
top: -5px;
left: -9px;
bottom: -5px;
right: -9px;
}
}
${antCls}-typography-copy:not(${antCls}-typography-copy-success) {
color: ${colorIcon};
@ -48,11 +61,14 @@ const LANGS = {
style: 'CSS',
};
interface CodePreviewProps {
interface CodePreviewProps
extends Omit<ComponentProps<typeof LiveCode>, 'initialValue' | 'lang' | 'onChange'> {
sourceCode?: string;
jsxCode?: string;
styleCode?: string;
entryName: string;
onCodeTypeChange?: (activeKey: string) => void;
onSourceChange?: (source: Record<string, string>) => void;
}
function toReactComponent(jsonML: any[]) {
@ -75,7 +91,10 @@ const CodePreview: React.FC<CodePreviewProps> = ({
sourceCode = '',
jsxCode = '',
styleCode = '',
entryName,
onCodeTypeChange,
onSourceChange,
error,
}) => {
// 避免 Tabs 数量不稳定的闪动问题
const initialCodes = {} as Record<'tsx' | 'jsx' | 'style', string>;
@ -90,9 +109,10 @@ const CodePreview: React.FC<CodePreviewProps> = ({
}
const [highlightedCodes, setHighlightedCodes] = React.useState(initialCodes);
const sourceCodes = {
tsx: sourceCode,
jsx: jsxCode,
style: styleCode,
// omit trailing line break
tsx: sourceCode?.trim(),
jsx: jsxCode?.trim(),
style: styleCode?.trim(),
} as Record<'tsx' | 'jsx' | 'style', string>;
useEffect(() => {
const codes = {
@ -109,12 +129,10 @@ const CodePreview: React.FC<CodePreviewProps> = ({
setHighlightedCodes(codes);
}, [jsxCode, sourceCode, styleCode]);
const langList = Object.keys(highlightedCodes);
const langList = Object.keys(highlightedCodes) as ('tsx' | 'jsx' | 'style')[];
const { styles } = useStyle();
const { enabled: liveEnabled } = useContext(LiveContext);
const items = useMemo(
() =>
langList.map((lang: keyof typeof LANGS) => ({
@ -122,8 +140,15 @@ const CodePreview: React.FC<CodePreviewProps> = ({
key: lang,
children: (
<div className={styles.code}>
{lang === 'tsx' && liveEnabled ? (
<LiveCode />
{lang === 'tsx' ? (
<LiveCode
error={error}
lang={lang}
initialValue={sourceCodes[lang]}
onChange={(code) => {
onSourceChange?.({ [entryName]: code });
}}
/>
) : (
toReactComponent(['pre', { lang, highlighted: highlightedCodes[lang] }])
)}
@ -141,17 +166,15 @@ const CodePreview: React.FC<CodePreviewProps> = ({
}
if (langList.length === 1) {
return liveEnabled ? (
<LiveCode />
) : (
toReactComponent([
'pre',
{
lang: langList[0],
highlighted: highlightedCodes[langList[0] as keyof typeof LANGS],
className: 'highlight',
},
])
return (
<LiveCode
error={error}
lang={langList[0]}
initialValue={sourceCodes[langList[0]]}
onChange={(code) => {
onSourceChange?.({ [entryName]: code });
}}
/>
);
}

View File

@ -1,7 +1,7 @@
/* eslint-disable global-require */
import React, { useMemo } from 'react';
import { HistoryOutlined } from '@ant-design/icons';
import { Button, Drawer, Timeline, Typography } from 'antd';
import { Button, Drawer, Timeline, Typography, Grid } from 'antd';
import { createStyles } from 'antd-style';
import useFetch from '../../../hooks/useFetch';
@ -158,6 +158,9 @@ export default function ComponentChangelog(props: ComponentChangelogProps) {
});
}, [list]);
const screens = Grid.useBreakpoint();
const width = screens.md ? '48vw' : '90vw';
if (!list || !list.length) {
return null;
}
@ -181,7 +184,7 @@ export default function ComponentChangelog(props: ComponentChangelogProps) {
</Link>
}
open={show}
width="40vw"
width={width}
onClose={() => {
setShow(false);
}}

View File

@ -1,11 +1,12 @@
import type { FC } from 'react';
import type { ComponentProps, FC } from 'react';
import React, { useEffect, useState } from 'react';
import { createStyles } from 'antd-style';
import LiveEditor from '../slots/LiveEditor';
import LiveError from '../slots/LiveError';
import { EditFilled } from '@ant-design/icons';
import { Tooltip } from 'antd';
import { createStyles } from 'antd-style';
import SourceCodeEditor from 'dumi/theme-default/slots/SourceCodeEditor';
import useLocale from '../../hooks/useLocale';
import LiveError from '../slots/LiveError';
const useStyle = createStyles(({ token, css }) => {
const { colorPrimaryBorder, colorIcon, colorPrimary } = token;
@ -23,10 +24,38 @@ const useStyle = createStyles(({ token, css }) => {
box-shadow: inset 0 0 0 1px ${colorPrimary} !important;
}
}
// override dumi editor styles
.dumi-default-source-code-editor {
.dumi-default-source-code > pre,
.dumi-default-source-code-editor-textarea {
padding: 12px 16px;
}
.dumi-default-source-code > pre {
font-size: 13px;
line-height: 2;
font-family: 'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
}
// disable dumi default copy button
.dumi-default-source-code-copy {
display: none;
}
&-textarea:hover {
box-shadow: 0 0 0 1px ${token.colorPrimaryBorderHover} inset;
}
&-textarea:focus {
box-shadow: 0 0 0 1px ${token.colorPrimary} inset;
}
}
`,
editableIcon: css`
position: absolute;
z-index: 2;
height: 32px;
width: 32px;
display: flex;
@ -50,7 +79,11 @@ const locales = {
const HIDE_LIVE_DEMO_TIP = 'hide-live-demo-tip';
const LiveCode: FC = () => {
const LiveCode: FC<
{
error: Error | null;
} & Pick<ComponentProps<typeof SourceCodeEditor>, 'lang' | 'initialValue' | 'onChange'>
> = (props) => {
const [open, setOpen] = useState(false);
const { styles } = useStyle();
const [locale] = useLocale(locales);
@ -72,8 +105,12 @@ const LiveCode: FC = () => {
return (
<>
<div className={styles.editor}>
<LiveEditor />
<LiveError />
<SourceCodeEditor
lang={props.lang}
initialValue={props.initialValue}
onChange={props.onChange}
/>
<LiveError error={props.error} />
</div>
<Tooltip title={locale.demoEditable} open={open} onOpenChange={handleOpenChange}>
<EditFilled className={styles.editableIcon} />

View File

@ -1,10 +1,9 @@
import React from 'react';
import { Flex, Skeleton, Spin } from 'antd';
import { useLocation } from 'dumi';
import { Skeleton, Space, Spin } from 'antd';
const Loading: React.FC = () => {
const { pathname } = useLocation();
if (
pathname.startsWith('/components') ||
pathname.startsWith('/docs') ||
@ -25,9 +24,9 @@ const Loading: React.FC = () => {
}
return (
<Space style={{ width: '100%', margin: '120px 0', justifyContent: 'center' }} align="center">
<Flex justify="center" align="center" gap="small" style={{ width: '100%', margin: '120px 0' }}>
<Spin size="large" />
</Space>
</Flex>
);
};

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { AvatarListItem } from '@qixian.cs/github-contributors-list';
import type { AvatarListItem } from '@qixian.cs/github-contributors-list/dist/AvatarList';
import { Avatar, Skeleton, Tooltip } from 'antd';
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => (

View File

@ -1,10 +1,15 @@
import React, { useLayoutEffect, useMemo, useState } from 'react';
import { CalendarOutlined } from '@ant-design/icons';
import { Avatar, Skeleton, Space, Typography } from 'antd';
import { Avatar, Flex, Skeleton, Typography } from 'antd';
import DayJS from 'dayjs';
import { useRouteMeta } from 'dumi';
const AuthorAvatar: React.FC<{ name: string; avatar: string }> = ({ name, avatar }) => {
interface AuthorAvatarPoprs {
name: string;
avatar: string;
}
const AuthorAvatar: React.FC<AuthorAvatarPoprs> = ({ name, avatar }) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useLayoutEffect(() => {
@ -52,26 +57,26 @@ const DocMeta: React.FC = () => {
return (
<Typography.Paragraph>
<Space>
<Flex gap="small">
{meta.frontmatter.date && (
<span style={{ opacity: 0.65 }}>
<CalendarOutlined /> {DayJS(meta.frontmatter.date).format('YYYY-MM-DD')}
</span>
)}
{mergedAuthorInfos.map((info) => (
{mergedAuthorInfos.map<React.ReactNode>((info) => (
<a
href={`https://github.com/${info.name}`}
target="_blank"
rel="noopener noreferrer"
key={info.name}
>
<Space size={3}>
<Flex gap={4}>
<AuthorAvatar name={info.name} avatar={info.avatar} />
<span style={{ opacity: 0.65 }}>@{info.name}</span>
</Space>
</Flex>
</a>
))}
</Space>
</Flex>
</Typography.Paragraph>
);
};

View File

@ -1,5 +1,5 @@
import React, { useContext, useLayoutEffect, useMemo } from 'react';
import { Col, Space, Typography } from 'antd';
import { Col, Flex, Typography } from 'antd';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import { FormattedMessage, useRouteMeta } from 'dumi';
@ -69,10 +69,9 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
<article className={classNames(styles.articleWrapper, { rtl: isRTL })}>
{meta.frontmatter?.title ? (
<Typography.Title style={{ fontSize: 30, position: 'relative' }}>
<Space size="small">
{meta.frontmatter?.title}
{meta.frontmatter?.subtitle}
<Flex gap="small">
<div>{meta.frontmatter?.title}</div>
<div>{meta.frontmatter?.subtitle}</div>
{!pathname.startsWith('/components/overview') && (
<InViewSuspense fallback={null}>
<EditButton
@ -81,7 +80,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
/>
</InViewSuspense>
)}
</Space>
</Flex>
{pathname.startsWith('/components/') && (
<InViewSuspense fallback={null}>
<ComponentChangelog pathname={pathname} />

View File

@ -1,99 +0,0 @@
import { DownOutlined } from '@ant-design/icons';
import { createStyles } from 'antd-style';
import { FormattedMessage } from 'dumi';
import React from 'react';
import classnames from 'classnames';
import type { MenuProps } from 'antd';
import { Button, Dropdown } from 'antd';
import type { SharedProps } from './interface';
const useStyle = createStyles(({ css, token }) => ({
smallStyle: css`
font-size: 12px;
color: #777;
margin-left: 0.3em;
`,
down: css`
color: ${token.colorTextQuaternary};
`,
downOutlined: css`
font-size: 9px;
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 { styles } = useStyle();
return (
<span className={styles.smallStyle}>
(<FormattedMessage id="app.implementation.community" />)
</span>
);
};
export const getEcosystemGroup = (): Exclude<MenuProps['items'], undefined> => [
{
label: (
<a href="https://charts.ant.design" target="_blank" rel="noopener noreferrer">
<FormattedMessage id="app.header.menu.charts" />
</a>
),
key: 'charts',
},
{
label: (
<a href="http://pro.ant.design" target="_blank" rel="noopener noreferrer">
<FormattedMessage id="app.header.menu.pro.v4" />
</a>
),
key: 'pro',
},
{
label: (
<a href="http://procomponents.ant.design" target="_blank" rel="noopener noreferrer">
<FormattedMessage id="app.header.menu.pro.components" />
</a>
),
key: 'procomponents',
},
{
label: (
<a href="http://ng.ant.design" target="_blank" rel="noopener noreferrer">
Ant Design of Angular
<Community />
</a>
),
key: 'ng',
},
{
label: (
<a href="http://antdv.com" target="_blank" rel="noopener noreferrer">
Ant Design of Vue
<Community />
</a>
),
key: 'vue',
},
];
const More: React.FC<SharedProps> = ({ isRTL }) => {
const { styles } = useStyle();
return (
<Dropdown menu={{ items: getEcosystemGroup() }} placement="bottomRight">
<Button size="small">
<FormattedMessage id="app.header.menu.more" />
<DownOutlined
className={classnames(isRTL ? styles.downOutlinedRTL : styles.downOutlined, styles.down)}
/>
</Button>
</Dropdown>
);
};
export default More;

View File

@ -4,7 +4,6 @@ import { MenuOutlined } from '@ant-design/icons';
import { createStyles, css } from 'antd-style';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import { getEcosystemGroup } from './More';
import * as utils from '../../utils';
import type { SharedProps } from './interface';
import useLocale from '../../../hooks/useLocale';
@ -170,7 +169,6 @@ export default ({
onClick: onDirectionChange,
key: 'switch-direction',
},
...getEcosystemGroup(),
];
if (isMobile) {

View File

@ -16,7 +16,6 @@ import type { SiteContextProps } from '../SiteContext';
import SiteContext from '../SiteContext';
import type { SharedProps } from './interface';
import Logo from './Logo';
import More from './More';
import Navigation from './Navigation';
import SwitchBtn from './SwitchBtn';
@ -309,7 +308,6 @@ const Header: React.FC = () => {
getPopupContainer={(trigger) => trigger.parentNode}
options={versionOptions}
/>,
<More key="more" {...sharedProps} />,
<SwitchBtn
key="lang"
onClick={onLangChange}

View File

@ -1,21 +0,0 @@
import type { FC } from 'react';
import React from 'react';
import DumiLiveEditor from 'dumi/theme-default/slots/LiveEditor';
const LiveEditor: FC = () => (
<DumiLiveEditor
style={{
fontSize: 13,
lineHeight: 2,
fontFamily: `'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace`,
}}
padding={{
top: 12,
right: 16,
bottom: 12,
left: 16,
}}
/>
);
export default LiveEditor;

View File

@ -1,14 +1,12 @@
import type { FC } from 'react';
import React, { useContext } from 'react';
import { LiveContext } from 'dumi';
import React from 'react';
import { Alert, theme } from 'antd';
const LiveError: FC = () => {
const { error } = useContext(LiveContext);
const LiveError: FC<{ error: Error | null }> = ({ error }) => {
const { token } = theme.useToken();
return error ? (
<Alert banner type="error" message={error} style={{ color: token.colorError }} />
<Alert banner type="error" message={error.toString()} style={{ color: token.colorError }} />
) : null;
};

View File

@ -15,7 +15,6 @@ export default defineConfig({
ssr: process.env.NODE_ENV === 'production' ? {} : false,
hash: true,
mfsu: false,
live: true,
crossorigin: {},
outputPath: '_site',
favicons: ['https://gw.alipayobjects.com/zos/rmsportal/rlpTLlbMzTNYuZGGCVYM.png'],

View File

@ -1,8 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: 🆕 Create new issue
url: http://new-issue.ant.design
about: The issue which is not created via http://new-issue.ant.design will be closed immediately.
url: https://new-issue.ant.design
about: The issue which is not created via https://new-issue.ant.design will be closed immediately.
- name: 🆕 创建一个新 Issue
url: http://new-issue.ant.design
about: 不是用 http://new-issue.ant.design 创建的 issue 会被机器人自动关闭。另外『如何使用...』类问题建议使用讨论区 https://github.com/ant-design/ant-design/discussions
url: https://new-issue.ant.design
about: ⚠️ 注意请不要使用上面的 Report a vulnerability报告安全漏洞来报告组件库的 bug 和特性请求,请点击右侧 Open 按钮。不是用 https://new-issue.ant.design 创建的 issue 会被机器人自动关闭。

View File

@ -25,4 +25,4 @@ updates:
update-types: ["major", "minor"]
dev-dependencies:
dependency-type: "development"
update-types: ["major", "minor"]
update-types: ["major"]

View File

@ -4,11 +4,6 @@ on:
pull_request:
types: [opened, synchronize]
# Cancel prev CI if new commit come
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
@ -18,50 +13,16 @@ jobs:
contents: read
pull-requests: write
runs-on: ubuntu-latest
env:
CI_JOB_NUMBER: 1
steps:
- name: checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18
- name: cache package-lock.json
uses: actions/cache@v3
with:
path: package-temp-dir
key: lock-${{ github.sha }}
- name: create package-lock.json
run: npm i --package-lock-only --ignore-scripts
- name: hack for single file
run: |
if [ ! -d "package-temp-dir" ]; then
mkdir package-temp-dir
fi
cp package-lock.json package-temp-dir
- name: cache node_modules
id: node_modules_cache_id
uses: actions/cache@v3
with:
path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
- name: install
if: steps.node_modules_cache_id.outputs.cache-hit != 'true'
run: npm ci
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- name: size-limit
uses: ant-design/size-limit-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
package_manager: bun
build_script: dist
skip_step: install
env:
NODE_OPTIONS: "--max_old_space_size=4096"
PRODUCTION_ONLY: 1

View File

@ -73,6 +73,12 @@ jobs:
- name: lint
run: npm run lint
- name: lint:react-16
run: npm run compile && npm run install-react-16 && npm run tsc:old
- name: lint:react-17
run: npm run compile && npm run install-react-17 && npm run tsc:old
needs: setup
check_metadata:

View File

@ -17,6 +17,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
jobs: ${{ steps.visual_diff_build_job_status.outputs.result }}
upstream-job-link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/job/${{ steps.visual_diff_build_job_status.outputs.job-id }}
build-status: ${{ steps.visual_diff_build_job_status.outputs.build-status }}
steps:
- name: summary jobs status
@ -33,7 +34,10 @@ jobs:
// { [name]: [conclusion] }, e.g. { 'test image': 'success' }
const jobs = (response.data?.jobs ?? []).reduce((acc, job) => {
if(job?.status === 'completed' && 'name' in job && 'conclusion' in job) {
acc[job.name] = job.conclusion;
acc[job.name] = {
id: job.id,
status: job.conclusion,
};
}
return acc;
}, {});
@ -42,10 +46,11 @@ jobs:
if(total === 0) core.setFailed('no jobs found');
// the name here must be the same as `jobs.xxx.{name}`
console.log('visual-diff report job status: %s', jobs['visual-diff report']);
console.log('visual-diff report job status: %s', jobs['visual-diff report'].status);
// set output
core.setOutput('build-status', jobs['visual-diff report']);
core.setOutput('job-id', jobs['visual-diff report'].id);
core.setOutput('build-status', jobs['visual-diff report'].status);
return jobs;
download-visual-regression-report:
@ -127,7 +132,7 @@ jobs:
body: |
## Visual Regression Build for PR #${{ steps.pr.outputs.id }} Failed ❌
Potential causes:
- `upstream workflow` status: ${{ needs.upstream-workflow-summary.outputs.build-status }}
- `upstream workflow` status: ${{ needs.upstream-workflow-summary.outputs.build-status }} [upstream job link](${{ needs.upstream-workflow-summary.outputs.upstream-job-link }})
- `download report artifact` status: ${{ steps.download_report.outcome }}
- `report upload` status: ${{ steps.report.outcome }}
<!-- VISUAL_DIFF_REGRESSION_HOOK -->

54
BUG_VERSIONS.json Normal file
View File

@ -0,0 +1,54 @@
{
"3.9.3": [
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
],
">= 3.10.0 <=3.10.9": [
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
],
">= 3.11.0 <=3.11.5": [
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
],
">= 4.21.6 < 4.22.0": ["https://github.com/ant-design/ant-design/pull/36682"],
">= 4.22.2 <= 4.22.5": [
"https://github.com/ant-design/ant-design/issues/36932",
"https://github.com/ant-design/ant-design/pull/36800",
"https://github.com/ant-design/ant-design/issues/37024"
],
"4.23.0": ["https://github.com/ant-design/ant-design/issues/37461"],
"4.23.5": [
"https://github.com/ant-design/ant-design/issues/37929",
"https://github.com/ant-design/ant-design/issues/37931"
],
"4.24.0": ["https://github.com/ant-design/ant-design/issues/38371"],
"5.0.4": ["https://github.com/ant-design/ant-design/issues/39284"],
"5.0.6": ["https://github.com/ant-design/ant-design/issues/39807"],
"5.1.0": ["https://github.com/react-component/drawer/pull/370"],
"5.1.2": ["https://github.com/ant-design/ant-design/issues/39949"],
"5.1.3": ["https://github.com/ant-design/ant-design/issues/40113"],
"5.1.4": ["https://github.com/ant-design/ant-design/issues/40186"],
">= 5.2.3 <= 5.3.0": [
"https://github.com/ant-design/ant-design/pull/40719#issuecomment-1453418135"
],
"5.4.1": ["https://github.com/ant-design/ant-design/issues/41751"],
">= 5.4.3 <= 5.4.5": [
"https://github.com/ant-design/cssinjs/pull/108",
"https://github.com/ant-design/ant-design/pull/41993"
],
"5.6.2": ["https://github.com/ant-design/ant-design/issues/43113"],
"5.6.3": ["https://github.com/ant-design/ant-design/issues/43190"],
"5.7.0": ["https://github.com/ant-design/ant-design/issues/43684"],
"5.7.1": [
"https://github.com/ant-design/ant-design/issues/43654",
"https://github.com/ant-design/ant-design/issues/43684"
],
"5.8.0": ["https://github.com/ant-design/ant-design/issues/43943"],
"5.9.1": ["https://github.com/ant-design/ant-design/issues/44907"],
"5.10.0": ["https://github.com/ant-design/ant-design/issues/45289"],
"5.11.0": ["https://github.com/ant-design/ant-design/issues/45742"],
"5.11.1": ["https://github.com/ant-design/ant-design/issues/45883"],
"5.11.2": ["https://github.com/ant-design/ant-design/issues/46005"],
"5.11.4": ["https://github.com/ant-design/ant-design/pull/46103"],
"5.12.3": ["https://github.com/ant-design/ant-design/issues/46525"],
"5.12.6": ["https://github.com/ant-design/ant-design/issues/46719"],
"5.13.0": ["https://github.com/ant-design/ant-design/pull/46962"]
}

View File

@ -16,6 +16,72 @@ tag: vVERSION
---
## 5.13.2
`2024-01-19`
- 🐞 Fix that the inline rendering does not take effect when the `preview.getContainer` value for Image is false. [#47034](https://github.com/ant-design/ant-design/pull/47034) [@FEyudong](https://github.com/FEyudong)
- 🐞 Fix Modal static function with `prefixCls` breaks children other component `prefixCls` and thus bring the motion miss. [#47010](https://github.com/ant-design/ant-design/pull/47010)
- 🐞 Fix ok button of the DatePicker becomes compacted when used with Space.Compact. [#46769](https://github.com/ant-design/ant-design/pull/46769) [@Fatpandac](https://github.com/Fatpandac)
- 💄 Optimize Tree draggable node cursor style and collaspe icon hover style. [#46974](https://github.com/ant-design/ant-design/pull/46974)
## 5.13.1
`2024-01-15`
- 🐞 Fix Checkbox type error with `@types/react` version 16 or 17. [#46962](https://github.com/ant-design/ant-design/pull/46962) [@crazyair](https://github.com/crazyair)
## 5.13.0
`2024-01-13`
- 🔥 Form support `variant` to control components variant inside. [#46573](https://github.com/ant-design/ant-design/pull/46573)
- 🆕 Cascader、DatePicker、Select、TreeSelect、Input、InputNumber、Mentions support `variant` props. [#46568](https://github.com/ant-design/ant-design/pull/46568) [#46549](https://github.com/ant-design/ant-design/pull/46549) [#46435](https://github.com/ant-design/ant-design/pull/46435) [#46381](https://github.com/ant-design/ant-design/pull/46381) [#46379](https://github.com/ant-design/ant-design/pull/46379) [#46337](https://github.com/ant-design/ant-design/pull/46337)
- 🆕 QRCode support `status` adds a new scanned option. [#46704](https://github.com/ant-design/ant-design/pull/46704)
- 🆕 Table support `hidden` to set hidden columns. [#46957](https://github.com/ant-design/ant-design/pull/46957) [@madocto](https://github.com/madocto)
- 🆕 Select support the `maxCount`, which is used to set the maximum selectable value. [#46667](https://github.com/ant-design/ant-design/pull/46667)
- 🆕 Mentions support `allowClear` for setting the clearing function. [#46396](https://github.com/ant-design/ant-design/pull/46396) [@yociduo](https://github.com/yociduo)
- 🆕 ColorPicker support displaying cleared status. [#45993](https://github.com/ant-design/ant-design/pull/45993)
- 🆕 Drawer adds `styles.wrapper` and discards the `contentWrapperStyle` `drawerStyle` `maskStyle` attributes, and simplifies the dom structure. [#46858](https://github.com/ant-design/ant-design/pull/46858)
- Tour
- 🆕 Tour support `disabledInteraction`, which is used to disable the interactive behavior of the highlighted area. [#46304](https://github.com/ant-design/ant-design/pull/46304)
- 🐞 Fixed the issue where modifying `pointAtCenter` under the `arrow` attribute of the Tour component does not take effect. [#46301](https://github.com/ant-design/ant-design/pull/46301)
- Tabs
- 🆕 Tabs support the `indicator: { align: xxx }` attribute, which is used to set the alignment of the Tabs indicator bar. [#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🛠 Tabs deprecated the `indicatorSize` attribute and replaced it with `indicator: { size: xxx }`. [#46786](https://github.com/ant-design/ant-design/pull/46786)
- ConfigProvider
- 🆕 ConfigProvider adds `ConfigProvider.config` to support `holderRender` for `message` `modal` `notification` static method setting `Provider`. [#46596](https://github.com/ant-design/ant-design/pull/46596)
- 🆕 ConfigProvider support the `indicator: { align: xxx }` attribute, which is used to set the alignment of the Tabs indicator bar. [#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🛠 ConfigProvider deprecated the Tabs `indicatorSize` attribute and replaced it with `indicator: { size: xxx }`. [#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🐞 Fix the problem of Segmented content being obscured in `hover` and `active`. [#46925](https://github.com/ant-design/ant-design/pull/46925) [@madocto](https://github.com/madocto)
- 🐞 Fixed the problem that the customized font size of Checkbox does not take effect under Form. [#46904](https://github.com/ant-design/ant-design/pull/46904)
- 🐞 Fixed the issue where the Radio component configuration `title` did not take effect. [#46809](https://github.com/ant-design/ant-design/pull/46809)
- 🐞 Fixed Input hover style in css var mode. [#46946](https://github.com/ant-design/ant-design/pull/46946)
- 💄 Fixed the problem of abnormal display of Dropdown style under multi-level menu. [#46888](https://github.com/ant-design/ant-design/pull/46888)
- 🛠 Refactor the popup panel logic of the ColorPicker component to avoid style conflicts when customizing using `panelRender`. [#46327](https://github.com/ant-design/ant-design/pull/46327)
- TypeScript
- 🆕 MISC: Export `GetProp` `GetProps` `GetRef` tool methods to facilitate developers to obtain unexported type definitions. [#46923](https://github.com/ant-design/ant-design/pull/46923)
- 🆕 Checkbox.Group now supports generic configurable `options.value`. [#46423](https://github.com/ant-design/ant-design/pull/46423) [@daledelv](https://github.com/daledelv)
- 🌈 Token
- 🆕 Button support the `contentLineHeight` series of tokens. [#46936](https://github.com/ant-design/ant-design/pull/46936)
- 🆕 Input support `inputFontSize` token. [#46875](https://github.com/ant-design/ant-design/pull/46875)
- 🆕 Menu support `darkPopupBg` token. [#46618](https://github.com/ant-design/ant-design/pull/46618)
- 🆕 Segmented support `trackPadding` and `trackBg` token. [#46674](https://github.com/ant-design/ant-design/pull/46674)
- 🐞 Fix the problem that `paddingBlock` does not take effect after customizing `contentFontSize` token in Button component. [#46901](https://github.com/ant-design/ant-design/pull/46901)
- 🐞 Fixed the issue where the InputNumber component cannot customize the `padding` token. [#46878](https://github.com/ant-design/ant-design/pull/46878)
- 🌐 Localization
- 🇩🇰 Improve da_DK Form local. [#46493](https://github.com/ant-design/ant-design/pull/46493) [@Eloi0424](https://github.com/Eloi0424)
## 5.12.8
`2024-01-05`
- 🐞 Fix Upload.Dragger not align center and focus ring style. [#46810](https://github.com/ant-design/ant-design/pull/46810)
- 🐞 Fix Popconfirm config empty `okText` and `cancelText` will not fallback to locale text. [#46812](https://github.com/ant-design/ant-design/pull/46812)
- 🐞 Fix Progress that line border-radius cannot be overrided. [#46789](https://github.com/ant-design/ant-design/pull/46789)
- 🐞 Fix Typography without `children` has extra `margin-left` when `copyable` is true. [#46748](https://github.com/ant-design/ant-design/pull/46748)
- 🐞 Fix Typography copied icon color. [#46748](https://github.com/ant-design/ant-design/pull/46748)
## 5.12.7
`2024-01-02`

View File

@ -16,6 +16,72 @@ tag: vVERSION
---
## 5.13.2
`2024-01-19`
- 🐞 修复 Image 组件 `preview.getContainer` 值为 false 时,内联渲染不生效的问题。[#47034](https://github.com/ant-design/ant-design/pull/47034) [@FEyudong](https://github.com/FEyudong)
- 🐞 修复 Modal 静态方法配置 `prefixCls` 时,会改变所有子元素的 `prefixCls` 并导致动画丢失的问题。[#47010](https://github.com/ant-design/ant-design/pull/47010)
- 🐞 修复 Space.Compact 与 DatePicker 一起使用导致 DatePicker 的确认按钮样式错误。[#46769](https://github.com/ant-design/ant-design/pull/46769) [@Fatpandac](https://github.com/Fatpandac)
- 💄 优化 Tree 拖拽节点和展开收起按钮的鼠标 hover 样式。[#46974](https://github.com/ant-design/ant-design/pull/46974)
## 5.13.1
`2024-01-15`
- 🐞 修复 Checkbox 组件在 `@types/react` 16 或 17 版本下 Typescript 报错。[#46962](https://github.com/ant-design/ant-design/pull/46962) [@crazyair](https://github.com/crazyair)
## 5.13.0
`2024-01-13`
- 🔥 Form 组件新增 `variant` 属性用于设置内部组件形态变体。[#46573](https://github.com/ant-design/ant-design/pull/46573)
- 🆕 Cascader、DatePicker、Select、TreeSelect、Input、InputNumber、Mentions 组件新增形态变体 `variant` 属性。[#46568](https://github.com/ant-design/ant-design/pull/46568) [#46549](https://github.com/ant-design/ant-design/pull/46549) [#46435](https://github.com/ant-design/ant-design/pull/46435) [#46381](https://github.com/ant-design/ant-design/pull/46381) [#46379](https://github.com/ant-design/ant-design/pull/46379) [#46337](https://github.com/ant-design/ant-design/pull/46337)
- 🆕 QRCode 组件 `status` 新增已扫描选项。[#46704](https://github.com/ant-design/ant-design/pull/46704)
- 🆕 Table 组件新增 `hidden` 属性可设置隐藏列。[#46957](https://github.com/ant-design/ant-design/pull/46957) [@madocto](https://github.com/madocto)
- 🆕 Select 组件新增支持 `maxCount` 属性,用于设置最大可选。[#46667](https://github.com/ant-design/ant-design/pull/46667)
- 🆕 Mentions 组件新增 `allowClear` 属性,用于设置清除功能。[#46396](https://github.com/ant-design/ant-design/pull/46396) [@yociduo](https://github.com/yociduo)
- 🆕 ColorPicker 新增支持显示清空状态。[#45993](https://github.com/ant-design/ant-design/pull/45993)
- 🆕 Drawer 组件新增 `styles.wrapper` 并废弃 `contentWrapperStyle` `drawerStyle` `maskStyle` 属性,并简化 dom 结构。[#46858](https://github.com/ant-design/ant-design/pull/46858)
- Tour
- 🆕 Tour 新增 `disabledInteraction` 属性,用于禁用高亮区域的交互行为。[#46304](https://github.com/ant-design/ant-design/pull/46304)
- 🐞 修复 Tour 组件在 `arrow` 属性下修改 `pointAtCenter` 不生效的问题。[#46301](https://github.com/ant-design/ant-design/pull/46301)
- Tabs
- 🆕 Tabs 组件支持 `indicator: { align: xxx }` 属性,用于设置 Tabs 指示条对齐方式。[#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🛠 Tabs 组件废弃 `indicatorSize` 属性,改为 `indicator: { size: xxx }` 代替。[#46786](https://github.com/ant-design/ant-design/pull/46786)
- ConfigProvider
- 🆕 ConfigProvider 组件新增 `ConfigProvider.config` 支持 `holderRender`,用于 `message` `modal` `notification` 静态方法设置 `Provider`。[#46596](https://github.com/ant-design/ant-design/pull/46596)
- 🆕 ConfigProvider 组件支持 `indicator: { align: xxx }` 属性,用于设置 Tabs 指示条对齐方式。[#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🛠 ConfigProvider 组件废弃 Tabs 组件的 `indicatorSize` 属性,改为 `indicator: { size: xxx }` 代替。[#46786](https://github.com/ant-design/ant-design/pull/46786)
- 🐞 修复 Segmented 在 `hover``active` 内容被遮挡的问题。[#46925](https://github.com/ant-design/ant-design/pull/46925) [@madocto](https://github.com/madocto)
- 🐞 修复 Checkbox 定制字体大小在 Form 下不生效的问题。[#46904](https://github.com/ant-design/ant-design/pull/46904)
- 🐞 修复 Radio 组件配置 `title` 未生效的问题。[#46809](https://github.com/ant-design/ant-design/pull/46809)
- 🐞 修复 Input 组件在 css 变量模式下的悬浮态样式问题。[#46946](https://github.com/ant-design/ant-design/pull/46946)
- 💄 修复 Dropdown 在多级菜单下样式显示异常的问题。[#46888](https://github.com/ant-design/ant-design/pull/46888)
- 🛠 重构 ColorPicker 组件弹出面板逻辑,避免使用 `panelRender` 自定义时样式冲突的问题。[#46327](https://github.com/ant-design/ant-design/pull/46327)
- TypeScript
- 🆕 MISC: 导出 `GetProp` `GetProps` `GetRef` 工具方法,便于开发者获取未导出的类型定义。[#46923](https://github.com/ant-design/ant-design/pull/46923)
- 🆕 Checkbox.Group 新增支持范型可配置 `options.value`。[#46423](https://github.com/ant-design/ant-design/pull/46423) [@daledelv](https://github.com/daledelv)
- 🌈 Token
- 🆕 Button 组件新增支持 `contentLineHeight` 系列 token。[#46936](https://github.com/ant-design/ant-design/pull/46936)
- 🆕 Input 组件新增支持 `inputFontSize` token。[#46875](https://github.com/ant-design/ant-design/pull/46875)
- 🆕 Menu 组件新增支持 `darkPopupBg` token。[#46618](https://github.com/ant-design/ant-design/pull/46618)
- 🆕 Segmented 组件新增 `trackPadding``trackBg` token。[#46674](https://github.com/ant-design/ant-design/pull/46674)
- 🐞 修复 Button 组件定制 `contentFontSize` token 后 `paddingBlock` 不生效的问题。[#46901](https://github.com/ant-design/ant-design/pull/46901)
- 🐞 修复 InputNumber 组件无法定制 `padding` token 的问题。[#46878](https://github.com/ant-design/ant-design/pull/46878)
- 🌐 国际化
- 🇩🇰 完善 da_DK Form 文案。[#46493](https://github.com/ant-design/ant-design/pull/46493) [@Eloi0424](https://github.com/Eloi0424)
## 5.12.8
`2024-01-05`
- 🐞 修复 Upload.Dragger 内容不居中和多余的 focus 样式的问题。[#46810](https://github.com/ant-design/ant-design/pull/46810)
- 🐞 修复 Popconfirm 配置空的 `okText``cancelText` 时不会被预设 locale 兜底的问题。[#46812](https://github.com/ant-design/ant-design/pull/46812)
- 🐞 修复 Progress 线性模式圆角无法覆盖的问题。[#46789](https://github.com/ant-design/ant-design/pull/46789)
- 🐞 修复 Typography 没有 `children` 并启用 `copyable` 时多余的 margin。[#46748](https://github.com/ant-design/ant-design/pull/46748)
- 🐞 修复 Typography 复制成功后的图标颜色问题。[#46748](https://github.com/ant-design/ant-design/pull/46748)
## 5.12.7
`2024-01-02`

View File

@ -0,0 +1,89 @@
import * as React from 'react';
import type { GetProp, GetProps, GetRef } from '../type';
describe('type', () => {
class CC extends React.Component<{ bamboo?: number }> {
getBamboo() {
return this.props.bamboo;
}
render() {
return this.props.bamboo;
}
}
interface TestRef {
nativeElement: HTMLDivElement;
}
const RefFC = React.forwardRef<TestRef, { bamboo?: number }>((props, ref) => {
const eleRef = React.useRef<HTMLDivElement>(null);
React.useImperativeHandle(ref, () => ({
nativeElement: eleRef.current!,
}));
return <div ref={eleRef}>{props.bamboo}</div>;
});
describe('GetProps', () => {
it('FC', () => {
const FC = (props: { bamboo: number }) => props.bamboo;
type Props = GetProps<typeof FC>;
const props: Props = { bamboo: 123 };
expect(props).toBeTruthy();
});
it('CC', () => {
type Props = GetProps<typeof CC>;
const props: Props = { bamboo: 123 };
expect(props).toBeTruthy();
});
it('RefFc', () => {
type Props = GetProps<typeof RefFC>;
const props: Props = { bamboo: 123 };
expect(props).toBeTruthy();
});
});
describe('GetRef', () => {
it('CC', () => {
type Ref = GetRef<CC>;
const ref = React.createRef<Ref>();
expect(<CC ref={ref} />).toBeTruthy();
});
it('RefFC', () => {
type Ref = GetRef<typeof RefFC>;
const ref = React.createRef<Ref>();
expect(<RefFC ref={ref} />).toBeTruthy();
});
});
describe('GetProp', () => {
it('optional', () => {
const Optional = (props: { list?: { bamboo: string }[] }) => props.list?.length;
type ListItemType = GetProp<typeof Optional, 'list'>[number];
const item: ListItemType = { bamboo: '123' };
expect(item).toBeTruthy();
});
it('interface directly', () => {
interface Props {
bamboo: number;
}
type BambooType = GetProp<Props, 'bamboo'>;
const bamboo: BambooType = 123;
expect(bamboo).toBeTruthy();
});
});
});

View File

@ -1,12 +1,8 @@
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import type { ReactNode } from 'react';
import React from 'react';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
function useInnerClosable(
closable?: boolean,
closeIcon?: boolean | ReactNode,
defaultClosable?: boolean,
): boolean {
function useInnerClosable(closable?: boolean, closeIcon?: ReactNode, defaultClosable?: boolean) {
if (typeof closable === 'boolean') {
return closable;
}
@ -18,15 +14,15 @@ function useInnerClosable(
export type UseClosableParams = {
closable?: boolean;
closeIcon?: boolean | ReactNode;
closeIcon?: ReactNode;
defaultClosable?: boolean;
defaultCloseIcon?: ReactNode;
customCloseIconRender?: (closeIcon: ReactNode) => ReactNode;
};
export default function useClosable(
function useClosable(
closable?: boolean,
closeIcon?: boolean | ReactNode,
closeIcon?: ReactNode,
customCloseIconRender?: (closeIcon: ReactNode) => ReactNode,
defaultCloseIcon: ReactNode = <CloseOutlined />,
defaultClosable = false,
@ -41,3 +37,5 @@ export default function useClosable(
: closeIcon;
return [true, customCloseIconRender ? customCloseIconRender(mergedCloseIcon) : mergedCloseIcon];
}
export default useClosable;

View File

@ -1,6 +1,32 @@
import type React from 'react';
/** https://github.com/Microsoft/TypeScript/issues/29729 */
export type LiteralUnion<T extends string> = T | (string & {});
export type AnyObject = Record<PropertyKey, any>;
export type CustomComponent<P = AnyObject> = React.ComponentType<P> | string;
export type GetProps<T extends React.ComponentType<any> | object> = T extends React.ComponentType<
infer P
>
? P
: T extends object
? T
: never;
export type GetProp<
T extends React.ComponentType<any> | object,
PropName extends keyof GetProps<T>,
> = NonNullable<GetProps<T>[PropName]>;
type ReactRefComponent<Props extends { ref?: React.Ref<any> }> = (
props: Props,
) => React.ReactElement | React.ReactNode | null;
export type GetRef<T extends ReactRefComponent<any> | React.Component<any>> =
T extends React.Component<any>
? T
: T extends ReactRefComponent<React.RefAttributes<infer RefType>>
? RefType
: never;

View File

@ -17,7 +17,7 @@ group:
当内容区域比较长,需要滚动页面时,这部分内容对应的操作或者导航需要在滚动范围内始终展现。常用于侧边菜单和按钮组合。
页面可视范围过小时,慎用此功能以免遮挡页面内容。
页面可视范围过小时,慎用此功能以免出现遮挡页面内容的情况
> 开发者注意事项:
>

View File

@ -43,7 +43,7 @@ export interface AlertProps {
banner?: boolean;
icon?: React.ReactNode;
/** Custom closeIcon */
closeIcon?: boolean | React.ReactNode;
closeIcon?: React.ReactNode;
action?: React.ReactNode;
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;

View File

@ -0,0 +1,39 @@
import React from 'react';
import BehaviorMap from '../../../.dumi/theme/common/BehaviorMap';
const BehaviorPattern: React.FC = () => (
<BehaviorMap
data={{
id: '200000004',
label: '了解页面/模块内需要关注的提示',
children: [
{
id: '500000061',
label: '了解提示信息',
targetType: 'mvp',
children: [
{
id: '707000085',
label: '了解提示内容',
link: 'components-alert-index-tab-design-demo-content',
},
{
id: '707000086',
label: '了解提示类型',
link: 'components-alert-index-tab-design-demo-type',
},
],
},
{
id: '200000005',
label: '针对提示进行操作',
targetType: 'extension',
link: 'components-alert-index-tab-design-demo-action',
},
],
}}
/>
);
export default BehaviorPattern;

View File

@ -0,0 +1,102 @@
import React from 'react';
import { Alert, Flex, Typography } from 'antd';
const Demo = () => {
const [expandA, setExpandA] = React.useState(false);
const [expandB, setExpandB] = React.useState(true);
return (
<Flex gap="large" vertical style={{ maxWidth: 600 }}>
<Flex gap="middle" vertical>
<div></div>
<Alert showIcon closable message="你好!欢迎使用专业版,你可以根据自身需求添加业务模块。" />
<Alert
showIcon
closable
message="帮助信息"
description="你好,由于你的良好信用,我们决定赠送你三个月产品会员,欲了解会员特权与活动请进首页会员专区查看。"
/>
</Flex>
<Flex gap="middle" vertical>
<div>/</div>
<Alert
showIcon
closable
message={
<div>
<Typography.Paragraph ellipsis={!expandA && { rows: 2 }} style={{ marginBottom: 8 }}>
2使2使2使2使2使
</Typography.Paragraph>
<Typography.Link onClick={() => setExpandA((prev) => !prev)}>
{expandA ? '收起' : '展开更多'}
</Typography.Link>
</div>
}
style={{ alignItems: 'baseline' }}
/>
<Alert
showIcon
closable
message={
<div>
<Typography.Paragraph ellipsis={!expandB && { rows: 2 }} style={{ marginBottom: 8 }}>
2使2使2使2使2使
</Typography.Paragraph>
<Typography.Link onClick={() => setExpandB((prev) => !prev)}>
{expandB ? '收起' : '展开更多'}
</Typography.Link>
</div>
}
style={{ alignItems: 'baseline' }}
/>
</Flex>
<Flex gap="middle" vertical>
<div></div>
<Alert
showIcon
closable
message="提示信息不超过一行时,按钮放在信息右侧。"
action={<Typography.Link></Typography.Link>}
/>
<Alert
showIcon
closable
message={
<div>
<Typography.Paragraph style={{ marginBottom: 8 }}>
</Typography.Paragraph>
<Flex gap={8}>
<Typography.Link>1</Typography.Link>
<Typography.Link>2</Typography.Link>
</Flex>
</div>
}
style={{ alignItems: 'baseline' }}
/>
<Alert
showIcon
closable
message="提示标题"
description={
<div>
<Typography.Paragraph style={{ marginBottom: 8 }}>
</Typography.Paragraph>
<Flex gap={8}>
<Typography.Link>1</Typography.Link>
<Typography.Link>2</Typography.Link>
</Flex>
</div>
}
/>
<Typography.Paragraph type="secondary">
使Link
Button线
</Typography.Paragraph>
</Flex>
</Flex>
);
};
export default Demo;

View File

@ -0,0 +1,14 @@
import React from 'react';
import { Alert, Flex } from 'antd';
const Demo = () => (
<Flex gap="middle" vertical style={{ maxWidth: 600 }}>
<Alert message="你好!欢迎使用专业版,你可以根据自身需求添加业务模块。" />
<Alert
message="帮助信息"
description="你好,由于你的良好信用,我们决定赠送你三个月产品会员,欲了解会员特权与活动请进首页会员专区查看。"
/>
</Flex>
);
export default Demo;

View File

@ -0,0 +1,61 @@
import React from 'react';
import { Alert, Flex } from 'antd';
const Demo = () => (
<Flex gap="large" vertical style={{ maxWidth: 600 }}>
<Flex gap="middle" vertical>
<div></div>
<Alert
showIcon
type="success"
message="恭喜!你所提交的信息已经审核通过,如有问题请联系客服。"
/>
<Alert
showIcon
type="success"
message="已成功!"
description="你所提交的信息已经审核通过,请及时跟进申请状况。如有问题,请联系审核人员或在线客服。"
/>
</Flex>
<Flex gap="middle" vertical>
<div></div>
<Alert
showIcon
type="info"
message="你好!欢迎使用专业版,你可以根据自身需求添加业务模块。"
/>
<Alert
showIcon
type="info"
message="帮助信息"
description="你好,由于你的良好信用,我们决定赠送你三个月产品会员,欲了解会员特权与活动请进首页会员专区查看。"
/>
</Flex>
<Flex gap="middle" vertical>
<div></div>
<Alert
showIcon
type="warning"
message="系统将于 15 : 00 - 17 : 00 进行升级,请及时保存你的资料!"
/>
<Alert
showIcon
type="warning"
message="请注意"
description="你所提交的信息已经审核失败,可以进入个人信箱查看原因,如有疑问,请联系客服人员。"
/>
</Flex>
<Flex gap="middle" vertical>
<div></div>
<Alert showIcon type="error" message="系统错误,请稍后重试。" />
<Alert
showIcon
type="error"
message="出错了!"
description="你的账户会员使用权限将在3天后到期请及时跟进申请状况。如有问题请联系审核人员。"
/>
</Flex>
</Flex>
);
export default Demo;

View File

@ -0,0 +1,15 @@
## 组件定义
Alert的本质是了解页面/模块内需要关注的提示
<code src="./design/behavior-pattern.tsx" inline></code>
## 基础使用
<code src="./design/demo/content" description="展示提示内容,也可以配合标题一起使用">了解提示内容</code>
<code src="./design/demo/type" description="配合底色和图标,了解提示类型(成功、信息、警告、错误)">了解提示类型</code>
## 交互变体
<code src="./design/demo/action" description="可对提示进行关闭、展开/收起,或执行其他操作">针对提示进行操作</code>

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { AutoComplete, Input } from 'antd';
import type { SelectProps } from 'antd/es/select';
import type { SelectProps } from 'antd';
const getRandomInt = (max: number, min = 0) => Math.floor(Math.random() * (max - min + 1)) + min;

View File

@ -0,0 +1,45 @@
import React from 'react';
import BehaviorMap from '../../../.dumi/theme/common/BehaviorMap';
const BehaviorPattern: React.FC = () => (
<BehaviorMap
data={{
id: '200000004',
label: '了解当前所处页面的位置并向上导航',
children: [
{
id: '500000061',
label: '确定位置',
targetType: 'mvp',
children: [
{
id: '707000085',
label: '了解当前页面的位置',
link: 'components-breadcrumb-index-tab-design-demo-basic',
},
{
id: '707000086',
label: '了解系统层级结构',
link: 'components-breadcrumb-index-tab-design-demo-basic',
},
],
},
{
id: '200000005',
label: '向上导航',
targetType: 'mvp',
link: 'components-breadcrumb-index-tab-design-demo-basic',
},
{
id: '200000006',
label: '快捷导航',
targetType: 'extension',
link: 'components-breadcrumb-index-tab-design-demo-overlay',
},
],
}}
/>
);
export default BehaviorPattern;

View File

@ -0,0 +1,19 @@
## 组件定义
Breadcrumb的本质是了解当前所处页面的位置并能向上导航。
<code src="./design/behavior-pattern.tsx" inline></code>
## 基础使用
<code src="./demo/basic" description="当用户需要了解当前页面在系统层级结构中的位置,或需要向上导航时使用,是最基础的使用方式">确定位置并向上导航</code>
## 交互变体
<code src="./demo/overlay" description="带有下拉菜单,下拉菜单中的内容可以承载该一级面包屑同级别内容,也可以承载该面包屑的子级内容,便于进行快速切换">快捷导航</code>
## 样式变体
<code src="./demo/withIcon" description="图标替代部分文字,或在文字前增加图标">图标样式</code>
<code src="./demo/separator" description="分割线可以采用数学中的大于符号">自定义分隔符样式</code>

View File

@ -312,74 +312,6 @@ exports[`renders components/button/demo/chinese-chars-loading.tsx extend context
exports[`renders components/button/demo/chinese-chars-loading.tsx extend context correctly 2`] = `[]`;
exports[`renders components/button/demo/component-token.tsx extend context correctly 1`] = `
<div
class="ant-flex ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-text"
type="button"
>
<span>
TEXT
</span>
</button>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
CONTAINED
</span>
</button>
<button
class="ant-btn ant-btn-default"
type="button"
>
<span>
OUTLINED
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-text"
disabled=""
type="button"
>
<span>
TEXT
</span>
</button>
<button
class="ant-btn ant-btn-primary"
disabled=""
type="button"
>
<span>
CONTAINED
</span>
</button>
<button
class="ant-btn ant-btn-default"
disabled=""
type="button"
>
<span>
OUTLINED
</span>
</button>
</div>
</div>
`;
exports[`renders components/button/demo/component-token.tsx extend context correctly 2`] = `[]`;
exports[`renders components/button/demo/danger.tsx extend context correctly 1`] = `
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"

View File

@ -301,72 +301,6 @@ exports[`renders components/button/demo/chinese-chars-loading.tsx correctly 1`]
</div>
`;
exports[`renders components/button/demo/component-token.tsx correctly 1`] = `
<div
class="ant-flex ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-text"
type="button"
>
<span>
TEXT
</span>
</button>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
CONTAINED
</span>
</button>
<button
class="ant-btn ant-btn-default"
type="button"
>
<span>
OUTLINED
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-text"
disabled=""
type="button"
>
<span>
TEXT
</span>
</button>
<button
class="ant-btn ant-btn-primary"
disabled=""
type="button"
>
<span>
CONTAINED
</span>
</button>
<button
class="ant-btn ant-btn-default"
disabled=""
type="button"
>
<span>
OUTLINED
</span>
</button>
</div>
</div>
`;
exports[`renders components/button/demo/danger.tsx correctly 1`] = `
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"

View File

@ -1,3 +1,5 @@
import { extendTest } from '../../../tests/shared/demoTest';
extendTest('button');
extendTest('button', {
skip: ['component-token.tsx'],
});

View File

@ -1,3 +1,5 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('button');
demoTest('button', {
skip: ['component-token.tsx'],
});

View File

@ -287,7 +287,7 @@ const InternalButton: React.ForwardRefRenderFunction<
{kids}
{/* Styles: compact */}
{compactItemClassnames && <CompactCmp key="compact" prefixCls={prefixCls} />}
{!!compactItemClassnames && <CompactCmp key="compact" prefixCls={prefixCls} />}
</button>
);

View File

@ -2,9 +2,9 @@ import React from 'react';
import { PoweroffOutlined } from '@ant-design/icons';
import { Button, Flex } from 'antd';
const Text1 = () => '部署';
const Text1 = () => <></>;
const Text2 = () => <span></span>;
const Text3 = () => 'Submit';
const Text3 = () => <>Submit</>;
const App: React.FC = () => (
<Flex wrap="wrap" gap="small">

View File

@ -18,6 +18,7 @@ const App: React.FC = () => (
borderRadius: 4,
colorTextDisabled: 'rgba(0, 0, 0, 0.26)',
colorBgContainerDisabled: 'rgba(0, 0, 0, 0.12)',
contentFontSizeSM: 12,
},
},
}}
@ -37,6 +38,15 @@ const App: React.FC = () => (
</Button>
<Button disabled>OUTLINED</Button>
</Flex>
<Flex wrap="wrap" gap="small">
<Button type="text" size="small">
TEXT
</Button>
<Button type="primary" size="small">
CONTAINED
</Button>
<Button size="small">OUTLINED</Button>
</Flex>
</Flex>
</ConfigProvider>
);

View File

@ -1,7 +1,16 @@
import React from 'react';
import { SearchOutlined } from '@ant-design/icons';
import { Button, ConfigProvider, Divider, Flex, Radio, Tooltip } from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext';
import {
Button,
ConfigProvider,
Divider,
Flex,
Radio,
Tooltip,
type ConfigProviderProps,
} from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const App: React.FC = () => {
const [size, setSize] = React.useState<SizeType>('large');

View File

@ -1,7 +1,9 @@
import { DownloadOutlined } from '@ant-design/icons';
import React from 'react';
import { DownloadOutlined } from '@ant-design/icons';
import { Button, Tooltip } from 'antd';
import type { ButtonGroupProps } from 'antd/es/button';
import type { GetProps } from 'antd';
type ButtonGroupProps = GetProps<typeof Button.Group>;
const CustomGroup: React.FC<ButtonGroupProps> = (props) => (
<Button.Group {...props}>

View File

@ -1,7 +1,9 @@
import React, { useState } from 'react';
import { DownloadOutlined } from '@ant-design/icons';
import { Button, Divider, Flex, Radio } from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext';
import type { ConfigProviderProps } from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const App: React.FC = () => {
const [size, setSize] = useState<SizeType>('large'); // default is 'middle'

View File

@ -1,6 +1,6 @@
// Style as inline component
import type { ButtonToken } from '.';
import { prepareComponentToken, prepareToken } from '.';
import type { ButtonToken } from './token';
import { prepareComponentToken, prepareToken } from './token';
import { genCompactItemStyle } from '../../style/compact-item';
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
import type { GenerateStyle } from '../../theme/internal';

View File

@ -1,4 +1,4 @@
import type { ButtonToken } from '.';
import type { ButtonToken } from './token';
import type { GenerateStyle } from '../../theme/internal';
const genButtonBorderStyle = (buttonTypeCls: string, borderColor: string) => ({

View File

@ -1,162 +1,14 @@
import type { CSSProperties } from 'react';
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import { unit } from '@ant-design/cssinjs';
import { genFocusStyle } from '../../style';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import type { GenerateStyle } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal';
import type { GenStyleFn } from '../../theme/util/genComponentStyleHook';
import genGroupStyle from './group';
import type { ButtonToken, ComponentToken } from './token';
import { prepareComponentToken, prepareToken } from './token';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
/**
* @desc
* @descEN Font weight of text
*/
fontWeight: CSSProperties['fontWeight'];
/**
* @desc
* @descEN Shadow of default button
*/
defaultShadow: string;
/**
* @desc
* @descEN Shadow of primary button
*/
primaryShadow: string;
/**
* @desc
* @descEN Shadow of danger button
*/
dangerShadow: string;
/**
* @desc
* @descEN Text color of primary button
*/
primaryColor: string;
/**
* @desc
* @descEN Text color of default button
*/
defaultColor: string;
/**
* @desc
* @descEN Background color of default button
*/
defaultBg: string;
/**
* @desc
* @descEN Border color of default button
*/
defaultBorderColor: string;
/**
* @desc
* @descEN Text color of danger button
*/
dangerColor: string;
/**
* @desc
* @descEN Border color of disabled button
*/
borderColorDisabled: string;
/**
* @desc
* @descEN Text color of default ghost button
*/
defaultGhostColor: string;
/**
* @desc
* @descEN Background color of ghost button
*/
ghostBg: string;
/**
* @desc
* @descEN Border color of default ghost button
*/
defaultGhostBorderColor: string;
/**
* @desc
* @descEN Horizontal padding of button
*/
paddingInline: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of large button
*/
paddingInlineLG: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of small button
*/
paddingInlineSM: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of button
*/
paddingBlock: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of large button
*/
paddingBlockLG: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of small button
*/
paddingBlockSM: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Icon size of button which only contains icon
*/
onlyIconSize: number;
/**
* @desc
* @descEN Icon size of large button which only contains icon
*/
onlyIconSizeLG: number;
/**
* @desc
* @descEN Icon size of small button which only contains icon
*/
onlyIconSizeSM: number;
/**
* @desc
* @descEN Border color of button group
*/
groupBorderColor: string;
/**
* @desc
* @descEN Background color of link button when hover
*/
linkHoverBg: string;
/**
* @desc
* @descEN Background color of text button when hover
*/
textHoverBg: string;
/**
* @desc
* @descEN Font size of button content
*/
contentFontSize: number;
/**
* @desc
* @descEN Font size of large button content
*/
contentFontSizeLG: number;
/**
* @desc
* @descEN Font size of small button content
*/
contentFontSizeSM: number;
}
export interface ButtonToken extends FullToken<'Button'> {
buttonPaddingHorizontal: CSSProperties['paddingInline'];
buttonPaddingVertical: CSSProperties['paddingBlock'];
buttonIconOnlyFontSize: number;
}
export type { ComponentToken };
// ============================== Shared ==============================
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
@ -177,7 +29,6 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
userSelect: 'none',
touchAction: 'manipulation',
lineHeight: token.lineHeight,
color: token.colorText,
'&:disabled > *': {
@ -542,11 +393,12 @@ const genTypeButtonStyle: GenerateStyle<ButtonToken> = (token) => {
};
// =============================== Size ===============================
const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = ''): CSSInterpolation => {
const genButtonStyle = (token: ButtonToken, prefixCls: string = ''): CSSInterpolation => {
const {
componentCls,
controlHeight,
fontSize,
lineHeight,
borderRadius,
buttonPaddingHorizontal,
iconCls,
@ -556,10 +408,10 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = ''): CSS
const iconOnlyCls = `${componentCls}-icon-only`;
return [
// Size
{
[`${componentCls}${sizePrefixCls}`]: {
[`${prefixCls}`]: {
fontSize,
lineHeight,
height: controlHeight,
padding: `${unit(buttonPaddingVertical!)} ${unit(buttonPaddingHorizontal!)}`,
borderRadius,
@ -590,25 +442,27 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = ''): CSS
// Shape - patch prefixCls again to override solid border radius style
{
[`${componentCls}${componentCls}-circle${sizePrefixCls}`]: genCircleButtonStyle(token),
[`${componentCls}${componentCls}-circle${prefixCls}`]: genCircleButtonStyle(token),
},
{
[`${componentCls}${componentCls}-round${sizePrefixCls}`]: genRoundButtonStyle(token),
[`${componentCls}${componentCls}-round${prefixCls}`]: genRoundButtonStyle(token),
},
];
};
const genSizeBaseButtonStyle: GenerateStyle<ButtonToken> = (token) =>
genSizeButtonStyle(
mergeToken<ButtonToken>(token, {
fontSize: token.contentFontSize,
}),
);
const genSizeBaseButtonStyle: GenerateStyle<ButtonToken> = (token) => {
const baseToken = mergeToken<ButtonToken>(token, {
fontSize: token.contentFontSize,
lineHeight: token.contentLineHeight,
});
return genButtonStyle(baseToken, token.componentCls);
};
const genSizeSmallButtonStyle: GenerateStyle<ButtonToken> = (token) => {
const smallToken = mergeToken<ButtonToken>(token, {
controlHeight: token.controlHeightSM,
fontSize: token.contentFontSizeSM,
lineHeight: token.contentLineHeightSM,
padding: token.paddingXS,
buttonPaddingHorizontal: token.paddingInlineSM,
buttonPaddingVertical: token.paddingBlockSM,
@ -616,20 +470,21 @@ const genSizeSmallButtonStyle: GenerateStyle<ButtonToken> = (token) => {
buttonIconOnlyFontSize: token.onlyIconSizeSM,
});
return genSizeButtonStyle(smallToken, `${token.componentCls}-sm`);
return genButtonStyle(smallToken, `${token.componentCls}-sm`);
};
const genSizeLargeButtonStyle: GenerateStyle<ButtonToken> = (token) => {
const largeToken = mergeToken<ButtonToken>(token, {
controlHeight: token.controlHeightLG,
fontSize: token.contentFontSizeLG,
lineHeight: token.contentLineHeightLG,
buttonPaddingHorizontal: token.paddingInlineLG,
buttonPaddingVertical: token.paddingBlockLG,
borderRadius: token.borderRadiusLG,
buttonIconOnlyFontSize: token.onlyIconSizeLG,
});
return genSizeButtonStyle(largeToken, `${token.componentCls}-lg`);
return genButtonStyle(largeToken, `${token.componentCls}-lg`);
};
const genBlockButtonStyle: GenerateStyle<ButtonToken> = (token) => {
@ -644,67 +499,6 @@ const genBlockButtonStyle: GenerateStyle<ButtonToken> = (token) => {
};
// ============================== Export ==============================
export const prepareToken: (token: Parameters<GenStyleFn<'Button'>>[0]) => ButtonToken = (
token,
) => {
const { paddingInline, onlyIconSize, paddingBlock } = token;
const buttonToken = mergeToken<ButtonToken>(token, {
buttonPaddingHorizontal: paddingInline,
buttonPaddingVertical: paddingBlock,
buttonIconOnlyFontSize: onlyIconSize,
});
return buttonToken;
};
export const prepareComponentToken: GetDefaultToken<'Button'> = (token) => {
const contentFontSize = token.fontSize;
const contentFontSizeSM = token.fontSize;
const contentFontSizeLG = token.fontSizeLG;
return {
fontWeight: 400,
defaultShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlTmpOutline}`,
primaryShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlOutline}`,
dangerShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`,
primaryColor: token.colorTextLightSolid,
dangerColor: token.colorTextLightSolid,
borderColorDisabled: token.colorBorder,
defaultGhostColor: token.colorBgContainer,
ghostBg: 'transparent',
defaultGhostBorderColor: token.colorBgContainer,
paddingInline: token.paddingContentHorizontal - token.lineWidth,
paddingInlineLG: token.paddingContentHorizontal - token.lineWidth,
paddingInlineSM: 8 - token.lineWidth,
paddingBlock: Math.max(
(token.controlHeight - contentFontSize * token.lineHeight) / 2 - token.lineWidth,
0,
),
paddingBlockSM: Math.max(
(token.controlHeightSM - contentFontSizeSM * token.lineHeight) / 2 - token.lineWidth,
0,
),
paddingBlockLG: Math.max(
(token.controlHeightLG - contentFontSizeLG * token.lineHeight) / 2 - token.lineWidth,
0,
),
onlyIconSize: token.fontSizeLG,
onlyIconSizeSM: token.fontSizeLG - 2,
onlyIconSizeLG: token.fontSizeLG + 2,
groupBorderColor: token.colorPrimaryHover,
linkHoverBg: 'transparent',
textHoverBg: token.colorBgTextHover,
defaultColor: token.colorText,
defaultBg: token.colorBgContainer,
defaultBorderColor: token.colorBorder,
defaultBorderColorDisabled: token.colorBorder,
contentFontSize,
contentFontSizeSM,
contentFontSizeLG,
};
};
export default genStyleHooks(
'Button',
(token) => {
@ -715,8 +509,8 @@ export default genStyleHooks(
genSharedButtonStyle(buttonToken),
// Size
genSizeSmallButtonStyle(buttonToken),
genSizeBaseButtonStyle(buttonToken),
genSizeSmallButtonStyle(buttonToken),
genSizeLargeButtonStyle(buttonToken),
// Block
@ -733,6 +527,9 @@ export default genStyleHooks(
{
unitless: {
fontWeight: true,
contentLineHeight: true,
contentLineHeightSM: true,
contentLineHeightLG: true,
},
},
);

View File

@ -0,0 +1,236 @@
import type { CSSProperties } from 'react';
import type { FullToken, GetDefaultToken } from '../../theme/internal';
import { getLineHeight, mergeToken } from '../../theme/internal';
import type { GenStyleFn } from '../../theme/util/genComponentStyleHook';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
/**
* @desc
* @descEN Font weight of text
*/
fontWeight: CSSProperties['fontWeight'];
/**
* @desc
* @descEN Shadow of default button
*/
defaultShadow: string;
/**
* @desc
* @descEN Shadow of primary button
*/
primaryShadow: string;
/**
* @desc
* @descEN Shadow of danger button
*/
dangerShadow: string;
/**
* @desc
* @descEN Text color of primary button
*/
primaryColor: string;
/**
* @desc
* @descEN Text color of default button
*/
defaultColor: string;
/**
* @desc
* @descEN Background color of default button
*/
defaultBg: string;
/**
* @desc
* @descEN Border color of default button
*/
defaultBorderColor: string;
/**
* @desc
* @descEN Text color of danger button
*/
dangerColor: string;
/**
* @desc
* @descEN Border color of disabled button
*/
borderColorDisabled: string;
/**
* @desc
* @descEN Text color of default ghost button
*/
defaultGhostColor: string;
/**
* @desc
* @descEN Background color of ghost button
*/
ghostBg: string;
/**
* @desc
* @descEN Border color of default ghost button
*/
defaultGhostBorderColor: string;
/**
* @desc
* @descEN Horizontal padding of button
*/
paddingInline: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of large button
*/
paddingInlineLG: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of small button
*/
paddingInlineSM: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of button
*/
paddingBlock: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of large button
*/
paddingBlockLG: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Horizontal padding of small button
*/
paddingBlockSM: CSSProperties['paddingInline'];
/**
* @desc
* @descEN Icon size of button which only contains icon
*/
onlyIconSize: number;
/**
* @desc
* @descEN Icon size of large button which only contains icon
*/
onlyIconSizeLG: number;
/**
* @desc
* @descEN Icon size of small button which only contains icon
*/
onlyIconSizeSM: number;
/**
* @desc
* @descEN Border color of button group
*/
groupBorderColor: string;
/**
* @desc
* @descEN Background color of link button when hover
*/
linkHoverBg: string;
/**
* @desc
* @descEN Background color of text button when hover
*/
textHoverBg: string;
/**
* @desc
* @descEN Font size of button content
*/
contentFontSize: number;
/**
* @desc
* @descEN Font size of large button content
*/
contentFontSizeLG: number;
/**
* @desc
* @descEN Font size of small button content
*/
contentFontSizeSM: number;
/**
* @desc
* @descEN Line height of button content
*/
contentLineHeight: number;
/**
* @desc
* @descEN Line height of large button content
*/
contentLineHeightLG: number;
/**
* @desc
* @descEN Line height of small button content
*/
contentLineHeightSM: number;
}
export interface ButtonToken extends FullToken<'Button'> {
buttonPaddingHorizontal: CSSProperties['paddingInline'];
buttonPaddingVertical: CSSProperties['paddingBlock'];
buttonIconOnlyFontSize: number;
}
export const prepareToken: (token: Parameters<GenStyleFn<'Button'>>[0]) => ButtonToken = (
token,
) => {
const { paddingInline, onlyIconSize, paddingBlock } = token;
const buttonToken = mergeToken<ButtonToken>(token, {
buttonPaddingHorizontal: paddingInline,
buttonPaddingVertical: paddingBlock,
buttonIconOnlyFontSize: onlyIconSize,
});
return buttonToken;
};
export const prepareComponentToken: GetDefaultToken<'Button'> = (token) => {
const contentFontSize = token.contentFontSize ?? token.fontSize;
const contentFontSizeSM = token.contentFontSizeSM ?? token.fontSize;
const contentFontSizeLG = token.contentFontSizeLG ?? token.fontSizeLG;
const contentLineHeight = token.contentLineHeight ?? getLineHeight(contentFontSize);
const contentLineHeightSM = token.contentLineHeightSM ?? getLineHeight(contentFontSizeSM);
const contentLineHeightLG = token.contentLineHeightLG ?? getLineHeight(contentFontSizeLG);
return {
fontWeight: 400,
defaultShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlTmpOutline}`,
primaryShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlOutline}`,
dangerShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`,
primaryColor: token.colorTextLightSolid,
dangerColor: token.colorTextLightSolid,
borderColorDisabled: token.colorBorder,
defaultGhostColor: token.colorBgContainer,
ghostBg: 'transparent',
defaultGhostBorderColor: token.colorBgContainer,
paddingInline: token.paddingContentHorizontal - token.lineWidth,
paddingInlineLG: token.paddingContentHorizontal - token.lineWidth,
paddingInlineSM: 8 - token.lineWidth,
onlyIconSize: token.fontSizeLG,
onlyIconSizeSM: token.fontSizeLG - 2,
onlyIconSizeLG: token.fontSizeLG + 2,
groupBorderColor: token.colorPrimaryHover,
linkHoverBg: 'transparent',
textHoverBg: token.colorBgTextHover,
defaultColor: token.colorText,
defaultBg: token.colorBgContainer,
defaultBorderColor: token.colorBorder,
defaultBorderColorDisabled: token.colorBorder,
contentFontSize,
contentFontSizeSM,
contentFontSizeLG,
contentLineHeight,
contentLineHeightSM,
contentLineHeightLG,
paddingBlock: Math.max(
(token.controlHeight - contentFontSize * contentLineHeight) / 2 - token.lineWidth,
0,
),
paddingBlockSM: Math.max(
(token.controlHeightSM - contentFontSizeSM * contentLineHeightSM) / 2 - token.lineWidth,
0,
),
paddingBlockLG: Math.max(
(token.controlHeightLG - contentFontSizeLG * contentLineHeightLG) / 2 - token.lineWidth,
0,
),
};
};

View File

@ -1,7 +1,3 @@
/**
* live: false
*/
import React from 'react';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

View File

@ -895,7 +895,7 @@ exports[`renders components/card/demo/meta.tsx extend context correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=8"
/>
</span>
</div>

View File

@ -856,7 +856,7 @@ exports[`renders components/card/demo/meta.tsx correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=8"
/>
</span>
</div>

View File

@ -20,7 +20,7 @@ const App: React.FC = () => (
]}
>
<Meta
avatar={<Avatar src="https://xsgames.co/randomusers/avatar.php?g=pixel" />}
avatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}
title="Card title"
description="This is the description"
/>

View File

@ -1,7 +1,8 @@
import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd';
import type { CarouselProps, RadioChangeEvent } from 'antd';
import { Carousel, Radio } from 'antd';
import type { DotPosition } from 'antd/es/carousel';
type DotPosition = CarouselProps['dotPosition'];
const contentStyle: React.CSSProperties = {
height: '160px',

View File

@ -1,6 +1,8 @@
import React from 'react';
import { Cascader } from 'antd';
import type { DefaultOptionType } from 'antd/es/cascader';
import type { CascaderProps, GetProp } from 'antd';
type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];
interface Option {
value: string;

View File

@ -1,6 +1,8 @@
import React from 'react';
import { Cascader } from 'antd';
import type { DefaultOptionType } from 'antd/es/cascader';
import type { GetProp, CascaderProps } from 'antd';
type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];
interface Option {
value: string;

View File

@ -170,4 +170,4 @@ export { GroupContext };
export default CheckboxGroup as <T extends CheckboxValueType = CheckboxValueType>(
props: CheckboxGroupProps<T> & React.RefAttributes<HTMLDivElement>,
) => React.ReactNode;
) => React.ReactElement;

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Checkbox } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { CheckboxProps } from 'antd';
const onChange = (e: CheckboxChangeEvent) => {
const onChange: CheckboxProps['onChange'] = (e) => {
console.log(`checked = ${e.target.checked}`);
};

View File

@ -1,7 +1,8 @@
import React, { useState } from 'react';
import { Checkbox, Divider } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
import type { CheckboxProps, GetProp } from 'antd';
type CheckboxValueType = GetProp<typeof Checkbox.Group, 'value'>[number];
const CheckboxGroup = Checkbox.Group;
@ -18,7 +19,7 @@ const App: React.FC = () => {
setCheckedList(list);
};
const onCheckAllChange = (e: CheckboxChangeEvent) => {
const onCheckAllChange: CheckboxProps['onChange'] = (e) => {
setCheckedList(e.target.checked ? plainOptions : []);
};

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Button, Checkbox } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { CheckboxProps } from 'antd';
const App: React.FC = () => {
const [checked, setChecked] = useState(true);
@ -14,7 +14,7 @@ const App: React.FC = () => {
setDisabled(!disabled);
};
const onChange = (e: CheckboxChangeEvent) => {
const onChange: CheckboxProps['onChange'] = (e) => {
console.log('checked = ', e.target.checked);
setChecked(e.target.checked);
};

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Checkbox } from 'antd';
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
import type { GetProp } from 'antd';
const onChange = (checkedValues: CheckboxValueType[]) => {
const onChange: GetProp<typeof Checkbox.Group, 'onChange'> = (checkedValues) => {
console.log('checked = ', checkedValues);
};

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Checkbox, Col, Row } from 'antd';
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
import type { GetProp } from 'antd';
const onChange = (checkedValues: CheckboxValueType[]) => {
const onChange: GetProp<typeof Checkbox.Group, 'onChange'> = (checkedValues) => {
console.log('checked = ', checkedValues);
};

View File

@ -94,7 +94,10 @@ Common props ref[Common props](/docs/react/common-props)
### Collapse.Panel
<Alert message="&gt;= 5.6.0 configure the panel by `items`."></Alert>
<!-- prettier-ignore -->
:::info{title=Deprecated}
When using version >= 5.6.0, we prefer to configuring the panel by `items`.
:::
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |

View File

@ -95,7 +95,10 @@ const items: CollapseProps['items'] = [
### Collapse.Panel
<Alert message="&gt;= 5.6.0 请使用 items 方式配置面板."></Alert>
<!-- prettier-ignore -->
:::info{title=已废弃}
版本 >= 5.6.0 时请使用 items 方式配置面板。
:::
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { App, ColorPicker } from 'antd';
import type { ColorPickerProps } from 'antd/es/color-picker';
import type { ColorPickerProps } from 'antd';
const Demo = () => {
const { message } = App.useApp();

View File

@ -1,9 +1,11 @@
import React, { useState } from 'react';
import { ColorPicker } from 'antd';
import type { ColorPickerProps } from 'antd/es/color-picker';
import type { ColorPickerProps, GetProp } from 'antd';
type Color = GetProp<ColorPickerProps, 'value'>;
const Demo: React.FC = () => {
const [color, setColor] = useState<ColorPickerProps['value']>('#1677ff');
const [color, setColor] = useState<Color>('#1677ff');
return <ColorPicker value={color} onChange={setColor} />;
};

View File

@ -1,12 +1,15 @@
import React, { useState } from 'react';
import { ColorPicker, Space } from 'antd';
import type { ColorPickerProps } from 'antd/es/color-picker';
import type { ColorPickerProps, GetProp } from 'antd';
type Color = GetProp<ColorPickerProps, 'value'>;
type Format = GetProp<ColorPickerProps, 'format'>;
const HexCase: React.FC = () => {
const [colorHex, setColorHex] = useState<ColorPickerProps['value']>('#1677ff');
const [formatHex, setFormatHex] = useState<ColorPickerProps['format']>('hex');
const [colorHex, setColorHex] = useState<Color>('#1677ff');
const [formatHex, setFormatHex] = useState<Format>('hex');
const hexString = React.useMemo(
const hexString = React.useMemo<string>(
() => (typeof colorHex === 'string' ? colorHex : colorHex?.toHexString()),
[colorHex],
);

View File

@ -1,15 +1,18 @@
import React, { useState } from 'react';
import { ColorPicker } from 'antd';
import type { ColorPickerProps } from 'antd/es/color-picker';
import type { ColorPickerProps, GetProp } from 'antd';
const PureRenderColorPicker = ColorPicker._InternalPanelDoNotUseOrYouWillBeFired;
const { _InternalPanelDoNotUseOrYouWillBeFired: PureRenderColorPicker } = ColorPicker;
export default () => {
const [color, setColor] = useState<ColorPickerProps['value']>('#1677ff');
type Color = GetProp<ColorPickerProps, 'value'>;
const Demo: React.FC = () => {
const [color, setColor] = useState<Color>('#1677ff');
return (
<div style={{ paddingLeft: 100 }}>
<PureRenderColorPicker value={color} onChange={setColor} />
</div>
);
};
export default Demo;

View File

@ -1,9 +1,11 @@
import React, { useMemo, useState } from 'react';
import { Button, ColorPicker } from 'antd';
import type { ColorPickerProps } from 'antd/es/color-picker';
import type { ColorPickerProps, GetProp } from 'antd';
type Color = GetProp<ColorPickerProps, 'value'>;
const Demo: React.FC = () => {
const [color, setColor] = useState<ColorPickerProps['value']>('#1677ff');
const [color, setColor] = useState<Color>('#1677ff');
const bgColor = useMemo<string>(
() => (typeof color === 'string' ? color : color!.toHexString()),

View File

@ -64,7 +64,6 @@ const genClearStyle = (
borderRadius: borderRadiusSM,
border: `${unit(lineWidth)} solid ${colorSplit}`,
position: 'relative',
cursor: 'pointer',
overflow: 'hidden',
...extraStyle,
'&::after': {

View File

@ -14217,46 +14217,42 @@ exports[`ConfigProvider components Drawer configProvider 1`] = `
role="dialog"
>
<div
class="config-drawer-wrapper-body"
class="config-drawer-header config-drawer-header-close-only"
>
<div
class="config-drawer-header config-drawer-header-close-only"
class="config-drawer-header-title"
>
<div
class="config-drawer-header-title"
<button
aria-label="Close"
class="config-drawer-close"
type="button"
>
<button
aria-label="Close"
class="config-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="config-drawer-body"
/>
</div>
<div
class="config-drawer-body"
/>
</div>
</div>
<div
@ -14292,46 +14288,42 @@ exports[`ConfigProvider components Drawer configProvider componentDisabled 1`] =
role="dialog"
>
<div
class="config-drawer-wrapper-body"
class="config-drawer-header config-drawer-header-close-only"
>
<div
class="config-drawer-header config-drawer-header-close-only"
class="config-drawer-header-title"
>
<div
class="config-drawer-header-title"
<button
aria-label="Close"
class="config-drawer-close"
type="button"
>
<button
aria-label="Close"
class="config-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="config-drawer-body"
/>
</div>
<div
class="config-drawer-body"
/>
</div>
</div>
<div
@ -14367,46 +14359,42 @@ exports[`ConfigProvider components Drawer configProvider componentSize large 1`]
role="dialog"
>
<div
class="config-drawer-wrapper-body"
class="config-drawer-header config-drawer-header-close-only"
>
<div
class="config-drawer-header config-drawer-header-close-only"
class="config-drawer-header-title"
>
<div
class="config-drawer-header-title"
<button
aria-label="Close"
class="config-drawer-close"
type="button"
>
<button
aria-label="Close"
class="config-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="config-drawer-body"
/>
</div>
<div
class="config-drawer-body"
/>
</div>
</div>
<div
@ -14442,46 +14430,42 @@ exports[`ConfigProvider components Drawer configProvider componentSize middle 1`
role="dialog"
>
<div
class="config-drawer-wrapper-body"
class="config-drawer-header config-drawer-header-close-only"
>
<div
class="config-drawer-header config-drawer-header-close-only"
class="config-drawer-header-title"
>
<div
class="config-drawer-header-title"
<button
aria-label="Close"
class="config-drawer-close"
type="button"
>
<button
aria-label="Close"
class="config-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="config-drawer-body"
/>
</div>
<div
class="config-drawer-body"
/>
</div>
</div>
<div
@ -14517,46 +14501,42 @@ exports[`ConfigProvider components Drawer configProvider componentSize small 1`]
role="dialog"
>
<div
class="config-drawer-wrapper-body"
class="config-drawer-header config-drawer-header-close-only"
>
<div
class="config-drawer-header config-drawer-header-close-only"
class="config-drawer-header-title"
>
<div
class="config-drawer-header-title"
<button
aria-label="Close"
class="config-drawer-close"
type="button"
>
<button
aria-label="Close"
class="config-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="config-drawer-body"
/>
</div>
<div
class="config-drawer-body"
/>
</div>
</div>
<div
@ -14592,46 +14572,42 @@ exports[`ConfigProvider components Drawer normal 1`] = `
role="dialog"
>
<div
class="ant-drawer-wrapper-body"
class="ant-drawer-header ant-drawer-header-close-only"
>
<div
class="ant-drawer-header ant-drawer-header-close-only"
class="ant-drawer-header-title"
>
<div
class="ant-drawer-header-title"
<button
aria-label="Close"
class="ant-drawer-close"
type="button"
>
<button
aria-label="Close"
class="ant-drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="ant-drawer-body"
/>
</div>
<div
class="ant-drawer-body"
/>
</div>
</div>
<div
@ -14667,46 +14643,42 @@ exports[`ConfigProvider components Drawer prefixCls 1`] = `
role="dialog"
>
<div
class="prefix-Drawer-wrapper-body"
class="prefix-Drawer-header prefix-Drawer-header-close-only"
>
<div
class="prefix-Drawer-header prefix-Drawer-header-close-only"
class="prefix-Drawer-header-title"
>
<div
class="prefix-Drawer-header-title"
<button
aria-label="Close"
class="prefix-Drawer-close"
type="button"
>
<button
aria-label="Close"
class="prefix-Drawer-close"
type="button"
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
<div
class="prefix-Drawer-body"
/>
</div>
<div
class="prefix-Drawer-body"
/>
</div>
</div>
<div
@ -17441,7 +17413,7 @@ exports[`ConfigProvider components List configProvider 1`] = `
class="config-avatar config-avatar-circle config-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17493,7 +17465,7 @@ exports[`ConfigProvider components List configProvider componentDisabled 1`] = `
class="config-avatar config-avatar-circle config-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17545,7 +17517,7 @@ exports[`ConfigProvider components List configProvider componentSize large 1`] =
class="config-avatar config-avatar-lg config-avatar-circle config-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17597,7 +17569,7 @@ exports[`ConfigProvider components List configProvider componentSize middle 1`]
class="config-avatar config-avatar-circle config-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17649,7 +17621,7 @@ exports[`ConfigProvider components List configProvider componentSize small 1`] =
class="config-avatar config-avatar-sm config-avatar-circle config-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17701,7 +17673,7 @@ exports[`ConfigProvider components List normal 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -17753,7 +17725,7 @@ exports[`ConfigProvider components List prefixCls 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel"
src="https://api.dicebear.com/7.x/miniavs/svg?seed=9"
/>
</span>
</div>
@ -21804,7 +21776,7 @@ exports[`ConfigProvider components Progress configProvider 1`] = `
>
<div
class="config-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21832,7 +21804,7 @@ exports[`ConfigProvider components Progress configProvider componentDisabled 1`]
>
<div
class="config-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21860,7 +21832,7 @@ exports[`ConfigProvider components Progress configProvider componentSize large 1
>
<div
class="config-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21888,7 +21860,7 @@ exports[`ConfigProvider components Progress configProvider componentSize middle
>
<div
class="config-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21916,7 +21888,7 @@ exports[`ConfigProvider components Progress configProvider componentSize small 1
>
<div
class="config-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21944,7 +21916,7 @@ exports[`ConfigProvider components Progress normal 1`] = `
>
<div
class="ant-progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>
@ -21972,7 +21944,7 @@ exports[`ConfigProvider components Progress prefixCls 1`] = `
>
<div
class="prefix-Progress-bg"
style="width: 100%; height: 8px; clip-path: inset(0 100% 0 0 round 100px);"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
</div>

View File

@ -355,7 +355,7 @@ describe('ConfigProvider', () => {
<List.Item {...props}>
<List.Item.Meta
{...props}
avatar={<Avatar src="https://xsgames.co/randomusers/avatar.php?g=pixel" />}
avatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=9" />}
title="Ant Design"
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
/>

View File

@ -958,7 +958,10 @@ describe('ConfigProvider support style and className props', () => {
it('Should Table className & style works', () => {
const { container } = render(
<ConfigProvider table={{ className: 'cp-table', style: { backgroundColor: 'blue' } }}>
<Table dataSource={[]} />
<Table
columns={[{ title: 'Address', dataIndex: 'address', key: 'address 1', ellipsis: true }]}
dataSource={[{ key: '1', name: 'Jim Green', age: 40, address: 'test', tags: ['loser'] }]}
/>
</ConfigProvider>,
);
const element = container.querySelector<HTMLDivElement>('.ant-table-wrapper');

View File

@ -212,7 +212,7 @@ describe('ConfigProvider.Theme', () => {
expect(button).toHaveStyle({
'--ant-color-text': 'rgba(0, 0, 0, 0.88)',
boxShadow: 'var(--ant-button-default-shadow)',
'line-height': 'var(--ant-line-height)',
'border-radius': 'var(--ant-border-radius)',
});
});
@ -235,14 +235,14 @@ describe('ConfigProvider.Theme', () => {
expect(fooBtn).toHaveStyle({
'--ant-color-text': 'rgba(0, 0, 0, 0.88)',
boxShadow: 'var(--ant-button-default-shadow)',
'line-height': 'var(--ant-line-height)',
'border-radius': 'var(--ant-border-radius)',
});
expect(barBtn).toHaveClass('bar');
expect(barBtn).toHaveStyle({
'--bar-color-text': 'rgba(0, 0, 0, 0.88)',
boxShadow: 'var(--bar-button-default-shadow)',
'line-height': 'var(--bar-line-height)',
'border-radius': 'var(--bar-border-radius)',
});
});

View File

@ -50,7 +50,7 @@ export interface ThemeConfig {
cssVar?:
| {
/**
* Prefix for css variable, default to `antd`.
* Prefix for css variable, default to `ant`.
*/
prefix?: string;
/**
@ -175,7 +175,7 @@ export interface ConfigConsumerProps {
tag?: ComponentStyleConfig;
table?: ComponentStyleConfig;
card?: ComponentStyleConfig;
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicatorSize'>;
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicator' | 'indicatorSize'>;
timeline?: ComponentStyleConfig;
timePicker?: ComponentStyleConfig;
upload?: ComponentStyleConfig;

View File

@ -1,3 +1,4 @@
import React, { useState } from 'react';
import {
DownloadOutlined,
LeftOutlined,
@ -7,8 +8,7 @@ import {
SearchOutlined as SearchIcon,
SmileOutlined,
} from '@ant-design/icons';
import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd';
import type { ConfigProviderProps, RadioChangeEvent } from 'antd';
import {
Badge,
Button,
@ -30,7 +30,8 @@ import {
Tree,
TreeSelect,
} from 'antd';
import type { DirectionType } from 'antd/es/config-provider';
type DirectionType = ConfigProviderProps['direction'];
const InputGroup = Input.Group;
const ButtonGroup = Button.Group;

View File

@ -1,40 +1,38 @@
/**
* live: false
*/
import { EllipsisOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import React, { useState } from 'react';
import type { RadioChangeEvent, TourProps, UploadFile } from 'antd';
import { EllipsisOutlined } from '@ant-design/icons';
import type { ConfigProviderProps, RadioChangeEvent, TourProps, UploadFile } from 'antd';
import {
Upload,
Tour,
Input,
Form,
QRCode,
Button,
Calendar,
ConfigProvider,
DatePicker,
Divider,
Form,
Image,
Input,
InputNumber,
Modal,
Pagination,
Popconfirm,
QRCode,
Radio,
Select,
Space,
Table,
theme,
TimePicker,
Tour,
Transfer,
Image,
InputNumber,
Divider,
Upload,
} from 'antd';
import type { Locale } from 'antd/es/locale';
import enUS from 'antd/locale/en_US';
import zhCN from 'antd/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
type Locale = ConfigProviderProps['locale'];
dayjs.locale('en');
const { Option } = Select;

View File

@ -12,7 +12,9 @@ import {
Table,
Tabs,
} from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext';
import type { ConfigProviderProps } from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const { TabPane } = Tabs;

View File

@ -10,7 +10,9 @@ import {
Space,
Switch,
} from 'antd';
import type { Color } from 'antd/es/color-picker';
import type { ColorPickerProps, GetProp } from 'antd';
type Color = Exclude<GetProp<ColorPickerProps, 'value'>, string>;
type ThemeData = {
borderRadius: number;

View File

@ -1,6 +1,8 @@
import React, { useState } from 'react';
import { Checkbox, ConfigProvider, Divider, Form, Input, Radio, Space } from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext';
import type { ConfigProviderProps } from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const ConfigDisplay = () => {
const { componentDisabled, componentSize } = ConfigProvider.useConfig();

View File

@ -1,8 +1,9 @@
import { HappyProvider } from '@ant-design/happy-work-theme';
import React from 'react';
import { HappyProvider } from '@ant-design/happy-work-theme';
import { Button, ConfigProvider, Space } from 'antd';
import type { ConfigProviderProps, GetProp } from 'antd';
type WaveConfig = NonNullable<Parameters<typeof ConfigProvider>[0]['wave']>;
type WaveConfig = GetProp<ConfigProviderProps, 'wave'>;
// Prepare effect holder
const createHolder = (node: HTMLElement) => {

View File

@ -147,7 +147,7 @@ const {
| statistic | Set Statistic common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| steps | Set Steps common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| table | Set Table common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tabs | Set Tabs common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tabs | Set Tabs common props | { className?: string, style?: React.CSSProperties, indicator?: { size?: GetIndicatorSize, align?: `start` \| `center` \| `end` }} | - | 5.7.0 |
| tag | Set Tag common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timeline | Set Timeline common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timePicker | Set TimePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -190,7 +190,7 @@ export interface ConfigProviderProps {
tag?: ComponentStyleConfig;
table?: ComponentStyleConfig;
card?: ComponentStyleConfig;
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicatorSize'>;
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicator' | 'indicatorSize'>;
timeline?: ComponentStyleConfig;
timePicker?: ComponentStyleConfig;
upload?: ComponentStyleConfig;
@ -266,6 +266,12 @@ const setGlobalConfig = (props: GlobalConfigProps) => {
};
export const globalConfig = () => ({
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) {
return customizePrefixCls;
}
return suffixCls ? `${getGlobalPrefixCls()}-${suffixCls}` : getGlobalPrefixCls();
},
getIconPrefixCls: getGlobalIconPrefixCls,
getRootPrefixCls: () => {
// If Global prefixCls provided, use this
@ -446,7 +452,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
warning: warningConfig,
};
const config = {
const config: ConfigConsumerProps = {
...parentContext,
};

View File

@ -149,7 +149,7 @@ const {
| statistic | 设置 Statistic 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| steps | 设置 Steps 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| table | 设置 Table 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tabs | 设置 Tabs 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tabs | 设置 Tabs 组件的通用属性 | { className?: string, style?: React.CSSProperties, indicator?: { size?: GetIndicatorSize, align?: `start` \| `center` \| `end` }} | - | 5.7.0 |
| tag | 设置 Tag 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timeline | 设置 Timeline 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timePicker | 设置 TimePicker 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import type { ButtonProps } from '../button';
import Button from '../button';
import type { ButtonProps } from '../button';
export default function PickerButton(props: ButtonProps) {
return <Button size="small" type="primary" {...props} />;

Some files were not shown because too many files have changed in this diff Show More