mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-29 18:50:00 +08:00
Merge branch 'master' into feature-merge-master
This commit is contained in:
commit
8e5c31413a
@ -32,33 +32,25 @@ const NotFoundPage: React.FC<NotFoundProps> = ({ router }) => {
|
||||
|
||||
// Report if necessary
|
||||
const { yuyanMonitor } = window as any;
|
||||
if (yuyanMonitor) {
|
||||
yuyanMonitor.log({
|
||||
code: 11,
|
||||
msg: `Page not found: ${location.href}; Source: ${document.referrer}`,
|
||||
});
|
||||
}
|
||||
yuyanMonitor?.log({
|
||||
code: 11,
|
||||
msg: `Page not found: ${location.href}; Source: ${document.referrer}`,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div id="page-404">
|
||||
<section>
|
||||
<Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle={
|
||||
isZhCN ? '你访问的页面貌似不存在?' : 'Sorry, the page you visited does not exist.'
|
||||
}
|
||||
extra={
|
||||
<Link to={utils.getLocalizedPathname('/', isZhCN)}>
|
||||
<Button type="primary" icon={<HomeOutlined />}>
|
||||
{isZhCN ? '返回 Ant Design 首页' : 'Back to home page'}
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
<Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle={isZhCN ? '你访问的页面貌似不存在?' : 'Sorry, the page you visited does not exist.'}
|
||||
extra={
|
||||
<Link to={utils.getLocalizedPathname('/', isZhCN)}>
|
||||
<Button type="primary" icon={<HomeOutlined />}>
|
||||
{isZhCN ? '返回 Ant Design 首页' : 'Back to home page'}
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { Button, Space, Typography } from 'antd';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import * as React from 'react';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import { GroupMask } from './Group';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import * as utils from '../../../theme/utils';
|
||||
import { GroupMask } from './Group';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import React, { useMemo } from 'react';
|
||||
import useSiteToken from '../../../../hooks/useSiteToken';
|
||||
import { COLOR_IMAGES, getClosetColor } from './colorUtil';
|
||||
|
||||
@ -7,49 +8,40 @@ export interface BackgroundImageProps {
|
||||
isLight?: boolean;
|
||||
}
|
||||
|
||||
export default function BackgroundImage({ colorPrimary, isLight }: BackgroundImageProps) {
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const activeColor = React.useMemo(() => getClosetColor(colorPrimary), [colorPrimary]);
|
||||
|
||||
const sharedStyle: React.CSSProperties = {
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
return {
|
||||
image: css`
|
||||
transition: all ${token.motionDurationSlow};
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
object-position: right top;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
const BackgroundImage: React.FC<BackgroundImageProps> = ({ colorPrimary, isLight }) => {
|
||||
const activeColor = useMemo(() => getClosetColor(colorPrimary), [colorPrimary]);
|
||||
|
||||
const { image } = useStyle();
|
||||
|
||||
return (
|
||||
<>
|
||||
{COLOR_IMAGES.map(({ color, url }) => {
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
key={color}
|
||||
style={{
|
||||
...sharedStyle,
|
||||
opacity: isLight && activeColor === color ? 1 : 0,
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'right top',
|
||||
}}
|
||||
src={url}
|
||||
alt=""
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* <div
|
||||
style={{
|
||||
...sharedStyle,
|
||||
opacity: isLight || !activeColor || activeColor === DEFAULT_COLOR ? 0 : 1,
|
||||
background: 'rgba(0,0,0,0.79)',
|
||||
}}
|
||||
/> */}
|
||||
{COLOR_IMAGES.filter(({ url }) => url).map(({ color, url }) => (
|
||||
<img
|
||||
css={image}
|
||||
style={{ opacity: isLight && activeColor === color ? 1 : 0 }}
|
||||
key={color}
|
||||
src={url}
|
||||
alt=""
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default BackgroundImage;
|
||||
|
@ -1,27 +1,35 @@
|
||||
import React from 'react';
|
||||
import { useLocale as useDumiLocale } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import { useLocale as useDumiLocale } from 'dumi';
|
||||
import React from 'react';
|
||||
import useLocale from '../../hooks/useLocale';
|
||||
import Banner from './components/Banner';
|
||||
import Group from './components/Group';
|
||||
import { useSiteData } from './components/util';
|
||||
import Theme from './components/Theme';
|
||||
import BannerRecommends from './components/BannerRecommends';
|
||||
import ComponentsList from './components/ComponentsList';
|
||||
import DesignFramework from './components/DesignFramework';
|
||||
import Group from './components/Group';
|
||||
import Theme from './components/Theme';
|
||||
import { useSiteData } from './components/util';
|
||||
|
||||
const useStyle = () => ({
|
||||
image: css`
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -50px;
|
||||
height: 160px;
|
||||
`,
|
||||
});
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
assetsTitle: '组件丰富,选用自如',
|
||||
assetsDesc: '大量实用组件满足你的需求,灵活定制与拓展',
|
||||
|
||||
designTitle: '设计语言与研发框架',
|
||||
designDesc: '配套生态,让你快速搭建网站应用',
|
||||
},
|
||||
en: {
|
||||
assetsTitle: 'Rich components',
|
||||
assetsDesc: 'Practical components to meet your needs, flexible customization and expansion',
|
||||
|
||||
designTitle: 'Design and framework',
|
||||
designDesc: 'Supporting ecology, allowing you to quickly build website applications',
|
||||
},
|
||||
@ -31,7 +39,7 @@ const Homepage: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
const { id: localeId } = useDumiLocale();
|
||||
const localeStr = localeId === 'zh-CN' ? 'cn' : 'en';
|
||||
|
||||
const { image } = useStyle();
|
||||
const [siteData] = useSiteData();
|
||||
|
||||
return (
|
||||
@ -40,7 +48,6 @@ const Homepage: React.FC = () => {
|
||||
<Banner>
|
||||
<BannerRecommends extras={siteData?.extras?.[localeStr]} icons={siteData?.icons} />
|
||||
</Banner>
|
||||
|
||||
<div>
|
||||
<Theme />
|
||||
<Group
|
||||
@ -57,14 +64,11 @@ const Homepage: React.FC = () => {
|
||||
description={locale.designDesc}
|
||||
background="#F5F8FF"
|
||||
decoration={
|
||||
<>
|
||||
{/* Image Left Top */}
|
||||
<img
|
||||
style={{ position: 'absolute', left: 0, top: -50, height: 160 }}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
|
||||
alt=""
|
||||
/>
|
||||
</>
|
||||
<img
|
||||
css={image}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
|
||||
alt=""
|
||||
/>
|
||||
}
|
||||
>
|
||||
<DesignFramework />
|
||||
|
@ -1,9 +1,8 @@
|
||||
import type { AlertProps } from 'antd';
|
||||
import { Alert } from 'antd';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
const MdAlert: FC<AlertProps> = ({ style, ...props }) => (
|
||||
const MdAlert: React.FC<AlertProps> = ({ style, ...props }) => (
|
||||
<Alert {...props} style={{ margin: '24px 0', ...style }} />
|
||||
);
|
||||
|
||||
|
@ -13,6 +13,7 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { FormattedMessage } from 'dumi';
|
||||
import ClientOnly from '../../common/ClientOnly';
|
||||
import BrowserFrame from '../../common/BrowserFrame';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import CodePenIcon from '../../common/CodePenIcon';
|
||||
@ -195,7 +196,7 @@ const Demo: React.FC<DemoProps> = (props) => {
|
||||
const codepenPrefillConfig = {
|
||||
title: `${localizedTitle} - antd@${dependencies.antd}`,
|
||||
html,
|
||||
js: `${'const { createRoot } = ReactDOM;\n'}${sourceCodes?.jsx
|
||||
js: `const { createRoot } = ReactDOM;\n${sourceCodes?.jsx
|
||||
.replace(/import\s+(?:React,\s+)?{(\s+[^}]*\s+)}\s+from\s+'react'/, `const { $1 } = React;`)
|
||||
.replace(/import\s+{(\s+[^}]*\s+)}\s+from\s+'antd';/, 'const { $1 } = antd;')
|
||||
.replace(/import\s+{(\s+[^}]*\s+)}\s+from\s+'@ant-design\/icons';/, 'const { $1 } = icons;')
|
||||
@ -407,7 +408,9 @@ const Demo: React.FC<DemoProps> = (props) => {
|
||||
codepenIconRef.current?.submit();
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="data" value={JSON.stringify(codepenPrefillConfig)} />
|
||||
<ClientOnly>
|
||||
<input type="hidden" name="data" value={JSON.stringify(codepenPrefillConfig)} />
|
||||
</ClientOnly>
|
||||
<Tooltip title={<FormattedMessage id="app.demo.codepen" />}>
|
||||
<CodePenIcon className="code-box-codepen" />
|
||||
</Tooltip>
|
||||
|
18
.dumi/theme/common/ClientOnly.tsx
Normal file
18
.dumi/theme/common/ClientOnly.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import type { FC, ReactElement, ReactNode } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export type ClientOnlyProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const ClientOnly: FC<ClientOnlyProps> = ({ children }) => {
|
||||
const [clientReady, setClientReady] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
setClientReady(true);
|
||||
}, []);
|
||||
|
||||
return clientReady ? (children as ReactElement) : null;
|
||||
};
|
||||
|
||||
export default ClientOnly;
|
@ -5,10 +5,15 @@ const CommonHelmet = () => {
|
||||
const meta = useRouteMeta();
|
||||
|
||||
const [title, description] = useMemo(() => {
|
||||
const helmetTitle = `${meta.frontmatter.subtitle || ''} ${
|
||||
meta.frontmatter?.title
|
||||
} - Ant Design`;
|
||||
const helmetDescription = meta.frontmatter.description;
|
||||
let helmetTitle;
|
||||
if (!meta.frontmatter.subtitle && !meta.frontmatter.title) {
|
||||
helmetTitle = '404 Not Found - Ant Design';
|
||||
} else {
|
||||
helmetTitle = `${meta.frontmatter.subtitle || ''} ${
|
||||
meta.frontmatter?.title || ''
|
||||
} - Ant Design`;
|
||||
}
|
||||
const helmetDescription = meta.frontmatter.description || '';
|
||||
return [helmetTitle, helmetDescription];
|
||||
}, [meta]);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { Tabs } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import { Tabs } from 'antd';
|
||||
import throttle from 'lodash/throttle';
|
||||
import * as React from 'react';
|
||||
import scrollTo from '../../../../components/_util/scrollTo';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
@ -45,18 +45,21 @@ const useStyle = () => {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
`,
|
||||
span: css`
|
||||
text-transform: capitalize;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
const VIEW_BALANCE = 32;
|
||||
|
||||
export default () => {
|
||||
const AffixTabs: React.FC = () => {
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
const idsRef = React.useRef<string[]>([]);
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
const [fixedId, setFixedId] = React.useState<string | null>(null);
|
||||
|
||||
const styles = useStyle();
|
||||
const { affixTabs, affixTabsFixed, span } = useStyle();
|
||||
|
||||
function scrollToId(id: string) {
|
||||
const targetNode = document.getElementById(id);
|
||||
@ -113,17 +116,17 @@ export default () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div css={[styles.affixTabs, fixedId && styles.affixTabsFixed]} ref={containerRef}>
|
||||
<div css={[affixTabs, fixedId && affixTabsFixed]} ref={containerRef}>
|
||||
<Tabs
|
||||
activeKey={fixedId}
|
||||
onChange={(key) => {
|
||||
scrollToId(key);
|
||||
}}
|
||||
onChange={scrollToId}
|
||||
items={idsRef.current.map((id) => ({
|
||||
key: id,
|
||||
label: <span style={{ textTransform: 'capitalize' }}>{id.replace(/-/g, ' ')}</span>,
|
||||
label: <span css={span}>{id.replace(/-/g, ' ')}</span>,
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AffixTabs;
|
||||
|
@ -1,24 +1,23 @@
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import { useRouteMeta, FormattedMessage } from 'dumi';
|
||||
import { Layout, Typography, ConfigProvider } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import Footer from '../../slots/Footer';
|
||||
import AffixTabs from './AffixTabs';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import { ConfigProvider, Layout, Typography } from 'antd';
|
||||
import { FormattedMessage, useRouteMeta } from 'dumi';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import CommonHelmet from '../../common/CommonHelmet';
|
||||
import EditButton from '../../common/EditButton';
|
||||
import Footer from '../../slots/Footer';
|
||||
import AffixTabs from './AffixTabs';
|
||||
|
||||
export type ResourceLayoutProps = PropsWithChildren<{}>;
|
||||
|
||||
const resourcePadding = 40;
|
||||
const articleMaxWidth = 1208;
|
||||
const resourcePaddingXS = 24;
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
const { antCls } = token;
|
||||
|
||||
const resourcePadding = 40;
|
||||
const articleMaxWidth = 1208;
|
||||
const resourcePaddingXS = 24;
|
||||
|
||||
return {
|
||||
resourcePage: css`
|
||||
footer {
|
||||
@ -110,10 +109,9 @@ const useStyle = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const ResourceLayout: FC<ResourceLayoutProps> = ({ children }) => {
|
||||
const ResourceLayout: React.FC<ResourceLayoutProps> = ({ children }) => {
|
||||
const styles = useStyle();
|
||||
const meta = useRouteMeta();
|
||||
|
||||
return (
|
||||
<ConfigProvider theme={{ token: { colorBgLayout: '#fff' } }}>
|
||||
<Layout>
|
||||
|
@ -1,15 +1,26 @@
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import Sidebar from '../../slots/Sidebar';
|
||||
import Content from '../../slots/Content';
|
||||
import CommonHelmet from '../../common/CommonHelmet';
|
||||
import Content from '../../slots/Content';
|
||||
import Sidebar from '../../slots/Sidebar';
|
||||
|
||||
const SidebarLayout: FC<PropsWithChildren<{}>> = ({ children }) => (
|
||||
<main style={{ display: 'flex', marginTop: 40 }}>
|
||||
<CommonHelmet />
|
||||
<Sidebar />
|
||||
<Content>{children}</Content>
|
||||
</main>
|
||||
);
|
||||
const useStyle = () => ({
|
||||
main: css`
|
||||
display: flex;
|
||||
margin-top: 40px;
|
||||
`,
|
||||
});
|
||||
|
||||
const SidebarLayout: React.FC<PropsWithChildren<{}>> = ({ children }) => {
|
||||
const { main } = useStyle();
|
||||
return (
|
||||
<main css={main}>
|
||||
<CommonHelmet />
|
||||
<Sidebar />
|
||||
<Content>{children}</Content>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidebarLayout;
|
||||
|
@ -187,18 +187,20 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
</section>
|
||||
</Affix>
|
||||
<article css={styles.articleWrapper} className={classNames({ rtl: isRTL })}>
|
||||
<Typography.Title style={{ fontSize: 30 }}>
|
||||
{meta.frontmatter?.title}
|
||||
{meta.frontmatter.subtitle && (
|
||||
<span style={{ marginLeft: 12 }}>{meta.frontmatter.subtitle}</span>
|
||||
)}
|
||||
{!pathname.startsWith('/components/overview') && (
|
||||
<EditButton
|
||||
title={<FormattedMessage id="app.content.edit-page" />}
|
||||
filename={meta.frontmatter.filename}
|
||||
/>
|
||||
)}
|
||||
</Typography.Title>
|
||||
{meta.frontmatter?.title && meta.frontmatter.subtitle ? (
|
||||
<Typography.Title style={{ fontSize: 30 }}>
|
||||
{meta.frontmatter?.title}
|
||||
{meta.frontmatter.subtitle && (
|
||||
<span style={{ marginLeft: 12 }}>{meta.frontmatter.subtitle}</span>
|
||||
)}
|
||||
{!pathname.startsWith('/components/overview') && (
|
||||
<EditButton
|
||||
title={<FormattedMessage id="app.content.edit-page" />}
|
||||
filename={meta.frontmatter.filename}
|
||||
/>
|
||||
)}
|
||||
</Typography.Title>
|
||||
) : null}
|
||||
{/* 添加作者、时间等信息 */}
|
||||
{meta.frontmatter.date || meta.frontmatter.author ? (
|
||||
<Typography.Paragraph style={{ opacity: 0.65 }}>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { removeCSS, updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
import * as React from 'react';
|
||||
import { updateCSS, removeCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
|
||||
const whereCls = 'ant-where-checker';
|
||||
|
@ -1,7 +1,3 @@
|
||||
import React, { useContext } from 'react';
|
||||
import RcFooter from 'rc-footer';
|
||||
import { Link, FormattedMessage } from 'dumi';
|
||||
import type { FooterColumn } from 'rc-footer/lib/column';
|
||||
import {
|
||||
AntDesignOutlined,
|
||||
BgColorsOutlined,
|
||||
@ -10,20 +6,24 @@ import {
|
||||
HistoryOutlined,
|
||||
IssuesCloseOutlined,
|
||||
MediumOutlined,
|
||||
MessageOutlined,
|
||||
QuestionCircleOutlined,
|
||||
TwitterOutlined,
|
||||
UsergroupAddOutlined,
|
||||
ZhihuOutlined,
|
||||
MessageOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { css } from '@emotion/react';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { css } from '@emotion/react';
|
||||
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
|
||||
import useLocation from '../../../hooks/useLocation';
|
||||
import { FormattedMessage, Link } from 'dumi';
|
||||
import RcFooter from 'rc-footer';
|
||||
import type { FooterColumn } from 'rc-footer/lib/column';
|
||||
import React, { useContext } from 'react';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import useLocation from '../../../hooks/useLocation';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import AdditionalInfo from './AdditionalInfo';
|
||||
import SiteContext from '../SiteContext';
|
||||
import AdditionalInfo from './AdditionalInfo';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
@ -87,7 +87,7 @@ const useStyle = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const Footer = () => {
|
||||
const Footer: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const [locale, lang] = useLocale(locales);
|
||||
const style = useStyle();
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import * as utils from '../../utils';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
import * as React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import * as utils from '../../utils';
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
@ -31,8 +31,8 @@ const useStyle = () => {
|
||||
|
||||
img {
|
||||
height: 32px;
|
||||
margin-inline-end: 12px;
|
||||
vertical-align: middle;
|
||||
margin-inline-end: 12px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: ${mobileMaxWidth}px) {
|
||||
@ -40,6 +40,9 @@ const useStyle = () => {
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
`,
|
||||
title: css`
|
||||
line-height: 32px;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
@ -48,15 +51,14 @@ export interface LogoProps {
|
||||
location: any;
|
||||
}
|
||||
|
||||
const Logo = ({ isZhCN }: LogoProps) => {
|
||||
const Logo: React.FC<LogoProps> = ({ isZhCN }) => {
|
||||
const { search } = useLocation();
|
||||
const { logo } = useStyle();
|
||||
|
||||
const { logo, title } = useStyle();
|
||||
return (
|
||||
<h1>
|
||||
<Link to={utils.getLocalizedPathname('/', isZhCN, search)} css={logo}>
|
||||
<img alt="logo" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
||||
<span style={{ lineHeight: '32px' }}>Ant Design</span>
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" alt="logo" />
|
||||
<span css={title}>Ant Design</span>
|
||||
</Link>
|
||||
</h1>
|
||||
);
|
||||
|
@ -1,79 +1,88 @@
|
||||
import * as React from 'react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { css } from '@emotion/react';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import { FormattedMessage } from 'dumi';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import type { SharedProps } from './interface';
|
||||
|
||||
const smallStyle = { fontSize: 12, color: '#777', marginLeft: '0.3em' };
|
||||
const useStyle = (rtl?: boolean) => ({
|
||||
smallStyle: css`
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
margin-left: 0.3em;
|
||||
`,
|
||||
downOutlined: css`
|
||||
font-size: 9px;
|
||||
margin: ${rtl ? '-1px 2px 0 0' : '-1px 0 0 2px'};
|
||||
vertical-align: middle;
|
||||
`,
|
||||
});
|
||||
|
||||
export function getEcosystemGroup(): Exclude<MenuProps['items'], undefined> {
|
||||
return [
|
||||
{
|
||||
label: (
|
||||
<a href="https://charts.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.charts" />
|
||||
</a>
|
||||
),
|
||||
key: 'charts',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://pro.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.v4" />
|
||||
</a>
|
||||
),
|
||||
key: 'pro',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://procomponents.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.components" />
|
||||
</a>
|
||||
),
|
||||
key: 'procomponents',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://ng.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Angular
|
||||
<span style={smallStyle}>
|
||||
(
|
||||
<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
</a>
|
||||
),
|
||||
key: 'ng',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://antdv.com" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Vue
|
||||
<span style={smallStyle}>
|
||||
(
|
||||
<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
</a>
|
||||
),
|
||||
key: 'vue',
|
||||
},
|
||||
];
|
||||
}
|
||||
const Community: React.FC = () => {
|
||||
const { smallStyle } = useStyle();
|
||||
return (
|
||||
<span css={smallStyle}>
|
||||
(<FormattedMessage id="app.implementation.community" />)
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default (props: SharedProps) => {
|
||||
const downStyle = props.isRTL ? '-1px 2px 0 0' : '-1px 0 0 2px';
|
||||
export const getEcosystemGroup = (): MenuProps['items'] => [
|
||||
{
|
||||
label: (
|
||||
<a href="https://charts.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.charts" />
|
||||
</a>
|
||||
),
|
||||
key: 'charts',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://pro.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.v4" />
|
||||
</a>
|
||||
),
|
||||
key: 'pro',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://procomponents.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
<FormattedMessage id="app.header.menu.pro.components" />
|
||||
</a>
|
||||
),
|
||||
key: 'procomponents',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://ng.ant.design" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Angular
|
||||
<Community />
|
||||
</a>
|
||||
),
|
||||
key: 'ng',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="http://antdv.com" target="_blank" rel="noopener noreferrer">
|
||||
Ant Design of Vue
|
||||
<Community />
|
||||
</a>
|
||||
),
|
||||
key: 'vue',
|
||||
},
|
||||
];
|
||||
|
||||
const More: React.FC<SharedProps> = ({ isRTL }) => {
|
||||
const { downOutlined } = useStyle(isRTL);
|
||||
return (
|
||||
<Dropdown menu={{ items: getEcosystemGroup() }} placement="bottomRight">
|
||||
<Button size="small">
|
||||
<FormattedMessage id="app.header.menu.more" />
|
||||
<DownOutlined
|
||||
style={{
|
||||
fontSize: '9px',
|
||||
margin: downStyle,
|
||||
verticalAlign: 'middle',
|
||||
}}
|
||||
/>
|
||||
<DownOutlined css={downOutlined} />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default More;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import { Tooltip } from 'antd';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export interface LangBtnProps {
|
||||
@ -17,12 +17,21 @@ const BASE_SIZE = '1.2em';
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
const { controlHeight, motionDurationMid } = token;
|
||||
|
||||
const {
|
||||
colorText,
|
||||
colorBorder,
|
||||
colorBgContainer,
|
||||
colorBgTextHover,
|
||||
borderRadius,
|
||||
controlHeight,
|
||||
motionDurationMid,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
btn: css`
|
||||
color: ${token.colorText};
|
||||
border-color: ${token.colorBorder};
|
||||
color: ${colorText};
|
||||
border-color: ${colorBorder};
|
||||
padding: 0 !important;
|
||||
width: ${controlHeight}px;
|
||||
height: ${controlHeight}px;
|
||||
@ -31,100 +40,67 @@ const useStyle = () => {
|
||||
justify-content: center;
|
||||
border: none;
|
||||
background: transparent;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
border-radius: ${borderRadius}px;
|
||||
transition: all ${motionDurationMid};
|
||||
cursor: pointer;
|
||||
|
||||
.btn-inner {
|
||||
transition: all ${motionDurationMid};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorBgTextHover};
|
||||
background: ${colorBgTextHover};
|
||||
}
|
||||
|
||||
img {
|
||||
width: ${BASE_SIZE};
|
||||
height: ${BASE_SIZE};
|
||||
}
|
||||
|
||||
.anticon {
|
||||
font-size: ${BASE_SIZE};
|
||||
}
|
||||
`,
|
||||
innerDiv: css`
|
||||
position: relative;
|
||||
width: ${BASE_SIZE};
|
||||
height: ${BASE_SIZE};
|
||||
`,
|
||||
labelStyle: css`
|
||||
position: absolute;
|
||||
font-size: ${BASE_SIZE};
|
||||
line-height: 1;
|
||||
border: 1px solid ${colorText};
|
||||
color: ${colorText};
|
||||
`,
|
||||
label1Style: css`
|
||||
left: -5%;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background-color: ${colorText};
|
||||
color: ${colorBgContainer};
|
||||
transform: scale(0.7);
|
||||
transform-origin: 0 0;
|
||||
`,
|
||||
label2Style: css`
|
||||
right: -5%;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
transform: scale(0.5);
|
||||
transform-origin: 100% 100%;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
export default function LangBtn({
|
||||
label1,
|
||||
label2,
|
||||
tooltip1,
|
||||
tooltip2,
|
||||
value,
|
||||
pure,
|
||||
onClick,
|
||||
}: LangBtnProps) {
|
||||
const { token } = useSiteToken();
|
||||
const style = useStyle();
|
||||
const LangBtn: React.FC<LangBtnProps> = (props) => {
|
||||
const { label1, label2, tooltip1, tooltip2, value, pure, onClick } = props;
|
||||
|
||||
let label1Style: React.CSSProperties;
|
||||
let label2Style: React.CSSProperties;
|
||||
const { btn, innerDiv, labelStyle, label1Style, label2Style } = useStyle();
|
||||
|
||||
const iconStyle: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
fontSize: BASE_SIZE,
|
||||
lineHeight: 1,
|
||||
border: `1px solid ${token.colorText}`,
|
||||
color: token.colorText,
|
||||
};
|
||||
|
||||
const fontStyle: React.CSSProperties = {
|
||||
left: '-5%',
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
background: token.colorText,
|
||||
color: token.colorBgContainer,
|
||||
transformOrigin: '0 0',
|
||||
transform: `scale(0.7)`,
|
||||
};
|
||||
const backStyle: React.CSSProperties = {
|
||||
right: '-5%',
|
||||
bottom: 0,
|
||||
zIndex: 0,
|
||||
transformOrigin: '100% 100%',
|
||||
transform: `scale(0.5)`,
|
||||
};
|
||||
|
||||
if (value === 1) {
|
||||
label1Style = fontStyle;
|
||||
label2Style = backStyle;
|
||||
} else {
|
||||
label1Style = backStyle;
|
||||
label2Style = fontStyle;
|
||||
}
|
||||
|
||||
let node = (
|
||||
<button onClick={onClick} css={[style.btn]} key="lang-button">
|
||||
const node = (
|
||||
<button onClick={onClick} css={btn} key="lang-button">
|
||||
<div className="btn-inner">
|
||||
{pure && (value === 1 ? label1 : label2)}
|
||||
{!pure && (
|
||||
<div style={{ position: 'relative', width: BASE_SIZE, height: BASE_SIZE }}>
|
||||
<span
|
||||
style={{
|
||||
...iconStyle,
|
||||
...label1Style,
|
||||
}}
|
||||
>
|
||||
{label1}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
...iconStyle,
|
||||
...label2Style,
|
||||
}}
|
||||
>
|
||||
{label2}
|
||||
</span>
|
||||
<div css={innerDiv}>
|
||||
<span css={[labelStyle, value === 1 ? label1Style : label2Style]}>{label1}</span>
|
||||
<span css={[labelStyle, value === 1 ? label2Style : label1Style]}>{label2}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -132,8 +108,10 @@ export default function LangBtn({
|
||||
);
|
||||
|
||||
if (tooltip1 || tooltip2) {
|
||||
node = <Tooltip title={value === 1 ? tooltip1 : tooltip2}>{node}</Tooltip>;
|
||||
return <Tooltip title={value === 1 ? tooltip1 : tooltip2}>{node}</Tooltip>;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
export default LangBtn;
|
||||
|
@ -1,20 +1,21 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
import classNames from 'classnames';
|
||||
import { Col, Modal, Popover, Row, Select } from 'antd';
|
||||
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
|
||||
import { ClassNames, css } from '@emotion/react';
|
||||
import { Col, Modal, Popover, Row, Select } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useLocation } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import packageJson from '../../../../package.json';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import * as utils from '../../utils';
|
||||
import { getThemeConfig, ping } from '../../utils';
|
||||
import packageJson from '../../../../package.json';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import type { SharedProps } from './interface';
|
||||
import Logo from './Logo';
|
||||
import More from './More';
|
||||
import Navigation from './Navigation';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SwitchBtn from './SwitchBtn';
|
||||
|
||||
const RESPONSIVE_XS = 1120;
|
||||
@ -262,7 +263,7 @@ const Header: React.FC = () => {
|
||||
'home-header': isHome,
|
||||
});
|
||||
|
||||
const sharedProps = {
|
||||
const sharedProps: SharedProps = {
|
||||
isZhCN,
|
||||
isRTL,
|
||||
isClient,
|
||||
|
@ -15,6 +15,25 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.1.7
|
||||
|
||||
`2023-1-31`
|
||||
|
||||
- Input
|
||||
- 🐞 Fix Input that unexpected cancel button is shown when `type="search"`. [#40457](https://github.com/ant-design/ant-design/pull/40457) [@MadCcc](https://github.com/MadCcc)
|
||||
- 🐞 Fix Input suffix color does not update bug when component status changed. [#40344](https://github.com/ant-design/ant-design/pull/40344) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- 🐞 Fix Switch text layout problem in Safari and Chrome <= 84 with compatible mode. [#40453](https://github.com/ant-design/ant-design/pull/40453) [@Ifeinstein](https://github.com/Ifeinstein)
|
||||
- 🐞 Fix Progress that throw error when `percent` is `null`. [#40378](https://github.com/ant-design/ant-design/pull/40378) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 Fix List title and avatar be rendered in the wrong position. [#40395](https://github.com/ant-design/ant-design/pull/40395) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 Fix Dropdown submenu wrong position. [#40349](https://github.com/ant-design/ant-design/pull/40349)
|
||||
- 🐞 Fix Badge throw `findDOMNode` warning in StrictMode when `dot` switch. [#40347](https://github.com/ant-design/ant-design/pull/40347)
|
||||
- 🐞 Fix Message wrong icon color problem. [#40471](https://github.com/ant-design/ant-design/pull/40471) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 💄 Adjust Empty component default style in dark theme. [#40447](https://github.com/ant-design/ant-design/pull/40447)
|
||||
- RTL
|
||||
- 💄 Fix Table scroll shadow in RTL mode. [#40441](https://github.com/ant-design/ant-design/pull/40441) [@ds1371dani](https://github.com/ds1371dani)
|
||||
- TypeScript
|
||||
- 🤖 Export ConfigProvider's ThemeConfig type. [#40370](https://github.com/ant-design/ant-design/pull/40370) [@Kamahl19](https://github.com/Kamahl19)
|
||||
|
||||
## 5.1.6
|
||||
|
||||
`2023-1-20`
|
||||
|
@ -15,6 +15,25 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.1.7
|
||||
|
||||
`2023-1-31`
|
||||
|
||||
- Input
|
||||
- 🐞 修复 Input 组件 `type="search"` 时未隐藏浏览器原生取消按钮的问题。[#40457](https://github.com/ant-design/ant-design/pull/40457) [@MadCcc](https://github.com/MadCcc)
|
||||
- 🐞 修复 Input 的 suffix 颜色不随组件状态改变的问题。[#40344](https://github.com/ant-design/ant-design/pull/40344) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- 🐞 修复 Switch 在 Safari 和 Chrome <= 84 兼容模式下文本的显示问题。[#40453](https://github.com/ant-design/ant-design/pull/40453) [@Ifeinstein](https://github.com/Ifeinstein)
|
||||
- 🐞 修复 Progress 的 `percent` 属性设置为 `null` 时报错的问题。[#40378](https://github.com/ant-design/ant-design/pull/40378) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 修复 List 中 title 和 avatar 渲染错位的问题。[#40395](https://github.com/ant-design/ant-design/pull/40395) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 修复 Dropdown 子菜单位置不正确的问题。[#40349](https://github.com/ant-design/ant-design/pull/40349)
|
||||
- 🐞 修复 Badge 在 StrictMode 下切换 `dot` 时会报 `findDOMNode` 警告的问题。[#40347](https://github.com/ant-design/ant-design/pull/40347)
|
||||
- 🐞 修复 Message 图标颜色错误的问题。[#40471](https://github.com/ant-design/ant-design/pull/40471) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 💄 优化 Empty 在暗色主题下默认的颜色。[#40447](https://github.com/ant-design/ant-design/pull/40447)
|
||||
- RTL
|
||||
- 💄 修复 Table 在 RTL 模式下的滚动阴影。[#40441](https://github.com/ant-design/ant-design/pull/40441) [@ds1371dani](https://github.com/ds1371dani)
|
||||
- TypeScript
|
||||
- 🤖 导出 ConfigProvider 组件的 ThemeConfig 类型。[#40370](https://github.com/ant-design/ant-design/pull/40370) [@Kamahl19](https://github.com/Kamahl19)
|
||||
|
||||
## 5.1.6
|
||||
|
||||
`2023-1-20`
|
||||
|
@ -1,7 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import * as React from 'react';
|
||||
import React, { createRef, forwardRef, useContext } from 'react';
|
||||
import type { ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
|
||||
@ -50,7 +50,6 @@ export interface AffixState {
|
||||
placeholderStyle?: React.CSSProperties;
|
||||
status: AffixStatus;
|
||||
lastAffix: boolean;
|
||||
|
||||
prevTarget: Window | HTMLElement | null;
|
||||
}
|
||||
|
||||
@ -63,11 +62,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
prevTarget: null,
|
||||
};
|
||||
|
||||
placeholderNode: HTMLDivElement;
|
||||
private placeholderNodeRef = createRef<HTMLDivElement>();
|
||||
|
||||
fixedNode: HTMLDivElement;
|
||||
private fixedNodeRef = createRef<HTMLDivElement>();
|
||||
|
||||
private timeout: NodeJS.Timeout | null;
|
||||
private timer: NodeJS.Timeout | null;
|
||||
|
||||
context: ConfigConsumerProps;
|
||||
|
||||
@ -88,7 +87,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
if (targetFunc) {
|
||||
// [Legacy] Wait for parent component ref has its value.
|
||||
// We should use target as directly element instead of function which makes element check hard.
|
||||
this.timeout = setTimeout(() => {
|
||||
this.timer = setTimeout(() => {
|
||||
addObserveTarget(targetFunc(), this);
|
||||
// Mock Event object.
|
||||
this.updatePosition();
|
||||
@ -119,14 +118,13 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
) {
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
this.measure();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
removeObserveTarget(this);
|
||||
this.updatePosition.cancel();
|
||||
@ -141,20 +139,17 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
|
||||
getOffsetBottom = () => this.props.offsetBottom;
|
||||
|
||||
savePlaceholderNode = (node: HTMLDivElement) => {
|
||||
this.placeholderNode = node;
|
||||
};
|
||||
|
||||
saveFixedNode = (node: HTMLDivElement) => {
|
||||
this.fixedNode = node;
|
||||
};
|
||||
|
||||
// =================== Measure ===================
|
||||
measure = () => {
|
||||
const { status, lastAffix } = this.state;
|
||||
const { onChange } = this.props;
|
||||
const targetFunc = this.getTargetFunc();
|
||||
if (status !== AffixStatus.Prepare || !this.fixedNode || !this.placeholderNode || !targetFunc) {
|
||||
if (
|
||||
status !== AffixStatus.Prepare ||
|
||||
!this.fixedNodeRef.current ||
|
||||
!this.placeholderNodeRef.current ||
|
||||
!targetFunc
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -170,7 +165,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
status: AffixStatus.None,
|
||||
};
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const placeholderReact = getTargetRect(this.placeholderNode);
|
||||
const placeholderReact = getTargetRect(this.placeholderNodeRef.current);
|
||||
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
|
||||
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
|
||||
|
||||
@ -244,9 +239,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
const offsetBottom = this.getOffsetBottom();
|
||||
|
||||
const targetNode = targetFunc();
|
||||
if (targetNode && this.placeholderNode) {
|
||||
if (targetNode && this.placeholderNodeRef.current) {
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const placeholderReact = getTargetRect(this.placeholderNode);
|
||||
const placeholderReact = getTargetRect(this.placeholderNodeRef.current);
|
||||
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
|
||||
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
|
||||
|
||||
@ -287,9 +282,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
|
||||
return (
|
||||
<ResizeObserver onResize={this.updatePosition}>
|
||||
<div {...props} ref={this.savePlaceholderNode}>
|
||||
<div {...props} ref={this.placeholderNodeRef}>
|
||||
{affixStyle && <div style={placeholderStyle} aria-hidden="true" />}
|
||||
<div className={className} ref={this.saveFixedNode} style={affixStyle}>
|
||||
<div className={className} ref={this.fixedNodeRef} style={affixStyle}>
|
||||
<ResizeObserver onResize={this.updatePosition}>{children}</ResizeObserver>
|
||||
</div>
|
||||
</div>
|
||||
@ -300,9 +295,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
// just use in test
|
||||
export type InternalAffixClass = Affix;
|
||||
|
||||
const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => {
|
||||
const AffixFC = forwardRef<Affix, AffixProps>((props, ref) => {
|
||||
const { prefixCls: customizePrefixCls, rootClassName } = props;
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
const { getPrefixCls } = useContext<ConfigConsumerProps>(ConfigContext);
|
||||
const affixPrefixCls = getPrefixCls('affix', customizePrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(affixPrefixCls);
|
||||
|
@ -276,20 +276,13 @@ describe('Button', () => {
|
||||
});
|
||||
|
||||
it('skip check 2 words when ConfigProvider disable this', () => {
|
||||
let buttonInstance: any;
|
||||
const buttonInstance = React.createRef<HTMLElement>();
|
||||
render(
|
||||
<ConfigProvider autoInsertSpaceInButton={false}>
|
||||
<Button
|
||||
ref={(node) => {
|
||||
buttonInstance = node;
|
||||
}}
|
||||
>
|
||||
test
|
||||
</Button>
|
||||
<Button ref={buttonInstance}>test</Button>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
Object.defineProperty(buttonInstance, 'textContent', {
|
||||
Object.defineProperty(buttonInstance.current, 'textContent', {
|
||||
get() {
|
||||
throw new Error('Should not called!!!');
|
||||
},
|
||||
|
@ -61,7 +61,7 @@ Different button styles can be generated by setting Button properties. The recom
|
||||
| htmlType | Set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
|
||||
| icon | Set the icon component of button | ReactNode | - | |
|
||||
| loading | Set the loading status of button | boolean \| { delay: number } | false | |
|
||||
| shape | Can be set button shape | `default` \| `circle` \| `round` | 'default' | |
|
||||
| shape | Can be set button shape | `default` \| `circle` \| `round` | `default` | |
|
||||
| size | Set the size of button | `large` \| `middle` \| `small` | `middle` | |
|
||||
| target | Same as target attribute of a, works when href is specified | string | - | |
|
||||
| type | Can be set to `primary` `ghost` `dashed` `link` `text` `default` | string | `default` | |
|
||||
|
@ -66,7 +66,7 @@ group:
|
||||
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
|
||||
| icon | 设置按钮的图标组件 | ReactNode | - | |
|
||||
| loading | 设置按钮载入状态 | boolean \| { delay: number } | false | |
|
||||
| shape | 设置按钮形状 | `default` \| `circle` \| `round` | 'default' | |
|
||||
| shape | 设置按钮形状 | `default` \| `circle` \| `round` | `default` | |
|
||||
| size | 设置按钮大小 | `large` \| `middle` \| `small` | `middle` | |
|
||||
| target | 相当于 a 链接的 target 属性,href 存在时生效 | string | - | |
|
||||
| type | 设置按钮类型 | `primary` \| `ghost` \| `dashed` \| `link` \| `text` \| `default` | `default` | |
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Dayjs } from 'dayjs';
|
||||
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
|
||||
import generateCalendar, { type CalendarProps } from './generateCalendar';
|
||||
import type { CalendarProps } from './generateCalendar';
|
||||
import generateCalendar from './generateCalendar';
|
||||
|
||||
const Calendar = generateCalendar<Dayjs>(dayjsGenerateConfig);
|
||||
|
||||
|
@ -214,17 +214,9 @@ describe('CheckboxGroup', () => {
|
||||
});
|
||||
|
||||
it('should get div ref', () => {
|
||||
const refCalls: HTMLDivElement[] = [];
|
||||
render(
|
||||
<Checkbox.Group
|
||||
options={['Apple', 'Pear', 'Orange']}
|
||||
ref={(node) => {
|
||||
refCalls.push(node!);
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
const [mountCall] = refCalls;
|
||||
expect(mountCall.nodeName).toBe('DIV');
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
render(<Checkbox.Group options={['Apple', 'Pear', 'Orange']} ref={ref} />);
|
||||
expect(ref.current?.nodeName).toBe('DIV');
|
||||
});
|
||||
|
||||
it('should support number option', () => {
|
||||
|
@ -1,17 +1,19 @@
|
||||
import React from 'react';
|
||||
import { Checkbox } from 'antd';
|
||||
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
|
||||
import React from 'react';
|
||||
|
||||
const onChange = (checkedValues: CheckboxValueType[]) => {
|
||||
console.log('checked = ', checkedValues);
|
||||
};
|
||||
|
||||
const plainOptions = ['Apple', 'Pear', 'Orange'];
|
||||
|
||||
const options = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
{ label: 'Orange', value: 'Orange' },
|
||||
];
|
||||
|
||||
const optionsWithDisabled = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
|
@ -28,8 +28,6 @@ Checkbox component.
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
#### Checkbox
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
@ -39,7 +37,7 @@ Checkbox component.
|
||||
| defaultChecked | Specifies the initial state: whether or not the checkbox is selected | boolean | false | |
|
||||
| disabled | If disable checkbox | boolean | false | |
|
||||
| indeterminate | The indeterminate checked state of checkbox | boolean | false | |
|
||||
| onChange | The callback function that is triggered when the state changes | function(e: CheckboxChangeEvent) | - | |
|
||||
| onChange | The callback function that is triggered when the state changes | (e: CheckboxChangeEvent) => void | - | |
|
||||
|
||||
#### Checkbox Group
|
||||
|
||||
@ -50,7 +48,17 @@ Checkbox component.
|
||||
| name | The `name` property of all `input[type="checkbox"]` children | string | - | |
|
||||
| options | Specifies options | string\[] \| number\[] \| Option\[] | \[] | |
|
||||
| value | Used for setting the currently selected value | (string \| number)\[] | \[] | |
|
||||
| onChange | The callback function that is triggered when the state changes | function(checkedValue) | - | |
|
||||
| onChange | The callback function that is triggered when the state changes | (checkedValue: CheckboxValueType[]) => void | - | |
|
||||
|
||||
##### Option
|
||||
|
||||
```typescript
|
||||
interface Option {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
|
@ -29,8 +29,6 @@ demo:
|
||||
|
||||
## API
|
||||
|
||||
### 属性
|
||||
|
||||
#### Checkbox
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
@ -40,7 +38,7 @@ demo:
|
||||
| defaultChecked | 初始是否选中 | boolean | false | |
|
||||
| disabled | 失效状态 | boolean | false | |
|
||||
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | |
|
||||
| onChange | 变化时的回调函数 | function(e: CheckboxChangeEvent) | - | |
|
||||
| onChange | 变化时的回调函数 | (e: CheckboxChangeEvent) => void | - | |
|
||||
|
||||
#### Checkbox Group
|
||||
|
||||
@ -51,7 +49,7 @@ demo:
|
||||
| name | CheckboxGroup 下所有 `input[type="checkbox"]` 的 `name` 属性 | string | - | |
|
||||
| options | 指定可选项 | string\[] \| number\[] \| Option\[] | \[] | |
|
||||
| value | 指定选中的选项 | (string \| number)\[] | \[] | |
|
||||
| onChange | 变化时的回调函数 | function(checkedValue) | - | |
|
||||
| onChange | 变化时的回调函数 | (checkedValue: CheckboxValueType[]) => void | - | |
|
||||
|
||||
##### Option
|
||||
|
||||
|
@ -54,11 +54,7 @@ interface PanelProps {
|
||||
collapsible?: CollapsibleType;
|
||||
}
|
||||
|
||||
type CompoundedComponent = React.FC<CollapseProps> & {
|
||||
Panel: typeof CollapsePanel;
|
||||
};
|
||||
|
||||
const Collapse: CompoundedComponent = (props) => {
|
||||
const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) => {
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const size = React.useContext(SizeContext);
|
||||
|
||||
@ -144,6 +140,7 @@ const Collapse: CompoundedComponent = (props) => {
|
||||
|
||||
return wrapSSR(
|
||||
<RcCollapse
|
||||
ref={ref}
|
||||
openMotion={openMotion}
|
||||
{...omit(props, ['rootClassName'])}
|
||||
expandIcon={renderExpandIcon}
|
||||
@ -153,12 +150,10 @@ const Collapse: CompoundedComponent = (props) => {
|
||||
{getItems()}
|
||||
</RcCollapse>,
|
||||
);
|
||||
};
|
||||
|
||||
Collapse.Panel = CollapsePanel;
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Collapse.displayName = 'Collapse';
|
||||
}
|
||||
|
||||
export default Collapse;
|
||||
export default Object.assign(Collapse, { Panel: CollapsePanel });
|
||||
|
@ -21,8 +21,7 @@ export interface CollapsePanelProps {
|
||||
collapsible?: CollapsibleType;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const CollapsePanel: React.FC<CollapsePanelProps> = (props) => {
|
||||
const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((props, ref) => {
|
||||
warning(
|
||||
!('disabled' in props),
|
||||
'Collapse.Panel',
|
||||
@ -38,7 +37,14 @@ const CollapsePanel: React.FC<CollapsePanelProps> = (props) => {
|
||||
},
|
||||
className,
|
||||
);
|
||||
return <RcCollapse.Panel {...props} prefixCls={prefixCls} className={collapsePanelClassName} />;
|
||||
};
|
||||
return (
|
||||
<RcCollapse.Panel
|
||||
ref={ref}
|
||||
{...props}
|
||||
prefixCls={prefixCls}
|
||||
className={collapsePanelClassName}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default CollapsePanel;
|
||||
|
@ -160,6 +160,30 @@ describe('Collapse', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('ref should work', () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
const panelRef1 = React.createRef<HTMLDivElement>();
|
||||
const panelRef2 = React.createRef<HTMLDivElement>();
|
||||
|
||||
const { container } = render(
|
||||
<Collapse ref={ref}>
|
||||
<Collapse.Panel ref={panelRef1} header="panel header 1" key="1">
|
||||
1
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel ref={panelRef2} header="panel header 2" key="2">
|
||||
2
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel header="panel header 3" key="3">
|
||||
2
|
||||
</Collapse.Panel>
|
||||
</Collapse>,
|
||||
);
|
||||
|
||||
expect(ref.current).toBe(container.firstChild);
|
||||
expect(panelRef1.current).toBe(document.querySelectorAll('.ant-collapse-item')[0]);
|
||||
expect(panelRef2.current).toBe(document.querySelectorAll('.ant-collapse-item')[1]);
|
||||
});
|
||||
|
||||
describe('expandIconPosition', () => {
|
||||
['left', 'right'].forEach((pos) => {
|
||||
it(`warning for legacy '${pos}'`, () => {
|
||||
|
@ -26633,12 +26633,13 @@ exports[`ConfigProvider components Table configProvider 1`] = `
|
||||
class="config-table-column-sorter config-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="config-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up config-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -26657,7 +26658,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down config-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -26939,12 +26940,13 @@ exports[`ConfigProvider components Table configProvider componentDisabled 1`] =
|
||||
class="config-table-column-sorter config-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="config-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up config-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -26963,7 +26965,7 @@ exports[`ConfigProvider components Table configProvider componentDisabled 1`] =
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down config-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27247,12 +27249,13 @@ exports[`ConfigProvider components Table configProvider componentSize large 1`]
|
||||
class="config-table-column-sorter config-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="config-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up config-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27271,7 +27274,7 @@ exports[`ConfigProvider components Table configProvider componentSize large 1`]
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down config-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27553,12 +27556,13 @@ exports[`ConfigProvider components Table configProvider componentSize middle 1`]
|
||||
class="config-table-column-sorter config-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="config-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up config-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27577,7 +27581,7 @@ exports[`ConfigProvider components Table configProvider componentSize middle 1`]
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down config-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27859,12 +27863,13 @@ exports[`ConfigProvider components Table configProvider virtual and dropdownMatc
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -27883,7 +27888,7 @@ exports[`ConfigProvider components Table configProvider virtual and dropdownMatc
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -28165,12 +28170,13 @@ exports[`ConfigProvider components Table normal 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -28189,7 +28195,7 @@ exports[`ConfigProvider components Table normal 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -28471,12 +28477,13 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
|
||||
class="prefix-Table-column-sorter prefix-Table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="prefix-Table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up prefix-Table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -28495,7 +28502,7 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down prefix-Table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
@ -919,7 +919,6 @@ const genPickerStyle: GenerateStyle<PickerToken> = (token) => {
|
||||
const {
|
||||
componentCls,
|
||||
antCls,
|
||||
boxShadowPopoverArrow,
|
||||
controlHeight,
|
||||
fontSize,
|
||||
inputPaddingHorizontal,
|
||||
@ -960,6 +959,7 @@ const genPickerStyle: GenerateStyle<PickerToken> = (token) => {
|
||||
controlItemBgHover,
|
||||
presetsWidth,
|
||||
presetsMaxWidth,
|
||||
boxShadowPopoverArrow,
|
||||
} = token;
|
||||
|
||||
return [
|
||||
@ -1018,6 +1018,7 @@ const genPickerStyle: GenerateStyle<PickerToken> = (token) => {
|
||||
padding: 0,
|
||||
background: 'transparent',
|
||||
border: 0,
|
||||
borderRadius: 0,
|
||||
|
||||
'&:focus': {
|
||||
boxShadow: 'none',
|
||||
|
@ -334,15 +334,12 @@ export default genComponentStyleHook(
|
||||
lineHeight,
|
||||
paddingXXS,
|
||||
componentCls,
|
||||
borderRadiusOuter,
|
||||
borderRadiusLG,
|
||||
} = token;
|
||||
|
||||
const dropdownPaddingVertical = (controlHeight - fontSize * lineHeight) / 2;
|
||||
const { dropdownArrowOffset } = getArrowOffset({
|
||||
sizePopupArrow,
|
||||
contentRadius: borderRadiusLG,
|
||||
borderRadiusOuter,
|
||||
});
|
||||
|
||||
const dropdownToken = mergeToken<DropdownToken>(token, {
|
||||
|
@ -1,3 +1,4 @@
|
||||
export type { Breakpoint } from './_util/responsiveObserver';
|
||||
export { default as Affix } from './affix';
|
||||
export type { AffixProps } from './affix';
|
||||
export { default as Alert } from './alert';
|
||||
@ -33,6 +34,7 @@ export type { ColProps } from './col';
|
||||
export { default as Collapse } from './collapse';
|
||||
export type { CollapsePanelProps, CollapseProps } from './collapse';
|
||||
export { default as ConfigProvider } from './config-provider';
|
||||
export type { ThemeConfig } from './config-provider';
|
||||
export { default as DatePicker } from './date-picker';
|
||||
export type { DatePickerProps } from './date-picker';
|
||||
export { default as Descriptions } from './descriptions';
|
||||
@ -127,6 +129,7 @@ export type { TabPaneProps, TabsProps } from './tabs';
|
||||
export { default as Tag } from './tag';
|
||||
export type { TagProps, TagType } from './tag';
|
||||
export { default as theme } from './theme';
|
||||
export type { GlobalToken } from './theme';
|
||||
export { default as TimePicker } from './time-picker';
|
||||
export type { TimePickerProps, TimeRangePickerProps } from './time-picker';
|
||||
export { default as Timeline } from './timeline';
|
||||
|
@ -139,22 +139,37 @@ exports[`renders ./components/mentions/demo/form.tsx extend context correctly 1`
|
||||
<div
|
||||
class="ant-form-item-control-input-content"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="submit"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
style="flex-wrap:wrap;margin-bottom:-8px"
|
||||
>
|
||||
<span>
|
||||
Submit
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Reset
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px;padding-bottom:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="submit"
|
||||
>
|
||||
<span>
|
||||
Submit
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="padding-bottom:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Reset
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,22 +139,37 @@ exports[`renders ./components/mentions/demo/form.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-form-item-control-input-content"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="submit"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
style="flex-wrap:wrap;margin-bottom:-8px"
|
||||
>
|
||||
<span>
|
||||
Submit
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Reset
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px;padding-bottom:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="submit"
|
||||
>
|
||||
<span>
|
||||
Submit
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="padding-bottom:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Reset
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
## en-US
|
||||
|
||||
async
|
||||
async.
|
||||
|
||||
<style>
|
||||
.antd-demo-dynamic-option img {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Button, Form, Mentions, Space } from 'antd';
|
||||
import React from 'react';
|
||||
import { Button, Form, Mentions } from 'antd';
|
||||
|
||||
const { getMentions } = Mentions;
|
||||
|
||||
@ -81,13 +81,14 @@ const App: React.FC = () => {
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item wrapperCol={{ span: 14, offset: 6 }}>
|
||||
<Button htmlType="submit" type="primary">
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
<Button htmlType="button" onClick={onReset}>
|
||||
Reset
|
||||
</Button>
|
||||
<Space wrap>
|
||||
<Button htmlType="submit" type="primary">
|
||||
Submit
|
||||
</Button>
|
||||
<Button htmlType="button" onClick={onReset}>
|
||||
Reset
|
||||
</Button>
|
||||
</Space>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
@ -13,6 +13,23 @@ Mention component.
|
||||
|
||||
When you need to mention someone or something.
|
||||
|
||||
### Usage upgrade after 5.1.0
|
||||
|
||||
<Alert message="After version 5.1.0, we provide a simpler usage <Mentions options={[...]} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 6.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=5.1.0, recommended ✅
|
||||
const options = [{ value: 'sample', label: 'sample' }];
|
||||
return <Mentions options={options} />;
|
||||
|
||||
// works when <5.1.0, deprecated when >=5.1.0 🙅🏻♀️
|
||||
return (
|
||||
<Mentions onChange={onChange}>
|
||||
<Mentions.Option value="sample">Sample</Mentions.Option>
|
||||
</Mentions>
|
||||
);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
@ -26,24 +43,6 @@ When you need to mention someone or something.
|
||||
<code src="./demo/status.tsx">Status</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
|
||||
### Usage upgrade after 5.1.0
|
||||
|
||||
```__react
|
||||
import Alert from '../alert';
|
||||
ReactDOM.render(<Alert message="After version 5.1.0, we provide a simpler usage <Mentions options={[...]} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 6.0." />, mountNode);
|
||||
```
|
||||
|
||||
```jsx
|
||||
// works when >=5.1.0, recommended ✅
|
||||
const options = [{ value: 'sample', label: 'sample' }];
|
||||
return <Mentions options={options} />;
|
||||
|
||||
// works when <5.1.0, deprecated when >=5.1.0 🙅🏻♀️
|
||||
<Mentions onChange={onChange}>
|
||||
<Mentions.Option value="sample">Sample</Mentions.Option>
|
||||
</Mentions>;
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Mention
|
||||
|
@ -14,6 +14,23 @@ demo:
|
||||
|
||||
用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
|
||||
|
||||
### 5.1.0 用法升级
|
||||
|
||||
<Alert message="在 5.1.0 版本后,我们提供了 <Mentions options={[...]} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 5.x 继续使用,但会在控制台看到警告,并会在 6.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=5.1.0 可用,推荐的写法 ✅
|
||||
const options = [{ value: 'sample', label: 'sample' }];
|
||||
return <Mentions options={options} />;
|
||||
|
||||
// <5.1.0 可用,>=5.1.0 时不推荐 🙅🏻♀️
|
||||
return (
|
||||
<Mentions onChange={onChange}>
|
||||
<Mentions.Option value="sample">Sample</Mentions.Option>
|
||||
</Mentions>
|
||||
);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
@ -27,24 +44,6 @@ demo:
|
||||
<code src="./demo/status.tsx">自定义状态</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
|
||||
### 5.1.0 用法升级
|
||||
|
||||
```__react
|
||||
import Alert from '../alert';
|
||||
ReactDOM.render(<Alert message="在 5.1.0 版本后,我们提供了 <Mentions options={[...]} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 5.x 继续使用,但会在控制台看到警告,并会在 6.0 后移除。" />, mountNode);
|
||||
```
|
||||
|
||||
```jsx
|
||||
// >=5.1.0 可用,推荐的写法 ✅
|
||||
const options = [{ value: 'sample', label: 'sample' }];
|
||||
return <Mentions options={options} />;
|
||||
|
||||
// <5.1.0 可用,>=5.1.0 时不推荐 🙅🏻♀️
|
||||
<Mentions onChange={onChange}>
|
||||
<Mentions.Option value="sample">Sample</Mentions.Option>
|
||||
</Mentions>;
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Mentions
|
||||
|
@ -19,7 +19,7 @@ const methods: NoticeType[] = ['success', 'info', 'warning', 'error', 'loading']
|
||||
|
||||
let message: GlobalMessage | null = null;
|
||||
|
||||
let act: (callback: VoidFunction) => Promise<void> | void = (callback: VoidFunction) => callback();
|
||||
let act: (callback: VoidFunction) => Promise<void> | void = (callback) => callback();
|
||||
|
||||
interface GlobalMessage {
|
||||
fragment: DocumentFragment;
|
||||
@ -84,7 +84,7 @@ interface GlobalHolderRef {
|
||||
}
|
||||
|
||||
const GlobalHolder = React.forwardRef<GlobalHolderRef, {}>((_, ref) => {
|
||||
const initializeMeassgConfig: () => ConfigOptions = () => {
|
||||
const initializeMessageConfig: () => ConfigOptions = () => {
|
||||
const { prefixCls, container, maxCount, duration, rtl, top } = getGlobalContext();
|
||||
|
||||
return {
|
||||
@ -97,16 +97,16 @@ const GlobalHolder = React.forwardRef<GlobalHolderRef, {}>((_, ref) => {
|
||||
};
|
||||
};
|
||||
|
||||
const [meassgConfig, setMeassgConfig] = React.useState<ConfigOptions>(initializeMeassgConfig);
|
||||
const [messageConfig, setMessageConfig] = React.useState<ConfigOptions>(initializeMessageConfig);
|
||||
|
||||
const [api, holder] = useInternalMessage(meassgConfig);
|
||||
const [api, holder] = useInternalMessage(messageConfig);
|
||||
|
||||
const global = globalConfig();
|
||||
const rootPrefixCls = global.getRootPrefixCls();
|
||||
const rootIconPrefixCls = global.getIconPrefixCls();
|
||||
|
||||
const sync = () => {
|
||||
setMeassgConfig(initializeMeassgConfig);
|
||||
setMessageConfig(initializeMessageConfig);
|
||||
};
|
||||
|
||||
React.useEffect(sync, []);
|
||||
|
@ -117,7 +117,7 @@ const genMessageStyle: GenerateStyle<MessageToken> = (token) => {
|
||||
padding: paddingXS,
|
||||
textAlign: 'center',
|
||||
|
||||
[iconCls]: {
|
||||
[`${componentCls}-custom-content > ${iconCls}`]: {
|
||||
verticalAlign: 'text-bottom',
|
||||
marginInlineEnd: marginXS, // affected by ltr or rtl
|
||||
fontSize: fontSizeLG,
|
||||
@ -132,18 +132,18 @@ const genMessageStyle: GenerateStyle<MessageToken> = (token) => {
|
||||
pointerEvents: 'all',
|
||||
},
|
||||
|
||||
[`${componentCls}-success ${iconCls}`]: {
|
||||
[`${componentCls}-success > ${iconCls}`]: {
|
||||
color: colorSuccess,
|
||||
},
|
||||
[`${componentCls}-error ${iconCls}`]: {
|
||||
[`${componentCls}-error > ${iconCls}`]: {
|
||||
color: colorError,
|
||||
},
|
||||
[`${componentCls}-warning ${iconCls}`]: {
|
||||
[`${componentCls}-warning > ${iconCls}`]: {
|
||||
color: colorWarning,
|
||||
},
|
||||
[`
|
||||
${componentCls}-info ${iconCls},
|
||||
${componentCls}-loading ${iconCls}`]: {
|
||||
${componentCls}-info > ${iconCls},
|
||||
${componentCls}-loading > ${iconCls}`]: {
|
||||
color: colorInfo,
|
||||
},
|
||||
},
|
||||
|
@ -98,7 +98,7 @@ const Holder = React.forwardRef<HolderRef, HolderProps>((props, ref) => {
|
||||
let keyIndex = 0;
|
||||
|
||||
export function useInternalMessage(
|
||||
notificationConfig?: HolderProps,
|
||||
messageConfig?: HolderProps,
|
||||
): readonly [MessageInstance, React.ReactElement] {
|
||||
const holderRef = React.useRef<HolderRef>(null);
|
||||
|
||||
@ -213,12 +213,9 @@ export function useInternalMessage(
|
||||
}, []);
|
||||
|
||||
// ============================== Return ===============================
|
||||
return [
|
||||
wrapAPI,
|
||||
<Holder key="message-holder" {...notificationConfig} ref={holderRef} />,
|
||||
] as const;
|
||||
return [wrapAPI, <Holder key="message-holder" {...messageConfig} ref={holderRef} />] as const;
|
||||
}
|
||||
|
||||
export default function useMessage(notificationConfig?: ConfigOptions) {
|
||||
return useInternalMessage(notificationConfig);
|
||||
export default function useMessage(messageConfig?: ConfigOptions) {
|
||||
return useInternalMessage(messageConfig);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
|
||||
},
|
||||
},
|
||||
|
||||
[`&${progressCls}-success-bg, ${progressCls}-bg`]: {
|
||||
[`${progressCls}-success-bg, ${progressCls}-bg`]: {
|
||||
position: 'relative',
|
||||
backgroundColor: token.colorInfo,
|
||||
borderRadius: token.progressLineRadius,
|
||||
|
@ -40,5 +40,5 @@ Segmented Controls. This component is available since `antd@4.20.0`.
|
||||
| disabled | Disable all segments | boolean | false | |
|
||||
| onChange | The callback function that is triggered when the state changes | function(value: string \| number) | | |
|
||||
| options | Set children optional | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | |
|
||||
| size | The size of the Segmented. | `large` \| `middle` \| `small` | - | |
|
||||
| size | The size of the Segmented. | `large` \| `middle` \| `small` | `middle` | |
|
||||
| value | Currently selected value | string \| number | | |
|
||||
|
@ -43,5 +43,5 @@ demo:
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| onChange | 选项变化时的回调函数 | function(value: string \| number) | | |
|
||||
| options | 数据化配置选项内容 | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | |
|
||||
| size | 控件尺寸 | `large` \| `middle` \| `small` | - | |
|
||||
| size | 控件尺寸 | `large` \| `middle` \| `small` | `middle` | |
|
||||
| value | 当前选中的值 | string \| number | | |
|
||||
|
@ -6076,15 +6076,16 @@ Array [
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-button-wrapper"
|
||||
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button"
|
||||
class="ant-radio-button ant-radio-button-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="default"
|
||||
value="middle"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
|
@ -2160,15 +2160,16 @@ Array [
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-button-wrapper"
|
||||
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button"
|
||||
class="ant-radio-button ant-radio-button-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="default"
|
||||
value="middle"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
|
@ -27,7 +27,7 @@ const App: React.FC = () => {
|
||||
<>
|
||||
<Radio.Group value={size} onChange={handleSizeChange}>
|
||||
<Radio.Button value="large">Large</Radio.Button>
|
||||
<Radio.Button value="default">Default</Radio.Button>
|
||||
<Radio.Button value="middle">Default</Radio.Button>
|
||||
<Radio.Button value="small">Small</Radio.Button>
|
||||
</Radio.Group>
|
||||
<br />
|
||||
|
@ -64,7 +64,6 @@ const genStatusStyle = (
|
||||
borderHoverColor: string;
|
||||
outlineColor: string;
|
||||
controlOutlineWidth: number;
|
||||
controlLineWidth: number;
|
||||
},
|
||||
overwriteDefaultBorder: boolean = false,
|
||||
): CSSObject => {
|
||||
@ -87,13 +86,11 @@ const genStatusStyle = (
|
||||
[`${componentCls}-focused& ${componentCls}-selector`]: {
|
||||
borderColor: borderHoverColor,
|
||||
boxShadow: `0 0 0 ${token.controlOutlineWidth}px ${outlineColor}`,
|
||||
borderInlineEndWidth: `${token.controlLineWidth}px !important`,
|
||||
outline: 0,
|
||||
},
|
||||
|
||||
[`&:hover ${componentCls}-selector`]: {
|
||||
borderColor: borderHoverColor,
|
||||
borderInlineEndWidth: `${token.controlLineWidth}px !important`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -212,8 +212,7 @@ export default function genMultipleStyle(token: SelectToken): CSSInterpolation {
|
||||
{
|
||||
[`${componentCls}-multiple${componentCls}-sm`]: {
|
||||
[`${componentCls}-selection-placeholder`]: {
|
||||
insetInlineStart: token.controlPaddingHorizontalSM - token.lineWidth,
|
||||
insetInlineEnd: 'auto',
|
||||
insetInline: token.controlPaddingHorizontalSM - token.lineWidth,
|
||||
},
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/29559
|
||||
|
@ -134,21 +134,13 @@ describe('Slider', () => {
|
||||
});
|
||||
|
||||
it('should keepAlign by calling forcePopupAlign', async () => {
|
||||
let ref: any;
|
||||
render(
|
||||
<SliderTooltip
|
||||
title="30"
|
||||
open
|
||||
ref={(node) => {
|
||||
ref = node;
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
ref.forcePopupAlign = jest.fn();
|
||||
const ref = React.createRef<any>();
|
||||
render(<SliderTooltip title="30" open ref={ref} />);
|
||||
ref.current.forcePopupAlign = jest.fn();
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
expect(ref.forcePopupAlign).toHaveBeenCalled();
|
||||
expect(ref.current.forcePopupAlign).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('tipFormatter should not crash with undefined value', () => {
|
||||
|
@ -197,4 +197,17 @@ describe('Space', () => {
|
||||
);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it('should render the hidden empty item wrapper', () => {
|
||||
const Null = () => null;
|
||||
const { container } = render(
|
||||
<Space>
|
||||
<Null />
|
||||
</Space>,
|
||||
);
|
||||
const item = container.querySelector('div.ant-space-item') as HTMLElement;
|
||||
|
||||
expect(item).toBeEmptyDOMElement();
|
||||
expect(getComputedStyle(item).display).toBe('none');
|
||||
});
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ const genSpaceStyle: GenerateStyle<SpaceToken> = (token) => {
|
||||
alignItems: 'baseline',
|
||||
},
|
||||
},
|
||||
[`${componentCls}-space-item`]: {
|
||||
[`${componentCls}-item`]: {
|
||||
'&:empty': {
|
||||
display: 'none',
|
||||
},
|
||||
|
@ -6,17 +6,14 @@ import { roundedArrow } from './roundedArrow';
|
||||
export const MAX_VERTICAL_CONTENT_RADIUS = 8;
|
||||
|
||||
export function getArrowOffset(options: {
|
||||
sizePopupArrow: number;
|
||||
contentRadius: number;
|
||||
borderRadiusOuter: number;
|
||||
limitVerticalRadius?: boolean;
|
||||
}) {
|
||||
const maxVerticalContentRadius = MAX_VERTICAL_CONTENT_RADIUS;
|
||||
const { sizePopupArrow, contentRadius, borderRadiusOuter, limitVerticalRadius } = options;
|
||||
const arrowInnerOffset = sizePopupArrow / 2 - Math.ceil(borderRadiusOuter * (Math.sqrt(2) - 1));
|
||||
const dropdownArrowOffset = (contentRadius > 12 ? contentRadius + 2 : 12) - arrowInnerOffset;
|
||||
const { contentRadius, limitVerticalRadius } = options;
|
||||
const dropdownArrowOffset = contentRadius > 12 ? contentRadius + 2 : 12;
|
||||
const dropdownArrowOffsetVertical = limitVerticalRadius
|
||||
? maxVerticalContentRadius - arrowInnerOffset
|
||||
? maxVerticalContentRadius
|
||||
: dropdownArrowOffset;
|
||||
return { dropdownArrowOffset, dropdownArrowOffsetVertical };
|
||||
}
|
||||
@ -59,9 +56,7 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
|
||||
} = options;
|
||||
|
||||
const { dropdownArrowOffsetVertical, dropdownArrowOffset } = getArrowOffset({
|
||||
sizePopupArrow,
|
||||
contentRadius,
|
||||
borderRadiusOuter,
|
||||
limitVerticalRadius,
|
||||
});
|
||||
|
||||
|
@ -10,31 +10,44 @@ export const roundedArrow = (
|
||||
): CSSObject => {
|
||||
const unitWidth = width / 2;
|
||||
|
||||
const ax = unitWidth - outerRadius * (Math.sqrt(2) - 1);
|
||||
const ax = 0;
|
||||
const ay = unitWidth;
|
||||
const bx = unitWidth + outerRadius * (1 - 1 / Math.sqrt(2));
|
||||
const bx = (outerRadius * 1) / Math.sqrt(2);
|
||||
const by = unitWidth - outerRadius * (1 - 1 / Math.sqrt(2));
|
||||
const cx = 2 * unitWidth - innerRadius * (1 / Math.sqrt(2));
|
||||
const cy = innerRadius * (1 / Math.sqrt(2));
|
||||
const dx = 4 * unitWidth - cx;
|
||||
const cx = unitWidth - innerRadius * (1 / Math.sqrt(2));
|
||||
const cy = outerRadius * (Math.sqrt(2) - 1) + innerRadius * (1 / Math.sqrt(2));
|
||||
const dx = 2 * unitWidth - cx;
|
||||
const dy = cy;
|
||||
const ex = 4 * unitWidth - bx;
|
||||
const ex = 2 * unitWidth - bx;
|
||||
const ey = by;
|
||||
const fx = 4 * unitWidth - ax;
|
||||
const fx = 2 * unitWidth - ax;
|
||||
const fy = ay;
|
||||
|
||||
const shadowWidth = unitWidth * Math.sqrt(2) + outerRadius * (Math.sqrt(2) - 2);
|
||||
|
||||
return {
|
||||
borderRadius: { _skip_check_: true, value: `0 0 ${innerRadius}px` },
|
||||
pointerEvents: 'none',
|
||||
width: width * 2,
|
||||
height: width * 2,
|
||||
width,
|
||||
height: width,
|
||||
overflow: 'hidden',
|
||||
|
||||
'&::before': {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
width,
|
||||
height: width / 2,
|
||||
background: bgColor,
|
||||
clipPath: `path('M ${ax} ${ay} A ${outerRadius} ${outerRadius} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${innerRadius} ${innerRadius} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${outerRadius} ${outerRadius} 0 0 0 ${fx} ${fy} Z')`,
|
||||
content: '""',
|
||||
},
|
||||
|
||||
'&::after': {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
width: width / Math.sqrt(2),
|
||||
height: width / Math.sqrt(2),
|
||||
width: shadowWidth,
|
||||
height: shadowWidth,
|
||||
bottom: 0,
|
||||
insetInline: 0,
|
||||
margin: 'auto',
|
||||
@ -47,16 +60,5 @@ export const roundedArrow = (
|
||||
zIndex: 0,
|
||||
background: 'transparent',
|
||||
},
|
||||
|
||||
'&::before': {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
width: width * 2,
|
||||
height: width / 2,
|
||||
background: bgColor,
|
||||
clipPath: `path('M ${ax} ${ay} A ${outerRadius} ${outerRadius} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${innerRadius} ${innerRadius} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${outerRadius} ${outerRadius} 0 0 0 ${fx} ${fy} Z')`,
|
||||
content: '""',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -2738,4 +2738,43 @@ describe('Table.filter', () => {
|
||||
expect(onFilterDropdownOpenChange).toHaveBeenCalledTimes(2);
|
||||
expect(onFilter).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('works with grouping columns correctly', () => {
|
||||
const columns = [
|
||||
{
|
||||
title: 'group',
|
||||
key: 'group',
|
||||
children: [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
filters: [
|
||||
{ text: 'Jack', value: 'Jack' },
|
||||
{ text: 'Lucy', value: 'Lucy' },
|
||||
],
|
||||
onFilter: filterFn,
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const testData = [
|
||||
{ key: 0, name: 'Jack', age: 11 },
|
||||
{ key: 1, name: 'Lucy', age: 20 },
|
||||
{ key: 2, name: 'Tom', age: 21 },
|
||||
{ key: 3, name: 'Jerry', age: 22 },
|
||||
];
|
||||
const { container } = render(<Table columns={columns} dataSource={testData} />);
|
||||
|
||||
fireEvent.click(container.querySelector('.ant-dropdown-trigger')!);
|
||||
fireEvent.click(container.querySelectorAll('.ant-dropdown-menu-item')[0]);
|
||||
fireEvent.click(container.querySelector('.ant-table-filter-dropdown-btns .ant-btn-primary')!);
|
||||
|
||||
expect(renderedNames(container)).toEqual(['Jack']);
|
||||
});
|
||||
});
|
||||
|
@ -23,12 +23,13 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -47,7 +48,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -116,12 +117,13 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up active"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -140,7 +142,7 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
@ -261,12 +261,13 @@ exports[`Table should render title 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -285,7 +286,7 @@ exports[`Table should render title 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -325,12 +326,13 @@ exports[`Table should render title 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -349,7 +351,7 @@ exports[`Table should render title 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -394,12 +396,13 @@ exports[`Table should render title 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -418,7 +421,7 @@ exports[`Table should render title 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -456,12 +459,13 @@ exports[`Table should render title 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -480,7 +484,7 @@ exports[`Table should render title 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -518,12 +522,13 @@ exports[`Table should render title 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -542,7 +547,7 @@ exports[`Table should render title 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
@ -1163,12 +1163,13 @@ exports[`renders ./components/table/demo/custom-filter-panel.tsx extend context
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -1187,7 +1188,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.tsx extend context
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -1581,9 +1582,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1598,13 +1604,18 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
New York No. 1 Lake Park
|
||||
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1623,9 +1634,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="3"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1640,7 +1656,296 @@ exports[`renders ./components/table/demo/drag-sorting.tsx extend context correct
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sydney No. 1 Lake Park
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-pagination ant-table-pagination ant-table-pagination-right"
|
||||
>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-prev ant-pagination-disabled"
|
||||
title="Previous Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="left"
|
||||
class="anticon anticon-left"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="left"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
|
||||
tabindex="0"
|
||||
title="1"
|
||||
>
|
||||
<a
|
||||
rel="nofollow"
|
||||
>
|
||||
1
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-next ant-pagination-disabled"
|
||||
title="Next Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="right"
|
||||
class="anticon anticon-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/table/demo/drag-sorting-handler.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-table-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-nested-loading"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-container"
|
||||
>
|
||||
<div
|
||||
class="ant-table"
|
||||
>
|
||||
<div
|
||||
class="ant-table-container"
|
||||
>
|
||||
<div
|
||||
class="ant-table-content"
|
||||
>
|
||||
<table
|
||||
style="table-layout:auto"
|
||||
>
|
||||
<colgroup />
|
||||
<thead
|
||||
class="ant-table-thead"
|
||||
>
|
||||
<tr>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
/>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Age
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Address
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
John Brown
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Jim Green
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
42
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
London No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="3"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Joe Black
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -2801,12 +3106,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -2825,7 +3131,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -3114,12 +3420,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -3138,7 +3445,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -7094,12 +7401,13 @@ exports[`renders ./components/table/demo/filter-in-tree.tsx extend context corre
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -7118,7 +7426,7 @@ exports[`renders ./components/table/demo/filter-in-tree.tsx extend context corre
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -7917,12 +8225,13 @@ exports[`renders ./components/table/demo/filter-search.tsx extend context correc
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -7941,7 +8250,7 @@ exports[`renders ./components/table/demo/filter-search.tsx extend context correc
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -8496,12 +8805,13 @@ exports[`renders ./components/table/demo/fixed-columns.tsx extend context correc
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -8520,7 +8830,7 @@ exports[`renders ./components/table/demo/fixed-columns.tsx extend context correc
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -11845,12 +12155,13 @@ exports[`renders ./components/table/demo/grouping-columns.tsx extend context cor
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -11869,7 +12180,7 @@ exports[`renders ./components/table/demo/grouping-columns.tsx extend context cor
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -12945,12 +13256,13 @@ exports[`renders ./components/table/demo/head.tsx extend context correctly 1`] =
|
||||
class="ant-table-column-sorter"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -13425,12 +13737,13 @@ exports[`renders ./components/table/demo/head.tsx extend context correctly 1`] =
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -13449,7 +13762,7 @@ exports[`renders ./components/table/demo/head.tsx extend context correctly 1`] =
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14302,12 +14615,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14326,7 +14640,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14388,12 +14702,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14412,7 +14727,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14474,12 +14789,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -14498,7 +14814,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx extend context corr
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20045,12 +20361,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20069,7 +20386,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20347,12 +20664,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20371,7 +20689,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20440,12 +20758,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20464,7 +20783,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -20977,12 +21296,13 @@ exports[`renders ./components/table/demo/resizable-column.tsx extend context cor
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -21001,7 +21321,7 @@ exports[`renders ./components/table/demo/resizable-column.tsx extend context cor
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
@ -967,12 +967,13 @@ exports[`renders ./components/table/demo/custom-filter-panel.tsx correctly 1`] =
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -991,7 +992,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.tsx correctly 1`] =
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -1263,9 +1264,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1280,13 +1286,18 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
New York No. 1 Lake Park
|
||||
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1305,9 +1316,14 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-1"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="3"
|
||||
role="button"
|
||||
style="cursor:move"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
@ -1322,7 +1338,296 @@ exports[`renders ./components/table/demo/drag-sorting.tsx correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sydney No. 1 Lake Park
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-pagination ant-table-pagination ant-table-pagination-right"
|
||||
>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-prev ant-pagination-disabled"
|
||||
title="Previous Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="left"
|
||||
class="anticon anticon-left"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="left"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
|
||||
tabindex="0"
|
||||
title="1"
|
||||
>
|
||||
<a
|
||||
rel="nofollow"
|
||||
>
|
||||
1
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-next ant-pagination-disabled"
|
||||
title="Next Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="right"
|
||||
class="anticon anticon-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/table/demo/drag-sorting-handler.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-table-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-nested-loading"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-container"
|
||||
>
|
||||
<div
|
||||
class="ant-table"
|
||||
>
|
||||
<div
|
||||
class="ant-table-container"
|
||||
>
|
||||
<div
|
||||
class="ant-table-content"
|
||||
>
|
||||
<table
|
||||
style="table-layout:auto"
|
||||
>
|
||||
<colgroup />
|
||||
<thead
|
||||
class="ant-table-thead"
|
||||
>
|
||||
<tr>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
/>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Age
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
scope="col"
|
||||
>
|
||||
Address
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
John Brown
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Jim Green
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
42
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
London No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
aria-describedby="DndDescribedBy-0"
|
||||
aria-disabled="false"
|
||||
aria-roledescription="sortable"
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="3"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<span
|
||||
aria-label="menu"
|
||||
class="anticon anticon-menu"
|
||||
role="img"
|
||||
style="touch-action:none;cursor:move"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="menu"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Joe Black
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -2483,12 +2788,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -2507,7 +2813,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -2584,12 +2890,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -2608,7 +2915,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -5582,12 +5889,13 @@ exports[`renders ./components/table/demo/filter-in-tree.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -5606,7 +5914,7 @@ exports[`renders ./components/table/demo/filter-in-tree.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -5931,12 +6239,13 @@ exports[`renders ./components/table/demo/filter-search.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -5955,7 +6264,7 @@ exports[`renders ./components/table/demo/filter-search.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -6260,12 +6569,13 @@ exports[`renders ./components/table/demo/fixed-columns.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -6284,7 +6594,7 @@ exports[`renders ./components/table/demo/fixed-columns.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -9189,12 +9499,13 @@ exports[`renders ./components/table/demo/grouping-columns.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -9213,7 +9524,7 @@ exports[`renders ./components/table/demo/grouping-columns.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10161,12 +10472,13 @@ exports[`renders ./components/table/demo/head.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10231,12 +10543,13 @@ exports[`renders ./components/table/demo/head.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10255,7 +10568,7 @@ exports[`renders ./components/table/demo/head.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10896,12 +11209,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10920,7 +11234,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10958,12 +11272,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -10982,7 +11297,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -11020,12 +11335,13 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -11044,7 +11360,7 @@ exports[`renders ./components/table/demo/multiple-sorter.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15302,12 +15618,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15326,7 +15643,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15392,12 +15709,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15416,7 +15734,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15461,12 +15779,13 @@ Array [
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15485,7 +15804,7 @@ Array [
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15786,12 +16105,13 @@ exports[`renders ./components/table/demo/resizable-column.tsx correctly 1`] = `
|
||||
class="ant-table-column-sorter ant-table-column-sorter-full"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-table-column-sorter-inner"
|
||||
>
|
||||
<span
|
||||
aria-label="caret-up"
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@ -15810,7 +16130,7 @@ exports[`renders ./components/table/demo/resizable-column.tsx correctly 1`] = `
|
||||
<span
|
||||
aria-label="caret-down"
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||
role="presentation"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
7
components/table/demo/drag-sorting-handler.md
Normal file
7
components/table/demo/drag-sorting-handler.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
使用 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现一个拖拽操作列。
|
||||
|
||||
## en-US
|
||||
|
||||
Alternatively you can implement drag sorting with handler using [dnd-kit](https://github.com/clauderic/dnd-kit).
|
139
components/table/demo/drag-sorting-handler.tsx
Normal file
139
components/table/demo/drag-sorting-handler.tsx
Normal file
@ -0,0 +1,139 @@
|
||||
import { MenuOutlined } from '@ant-design/icons';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { DndContext } from '@dnd-kit/core';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { Table } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface DataType {
|
||||
key: string;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
const columns: ColumnsType<DataType> = [
|
||||
{
|
||||
key: 'sort',
|
||||
},
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
},
|
||||
];
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
'data-row-key': string;
|
||||
}
|
||||
|
||||
const Row = ({ children, ...props }: RowProps) => {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
setActivatorNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({
|
||||
id: props['data-row-key'],
|
||||
});
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Transform.toString(transform && { ...transform, scaleY: 1 }),
|
||||
transition,
|
||||
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
return (
|
||||
<tr {...props} ref={setNodeRef} style={style} {...attributes}>
|
||||
{React.Children.map(children, (child) => {
|
||||
if ((child as React.ReactElement).key === 'sort') {
|
||||
return React.cloneElement(child as React.ReactElement, {
|
||||
children: (
|
||||
<MenuOutlined
|
||||
ref={setActivatorNodeRef}
|
||||
style={{ touchAction: 'none', cursor: 'move' }}
|
||||
{...listeners}
|
||||
/>
|
||||
),
|
||||
});
|
||||
}
|
||||
return child;
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [dataSource, setDataSource] = useState([
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address:
|
||||
'Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
},
|
||||
]);
|
||||
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
setDataSource((previous) => {
|
||||
const activeIndex = previous.findIndex((i) => i.key === active.id);
|
||||
const overIndex = previous.findIndex((i) => i.key === over?.id);
|
||||
return arrayMove(previous, activeIndex, overIndex);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DndContext onDragEnd={onDragEnd}>
|
||||
<SortableContext
|
||||
// rowKey array
|
||||
items={dataSource.map((i) => i.key)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
<Table
|
||||
components={{
|
||||
body: {
|
||||
row: Row,
|
||||
},
|
||||
}}
|
||||
rowKey="key"
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
@ -1,17 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
使用自定义元素,我们可以集成 [react-dnd](https://github.com/react-dnd/react-dnd) 来实现拖拽排序。
|
||||
使用自定义元素,我们可以集成 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现拖拽排序。
|
||||
|
||||
## en-US
|
||||
|
||||
By using `components`, we can integrate table with [react-dnd](https://github.com/react-dnd/react-dnd) to implement drag sorting function.
|
||||
|
||||
```css
|
||||
#components-table-demo-drag-sorting tr.drop-over-downward td {
|
||||
border-bottom: 2px dashed #1677ff !important;
|
||||
}
|
||||
|
||||
#components-table-demo-drag-sorting tr.drop-over-upward td {
|
||||
border-top: 2px dashed #1677ff !important;
|
||||
}
|
||||
```
|
||||
By using `components`, we can integrate table with [dnd-kit](https://github.com/clauderic/dnd-kit) to implement drag sorting function.
|
||||
|
@ -1,9 +1,15 @@
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { DndContext } from '@dnd-kit/core';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { Table } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import update from 'immutability-helper';
|
||||
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface DataType {
|
||||
key: string;
|
||||
@ -12,81 +18,49 @@ interface DataType {
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface DraggableBodyRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
index: number;
|
||||
moveRow: (dragIndex: number, hoverIndex: number) => void;
|
||||
}
|
||||
|
||||
const type = 'DraggableBodyRow';
|
||||
|
||||
const DraggableBodyRow = ({
|
||||
index,
|
||||
moveRow,
|
||||
className,
|
||||
style,
|
||||
...restProps
|
||||
}: DraggableBodyRowProps) => {
|
||||
const ref = useRef<HTMLTableRowElement>(null);
|
||||
const [{ isOver, dropClassName }, drop] = useDrop({
|
||||
accept: type,
|
||||
collect: (monitor) => {
|
||||
const { index: dragIndex } = monitor.getItem() || {};
|
||||
if (dragIndex === index) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
isOver: monitor.isOver(),
|
||||
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
|
||||
};
|
||||
},
|
||||
drop: (item: { index: number }) => {
|
||||
moveRow(item.index, index);
|
||||
},
|
||||
});
|
||||
const [, drag] = useDrag({
|
||||
type,
|
||||
item: { index },
|
||||
collect: (monitor) => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
}),
|
||||
});
|
||||
drop(drag(ref));
|
||||
|
||||
return (
|
||||
<tr
|
||||
ref={ref}
|
||||
className={`${className}${isOver ? dropClassName : ''}`}
|
||||
style={{ cursor: 'move', ...style }}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const columns: ColumnsType<DataType> = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
},
|
||||
];
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
'data-row-key': string;
|
||||
}
|
||||
|
||||
const Row = (props: RowProps) => {
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
||||
id: props['data-row-key'],
|
||||
});
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Transform.toString(transform && { ...transform, scaleY: 1 }),
|
||||
transition,
|
||||
cursor: 'move',
|
||||
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
return <tr {...props} ref={setNodeRef} style={style} {...attributes} {...listeners} />;
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [data, setData] = useState([
|
||||
const [dataSource, setDataSource] = useState([
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
address:
|
||||
'Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
@ -98,46 +72,39 @@ const App: React.FC = () => {
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sydney No. 1 Lake Park',
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
},
|
||||
]);
|
||||
|
||||
const components = {
|
||||
body: {
|
||||
row: DraggableBodyRow,
|
||||
},
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
setDataSource((prev) => {
|
||||
const activeIndex = prev.findIndex((i) => i.key === active.id);
|
||||
const overIndex = prev.findIndex((i) => i.key === over?.id);
|
||||
return arrayMove(prev, activeIndex, overIndex);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const moveRow = useCallback(
|
||||
(dragIndex: number, hoverIndex: number) => {
|
||||
const dragRow = data[dragIndex];
|
||||
setData(
|
||||
update(data, {
|
||||
$splice: [
|
||||
[dragIndex, 1],
|
||||
[hoverIndex, 0, dragRow],
|
||||
],
|
||||
}),
|
||||
);
|
||||
},
|
||||
[data],
|
||||
);
|
||||
|
||||
return (
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
components={components}
|
||||
onRow={(_, index) => {
|
||||
const attr = {
|
||||
index,
|
||||
moveRow,
|
||||
};
|
||||
return attr as React.HTMLAttributes<any>;
|
||||
}}
|
||||
/>
|
||||
</DndProvider>
|
||||
<DndContext onDragEnd={onDragEnd}>
|
||||
<SortableContext
|
||||
// rowKey array
|
||||
items={dataSource.map((i) => i.key)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
<Table
|
||||
components={{
|
||||
body: {
|
||||
row: Row,
|
||||
},
|
||||
}}
|
||||
rowKey="key"
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -193,10 +193,20 @@ interface FilterConfig<RecordType> {
|
||||
getPopupContainer?: GetPopupContainer;
|
||||
}
|
||||
|
||||
const getMergedColumns = <RecordType extends unknown>(
|
||||
rawMergedColumns: ColumnsType<RecordType>,
|
||||
): ColumnsType<RecordType> =>
|
||||
rawMergedColumns.flatMap((column) => {
|
||||
if ('children' in column) {
|
||||
return [column, ...getMergedColumns(column.children || [])];
|
||||
}
|
||||
return [column];
|
||||
});
|
||||
|
||||
function useFilter<RecordType>({
|
||||
prefixCls,
|
||||
dropdownPrefixCls,
|
||||
mergedColumns,
|
||||
mergedColumns: rawMergedColumns,
|
||||
onFilterChange,
|
||||
getPopupContainer,
|
||||
locale: tableLocale,
|
||||
@ -205,6 +215,8 @@ function useFilter<RecordType>({
|
||||
FilterState<RecordType>[],
|
||||
Record<string, FilterValue | null>,
|
||||
] {
|
||||
const mergedColumns = getMergedColumns(rawMergedColumns || []);
|
||||
|
||||
const [filterStates, setFilterStates] = React.useState<FilterState<RecordType>[]>(() =>
|
||||
collectFilterStates(mergedColumns, true),
|
||||
);
|
||||
|
@ -132,7 +132,6 @@ function injectSorter<RecordType>(
|
||||
className={classNames(`${prefixCls}-column-sorter-up`, {
|
||||
active: sorterOrder === ASCEND,
|
||||
})}
|
||||
role="presentation"
|
||||
/>
|
||||
);
|
||||
const downNode: React.ReactNode = sortDirections.includes(DESCEND) && (
|
||||
@ -140,7 +139,6 @@ function injectSorter<RecordType>(
|
||||
className={classNames(`${prefixCls}-column-sorter-down`, {
|
||||
active: sorterOrder === DESCEND,
|
||||
})}
|
||||
role="presentation"
|
||||
/>
|
||||
);
|
||||
const { cancelSort, triggerAsc, triggerDesc } = tableLocale || {};
|
||||
@ -166,7 +164,7 @@ function injectSorter<RecordType>(
|
||||
[`${prefixCls}-column-sorter-full`]: !!(upNode && downNode),
|
||||
})}
|
||||
>
|
||||
<span className={`${prefixCls}-column-sorter-inner`}>
|
||||
<span className={`${prefixCls}-column-sorter-inner`} aria-hidden="true">
|
||||
{upNode}
|
||||
{downNode}
|
||||
</span>
|
||||
|
@ -91,6 +91,7 @@ const columns = [
|
||||
<code src="./demo/edit-row.tsx">Editable Rows</code>
|
||||
<code src="./demo/nested-table.tsx">Nested tables</code>
|
||||
<code src="./demo/drag-sorting.tsx">Drag sorting</code>
|
||||
<code src="./demo/drag-sorting-handler.tsx">Drag sorting with handler</code>
|
||||
<code src="./demo/resizable-column.tsx" debug>Resizable column</code>
|
||||
<code src="./demo/ellipsis.tsx">ellipsis column</code>
|
||||
<code src="./demo/ellipsis-custom-tooltip.tsx">ellipsis column custom tooltip</code>
|
||||
@ -306,7 +307,7 @@ const data: User[] = [
|
||||
export default () => (
|
||||
<>
|
||||
<Table<User> columns={columns} dataSource={data} />
|
||||
/* JSX style usage */
|
||||
{/* JSX style usage */}
|
||||
<Table<User> dataSource={data}>
|
||||
<Table.Column<User> key="name" title="Name" dataIndex="name" />
|
||||
</Table>
|
||||
|
@ -92,6 +92,7 @@ const columns = [
|
||||
<code src="./demo/edit-row.tsx">可编辑行</code>
|
||||
<code src="./demo/nested-table.tsx">嵌套子表格</code>
|
||||
<code src="./demo/drag-sorting.tsx">拖拽排序</code>
|
||||
<code src="./demo/drag-sorting-handler.tsx">拖拽手柄列</code>
|
||||
<code src="./demo/resizable-column.tsx" debug>可伸缩列</code>
|
||||
<code src="./demo/ellipsis.tsx">单元格自动省略</code>
|
||||
<code src="./demo/ellipsis-custom-tooltip.tsx">自定义单元格省略提示</code>
|
||||
@ -309,7 +310,7 @@ const data: User[] = [
|
||||
export default () => (
|
||||
<>
|
||||
<Table<User> columns={columns} dataSource={data} />
|
||||
/* 使用 JSX 风格的 API */
|
||||
{/* 使用 JSX 风格的 API */}
|
||||
<Table<User> dataSource={data}>
|
||||
<Table.Column<User> key="name" title="Name" dataIndex="name" />
|
||||
</Table>
|
||||
|
@ -170,7 +170,7 @@ const genDropdownStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject
|
||||
backgroundClip: 'padding-box',
|
||||
borderRadius: token.borderRadiusLG,
|
||||
outline: 'none',
|
||||
boxShadow: token.boxShadowTertiary,
|
||||
boxShadow: token.boxShadowSecondary,
|
||||
|
||||
'&-item': {
|
||||
...textEllipsis,
|
||||
|
@ -157,8 +157,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
||||
screenXXL,
|
||||
screenXXLMin: screenXXL,
|
||||
|
||||
// FIXME: component box-shadow, should be removed
|
||||
boxShadowPopoverArrow: '3px 3px 7px rgba(0, 0, 0, 0.1)',
|
||||
boxShadowPopoverArrow: '2px 2px 5px rgba(0, 0, 0, 0.05)',
|
||||
boxShadowCard: `
|
||||
0 1px 2px -2px ${new TinyColor('rgba(0, 0, 0, 0.16)').toRgbString()},
|
||||
0 3px 6px 0 ${new TinyColor('rgba(0, 0, 0, 0.12)').toRgbString()},
|
||||
|
@ -112,37 +112,37 @@ export interface TreeProps<T extends BasicDataNode = DataNode>
|
||||
> {
|
||||
showLine?: boolean | { showLeafIcon: boolean | TreeLeafIcon };
|
||||
className?: string;
|
||||
/** 是否支持多选 */
|
||||
/** Whether to support multiple selection */
|
||||
multiple?: boolean;
|
||||
/** 是否自动展开父节点 */
|
||||
/** Whether to automatically expand the parent node */
|
||||
autoExpandParent?: boolean;
|
||||
/** Checkable状态下节点选择完全受控(父子节点选中状态不再关联) */
|
||||
/** Node selection in Checkable state is fully controlled (the selected state of parent and child nodes is no longer associated) */
|
||||
checkStrictly?: boolean;
|
||||
/** 是否支持选中 */
|
||||
/** Whether to support selection */
|
||||
checkable?: boolean;
|
||||
/** 是否禁用树 */
|
||||
/** whether to disable the tree */
|
||||
disabled?: boolean;
|
||||
/** 默认展开所有树节点 */
|
||||
/** Expand all tree nodes by default */
|
||||
defaultExpandAll?: boolean;
|
||||
/** 默认展开对应树节点 */
|
||||
/** Expand the corresponding tree node by default */
|
||||
defaultExpandParent?: boolean;
|
||||
/** 默认展开指定的树节点 */
|
||||
/** Expand the specified tree node by default */
|
||||
defaultExpandedKeys?: Key[];
|
||||
/** (受控)展开指定的树节点 */
|
||||
/** (Controlled) Expand the specified tree node */
|
||||
expandedKeys?: Key[];
|
||||
/** (受控)选中复选框的树节点 */
|
||||
/** (Controlled) Tree node with checked checkbox */
|
||||
checkedKeys?: Key[] | { checked: Key[]; halfChecked: Key[] };
|
||||
/** 默认选中复选框的树节点 */
|
||||
/** Tree node with checkbox checked by default */
|
||||
defaultCheckedKeys?: Key[];
|
||||
/** (受控)设置选中的树节点 */
|
||||
/** (Controlled) Set the selected tree node */
|
||||
selectedKeys?: Key[];
|
||||
/** 默认选中的树节点 */
|
||||
/** Tree node selected by default */
|
||||
defaultSelectedKeys?: Key[];
|
||||
selectable?: boolean;
|
||||
/** 点击树节点触发 */
|
||||
/** Click on the tree node to trigger */
|
||||
filterAntTreeNode?: (node: AntTreeNode) => boolean;
|
||||
loadedKeys?: Key[];
|
||||
/** 设置节点可拖拽(IE>8) */
|
||||
/** Set the node to be draggable (IE>8) */
|
||||
draggable?: DraggableFn | boolean | DraggableConfig;
|
||||
style?: React.CSSProperties;
|
||||
showIcon?: boolean;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.1.6",
|
||||
"version": "5.1.7",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
"keywords": [
|
||||
@ -121,7 +121,7 @@
|
||||
"qrcode.react": "^3.1.0",
|
||||
"rc-cascader": "~3.8.0",
|
||||
"rc-checkbox": "~2.3.0",
|
||||
"rc-collapse": "~3.4.2",
|
||||
"rc-collapse": "~3.5.2",
|
||||
"rc-dialog": "~9.0.2",
|
||||
"rc-drawer": "~6.1.1",
|
||||
"rc-dropdown": "~4.0.0",
|
||||
@ -158,6 +158,9 @@
|
||||
"devDependencies": {
|
||||
"@ant-design/tools": "^17.0.0",
|
||||
"@babel/eslint-plugin": "^7.19.1",
|
||||
"@dnd-kit/core": "^6.0.7",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@dnd-kit/utilities": "^3.2.1",
|
||||
"@emotion/babel-preset-css-prop": "^11.10.0",
|
||||
"@emotion/css": "^11.10.5",
|
||||
"@emotion/react": "^11.10.4",
|
||||
@ -231,7 +234,7 @@
|
||||
"jest-environment-jsdom": "^29.0.1",
|
||||
"jest-environment-node": "^29.0.0",
|
||||
"jest-image-snapshot": "^6.0.0",
|
||||
"jest-puppeteer": "^6.0.0",
|
||||
"jest-puppeteer": "^7.0.0",
|
||||
"jquery": "^3.4.1",
|
||||
"jsdom": "^21.0.0",
|
||||
"jsonml-to-react-element": "^1.1.11",
|
||||
|
@ -35,7 +35,7 @@ const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>
|
||||
export function renderHook<T>(func: () => T): { result: React.RefObject<T> } {
|
||||
const result = React.createRef<T>();
|
||||
|
||||
const Demo = () => {
|
||||
const Demo: React.FC = () => {
|
||||
(result as any).current = func();
|
||||
|
||||
return null;
|
||||
|
Loading…
Reference in New Issue
Block a user