mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 02:59:04 +08:00
Merge branch 'master' into feature-merge-master
This commit is contained in:
commit
3cd47b9a4e
@ -1,11 +1,11 @@
|
||||
export default function use<T>(promise: PromiseLike<T>): T {
|
||||
function use<T>(promise: PromiseLike<T>): T {
|
||||
const internal: PromiseLike<T> & {
|
||||
status?: 'pending' | 'fulfilled' | 'rejected';
|
||||
value?: T;
|
||||
reason?: any;
|
||||
} = promise;
|
||||
if (internal.status === 'fulfilled') {
|
||||
return internal.value;
|
||||
return internal.value as T;
|
||||
}
|
||||
if (internal.status === 'rejected') {
|
||||
throw internal.reason;
|
||||
@ -26,3 +26,5 @@ export default function use<T>(promise: PromiseLike<T>): T {
|
||||
throw internal;
|
||||
}
|
||||
}
|
||||
|
||||
export default use;
|
||||
|
@ -5,10 +5,12 @@ export interface LocaleMap<Key extends string> {
|
||||
en: Record<Key, string>;
|
||||
}
|
||||
|
||||
export default function useLocale<Key extends string>(
|
||||
function useLocale<Key extends string>(
|
||||
localeMap?: LocaleMap<Key>,
|
||||
): [Record<Key, string>, 'cn' | 'en'] {
|
||||
const { id } = useDumiLocale();
|
||||
const localeType = id === 'zh-CN' ? 'cn' : 'en';
|
||||
return [localeMap?.[localeType], localeType];
|
||||
const localeType = id === 'zh-CN' ? ('cn' as const) : ('en' as const);
|
||||
return [localeMap?.[localeType]!, localeType];
|
||||
}
|
||||
|
||||
export default useLocale;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { useFullSidebarData, useSidebarData } from 'dumi';
|
||||
import React, { useMemo } from 'react';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Tag, version } from 'antd';
|
||||
import { useFullSidebarData, useSidebarData } from 'dumi';
|
||||
|
||||
import Link from '../theme/common/Link';
|
||||
import useLocation from './useLocation';
|
||||
|
||||
@ -136,7 +137,7 @@ const useMenu = (options: UseMenuOptions = {}): [MenuProps['items'], string] =>
|
||||
const list = group.children || [];
|
||||
// 如果有 date 字段,我们就对其进行排序
|
||||
if (list.every((info) => info?.frontmatter?.date)) {
|
||||
list.sort((a, b) => (a.frontmatter.date > b.frontmatter.date ? -1 : 1));
|
||||
list.sort((a, b) => (a.frontmatter?.date > b.frontmatter?.date ? -1 : 1));
|
||||
}
|
||||
|
||||
result.push(
|
||||
|
@ -32,11 +32,7 @@ const useThemeAnimation = () => {
|
||||
token: { colorBgElevated },
|
||||
} = theme.useToken();
|
||||
|
||||
const animateRef = useRef<{
|
||||
colorBgElevated: string;
|
||||
}>({
|
||||
colorBgElevated,
|
||||
});
|
||||
const animateRef = useRef<{ colorBgElevated: string }>({ colorBgElevated });
|
||||
|
||||
const startAnimationTheme = (clipPath: string[], isDark: boolean) => {
|
||||
updateCSS(
|
||||
@ -64,9 +60,14 @@ const useThemeAnimation = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const toggleAnimationTheme = (event: MouseEvent, isDark: boolean) => {
|
||||
const toggleAnimationTheme = (
|
||||
event: React.MouseEvent<HTMLElement, MouseEvent>,
|
||||
isDark: boolean,
|
||||
) => {
|
||||
// @ts-ignore
|
||||
if (!(event && typeof document.startViewTransition === 'function')) return;
|
||||
if (!(event && typeof document.startViewTransition === 'function')) {
|
||||
return;
|
||||
}
|
||||
const x = event.clientX;
|
||||
const y = event.clientY;
|
||||
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
|
||||
|
@ -83,8 +83,8 @@ const Group: React.FC<GroupProps> = (props) => {
|
||||
</Typography.Title>
|
||||
<Typography.Paragraph
|
||||
style={{
|
||||
marginBottom: isMobile ? token.marginXXL : token.marginFarXS,
|
||||
color: titleColor,
|
||||
marginBottom: isMobile ? token.marginXXL : (token as any).marginFarXS,
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
@ -111,7 +111,7 @@ const Group: React.FC<GroupProps> = (props) => {
|
||||
<GroupMask
|
||||
disabled={!!background}
|
||||
style={{
|
||||
paddingBlock: token.marginFarSM,
|
||||
paddingBlock: (token as any).marginFarSM,
|
||||
}}
|
||||
>
|
||||
{childNode}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { createStyles, css } from 'antd-style';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { CSSMotionList } from 'rc-motion';
|
||||
import { createStyles, css } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
import { CSSMotionList } from 'rc-motion';
|
||||
|
||||
import { COLOR_IMAGES, getClosetColor } from './colorUtil';
|
||||
|
||||
export interface BackgroundImageProps {
|
||||
@ -36,7 +37,7 @@ const BackgroundImage: React.FC<BackgroundImageProps> = ({ colorPrimary, isLight
|
||||
const [keyList, setKeyList] = useState<string[]>([]);
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
setKeyList([activeColor]);
|
||||
setKeyList([activeColor as string]);
|
||||
}, [activeColor]);
|
||||
|
||||
return (
|
||||
@ -56,7 +57,7 @@ const BackgroundImage: React.FC<BackgroundImageProps> = ({ colorPrimary, isLight
|
||||
const entity = COLOR_IMAGES.find((ent) => ent.color === color);
|
||||
|
||||
if (!entity || !entity.url) {
|
||||
return null;
|
||||
return null as unknown as React.ReactElement;
|
||||
}
|
||||
|
||||
const { opacity } = style || {};
|
||||
|
@ -1,39 +1,47 @@
|
||||
import { createStyles } from 'antd-style';
|
||||
import type { FC } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ColorPicker, Input, Space } from 'antd';
|
||||
import type { Color, ColorPickerProps } from 'antd/es/color-picker';
|
||||
import { createStyles } from 'antd-style';
|
||||
import type { Color } from 'antd/es/color-picker';
|
||||
import { generateColor } from 'antd/es/color-picker/util';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { PRESET_COLORS } from './colorUtil';
|
||||
|
||||
const useStyle = createStyles(({ token, css }) => ({
|
||||
color: css`
|
||||
width: ${token.controlHeightLG / 2}px;
|
||||
height: ${token.controlHeightLG / 2}px;
|
||||
border-radius: 100%;
|
||||
cursor: pointer;
|
||||
transition: all ${token.motionDurationFast};
|
||||
display: inline-block;
|
||||
width: ${token.controlHeightLG / 2}px;
|
||||
height: ${token.controlHeightLG / 2}px;
|
||||
border-radius: 100%;
|
||||
cursor: pointer;
|
||||
transition: all ${token.motionDurationFast};
|
||||
display: inline-block;
|
||||
|
||||
& > input[type='radio'] {
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
& > input[type='radio'] {
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
// need ?
|
||||
}
|
||||
`,
|
||||
&:focus-within {
|
||||
// need ?
|
||||
}
|
||||
`,
|
||||
|
||||
colorActive: css`
|
||||
box-shadow: 0 0 0 1px ${token.colorBgContainer},
|
||||
0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary};
|
||||
`,
|
||||
box-shadow:
|
||||
0 0 0 1px ${token.colorBgContainer},
|
||||
0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary};
|
||||
`,
|
||||
}));
|
||||
|
||||
const DebouncedColorPicker: FC<ColorPickerProps> = ({ value: color, onChange, children }) => {
|
||||
export interface ColorPickerProps {
|
||||
children?: React.ReactNode;
|
||||
value?: string | Color;
|
||||
onChange?: (value?: Color | string) => void;
|
||||
}
|
||||
|
||||
const DebouncedColorPicker: React.FC<ColorPickerProps> = (props) => {
|
||||
const { value: color, children, onChange } = props;
|
||||
const [value, setValue] = useState(color);
|
||||
|
||||
useEffect(() => {
|
||||
@ -51,40 +59,24 @@ const DebouncedColorPicker: FC<ColorPickerProps> = ({ value: color, onChange, ch
|
||||
<ColorPicker
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
presets={[
|
||||
{
|
||||
label: 'PresetColors',
|
||||
colors: PRESET_COLORS,
|
||||
},
|
||||
]}
|
||||
presets={[{ label: 'PresetColors', colors: PRESET_COLORS }]}
|
||||
>
|
||||
{children}
|
||||
</ColorPicker>
|
||||
);
|
||||
};
|
||||
|
||||
export interface RadiusPickerProps {
|
||||
value?: string | Color;
|
||||
onChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps) {
|
||||
const ThemeColorPicker: React.FC<ColorPickerProps> = ({ value, onChange }) => {
|
||||
const { styles } = useStyle();
|
||||
|
||||
const matchColors = React.useMemo(() => {
|
||||
const valueStr = generateColor(value).toRgbString();
|
||||
const valueStr = generateColor(value || '').toRgbString();
|
||||
let existActive = false;
|
||||
|
||||
const colors = PRESET_COLORS.map((color) => {
|
||||
const colorStr = generateColor(color).toRgbString();
|
||||
const active = colorStr === valueStr;
|
||||
existActive = existActive || active;
|
||||
|
||||
return {
|
||||
color,
|
||||
active,
|
||||
picker: false,
|
||||
};
|
||||
return { color, active, picker: false };
|
||||
});
|
||||
|
||||
return [
|
||||
@ -100,10 +92,8 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps)
|
||||
return (
|
||||
<Space size="large">
|
||||
<Input
|
||||
value={typeof value === 'string' ? value : value.toHexString()}
|
||||
onChange={(event) => {
|
||||
onChange?.(event.target.value);
|
||||
}}
|
||||
value={typeof value === 'string' ? value : value?.toHexString()}
|
||||
onChange={(event) => onChange?.(event.target.value)}
|
||||
style={{ width: 120 }}
|
||||
/>
|
||||
|
||||
@ -114,9 +104,7 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps)
|
||||
<label
|
||||
key={color}
|
||||
className={classNames(styles.color, active && styles.colorActive)}
|
||||
style={{
|
||||
background: color,
|
||||
}}
|
||||
style={{ background: color }}
|
||||
onClick={() => {
|
||||
if (!picker) {
|
||||
onChange?.(color);
|
||||
@ -149,4 +137,6 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps)
|
||||
</Space>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ThemeColorPicker;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { Color } from 'antd/es/color-picker';
|
||||
import { generateColor } from 'antd/es/color-picker/util';
|
||||
|
||||
export const DEFAULT_COLOR = '#1677FF';
|
||||
@ -50,7 +51,8 @@ export const COLOR_IMAGES = [
|
||||
export const PRESET_COLORS = COLOR_IMAGES.map(({ color }) => color);
|
||||
|
||||
const DISTANCE = 33;
|
||||
export function getClosetColor(colorPrimary?: string | null) {
|
||||
|
||||
export function getClosetColor(colorPrimary?: Color | string | null) {
|
||||
if (!colorPrimary) {
|
||||
return null;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ const useStyle = createStyles(({ token, cx }) => {
|
||||
});
|
||||
|
||||
// ========================== Menu Config ==========================
|
||||
const subMenuItems: MenuProps['items'] = [
|
||||
const subMenuItems = [
|
||||
{
|
||||
key: `Design Values`,
|
||||
label: `Design Values`,
|
||||
@ -287,11 +287,12 @@ const ThemesInfo: Record<THEME, Partial<ThemeData>> = {
|
||||
},
|
||||
};
|
||||
|
||||
const normalize = (value: number) => value / 255;
|
||||
|
||||
function rgbToColorMatrix(color: string) {
|
||||
const rgb = new TinyColor(color).toRgb();
|
||||
const { r, g, b } = rgb;
|
||||
|
||||
const normalize = (value) => value / 255;
|
||||
const invertValue = normalize(r) * 100;
|
||||
const sepiaValue = 100;
|
||||
const saturateValue = Math.max(normalize(r), normalize(g), normalize(b)) * 10000;
|
||||
@ -360,10 +361,7 @@ export default function Theme() {
|
||||
const isRootDark = useDark();
|
||||
|
||||
React.useEffect(() => {
|
||||
onThemeChange(null, {
|
||||
...themeData,
|
||||
themeType: isRootDark ? 'dark' : 'default',
|
||||
});
|
||||
onThemeChange({}, { ...themeData, themeType: isRootDark ? 'dark' : 'default' });
|
||||
}, [isRootDark]);
|
||||
|
||||
// ================================ Tokens ================================
|
||||
|
@ -62,12 +62,12 @@ function rehypeAntd(): UnifiedTransformer<HastRoot> {
|
||||
(node.properties.className as string[]).push('component-api-table');
|
||||
} else if (node.type === 'element' && (node.tagName === 'Link' || node.tagName === 'a')) {
|
||||
const { tagName } = node;
|
||||
node.properties.sourceType = tagName;
|
||||
node.properties!.sourceType = tagName;
|
||||
node.tagName = 'LocaleLink';
|
||||
} else if (node.type === 'element' && node.tagName === 'video') {
|
||||
node.tagName = 'VideoPlayer';
|
||||
} else if (node.tagName === 'SourceCode') {
|
||||
const { lang } = node.properties;
|
||||
const { lang } = node.properties!;
|
||||
|
||||
if (typeof lang === 'string' && lang.startsWith('sandpack')) {
|
||||
const code = (node.children[0] as any).value as string;
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { unistUtilVisit } from 'dumi';
|
||||
import type { UnifiedTransformer } from 'dumi';
|
||||
|
||||
export default function remarkMeta() {
|
||||
function remarkMeta(): UnifiedTransformer<any> {
|
||||
return (tree, vFile) => {
|
||||
// read frontmatter
|
||||
unistUtilVisit.visit(tree, 'yaml', (node) => {
|
||||
if (!/(^|[\n\r])description:/.test(node.value)) {
|
||||
vFile.data.frontmatter.__autoDescription = true;
|
||||
(vFile.data.frontmatter as any).__autoDescription = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default remarkMeta;
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { theme as antdTheme, ConfigProvider } from 'antd';
|
||||
import type { ThemeConfig } from 'antd';
|
||||
import type { ThemeProviderProps } from 'antd-style';
|
||||
import { ThemeProvider } from 'antd-style';
|
||||
import type { FC } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { ConfigProvider, theme as antdTheme } from 'antd';
|
||||
|
||||
interface NewToken {
|
||||
bannerHeight: number;
|
||||
headerHeight: number;
|
||||
menuItemBorder: number;
|
||||
mobileMaxWidth: number;
|
||||
@ -18,21 +19,13 @@ interface NewToken {
|
||||
contentMarginTop: number;
|
||||
}
|
||||
|
||||
// 通过给 antd-style 扩展 CustomToken 对象类型定义,可以为 useTheme 中增加相应的 token 对象
|
||||
declare module 'antd-style' {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface CustomToken extends NewToken {}
|
||||
}
|
||||
|
||||
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, theme, ...rest }) => {
|
||||
const SiteThemeProvider: React.FC<ThemeProviderProps<any>> = ({ children, theme, ...rest }) => {
|
||||
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const { token } = antdTheme.useToken();
|
||||
|
||||
React.useEffect(() => {
|
||||
ConfigProvider.config({
|
||||
theme,
|
||||
});
|
||||
ConfigProvider.config({ theme: theme as ThemeConfig });
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
|
@ -1,11 +1,12 @@
|
||||
/* eslint-disable global-require */
|
||||
import React, { useMemo } from 'react';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { HistoryOutlined } from '@ant-design/icons';
|
||||
import { Button, Drawer, Timeline, Typography } from 'antd';
|
||||
import Link from '../Link';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
import useFetch from '../../../hooks/useFetch';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import Link from '../Link';
|
||||
|
||||
const useStyle = createStyles(({ token, css }) => ({
|
||||
history: css`
|
||||
@ -46,7 +47,7 @@ function ParseChangelog(props: { changelog: string; refs: string[]; styles: any
|
||||
const { changelog = '', refs = [], styles } = props;
|
||||
|
||||
const parsedChangelog = React.useMemo(() => {
|
||||
const nodes: React.ReactElement[] = [];
|
||||
const nodes: React.ReactNode[] = [];
|
||||
|
||||
let isQuota = false;
|
||||
let lastStr = '';
|
||||
@ -57,7 +58,7 @@ function ParseChangelog(props: { changelog: string; refs: string[]; styles: any
|
||||
if (char !== '`') {
|
||||
lastStr += char;
|
||||
} else {
|
||||
let node = lastStr;
|
||||
let node: React.ReactNode = lastStr;
|
||||
if (isQuota) {
|
||||
node = <code>{node}</code>;
|
||||
}
|
||||
@ -88,8 +89,14 @@ function ParseChangelog(props: { changelog: string; refs: string[]; styles: any
|
||||
);
|
||||
}
|
||||
|
||||
function useChangelog(componentPath, lang) {
|
||||
const data = useFetch(
|
||||
type ChangelogInfo = {
|
||||
version: string;
|
||||
changelog: string;
|
||||
refs: string[];
|
||||
};
|
||||
|
||||
function useChangelog(componentPath: string, lang: 'cn' | 'en'): ChangelogInfo[] {
|
||||
const data: any = useFetch(
|
||||
lang === 'cn'
|
||||
? {
|
||||
key: 'component-changelog-cn',
|
||||
@ -108,7 +115,7 @@ function useChangelog(componentPath, lang) {
|
||||
(name) => name.toLowerCase() === component.toLowerCase(),
|
||||
);
|
||||
|
||||
return data[componentName];
|
||||
return data[componentName!];
|
||||
}, [data, componentPath]);
|
||||
}
|
||||
|
||||
@ -124,7 +131,7 @@ export default function ComponentChangelog(props: ComponentChangelogProps) {
|
||||
const list = useChangelog(componentPath, lang);
|
||||
|
||||
const timelineItems = React.useMemo(() => {
|
||||
const changelogMap = {};
|
||||
const changelogMap: Record<string, ChangelogInfo[]> = {};
|
||||
|
||||
list?.forEach((info) => {
|
||||
changelogMap[info.version] = changelogMap[info.version] || [];
|
||||
|
@ -3,12 +3,12 @@ import React, { forwardRef, useLayoutEffect, useMemo, useTransition } from 'reac
|
||||
import { useLocation, useNavigate } from 'dumi';
|
||||
import nprogress from 'nprogress';
|
||||
|
||||
export type LinkProps = {
|
||||
export interface LinkProps {
|
||||
to?: string | { pathname?: string; search?: string; hash?: string };
|
||||
children?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
};
|
||||
}
|
||||
|
||||
const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
const { to, children, ...rest } = props;
|
||||
@ -24,12 +24,14 @@ const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
}, [to]);
|
||||
|
||||
const handleClick = (e: MouseEvent<HTMLAnchorElement>) => {
|
||||
if (!href.startsWith('http')) {
|
||||
if (!href?.startsWith('http')) {
|
||||
// Should support open in new tab
|
||||
if (!e.metaKey && !e.ctrlKey && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
startTransition(() => {
|
||||
navigate(href);
|
||||
if (href) {
|
||||
navigate(href);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ import ThemeIcon from './ThemeIcon';
|
||||
|
||||
export type ThemeName = 'light' | 'dark' | 'compact' | 'motion-off' | 'happy-work';
|
||||
|
||||
export type ThemeSwitchProps = {
|
||||
export interface ThemeSwitchProps {
|
||||
value?: ThemeName[];
|
||||
onChange: (value: ThemeName[]) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const ThemeSwitch: React.FC<ThemeSwitchProps> = (props) => {
|
||||
const { value = ['light'], onChange } = props;
|
||||
@ -72,23 +72,6 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = (props) => {
|
||||
}}
|
||||
tooltip={<FormattedMessage id="app.theme.switch.compact" />}
|
||||
/>
|
||||
{/* Too many float button. Hide motion one */}
|
||||
{/* <FloatButton
|
||||
icon={<Motion />}
|
||||
type={!isMotionOff ? 'primary' : 'default'}
|
||||
onClick={() => {
|
||||
if (isMotionOff) {
|
||||
onChange(value.filter((theme) => theme !== 'motion-off'));
|
||||
} else {
|
||||
onChange([...value, 'motion-off']);
|
||||
}
|
||||
}}
|
||||
tooltip={
|
||||
<FormattedMessage
|
||||
id={isMotionOff ? 'app.theme.switch.motion.off' : 'app.theme.switch.motion.on'}
|
||||
/>
|
||||
}
|
||||
/> */}
|
||||
<FloatButton
|
||||
badge={{ dot: true }}
|
||||
icon={<SmileOutlined />}
|
||||
|
@ -63,10 +63,6 @@ export default () => {
|
||||
html {
|
||||
scroll-padding-top: ${headerHeight + margin}px;
|
||||
}
|
||||
|
||||
[data-prefers-color='dark'] {
|
||||
color-scheme: dark;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
|
@ -26,6 +26,10 @@ const GlobalStyle: React.FC = () => {
|
||||
.markdown img {
|
||||
max-width: calc(100% - 32px);
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.markdown > a > img,
|
||||
.markdown > img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useCallback, useEffect, useMemo, startTransition } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
createCache,
|
||||
extractStyle,
|
||||
@ -9,15 +10,9 @@ import {
|
||||
} from '@ant-design/cssinjs';
|
||||
import { HappyProvider } from '@ant-design/happy-work-theme';
|
||||
import { getSandpackCssText } from '@codesandbox/sandpack-react';
|
||||
import { theme as antdTheme, App } from 'antd';
|
||||
import { App, theme as antdTheme } from 'antd';
|
||||
import type { DirectionType } from 'antd/es/config-provider';
|
||||
import {
|
||||
createSearchParams,
|
||||
useOutlet,
|
||||
useSearchParams,
|
||||
useServerInsertedHTML,
|
||||
usePrefersColor,
|
||||
} from 'dumi';
|
||||
import { createSearchParams, useOutlet, useSearchParams, useServerInsertedHTML } from 'dumi';
|
||||
|
||||
import { DarkContext } from '../../hooks/useDark';
|
||||
import useLayoutState from '../../hooks/useLayoutState';
|
||||
@ -32,6 +27,7 @@ type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T][];
|
||||
type SiteState = Partial<Omit<SiteContextProps, 'updateSiteContext'>>;
|
||||
|
||||
const RESPONSIVE_MOBILE = 768;
|
||||
export const ANT_DESIGN_NOT_SHOW_BANNER = 'ANT_DESIGN_NOT_SHOW_BANNER';
|
||||
|
||||
// const styleCache = createCache();
|
||||
// if (typeof global !== 'undefined') {
|
||||
@ -55,13 +51,12 @@ const GlobalLayout: React.FC = () => {
|
||||
const outlet = useOutlet();
|
||||
const { pathname } = useLocation();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [, , setPrefersColor] = usePrefersColor();
|
||||
const [{ theme = [], direction, isMobile, bannerVisible = true }, setSiteState] =
|
||||
const [{ theme = [], direction, isMobile, bannerVisible = false }, setSiteState] =
|
||||
useLayoutState<SiteState>({
|
||||
isMobile: false,
|
||||
direction: 'ltr',
|
||||
theme: [],
|
||||
bannerVisible: true,
|
||||
bannerVisible: false,
|
||||
});
|
||||
|
||||
const updateSiteConfig = useCallback(
|
||||
@ -81,13 +76,9 @@ const GlobalLayout: React.FC = () => {
|
||||
}
|
||||
}
|
||||
if (key === 'theme') {
|
||||
const _theme = value.filter((t) => t !== 'light');
|
||||
nextSearchParams = createSearchParams({
|
||||
...nextSearchParams,
|
||||
theme: _theme,
|
||||
});
|
||||
startTransition(() => {
|
||||
setPrefersColor(_theme.includes('dark') ? 'dark' : 'light');
|
||||
theme: value.filter((t) => t !== 'light'),
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -106,8 +97,16 @@ const GlobalLayout: React.FC = () => {
|
||||
useEffect(() => {
|
||||
const _theme = searchParams.getAll('theme') as ThemeName[];
|
||||
const _direction = searchParams.get('direction') as DirectionType;
|
||||
const storedBannerVisibleLastTime =
|
||||
localStorage && localStorage.getItem(ANT_DESIGN_NOT_SHOW_BANNER);
|
||||
const storedBannerVisible =
|
||||
storedBannerVisibleLastTime && dayjs().diff(dayjs(storedBannerVisibleLastTime), 'day') >= 1;
|
||||
|
||||
setSiteState({ theme: _theme, direction: _direction === 'rtl' ? 'rtl' : 'ltr' });
|
||||
setSiteState({
|
||||
theme: _theme,
|
||||
direction: _direction === 'rtl' ? 'rtl' : 'ltr',
|
||||
bannerVisible: storedBannerVisibleLastTime ? storedBannerVisible : true,
|
||||
});
|
||||
// Handle isMobile
|
||||
updateMobileMode();
|
||||
|
||||
|
@ -1,21 +1,24 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
|
||||
import { Alert, Col, Popover, Row, Select } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
import dayjs from 'dayjs';
|
||||
import { useLocation, useSiteData } from 'dumi';
|
||||
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Alert, Col, Popover, Row, Select } from 'antd';
|
||||
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import DirectionIcon from '../../common/DirectionIcon';
|
||||
import { ANT_DESIGN_NOT_SHOW_BANNER } from '../../layouts/GlobalLayout';
|
||||
import * as utils from '../../utils';
|
||||
import { getThemeConfig } from '../../utils';
|
||||
import type { SiteContextProps } from '../SiteContext';
|
||||
import SiteContext from '../SiteContext';
|
||||
import type { SharedProps } from './interface';
|
||||
import Logo from './Logo';
|
||||
import More from './More';
|
||||
import Navigation from './Navigation';
|
||||
import SwitchBtn from './SwitchBtn';
|
||||
import type { SharedProps } from './interface';
|
||||
|
||||
const RESPONSIVE_XS = 1120;
|
||||
const RESPONSIVE_SM = 1200;
|
||||
@ -133,6 +136,9 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
`,
|
||||
message: css`
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
@ -154,7 +160,8 @@ const Header: React.FC = () => {
|
||||
windowWidth: 1400,
|
||||
searching: false,
|
||||
});
|
||||
const { direction, isMobile, updateSiteConfig } = useContext<SiteContextProps>(SiteContext);
|
||||
const { direction, isMobile, bannerVisible, updateSiteConfig } =
|
||||
useContext<SiteContextProps>(SiteContext);
|
||||
const pingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const location = useLocation();
|
||||
const { pathname, search } = location;
|
||||
@ -178,6 +185,10 @@ const Header: React.FC = () => {
|
||||
};
|
||||
const onBannerClose = () => {
|
||||
updateSiteConfig({ bannerVisible: false });
|
||||
|
||||
if (utils.isLocalStorageNameSupported()) {
|
||||
localStorage.setItem(ANT_DESIGN_NOT_SHOW_BANNER, dayjs().toISOString());
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -352,7 +363,7 @@ const Header: React.FC = () => {
|
||||
<MenuOutlined className="nav-phone-icon" onClick={handleShowMenu} />
|
||||
</Popover>
|
||||
)}
|
||||
{isZhCN && (
|
||||
{isZhCN && bannerVisible && (
|
||||
<Alert
|
||||
className={styles.banner}
|
||||
message={
|
||||
@ -362,7 +373,9 @@ const Header: React.FC = () => {
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/XuVpGqBFxXplzvLjJBZB.svg"
|
||||
alt="yuque"
|
||||
/>
|
||||
{isMobile ? locale.shortMessage : locale.message}
|
||||
<span className={styles.message}>
|
||||
{isMobile ? locale.shortMessage : locale.message}
|
||||
</span>
|
||||
<a
|
||||
className={styles.link}
|
||||
href="https://www.yuque.com/yuque/blog/welfare-edu?source=antd"
|
||||
|
@ -1,5 +1,6 @@
|
||||
import flatten from 'lodash/flatten';
|
||||
import flattenDeep from 'lodash/flattenDeep';
|
||||
|
||||
import themeConfig from './themeConfig';
|
||||
|
||||
interface Meta {
|
||||
|
@ -1,15 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": "../",
|
||||
"paths": {
|
||||
"@@/*": [".dumi/tmp/*"],
|
||||
"antd": ["components/index.tsx"],
|
||||
"antd/es/*": ["components/*"],
|
||||
"dumi/theme/*": [".dumi/theme/*"]
|
||||
}
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["./**/*", "../site/theme/template/Content"]
|
||||
"include": ["**/*"]
|
||||
}
|
||||
|
@ -16,6 +16,16 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.9.2
|
||||
|
||||
`2023-09-19`
|
||||
|
||||
- 🐞 Fix Table selection column not align in center when `size` is `small`. [#44922](https://github.com/ant-design/ant-design/pull/44922)
|
||||
- 🐞 Fix Select style problem when `label` contains `div` element. [#44927](https://github.com/ant-design/ant-design/pull/44927)
|
||||
- 🐞 Fix Modal broken style of buttons when custom `footer`. [#44929](https://github.com/ant-design/ant-design/pull/44929) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 Fix notification wrong pop-up animation when `placement` is `bottom`. [#44918](https://github.com/ant-design/ant-design/pull/44918) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🐞 Fix missing inherited feedbackIcon in Form.Item with `noStyle`. [#44937](https://github.com/ant-design/ant-design/pull/44937)
|
||||
|
||||
## 5.9.1
|
||||
|
||||
`2023-09-15`
|
||||
|
@ -16,6 +16,16 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.9.2
|
||||
|
||||
`2023-09-19`
|
||||
|
||||
- 🐞 修复 Table `small` 尺寸时选择列没有居中对齐的问题。[#44922](https://github.com/ant-design/ant-design/pull/44922)
|
||||
- 🐞 修复 Select 当 `label` 内使用了 `div` 块级元素时的样式问题。[#44927](https://github.com/ant-design/ant-design/pull/44927)
|
||||
- 🐞 修复 Modal 自定义 `footer` 时按钮内容丢失的问题。[#44929](https://github.com/ant-design/ant-design/pull/44929) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 修复 notification 底部弹出动画的问题。[#44918](https://github.com/ant-design/ant-design/pull/44918) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🐞 修复 Form.Item 有 `noStyle` 属性时没有继承上下文的反馈图标的问题。[#44937](https://github.com/ant-design/ant-design/pull/44937)
|
||||
|
||||
## 5.9.1
|
||||
|
||||
`2023-09-15`
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import useForceUpdate from './useForceUpdate';
|
||||
|
||||
type UseSyncStateProps<T> = readonly [() => T, (newValue: T) => void];
|
||||
|
@ -62,7 +62,7 @@ const showInsetEffect: WaveConfig['showEffect'] = (node, { event, component }) =
|
||||
// Motion
|
||||
requestAnimationFrame(() => {
|
||||
dot.ontransitionend = () => {
|
||||
holder.parentElement?.removeChild(holder);
|
||||
holder.remove();
|
||||
};
|
||||
|
||||
dot.style.width = '200px';
|
||||
|
@ -50,8 +50,12 @@ export default function StatusProvider({
|
||||
validateStatus,
|
||||
);
|
||||
|
||||
const { isFormItemInput: parentIsFormItemInput, status: parentStatus } =
|
||||
React.useContext(FormItemInputContext);
|
||||
const {
|
||||
isFormItemInput: parentIsFormItemInput,
|
||||
status: parentStatus,
|
||||
hasFeedback: parentHasFeedback,
|
||||
feedbackIcon: parentFeedbackIcon,
|
||||
} = React.useContext(FormItemInputContext);
|
||||
|
||||
// ====================== Context =======================
|
||||
const formItemStatusContext = React.useMemo<FormItemStatusContextProps>(() => {
|
||||
@ -75,23 +79,24 @@ export default function StatusProvider({
|
||||
) : null;
|
||||
}
|
||||
|
||||
let isFormItemInput: boolean | undefined = true;
|
||||
let status: ValidateStatus = mergedValidateStatus || '';
|
||||
|
||||
// No style will follow parent context
|
||||
if (noStyle) {
|
||||
isFormItemInput = parentIsFormItemInput;
|
||||
status = (mergedValidateStatus ?? parentStatus) || '';
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
const context: FormItemStatusContextProps = {
|
||||
status: mergedValidateStatus || '',
|
||||
errors,
|
||||
warnings,
|
||||
hasFeedback: !!hasFeedback,
|
||||
feedbackIcon,
|
||||
isFormItemInput,
|
||||
isFormItemInput: true,
|
||||
};
|
||||
|
||||
// No style will follow parent context
|
||||
if (noStyle) {
|
||||
context.status = (mergedValidateStatus ?? parentStatus) || '';
|
||||
context.isFormItemInput = parentIsFormItemInput;
|
||||
context.hasFeedback = !!(hasFeedback ?? parentHasFeedback);
|
||||
context.feedbackIcon = hasFeedback !== undefined ? context.feedbackIcon : parentFeedbackIcon;
|
||||
}
|
||||
|
||||
return context;
|
||||
}, [mergedValidateStatus, hasFeedback, noStyle, parentIsFormItemInput, parentStatus]);
|
||||
|
||||
// ======================= Render =======================
|
||||
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Field, FieldContext, ListContext } from 'rc-field-form';
|
||||
import type { FieldProps } from 'rc-field-form/lib/Field';
|
||||
import type { Meta } from 'rc-field-form/lib/interface';
|
||||
import type { InternalNamePath, Meta } from 'rc-field-form/lib/interface';
|
||||
import useState from 'rc-util/lib/hooks/useState';
|
||||
import { supportRef } from 'rc-util/lib/ref';
|
||||
|
||||
@ -138,7 +138,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
// ========================= MISC =========================
|
||||
// Get `noStyle` required info
|
||||
const listContext = React.useContext(ListContext);
|
||||
const fieldKeyPathRef = React.useRef<React.Key[]>();
|
||||
const fieldKeyPathRef = React.useRef<InternalNamePath>();
|
||||
|
||||
// ======================== Errors ========================
|
||||
// >>>>> Collect sub field errors
|
||||
|
@ -1418,15 +1418,15 @@ describe('Form', () => {
|
||||
</Form.Item>
|
||||
|
||||
{/* should follow parent status */}
|
||||
<Form.Item validateStatus="error">
|
||||
<Form.Item validateStatus="error" hasFeedback>
|
||||
<Form.Item noStyle>
|
||||
<Select className="custom-select-b" />
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
{/* should follow child status */}
|
||||
<Form.Item validateStatus="error">
|
||||
<Form.Item noStyle validateStatus="warning">
|
||||
<Form.Item validateStatus="error" hasFeedback>
|
||||
<Form.Item noStyle validateStatus="warning" hasFeedback={false}>
|
||||
<Select className="custom-select-c" />
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
@ -1455,9 +1455,19 @@ describe('Form', () => {
|
||||
|
||||
expect(container.querySelector('.custom-select-b')).toHaveClass('ant-select-status-error');
|
||||
expect(container.querySelector('.custom-select-b')).toHaveClass('ant-select-in-form-item');
|
||||
expect(
|
||||
container
|
||||
.querySelector('.custom-select-b')
|
||||
?.querySelector('.ant-form-item-feedback-icon-error'),
|
||||
).toBeTruthy();
|
||||
|
||||
expect(container.querySelector('.custom-select-c')).toHaveClass('ant-select-status-warning');
|
||||
expect(container.querySelector('.custom-select-c')).toHaveClass('ant-select-in-form-item');
|
||||
expect(
|
||||
container
|
||||
.querySelector('.custom-select-c')
|
||||
?.querySelector('.ant-form-item-feedback-icon-warning'),
|
||||
).toBeFalsy();
|
||||
|
||||
expect(container.querySelector('.custom-select-d')).toHaveClass('ant-select-status-warning');
|
||||
expect(container.querySelector('.custom-select-d')).toHaveClass('ant-select-in-form-item');
|
||||
|
@ -69,7 +69,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| component | Set the Form rendering element. Do not create a DOM node for `false` | ComponentType \| false | form | |
|
||||
| fields | Control of form fields through state management (such as redux). Not recommended for non-strong demand. View [example](#components-form-demo-global-state) | [FieldData](#fielddata)\[] | - | |
|
||||
| form | Form control instance created by `Form.useForm()`. Automatically created when not provided | [FormInstance](#forminstance) | - | |
|
||||
| feedbackIcons | Can be passed custom icons while `Form.Item` element has `hasFeedback` | [FeedbackIcons](#feedbackicons) | - | |
|
||||
| feedbackIcons | Can be passed custom icons while `Form.Item` element has `hasFeedback` | [FeedbackIcons](#feedbackicons) | - | 5.9.0 |
|
||||
| initialValues | Set value by Form initialization or reset | object | - | |
|
||||
| labelAlign | The text align of label of all items | `left` \| `right` | `right` | |
|
||||
| labelWrap | whether label can be wrap | boolean | false | 4.18.0 |
|
||||
@ -125,7 +125,7 @@ Form field component for data bidirectional binding, validation, layout, and so
|
||||
| extra | The extra prompt message. It is similar to help. Usage example: to display error message and prompt message at the same time | ReactNode | - | |
|
||||
| getValueFromEvent | Specify how to get value from event or other onChange arguments | (..args: any\[]) => any | - | |
|
||||
| getValueProps | Additional props with sub component | (value: any) => any | - | 4.2.0 |
|
||||
| hasFeedback | Used with `validateStatus`, this option specifies the validation status icon. Recommended to be used only with `Input`. Also, It can get feedback icons via icons prop. | boolean \| {icons:[FeedbackIcons](#feedbackicons)} | false | icons: 5.9.0 |
|
||||
| hasFeedback | Used with `validateStatus`, this option specifies the validation status icon. Recommended to be used only with `Input`. Also, It can get feedback icons via icons prop. | boolean \| { icons: [FeedbackIcons](#feedbackicons) } | false | icons: 5.9.0 |
|
||||
| help | The prompt message. If not provided, the prompt message will be generated by the validation rule. | ReactNode | - | |
|
||||
| hidden | Whether to hide Form.Item (still collect and validate value) | boolean | false | 4.4.0 |
|
||||
| htmlFor | Set sub label `htmlFor` | string | - | |
|
||||
@ -164,7 +164,7 @@ Used when there are dependencies between fields. If a field has the `dependencie
|
||||
|
||||
### FeedbackIcons
|
||||
|
||||
`({status:ValidateStatus, errors: ReactNode, warnings: ReactNode}) => Record<ValidateStatus,ReactNode>`
|
||||
`({ status: ValidateStatus, errors: ReactNode, warnings: ReactNode }) => Record<ValidateStatus, ReactNode>`
|
||||
|
||||
### shouldUpdate
|
||||
|
||||
|
@ -70,7 +70,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*ylFATY6w-ygAAA
|
||||
| component | 设置 Form 渲染元素,为 `false` 则不创建 DOM 节点 | ComponentType \| false | form | |
|
||||
| fields | 通过状态管理(如 redux)控制表单字段,如非强需求不推荐使用。查看[示例](#components-form-demo-global-state) | [FieldData](#fielddata)\[] | - | |
|
||||
| form | 经 `Form.useForm()` 创建的 form 控制实例,不提供时会自动创建 | [FormInstance](#forminstance) | - | |
|
||||
| feedbackIcons | Can be passed custom icons while `Form.Item` element has `hasFeedback` | ({status:ValidateStatus, errors: ReactNode, warnings: ReactNode}) => Record<ValidateStatus,ReactNode> | - | 5.9.0 |
|
||||
| feedbackIcons | 当 `Form.Item` 有 `hasFeedback` 属性时可以自定义图标 | [FeedbackIcons](#feedbackicons) | - | 5.9.0 |
|
||||
| initialValues | 表单默认值,只有初始化以及重置时生效 | object | - | |
|
||||
| labelAlign | label 标签的文本对齐方式 | `left` \| `right` | `right` | |
|
||||
| labelWrap | label 标签的文本换行方式 | boolean | false | 4.18.0 |
|
||||
@ -126,7 +126,7 @@ const validateMessages = {
|
||||
| extra | 额外的提示信息,和 `help` 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 | ReactNode | - | |
|
||||
| getValueFromEvent | 设置如何将 event 的值转换成字段值 | (..args: any\[]) => any | - | |
|
||||
| getValueProps | 为子元素添加额外的属性 | (value: any) => any | - | 4.2.0 |
|
||||
| hasFeedback | 配合 `validateStatus` 属性使用,展示校验状态图标,建议只配合 Input 组件使用 此外,它还可以通过 Icons 属性获取反馈图标。 | boolean \| {icons:({status:ValidateStatus, errors: ReactNode, warnings: ReactNode}) => Record<ValidateStatus,ReactNode>} | false | |
|
||||
| hasFeedback | 配合 `validateStatus` 属性使用,展示校验状态图标,建议只配合 Input 组件使用 此外,它还可以通过 Icons 属性获取反馈图标。 | boolean \| { icons: [FeedbackIcons](#feedbackicons) } | false | icons: 5.9.0 |
|
||||
| help | 提示信息,如不设置,则会根据校验规则自动生成 | ReactNode | - | |
|
||||
| hidden | 是否隐藏字段(依然会收集和校验字段) | boolean | false | 4.4.0 |
|
||||
| htmlFor | 设置子元素 label `htmlFor` 属性 | string | - | |
|
||||
@ -163,6 +163,10 @@ const validateMessages = {
|
||||
|
||||
`dependencies` 不应和 `shouldUpdate` 一起使用,因为这可能带来更新逻辑的混乱。
|
||||
|
||||
### FeedbackIcons
|
||||
|
||||
`({ status: ValidateStatus, errors: ReactNode, warnings: ReactNode }) => Record<ValidateStatus, ReactNode>`
|
||||
|
||||
### shouldUpdate
|
||||
|
||||
Form 通过增量更新方式,只更新被修改的字段相关组件以达到性能优化目的。大部分场景下,你只需要编写代码或者与 [`dependencies`](#dependencies) 属性配合校验即可。而在某些特定场景,例如修改某个字段值后出现新的字段选项、或者纯粹希望表单任意变化都对某一个区域进行渲染。你可以通过 `shouldUpdate` 修改 Form.Item 的更新逻辑。
|
||||
|
@ -2916,15 +2916,121 @@ Array [
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
style="width: 100px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="rc_select_TEST_OR_SSR_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="rc_select_TEST_OR_SSR_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
id="rc_select_TEST_OR_SSR"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity: 0;"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="rc_select_TEST_OR_SSR_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-label="Jack"
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_0"
|
||||
role="option"
|
||||
>
|
||||
jack
|
||||
</div>
|
||||
<div
|
||||
aria-label="Lucy"
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_1"
|
||||
role="option"
|
||||
>
|
||||
lucy
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-disabled"
|
||||
title="Disabled"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active"
|
||||
title="Jack"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Disabled
|
||||
Jack
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
@ -2936,12 +3042,151 @@ Array [
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="yiminghe"
|
||||
title="Lucy"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
yiminghe
|
||||
Lucy
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
style="width: 100px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="rc_select_TEST_OR_SSR_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="rc_select_TEST_OR_SSR_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
id="rc_select_TEST_OR_SSR"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity: 0;"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-placeholder"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="rc_select_TEST_OR_SSR_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-label="Jack"
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_0"
|
||||
role="option"
|
||||
>
|
||||
jack
|
||||
</div>
|
||||
<div
|
||||
aria-label="Lucy"
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_1"
|
||||
role="option"
|
||||
>
|
||||
lucy
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active"
|
||||
title="Jack"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Jack
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="Lucy"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Lucy
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
|
@ -655,6 +655,123 @@ Array [
|
||||
</span>
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
style="width:100px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title=""
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
style="width:100px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-placeholder"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-select ant-tree-select ant-select-single ant-select-show-arrow"
|
||||
style="width:100px"
|
||||
|
@ -1 +1,7 @@
|
||||
undefined
|
||||
## zh-CN
|
||||
|
||||
默认对齐效果。
|
||||
|
||||
## en-US
|
||||
|
||||
Align without Space.
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
} from 'antd';
|
||||
|
||||
const { Text } = Typography;
|
||||
const { Option } = Select;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const narrowStyle: React.CSSProperties = {
|
||||
@ -57,6 +56,11 @@ const options = [
|
||||
},
|
||||
];
|
||||
|
||||
const selectOptions = [
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
];
|
||||
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Mentions style={{ width: 100 }} rows={1} />
|
||||
@ -69,14 +73,9 @@ const App: React.FC = () => (
|
||||
<InputNumber style={{ width: 100 }} />
|
||||
<DatePicker style={{ width: 100 }} />
|
||||
<TimePicker style={{ width: 100 }} />
|
||||
<Select style={{ width: 100 }} defaultValue="jack">
|
||||
<Option value="jack">Jack</Option>
|
||||
<Option value="lucy">Lucy</Option>
|
||||
<Option value="disabled" disabled>
|
||||
Disabled
|
||||
</Option>
|
||||
<Option value="Yiminghe">yiminghe</Option>
|
||||
</Select>
|
||||
<Select style={{ width: 100 }} defaultValue="jack" options={selectOptions} />
|
||||
<Select style={{ width: 100 }} defaultValue="" options={selectOptions} />
|
||||
<Select style={{ width: 100 }} options={selectOptions} />
|
||||
<TreeSelect style={{ width: 100 }} />
|
||||
<Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} />
|
||||
<RangePicker />
|
||||
|
@ -78884,7 +78884,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
آذر
|
||||
سپتامبر
|
||||
</button>
|
||||
<button
|
||||
class="ant-picker-year-btn"
|
||||
@ -80943,7 +80943,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
آذر
|
||||
سپتامبر
|
||||
</button>
|
||||
<button
|
||||
class="ant-picker-year-btn"
|
||||
@ -81481,7 +81481,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
دی
|
||||
اکتبر
|
||||
</button>
|
||||
<button
|
||||
class="ant-picker-year-btn"
|
||||
@ -82578,9 +82578,9 @@ exports[`Locale Provider should display the text as fa 1`] = `
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title="آذر"
|
||||
title="سپتامبر"
|
||||
>
|
||||
آذر
|
||||
سپتامبر
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
|
@ -135,6 +135,18 @@ describe('Modal', () => {
|
||||
expect(document.querySelector('.custom-footer')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Should custom footer function second param work', () => {
|
||||
const footerFn = jest.fn();
|
||||
render(<Modal open footer={footerFn} />);
|
||||
|
||||
expect(footerFn).toHaveBeenCalled();
|
||||
expect(footerFn.mock.calls[0][0]).toBeTruthy();
|
||||
expect(footerFn.mock.calls[0][1]).toEqual({
|
||||
OkBtn: expect.any(Function),
|
||||
CancelBtn: expect.any(Function),
|
||||
});
|
||||
});
|
||||
|
||||
it('Should custom footer function work', () => {
|
||||
render(
|
||||
<Modal
|
||||
@ -150,4 +162,24 @@ describe('Modal', () => {
|
||||
);
|
||||
expect(document.querySelector('.custom-footer-ele')).toBeTruthy();
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/
|
||||
it('Both ways should be rendered normally on the page', () => {
|
||||
render(
|
||||
<Modal
|
||||
open
|
||||
footer={(origin, { OkBtn, CancelBtn }) => (
|
||||
<>
|
||||
<div className="first-origin">{origin}</div>
|
||||
<div className="second-props-origin">
|
||||
<OkBtn />
|
||||
<CancelBtn />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
/>,
|
||||
);
|
||||
expect(document.querySelector('.first-origin')).toMatchSnapshot();
|
||||
expect(document.querySelector('.second-props-origin')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,51 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Modal Both ways should be rendered normally on the page 1`] = `
|
||||
<div
|
||||
class="first-origin"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
OK
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Modal Both ways should be rendered normally on the page 2`] = `
|
||||
<div
|
||||
class="second-props-origin"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
OK
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Modal render correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
|
@ -71,17 +71,20 @@ export const Footer: React.FC<
|
||||
let footerNode;
|
||||
if (typeof footer === 'function' || typeof footer === 'undefined') {
|
||||
footerNode = (
|
||||
<ModalContextProvider value={btnCtxValueMemo}>
|
||||
<>
|
||||
<NormalCancelBtn />
|
||||
<NormalOkBtn />
|
||||
</ModalContextProvider>
|
||||
</>
|
||||
);
|
||||
|
||||
if (typeof footer === 'function') {
|
||||
footerNode = footer(footerNode, {
|
||||
OkBtn: NormalOkBtn,
|
||||
CancelBtn: NormalCancelBtn,
|
||||
});
|
||||
}
|
||||
|
||||
footerNode = <ModalContextProvider value={btnCtxValueMemo}>{footerNode}</ModalContextProvider>;
|
||||
} else {
|
||||
footerNode = footer;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import type { NotificationToken } from '.';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
|
||||
const genNotificationPlacementStyle: GenerateStyle<NotificationToken, CSSObject> = (token) => {
|
||||
const { componentCls, notificationMarginEdge } = token;
|
||||
const { componentCls, width, notificationMarginEdge, animationMaxHeight } = token;
|
||||
|
||||
const noticeCls = `${componentCls}-notice`;
|
||||
|
||||
@ -22,12 +22,12 @@ const genNotificationPlacementStyle: GenerateStyle<NotificationToken, CSSObject>
|
||||
|
||||
const topFadeIn = new Keyframes('antNotificationTopFadeIn', {
|
||||
'0%': {
|
||||
top: -token.animationMaxHeight,
|
||||
bottom: -animationMaxHeight,
|
||||
opacity: 0,
|
||||
},
|
||||
|
||||
'100%': {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
opacity: 1,
|
||||
},
|
||||
});
|
||||
|
@ -6071,12 +6071,13 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="normal"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
normal
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
@ -6264,12 +6265,13 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="normal"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
normal
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
@ -6312,6 +6314,457 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||
style="width: 120px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="rc_select_TEST_OR_SSR_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="rc_select_TEST_OR_SSR_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
id="rc_select_TEST_OR_SSR"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity: 0;"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="rc_select_TEST_OR_SSR_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_0"
|
||||
role="option"
|
||||
>
|
||||
long
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_1"
|
||||
role="option"
|
||||
>
|
||||
short
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<article
|
||||
class="ant-typography"
|
||||
>
|
||||
long, long, long piece of text
|
||||
</article>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<article
|
||||
class="ant-typography"
|
||||
>
|
||||
short
|
||||
</article>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="true"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-selected"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-clear"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close-circle"
|
||||
class="anticon anticon-close-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close-circle"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-multiple ant-select-allow-clear ant-select-show-arrow ant-select-show-search"
|
||||
style="width: 120px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-overflow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-overflow-item"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-item-content"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-selection-item-remove"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close"
|
||||
class="anticon anticon-close"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-search"
|
||||
style="width: 0px;"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="rc_select_TEST_OR_SSR_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="rc_select_TEST_OR_SSR_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
id="rc_select_TEST_OR_SSR"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity: 0;"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-selection-search-mirror"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="rc_select_TEST_OR_SSR_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_0"
|
||||
role="option"
|
||||
>
|
||||
long
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_1"
|
||||
role="option"
|
||||
>
|
||||
short
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<article
|
||||
class="ant-typography"
|
||||
>
|
||||
long, long, long piece of text
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<article
|
||||
class="ant-typography"
|
||||
>
|
||||
short
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="true"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-selected"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="check"
|
||||
class="anticon anticon-check"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-clear"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close-circle"
|
||||
class="anticon anticon-close-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close-circle"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
@ -6433,12 +6886,13 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="normal"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
normal
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -6561,12 +7015,13 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
class="ant-cascader-menu-item"
|
||||
data-path-key="normal"
|
||||
role="menuitemcheckbox"
|
||||
title="normal"
|
||||
>
|
||||
<div
|
||||
class="ant-cascader-menu-item-content"
|
||||
>
|
||||
normal
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@ -6802,12 +7257,14 @@ exports[`renders components/select/demo/option-label-center.tsx extend context c
|
||||
/>
|
||||
<span
|
||||
class="ant-select-tree-node-content-wrapper ant-select-tree-node-content-wrapper-normal"
|
||||
title="normal"
|
||||
title=""
|
||||
>
|
||||
<span
|
||||
class="ant-select-tree-title"
|
||||
>
|
||||
normal
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1931,6 +1931,243 @@ exports[`renders components/select/demo/option-label-center.tsx correctly 1`] =
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||
style="width:120px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-clear"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close-circle"
|
||||
class="anticon anticon-close-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close-circle"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-multiple ant-select-allow-clear ant-select-show-arrow ant-select-show-search"
|
||||
style="width:120px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-overflow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-overflow-item"
|
||||
style="opacity:1"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-item-content"
|
||||
>
|
||||
<div>
|
||||
normal
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-selection-item-remove"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close"
|
||||
class="anticon anticon-close"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix"
|
||||
style="opacity:1"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection-search"
|
||||
style="width:0"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-label="Search"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-selection-search-mirror"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-clear"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="close-circle"
|
||||
class="anticon anticon-close-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close-circle"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
|
@ -4,7 +4,7 @@ import { Select, Space, Cascader, Typography, TreeSelect } from 'antd';
|
||||
const options = [
|
||||
{ value: 'long', label: <Typography>long, long, long piece of text</Typography> },
|
||||
{ value: 'short', label: <Typography>short</Typography> },
|
||||
{ value: 'normal', label: 'normal' },
|
||||
{ value: 'normal', label: <div>normal</div> },
|
||||
];
|
||||
|
||||
const App: React.FC = () => (
|
||||
@ -23,6 +23,23 @@ const App: React.FC = () => (
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
defaultValue="normal"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
defaultValue={['normal']}
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
|
@ -55,9 +55,9 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
[[
|
||||
'&:after',
|
||||
/* For '' value baseline align */
|
||||
`${componentCls}-selection-item:after`,
|
||||
`${componentCls}-selection-item:empty:after`,
|
||||
/* For undefined value baseline align */
|
||||
`${componentCls}-selection-placeholder:after`,
|
||||
`${componentCls}-selection-placeholder:empty:after`,
|
||||
].join(',')]: {
|
||||
display: 'inline-block',
|
||||
width: 0,
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* eslint-disable no-unsafe-optional-chaining */
|
||||
/* eslint-disable react/no-multi-comp */
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import type { ColumnGroupType, ColumnType, TableProps } from '..';
|
||||
import Table from '..';
|
||||
import { act, fireEvent, render, waitFor } from '../../../tests/utils';
|
||||
import { resetWarned } from '../../_util/warning';
|
||||
import { act, fireEvent, render, waitFor } from '../../../tests/utils';
|
||||
import Button from '../../button';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import Input from '../../input';
|
||||
|
@ -22,6 +22,7 @@ import Tree from '../../../tree';
|
||||
import type {
|
||||
ColumnFilterItem,
|
||||
ColumnType,
|
||||
FilterKey,
|
||||
FilterSearchType,
|
||||
FilterValue,
|
||||
GetPopupContainer,
|
||||
@ -31,7 +32,7 @@ import type {
|
||||
import FilterSearch from './FilterSearch';
|
||||
import FilterDropdownMenuWrapper from './FilterWrapper';
|
||||
|
||||
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: React.Key }>;
|
||||
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: string }>;
|
||||
|
||||
interface FilterRestProps {
|
||||
confirm?: Boolean;
|
||||
@ -134,6 +135,10 @@ export interface FilterDropdownProps<RecordType> {
|
||||
filterResetToDefaultFilteredValue?: boolean;
|
||||
}
|
||||
|
||||
function wrapStringListType(keys?: FilterKey) {
|
||||
return (keys as string[]) || [];
|
||||
}
|
||||
|
||||
function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
const {
|
||||
tablePrefixCls,
|
||||
@ -196,20 +201,22 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
|
||||
// ===================== Select Keys =====================
|
||||
const propFilteredKeys = filterState?.filteredKeys;
|
||||
const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(propFilteredKeys || []);
|
||||
const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(
|
||||
wrapStringListType(propFilteredKeys),
|
||||
);
|
||||
|
||||
const onSelectKeys = ({ selectedKeys }: { selectedKeys: Key[] }) => {
|
||||
const onSelectKeys = ({ selectedKeys }: { selectedKeys: string[] }) => {
|
||||
setFilteredKeysSync(selectedKeys);
|
||||
};
|
||||
|
||||
const onCheck = (
|
||||
keys: Key[],
|
||||
keys: string[],
|
||||
{ node, checked }: { node: EventDataNode<FilterTreeDataNode>; checked: boolean },
|
||||
) => {
|
||||
if (!filterMultiple) {
|
||||
onSelectKeys({ selectedKeys: checked && node.key ? [node.key] : [] });
|
||||
} else {
|
||||
onSelectKeys({ selectedKeys: keys as Key[] });
|
||||
onSelectKeys({ selectedKeys: keys });
|
||||
}
|
||||
};
|
||||
|
||||
@ -217,7 +224,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
onSelectKeys({ selectedKeys: propFilteredKeys || [] });
|
||||
onSelectKeys({ selectedKeys: wrapStringListType(propFilteredKeys) });
|
||||
}, [propFilteredKeys]);
|
||||
|
||||
// ====================== Open Keys ======================
|
||||
@ -240,7 +247,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
}, [visible]);
|
||||
|
||||
// ======================= Submit ========================
|
||||
const internalTriggerFilter = (keys?: Key[]) => {
|
||||
const internalTriggerFilter = (keys?: string[]) => {
|
||||
const mergedKeys = keys && keys.length ? keys : null;
|
||||
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
|
||||
return null;
|
||||
@ -291,7 +298,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
const onVisibleChange = (newVisible: boolean) => {
|
||||
if (newVisible && propFilteredKeys !== undefined) {
|
||||
// Sync filteredKeys on appear in controlled mode (propFilteredKeys !== undefined)
|
||||
setFilteredKeysSync(propFilteredKeys || []);
|
||||
setFilteredKeysSync(wrapStringListType(propFilteredKeys));
|
||||
}
|
||||
|
||||
triggerVisible(newVisible);
|
||||
@ -321,7 +328,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
const key = String(filter.value);
|
||||
const item: FilterTreeDataNode = {
|
||||
title: filter.text,
|
||||
key: filter.value !== undefined ? key : index,
|
||||
key: filter.value !== undefined ? key : String(index),
|
||||
};
|
||||
if (filter.children) {
|
||||
item.children = getTreeData({ filters: filter.children });
|
||||
@ -340,7 +347,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
if (typeof column.filterDropdown === 'function') {
|
||||
dropdownContent = column.filterDropdown({
|
||||
prefixCls: `${dropdownPrefixCls}-custom`,
|
||||
setSelectedKeys: (selectedKeys: Key[]) => onSelectKeys({ selectedKeys }),
|
||||
setSelectedKeys: (selectedKeys: string[]) => onSelectKeys({ selectedKeys }),
|
||||
selectedKeys: getFilteredKeysSync(),
|
||||
confirm: doFilter,
|
||||
clearFilters: onReset,
|
||||
@ -439,7 +446,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
||||
className={dropdownMenuClass}
|
||||
onSelect={onSelectKeys}
|
||||
onDeselect={onSelectKeys}
|
||||
selectedKeys={selectedKeys as string[]}
|
||||
selectedKeys={selectedKeys}
|
||||
getPopupContainer={getPopupContainer}
|
||||
openKeys={openKeys}
|
||||
onOpenChange={onOpenChange}
|
||||
|
@ -9,6 +9,7 @@ import type {
|
||||
FilterValue,
|
||||
GetPopupContainer,
|
||||
Key,
|
||||
SafeKey,
|
||||
TableLocale,
|
||||
TransformColumns,
|
||||
} from '../../interface';
|
||||
@ -133,14 +134,17 @@ function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[])
|
||||
const currentFilters: Record<string, FilterValue | null> = {};
|
||||
|
||||
filterStates.forEach(({ key, filteredKeys, column }) => {
|
||||
const keyAsString = key as SafeKey;
|
||||
const { filters, filterDropdown } = column;
|
||||
if (filterDropdown) {
|
||||
currentFilters[key] = filteredKeys || null;
|
||||
currentFilters[keyAsString] = filteredKeys || null;
|
||||
} else if (Array.isArray(filteredKeys)) {
|
||||
const keys = flattenKeys(filters);
|
||||
currentFilters[key] = keys.filter((originKey) => filteredKeys.includes(String(originKey)));
|
||||
currentFilters[keyAsString] = keys.filter((originKey) =>
|
||||
filteredKeys.includes(String(originKey)),
|
||||
);
|
||||
} else {
|
||||
currentFilters[key] = null;
|
||||
currentFilters[keyAsString] = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type * as React from 'react';
|
||||
import type {
|
||||
FixedType,
|
||||
GetComponentProps,
|
||||
@ -5,14 +6,14 @@ import type {
|
||||
RenderedCell as RcRenderedCell,
|
||||
} from 'rc-table/lib/interface';
|
||||
import { ExpandableConfig, GetRowKey } from 'rc-table/lib/interface';
|
||||
import type * as React from 'react';
|
||||
|
||||
import type { Breakpoint } from '../_util/responsiveObserver';
|
||||
import type { AnyObject } from '../_util/type';
|
||||
import type { CheckboxProps } from '../checkbox';
|
||||
import type { PaginationProps } from '../pagination';
|
||||
import type { TooltipProps } from '../tooltip';
|
||||
import type { InternalTableProps, TableProps } from './InternalTable';
|
||||
import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection';
|
||||
import type { InternalTableProps, TableProps } from './InternalTable';
|
||||
|
||||
export type RefTable = <RecordType extends AnyObject = AnyObject>(
|
||||
props: React.PropsWithChildren<TableProps<RecordType>> & { ref?: React.Ref<HTMLDivElement> },
|
||||
@ -28,6 +29,8 @@ export { ExpandableConfig, GetRowKey };
|
||||
|
||||
export type Key = React.Key;
|
||||
|
||||
export type SafeKey = Exclude<Key, bigint>;
|
||||
|
||||
export type RowSelectionType = 'checkbox' | 'radio';
|
||||
|
||||
export type SelectionItemSelectFn = (currentRowKeys: Key[]) => void;
|
||||
@ -57,13 +60,13 @@ export interface TableLocale {
|
||||
export type SortOrder = 'descend' | 'ascend' | null;
|
||||
|
||||
const TableActions = ['paginate', 'sort', 'filter'] as const;
|
||||
export type TableAction = (typeof TableActions)[number];
|
||||
export type TableAction = typeof TableActions[number];
|
||||
|
||||
export type CompareFn<T> = (a: T, b: T, sortOrder?: SortOrder) => number;
|
||||
|
||||
export interface ColumnFilterItem {
|
||||
text: React.ReactNode;
|
||||
value: string | number | boolean;
|
||||
value: React.Key | boolean;
|
||||
children?: ColumnFilterItem[];
|
||||
}
|
||||
|
||||
@ -82,7 +85,7 @@ export type ColumnTitle<RecordType> =
|
||||
| ((props: ColumnTitleProps<RecordType>) => React.ReactNode);
|
||||
|
||||
export type FilterValue = (Key | boolean)[];
|
||||
export type FilterKey = Key[] | null;
|
||||
export type FilterKey = (string | number)[] | null;
|
||||
export type FilterSearchType<RecordType = AnyObject> =
|
||||
| boolean
|
||||
| ((input: string, record: RecordType) => boolean);
|
||||
@ -133,7 +136,7 @@ export interface ColumnType<RecordType> extends Omit<RcColumnType<RecordType>, '
|
||||
filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode);
|
||||
filterMode?: 'menu' | 'tree';
|
||||
filterSearch?: FilterSearchType<ColumnFilterItem>;
|
||||
onFilter?: (value: string | number | boolean, record: RecordType) => boolean;
|
||||
onFilter?: (value: React.Key | boolean, record: RecordType) => boolean;
|
||||
filterDropdownOpen?: boolean;
|
||||
onFilterDropdownOpenChange?: (visible: boolean) => void;
|
||||
filterResetToDefaultFilteredValue?: boolean;
|
||||
|
@ -44,7 +44,7 @@ const genSizeStyle: GenerateStyle<TableToken, CSSObject> = (token) => {
|
||||
},
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/35167
|
||||
[`${componentCls}-selection-column`]: {
|
||||
[`${componentCls}-selection-extra`]: {
|
||||
paddingInlineStart: `${paddingHorizontal / 4}px`,
|
||||
},
|
||||
},
|
||||
|
@ -289,6 +289,8 @@ describe('Theme', () => {
|
||||
expect(token2.colorLink).toEqual(token2.colorInfo);
|
||||
expect(token2.colorLinkHover).toEqual(token2.colorInfoHover);
|
||||
expect(token2.colorLinkActive).toEqual(token2.colorInfoActive);
|
||||
// colorInfo should not follow colorPrimary
|
||||
expect(token2.colorLink).not.toEqual('#189cff');
|
||||
|
||||
const token3 = getHookToken({ algorithm: [theme.darkAlgorithm] });
|
||||
expect(token3.colorLink).toEqual(token3.colorInfo);
|
||||
|
@ -10,7 +10,7 @@ interface TreeTransferProps {
|
||||
}
|
||||
|
||||
// Customize Table Transfer
|
||||
const isChecked = (selectedKeys: (string | number)[], eventKey: string | number) =>
|
||||
const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) =>
|
||||
selectedKeys.includes(eventKey);
|
||||
|
||||
const generateTree = (treeNodes: DataNode[] = [], checkedKeys: string[] = []): DataNode[] =>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import debounce from 'lodash/debounce';
|
||||
import type RcTree from 'rc-tree';
|
||||
import type { Key } from 'react';
|
||||
import type { Key } from 'rc-tree/lib/interface';
|
||||
import React from 'react';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
import { CarryOutOutlined } from '@ant-design/icons';
|
||||
import type { DataNode } from 'rc-tree/lib/interface';
|
||||
import React from 'react';
|
||||
import { CarryOutOutlined } from '@ant-design/icons';
|
||||
import type { TreeProps } from 'antd';
|
||||
import { Switch, Tree } from 'antd';
|
||||
import type { DataNode } from 'rc-tree/lib/interface';
|
||||
|
||||
const x = 3;
|
||||
const y = 2;
|
||||
|
@ -79,8 +79,8 @@ const App: React.FC = () => {
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((item, i, self) => item && self.indexOf(item) === i);
|
||||
setExpandedKeys(newExpandedKeys as React.Key[]);
|
||||
.filter((item, i, self): item is React.Key => !!(item && self.indexOf(item) === i));
|
||||
setExpandedKeys(newExpandedKeys);
|
||||
setSearchValue(value);
|
||||
setAutoExpandParent(true);
|
||||
};
|
||||
|
@ -12,19 +12,19 @@ author: Redjue
|
||||
|
||||
### RGB 色彩模型
|
||||
|
||||
`RGB` 色彩模型是通过三原色(红、绿、蓝)的不同组合来表示色彩的,每个原色的取值范围是 0-255,三原色的组合可以表示 256<sup>3</sup> 种颜色,这些颜色可以组成一个立方体,如下图所示: ![RGB](https://user-images.githubusercontent.com/21119589/266228482-f1ff94b1-e7ca-40c5-8512-1bc5ab79c388.jpg)
|
||||
`RGB` 色彩模型是通过三原色(红、绿、蓝)的不同组合来表示色彩的,每个原色的取值范围是 0-255,三原色的组合可以表示 256<sup>3</sup> 种颜色,这些颜色可以组成一个立方体,如下图所示: ![RGB](https://user-images.githubusercontent.com/21119589/268834307-79fca808-d3a3-4fe8-b370-ea1ec472023c.png)
|
||||
|
||||
在 `RGB` 色彩模型中,每个颜色都可以用一个三元组 `(R, G, B)` 来表示,其中 `R` 表示红色的取值,`G` 表示绿色的取值,`B` 表示蓝色的取值。例如,红色可以表示为 `(255, 0, 0)`,绿色可以表示为 `(0, 255, 0)`,蓝色可以表示为 `(0, 0, 255)`。
|
||||
|
||||
### HSV/HSB 色彩模型
|
||||
|
||||
`HSV` 色彩模型是通过色相(Hue)、饱和度(Saturation)、明度(Value)来表示色彩的,其中色相的取值范围是 0-360,饱和度和明度的取值范围是 0-100。HSV 色彩模型可以用一个圆锥体来表示,如下图所示: ![HSV](https://user-images.githubusercontent.com/21119589/266231236-d68ad9d7-9654-4bc5-8489-7cc52f2aabb1.png)
|
||||
`HSV` 色彩模型是通过色相(Hue)、饱和度(Saturation)、明度(Value)来表示色彩的,其中色相的取值范围是 0-360,饱和度和明度的取值范围是 0-100。HSV 色彩模型可以用一个圆锥体来表示,如下图所示: ![HSV](https://user-images.githubusercontent.com/21119589/268834741-83940b90-c709-492b-8a7e-f59d317411e9.png)
|
||||
|
||||
在 `HSV` 色彩模型中,每个颜色都可以用一个三元组 `(H, S, V)` 来表示,其中 `H` 表示色相的取值,`S` 表示饱和度的取值,`V` 表示明度的取值。例如,红色可以表示为 `(0, 100, 100)`,绿色可以表示为 `(120, 100, 100)`,蓝色可以表示为 `(240, 100, 100)`。
|
||||
|
||||
### HEX 色彩模型
|
||||
|
||||
`HEX` 色彩模型是通过十六进制数来表示色彩的,其中前两位表示红色的取值,中间两位表示绿色的取值,后两位表示蓝色的取值。例如,红色可以表示为 `#FF0000`,绿色可以表示为 `#00FF00`,蓝色可以表示为 `#0000FF`。如下图所示: ![HEX](https://user-images.githubusercontent.com/21119589/266569791-7f6afedd-3b84-4ee1-8c98-d3d4b16e8317.png)
|
||||
`HEX` 色彩模型是通过十六进制数来表示色彩的,其中前两位表示红色的取值,中间两位表示绿色的取值,后两位表示蓝色的取值。例如,红色可以表示为 `#FF0000`,绿色可以表示为 `#00FF00`,蓝色可以表示为 `#0000FF`。如下图所示: ![HEX](https://user-images.githubusercontent.com/21119589/268841812-1b8310f5-322b-45ec-b768-d4115cf7091d.png)
|
||||
|
||||
这也是我们最常见的颜色表示方式,因为它可以直接在 CSS 中使用。而且表示方式非常简单,只需要将 RGB 色彩模型中的三个数字转换为十六进制数即可。
|
||||
|
||||
@ -111,3 +111,11 @@ const alpha = (offset.x + centerOffsetX) / width;
|
||||
## 总结
|
||||
|
||||
通过这次开发之旅,我对色彩模型有了更深入的了解,也对 **Ant Design** 的开发流程有了更深入的了解。感谢 **Ant Design** 团队给我这次机会,也感谢大家的阅读。如果对细节实现感兴趣的童鞋,可以移步 [@rc-component/color-picker](https://github.com/react-component/color-picker) 查看源码实现。
|
||||
|
||||
## 图片来源
|
||||
|
||||
https://zh.wikipedia.org/wiki/%E4%B8%89%E5%8E%9F%E8%89%B2%E5%85%89%E6%A8%A1%E5%BC%8F#/media/File:RGB_color_solid_cube.png
|
||||
|
||||
https://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4#/media/File:HSV_cone.png
|
||||
|
||||
https://zh.wikipedia.org/wiki/%E7%BD%91%E9%A1%B5%E9%A2%9C%E8%89%B2#/media/File:Web_Color_Charts.svg
|
||||
|
@ -211,6 +211,10 @@ Please ref document [Shadow Dom Usage](/docs/react/customize-theme#shadow-dom-us
|
||||
|
||||
Please ref dynamic theme document [SSR](/docs/react/customize-theme#server-side-render-ssr) part.
|
||||
|
||||
## What is the relationship between colorPrimary and colorInfo and colorLink in V5?
|
||||
|
||||
In the Ant Design Token system, `colorPrimary` and `colorInfo` are both [Seed Token](../react/customize-theme.en-US.md#seed-token), so they are independent of each other. `colorLink` is an [Alias Token](../react/customize-theme.en-US.md#alias-token), inherits `colorInfo` by default, and is independent of `colorPrimary`.
|
||||
|
||||
## How to spell Ant Design correctly?
|
||||
|
||||
- ✅ **Ant Design**: Capitalized with space, for the design language.
|
||||
|
@ -239,6 +239,10 @@ import { ConfigProvider } from 'antd';
|
||||
|
||||
请参考动态主题文档 [服务端渲染](/docs/react/customize-theme-cn#服务端渲染) 部分内容。
|
||||
|
||||
## V5 中 colorPrimary 和 colorInfo 及 colorLink 之间是什么关系?
|
||||
|
||||
在 Ant Design Token 系统中 `colorPrimary` 和 `colorInfo` 同属于 [基础变量(Seed Token)](../react/customize-theme.zh-CN.md#基础变量seed-token),所以两者是互相独立的。`colorLink` 则属于 [别名变量(Alias Token)](../react/customize-theme.zh-CN.md#别名变量alias-token), 默认继承 `colorInfo` 且和 `colorPrimary` 无关。
|
||||
|
||||
## 如何正确的拼写 Ant Design?
|
||||
|
||||
- ✅ **Ant Design**:用空格分隔的首字母大写单词,指代设计语言。
|
||||
|
@ -175,8 +175,8 @@ import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
|
||||
import type Entity from '@ant-design/cssinjs/es/Cache';
|
||||
import { useServerInsertedHTML } from 'next/navigation';
|
||||
|
||||
const StyledComponentsRegistry = ({ children }: { children: React.ReactNode }) => {
|
||||
const cache = React.useMemo<Entity>(() => createCache(), [createCache]);
|
||||
const StyledComponentsRegistry = ({ children }: React.PropsWithChildren) => {
|
||||
const cache = React.useMemo<Entity>(() => createCache(), []);
|
||||
useServerInsertedHTML(() => (
|
||||
<style id="antd" dangerouslySetInnerHTML={{ __html: extractStyle(cache, true) }} />
|
||||
));
|
||||
@ -203,7 +203,7 @@ export const metadata = {
|
||||
description: 'Generated by create next app',
|
||||
};
|
||||
|
||||
const RootLayout = ({ children }: { children: React.ReactNode }) => (
|
||||
const RootLayout = ({ children }: React.PropsWithChildren) => (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>
|
||||
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
|
||||
|
@ -175,8 +175,8 @@ import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
|
||||
import type Entity from '@ant-design/cssinjs/es/Cache';
|
||||
import { useServerInsertedHTML } from 'next/navigation';
|
||||
|
||||
const StyledComponentsRegistry = ({ children }: { children: React.ReactNode }) => {
|
||||
const cache = React.useMemo<Entity>(() => createCache(), [createCache]);
|
||||
const StyledComponentsRegistry = ({ children }: React.PropsWithChildren) => {
|
||||
const cache = React.useMemo<Entity>(() => createCache(), []);
|
||||
useServerInsertedHTML(() => (
|
||||
<style id="antd" dangerouslySetInnerHTML={{ __html: extractStyle(cache, true) }} />
|
||||
));
|
||||
@ -203,7 +203,7 @@ export const metadata = {
|
||||
description: 'Generated by create next app',
|
||||
};
|
||||
|
||||
const RootLayout = ({ children }: { children: React.ReactNode }) => (
|
||||
const RootLayout = ({ children }: React.PropsWithChildren) => (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>
|
||||
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
|
||||
|
23
package.json
23
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.9.1",
|
||||
"version": "5.9.2",
|
||||
"packageManager": "^npm@9.0.0",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
@ -119,7 +119,6 @@
|
||||
"@rc-component/mutate-observer": "^1.1.0",
|
||||
"@rc-component/tour": "~1.10.0",
|
||||
"@rc-component/trigger": "^1.15.6",
|
||||
"@types/jsdom": "^21.1.2",
|
||||
"classnames": "^2.2.6",
|
||||
"copy-to-clipboard": "^3.2.0",
|
||||
"dayjs": "^1.11.1",
|
||||
@ -130,11 +129,11 @@
|
||||
"rc-dialog": "~9.2.0",
|
||||
"rc-drawer": "~6.4.1",
|
||||
"rc-dropdown": "~4.1.0",
|
||||
"rc-field-form": "~1.38.0",
|
||||
"rc-field-form": "~1.38.1",
|
||||
"rc-image": "~7.2.0",
|
||||
"rc-input": "~1.1.1",
|
||||
"rc-input-number": "~8.0.4",
|
||||
"rc-mentions": "~2.7.0",
|
||||
"rc-input": "~1.2.1",
|
||||
"rc-input-number": "~8.1.0",
|
||||
"rc-mentions": "~2.8.0",
|
||||
"rc-menu": "~9.12.0",
|
||||
"rc-motion": "^2.9.0",
|
||||
"rc-notification": "~5.2.0",
|
||||
@ -150,9 +149,9 @@
|
||||
"rc-switch": "~4.1.0",
|
||||
"rc-table": "~7.34.0",
|
||||
"rc-tabs": "~12.12.1",
|
||||
"rc-textarea": "~1.3.4",
|
||||
"rc-textarea": "~1.4.0",
|
||||
"rc-tooltip": "~6.0.1",
|
||||
"rc-tree": "~5.7.10",
|
||||
"rc-tree": "~5.7.12",
|
||||
"rc-tree-select": "~5.12.1",
|
||||
"rc-upload": "~4.3.4",
|
||||
"rc-util": "^5.37.0",
|
||||
@ -164,7 +163,7 @@
|
||||
"@ant-design/happy-work-theme": "^1.0.0",
|
||||
"@ant-design/tools": "^17.3.1",
|
||||
"@antv/g6": "^4.8.13",
|
||||
"@argos-ci/core": "^0.11.0",
|
||||
"@argos-ci/core": "^0.12.0",
|
||||
"@babel/eslint-plugin": "^7.19.1",
|
||||
"@biomejs/biome": "^1.0.0",
|
||||
"@codesandbox/sandpack-react": "^2.6.9",
|
||||
@ -192,8 +191,10 @@
|
||||
"@types/jest-environment-puppeteer": "^5.0.0",
|
||||
"@types/jest-image-snapshot": "^6.1.0",
|
||||
"@types/jquery": "^3.5.14",
|
||||
"@types/jsdom": "^21.1.2",
|
||||
"@types/lodash": "^4.14.139",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@types/progress": "^2.0.5",
|
||||
"@types/qs": "^6.9.7",
|
||||
@ -216,7 +217,7 @@
|
||||
"cross-fetch": "^4.0.0",
|
||||
"crypto": "^1.0.1",
|
||||
"dekko": "^0.2.1",
|
||||
"dumi": "^2.1.23",
|
||||
"dumi": "^2.2.10",
|
||||
"duplicate-package-checker-webpack-plugin": "^3.0.0",
|
||||
"esbuild-loader": "^4.0.0",
|
||||
"eslint": "^8.40.0",
|
||||
@ -285,7 +286,7 @@
|
||||
"react-router-dom": "^6.0.2",
|
||||
"react-sticky-box": "^2.0.0",
|
||||
"regenerator-runtime": "^0.14.0",
|
||||
"remark": "^14.0.1",
|
||||
"remark": "^15.0.1",
|
||||
"remark-cli": "^11.0.0",
|
||||
"remark-lint": "^9.0.0",
|
||||
"remark-preset-lint-recommended": "^6.0.0",
|
||||
|
@ -8,7 +8,10 @@ const output = '.dumi/preset';
|
||||
|
||||
// Collect components
|
||||
const componentNames = globSync(
|
||||
path.join(process.cwd(), 'components/!(version|icon|col|row)/index.zh-CN.md').split(path.sep).join('/'),
|
||||
path
|
||||
.join(process.cwd(), 'components/!(version|icon|col|row)/index.zh-CN.md')
|
||||
.split(path.sep)
|
||||
.join('/'),
|
||||
)
|
||||
.map((filePath) => filePath.replace(/\\/g, '/').match(/components\/([^/]*)\//)![1])
|
||||
.filter((name) => name !== 'overview');
|
||||
@ -133,11 +136,16 @@ const miscKeys = [
|
||||
let changelogLine = line.trim().replace('- ', '');
|
||||
changelogLine = changelogLine
|
||||
.replace(/\[([^\]]+)]\(([^)]+)\)/g, (...match) => {
|
||||
const [, , ref] = match;
|
||||
const [, title, ref] = match;
|
||||
if (ref.includes('/pull/')) {
|
||||
refs.push(ref);
|
||||
}
|
||||
return '';
|
||||
|
||||
if (title && (title[0] === '#' || title[0] === '@')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return title;
|
||||
})
|
||||
.trim();
|
||||
|
||||
|
@ -46,6 +46,7 @@ const DEPRECIATED_VERSION = {
|
||||
'https://github.com/ant-design/ant-design/issues/43684',
|
||||
],
|
||||
'5.8.0': ['https://github.com/ant-design/ant-design/issues/43943'],
|
||||
'5.9.1': ['https://github.com/ant-design/ant-design/issues/44907'],
|
||||
} as const;
|
||||
|
||||
function matchDeprecated(v: string) {
|
||||
|
@ -7,6 +7,7 @@ import { globSync } from 'glob';
|
||||
import { configureToMatchImageSnapshot } from 'jest-image-snapshot';
|
||||
import MockDate from 'mockdate';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
|
||||
import { App, ConfigProvider, theme } from '../../components';
|
||||
|
||||
const toMatchImageSnapshot = configureToMatchImageSnapshot({
|
||||
@ -77,7 +78,6 @@ export default function imageTest(component: React.ReactElement, options: ImageT
|
||||
|
||||
const image = await page.screenshot({
|
||||
fullPage: !options.onlyViewport,
|
||||
optimizeForSpeed: true,
|
||||
});
|
||||
|
||||
expect(image).toMatchImageSnapshot();
|
||||
|
@ -2,6 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@@/*": [".dumi/tmp/*"],
|
||||
"antd": ["components/index.ts"],
|
||||
"antd/es/*": ["components/*"],
|
||||
"antd/lib/*": ["components/*"],
|
||||
@ -23,5 +24,6 @@
|
||||
"skipLibCheck": true,
|
||||
"stripInternal": true
|
||||
},
|
||||
"include": [".dumirc.ts", "**/*"],
|
||||
"exclude": ["node_modules", "lib", "es"]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user