chore: auto merge branches (#42668)

chore: feature merge master
This commit is contained in:
github-actions[bot] 2023-05-27 03:42:37 +00:00 committed by GitHub
commit a8bc13e77b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 810 additions and 142 deletions

View File

@ -1,9 +1,10 @@
/* eslint import/no-unresolved: 0 */ import { RightOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { ConfigProvider, Table } from 'antd'; import { ConfigProvider, Table } from 'antd';
import { getDesignToken } from 'antd-token-previewer'; import { getDesignToken } from 'antd-token-previewer';
import tokenMeta from 'antd/es/version/token-meta.json'; import tokenMeta from 'antd/es/version/token-meta.json';
import tokenData from 'antd/es/version/token.json'; import tokenData from 'antd/es/version/token.json';
import React from 'react'; import React, { useMemo, useState } from 'react';
import useLocale from '../../../hooks/useLocale'; import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken'; import useSiteToken from '../../../hooks/useSiteToken';
import { useColumns } from '../TokenTable'; import { useColumns } from '../TokenTable';
@ -25,17 +26,39 @@ const locales = {
}, },
}; };
const useStyle = () => ({
tableTitle: css`
cursor: pointer;
position: relative;
display: flex;
align-items: center;
justify-content: flex-start;
line-height: 40px;
`,
arrowIcon: css`
font-size: 16px;
margin-right: 8px;
& svg {
transition: all 0.3s;
}
`,
});
interface SubTokenTableProps { interface SubTokenTableProps {
defaultOpen?: boolean; defaultOpen?: boolean;
title: string; title: string;
tokens: string[]; tokens: string[];
} }
function SubTokenTable({ defaultOpen, tokens, title }: SubTokenTableProps) { const SubTokenTable: React.FC<SubTokenTableProps> = ({ defaultOpen, tokens, title }) => {
const [, lang] = useLocale(locales); const [, lang] = useLocale(locales);
const { token } = useSiteToken(); const { token } = useSiteToken();
const columns = useColumns(); const columns = useColumns();
const [open, setOpen] = useState<boolean>(defaultOpen || process.env.NODE_ENV !== 'production');
const { tableTitle, arrowIcon } = useStyle();
if (!tokens.length) { if (!tokens.length) {
return null; return null;
} }
@ -66,44 +89,40 @@ function SubTokenTable({ defaultOpen, tokens, title }: SubTokenTableProps) {
name, name,
desc: lang === 'cn' ? meta.desc : meta.descEn, desc: lang === 'cn' ? meta.desc : meta.descEn,
type: meta.type, type: meta.type,
value: (defaultToken as any)[name], value: defaultToken[name],
}; };
}) })
.filter((info) => info); .filter(Boolean);
return ( return (
// Reuse `.markdown` style <div>
<details className="markdown" open={defaultOpen || process.env.NODE_ENV !== 'production'}> <div css={tableTitle} onClick={() => setOpen(!open)}>
<summary> <RightOutlined css={arrowIcon} rotate={open ? 90 : 0} />
<h3 style={{ display: 'inline' }}>{title}</h3> <h3>{title}</h3>
</summary> </div>
<ConfigProvider {open && (
theme={{ <ConfigProvider theme={{ token: { borderRadius: 0 } }}>
token: { <Table
borderRadius: 0, size="middle"
}, columns={columns}
}} bordered
> dataSource={data}
<Table style={{ marginBottom: token.margin }}
size="middle" pagination={false}
columns={columns} rowKey={(record) => record.name}
bordered />
dataSource={data} </ConfigProvider>
style={{ marginBottom: token.margin }} )}
pagination={false} </div>
rowKey={(record) => record.name}
/>
</ConfigProvider>
</details>
); );
} };
export interface ComponentTokenTableProps { export interface ComponentTokenTableProps {
component: string; component: string;
} }
function ComponentTokenTable({ component }: ComponentTokenTableProps) { const ComponentTokenTable: React.FC<ComponentTokenTableProps> = ({ component }) => {
const [mergedGlobalTokens] = React.useMemo(() => { const [mergedGlobalTokens] = useMemo(() => {
const globalTokenSet = new Set<string>(); const globalTokenSet = new Set<string>();
let componentTokens: Record<string, string> = {}; let componentTokens: Record<string, string> = {};
@ -121,16 +140,10 @@ function ComponentTokenTable({ component }: ComponentTokenTableProps) {
}; };
}); });
return [Array.from(globalTokenSet), componentTokens]; return [Array.from(globalTokenSet), componentTokens] as const;
}, [component]); }, [component]);
return ( return <SubTokenTable title="Global Token" tokens={mergedGlobalTokens} />;
<> };
{/* Component Token 先不展示 */}
{/* <SubTokenTable title="Component Token" tokens={mergedComponentTokens} defaultOpen /> */}
<SubTokenTable title="Global Token" tokens={mergedGlobalTokens} />
</>
);
}
export default React.memo(ComponentTokenTable); export default React.memo(ComponentTokenTable);

13
.github/workflows/pr-stat.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Pull Request Stats
on:
pull_request:
types: [opened]
jobs:
stats:
if: github.repository == 'ant-design/ant-design'
runs-on: ubuntu-latest
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@master

1
.npmrc Normal file
View File

@ -0,0 +1 @@
package-lock=false

View File

@ -224,6 +224,7 @@ const genCardLoadingStyle: GenerateStyle<CardToken> = (token): CSSObject => {
// ============================== Basic ============================== // ============================== Basic ==============================
const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => { const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
const { const {
antCls,
componentCls, componentCls,
cardShadow, cardShadow,
cardHeadPadding, cardHeadPadding,
@ -268,7 +269,7 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
width: '100%', width: '100%',
}, },
img: { [`img, img + ${antCls}-image-mask`]: {
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`, borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
}, },
}, },

View File

@ -406,24 +406,50 @@ exports[`renders components/checkbox/demo/debug-line.tsx extend context correctl
</span> </span>
</label> </label>
</div> </div>
<label <div>
class="ant-checkbox-wrapper" <label
> class="ant-checkbox-wrapper"
<span
class="ant-checkbox"
> >
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span <span
class="ant-checkbox-inner" class="ant-checkbox"
/> >
</span> <input
<span> class="ant-checkbox-input"
Aligned type="checkbox"
</span> />
</label> <span
class="ant-checkbox-inner"
/>
</span>
<span>
Aligned
</span>
</label>
</div>
<div>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
<span>
<span
style="font-size: 32px;"
>
Aligned
</span>
</span>
</label>
</div>
</div> </div>
`; `;

View File

@ -383,24 +383,50 @@ exports[`renders components/checkbox/demo/debug-line.tsx correctly 1`] = `
</span> </span>
</label> </label>
</div> </div>
<label <div>
class="ant-checkbox-wrapper" <label
> class="ant-checkbox-wrapper"
<span
class="ant-checkbox"
> >
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span <span
class="ant-checkbox-inner" class="ant-checkbox"
/> >
</span> <input
<span> class="ant-checkbox-input"
Aligned type="checkbox"
</span> />
</label> <span
class="ant-checkbox-inner"
/>
</span>
<span>
Aligned
</span>
</label>
</div>
<div>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
<span>
<span
style="font-size:32px"
>
Aligned
</span>
</span>
</label>
</div>
</div> </div>
`; `;

View File

@ -44,15 +44,23 @@ const App: React.FC = () => (
<Radio value="little">Little</Radio> <Radio value="little">Little</Radio>
</div> </div>
<ConfigProvider <div>
theme={{ <ConfigProvider
token: { theme={{
controlHeight: 48, token: {
}, controlHeight: 48,
}} },
> }}
<Checkbox>Aligned</Checkbox> >
</ConfigProvider> <Checkbox>Aligned</Checkbox>
</ConfigProvider>
</div>
<div>
<Checkbox>
<span style={{ fontSize: 32 }}>Aligned</span>
</Checkbox>
</div>
</div> </div>
); );

View File

@ -83,13 +83,9 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
lineHeight: 1, lineHeight: 1,
cursor: 'pointer', cursor: 'pointer',
alignSelf: 'start', // To make alignment right when `controlHeight` is changed
// https://github.com/ant-design/ant-design/issues/41564 // Ref: https://github.com/ant-design/ant-design/issues/41564
// Since `checkboxSize` is dynamic which should align with the text box, alignSelf: 'center',
// We need do calculation here for offset.
transform: `translate(0, ${
(token.lineHeight * token.fontSize) / 2 - token.checkboxSize / 2
}px)`,
// Wrapper > Checkbox > input // Wrapper > Checkbox > input
[`${checkboxCls}-input`]: { [`${checkboxCls}-input`]: {

View File

@ -4737,3 +4737,385 @@ Array [
</div>, </div>,
] ]
`; `;
exports[`renders components/color-picker/demo/trigger-event.tsx extend context correctly 1`] = `
Array [
<div
class="ant-color-picker-trigger"
>
<div
class="ant-color-picker-color-block"
>
<div
class="ant-color-picker-color-block-inner"
style="background: rgb(22, 119, 255);"
/>
</div>
</div>,
<div
class="ant-popover ant-zoom-big-appear ant-zoom-big-appear-prepare ant-zoom-big ant-color-picker ant-popover-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-popover-arrow"
style="position: absolute;"
/>
<div
class="ant-popover-content"
>
<div
class="ant-popover-inner"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<div
class="ant-color-picker-panel"
>
<div
class="ant-color-picker-inner-panel"
>
<div
class="ant-color-picker-select"
>
<div
class="ant-color-picker-palette"
style="position: relative;"
>
<div
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
>
<div
class="ant-color-picker-handler"
style="background-color: rgb(22, 119, 255);"
/>
</div>
<div
class="ant-color-picker-saturation"
style="background-color: rgb(0, 0, 0);"
/>
</div>
</div>
<div
class="ant-color-picker-slider-container"
>
<div
class="ant-color-picker-slider-group"
>
<div
class="ant-color-picker-slider ant-color-picker-slider-hue"
>
<div
class="ant-color-picker-palette"
style="position: relative;"
>
<div
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
>
<div
class="ant-color-picker-handler ant-color-picker-handler-sm"
style="background-color: rgb(0, 0, 0);"
/>
</div>
<div
class="ant-color-picker-gradient"
style="position: absolute; inset: 0;"
/>
</div>
</div>
<div
class="ant-color-picker-slider ant-color-picker-slider-alpha"
>
<div
class="ant-color-picker-palette"
style="position: relative;"
>
<div
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
>
<div
class="ant-color-picker-handler ant-color-picker-handler-sm"
style="background-color: rgb(22, 119, 255);"
/>
</div>
<div
class="ant-color-picker-gradient"
style="position: absolute; inset: 0;"
/>
</div>
</div>
</div>
<div
class="ant-color-picker-color-block"
>
<div
class="ant-color-picker-color-block-inner"
style="background: rgb(22, 119, 255);"
/>
</div>
</div>
<div
class="ant-color-picker-input-container"
>
<div
class="ant-select ant-select-sm ant-select-borderless ant-color-picker-format-select ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
>
<span
class="ant-select-selection-search"
>
<input
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
aria-autocomplete="list"
aria-controls="rc_select_TEST_OR_SSR_list"
aria-expanded="false"
aria-haspopup="listbox"
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="HEX"
>
HEX
</span>
</div>
<div
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomRight"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; width: 68px;"
>
<div>
<div
id="rc_select_TEST_OR_SSR_list"
role="listbox"
style="height: 0px; width: 0px; overflow: hidden;"
>
<div
aria-label="HEX"
aria-selected="true"
id="rc_select_TEST_OR_SSR_list_0"
role="option"
>
hex
</div>
<div
aria-label="HSB"
aria-selected="false"
id="rc_select_TEST_OR_SSR_list_1"
role="option"
>
hsb
</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="true"
class="ant-select-item ant-select-item-option ant-select-item-option-active ant-select-item-option-selected"
title="HEX"
>
<div
class="ant-select-item-option-content"
>
HEX
</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="HSB"
>
<div
class="ant-select-item-option-content"
>
HSB
</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="RGB"
>
<div
class="ant-select-item-option-content"
>
RGB
</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-color-picker-input"
>
<span
class="ant-input-affix-wrapper ant-color-picker-hex-input ant-input-affix-wrapper-sm"
>
<span
class="ant-input-prefix"
>
#
</span>
<input
class="ant-input ant-input-sm"
type="text"
value="1677FF"
/>
</span>
</div>
<div
class="ant-input-number ant-input-number-sm ant-color-picker-steppers ant-color-picker-alpha-input"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="true"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up ant-input-number-handler-up-disabled"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
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-input-number-input-wrap"
>
<input
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="100"
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value="100%"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>,
]
`;

View File

@ -265,3 +265,18 @@ exports[`renders components/color-picker/demo/trigger.tsx correctly 1`] = `
</div> </div>
</div> </div>
`; `;
exports[`renders components/color-picker/demo/trigger-event.tsx correctly 1`] = `
<div
class="ant-color-picker-trigger"
>
<div
class="ant-color-picker-color-block"
>
<div
class="ant-color-picker-color-block-inner"
style="background:rgb(22, 119, 255)"
/>
</div>
</div>
`;

View File

@ -0,0 +1,7 @@
## zh-CN
自定义颜色面板的触发事件,提供 `click``hover` 两个选项。
## en-US
Triggers event for customizing color panels.

View File

@ -0,0 +1,6 @@
import { ColorPicker } from 'antd';
import React from 'react';
const Demo = () => <ColorPicker trigger="hover" />;
export default Demo;

View File

@ -24,6 +24,7 @@ Used when the user needs to customize the color selection.
<code src="./demo/disabled.tsx" debug>Disable</code> <code src="./demo/disabled.tsx" debug>Disable</code>
<code src="./demo/allowClear.tsx">Clear Color</code> <code src="./demo/allowClear.tsx">Clear Color</code>
<code src="./demo/trigger.tsx">Custom Trigger</code> <code src="./demo/trigger.tsx">Custom Trigger</code>
<code src="./demo/trigger-event.tsx">Custom Trigger Event</code>
<code src="./demo/format.tsx">Color Format</code> <code src="./demo/format.tsx">Color Format</code>
<code src="./demo/presets.tsx">Preset Colors</code> <code src="./demo/presets.tsx">Preset Colors</code>
<code src="./demo/pure-panel.tsx" debug>Pure Render</code> <code src="./demo/pure-panel.tsx" debug>Pure Render</code>

View File

@ -25,6 +25,7 @@ group:
<code src="./demo/disabled.tsx" debug>禁用</code> <code src="./demo/disabled.tsx" debug>禁用</code>
<code src="./demo/allowClear.tsx">清除颜色</code> <code src="./demo/allowClear.tsx">清除颜色</code>
<code src="./demo/trigger.tsx">自定义触发器</code> <code src="./demo/trigger.tsx">自定义触发器</code>
<code src="./demo/trigger-event.tsx">自定义触发事件</code>
<code src="./demo/format.tsx">颜色编码</code> <code src="./demo/format.tsx">颜色编码</code>
<code src="./demo/presets.tsx">预设颜色</code> <code src="./demo/presets.tsx">预设颜色</code>
<code src="./demo/pure-panel.tsx" debug>Pure Render</code> <code src="./demo/pure-panel.tsx" debug>Pure Render</code>

View File

@ -1,13 +1,13 @@
import { createTheme } from '@ant-design/cssinjs'; import { createTheme } from '@ant-design/cssinjs';
import IconContext from '@ant-design/icons/lib/components/Context'; import IconContext from '@ant-design/icons/lib/components/Context';
import { FormProvider as RcFormProvider } from 'rc-field-form';
import type { ValidateMessages } from 'rc-field-form/lib/interface'; import type { ValidateMessages } from 'rc-field-form/lib/interface';
import { setValues } from 'rc-field-form/lib/utils/valueUtil';
import useMemo from 'rc-util/lib/hooks/useMemo'; import useMemo from 'rc-util/lib/hooks/useMemo';
import { merge } from 'rc-util/lib/utils/set';
import type { ReactElement } from 'react'; import type { ReactElement } from 'react';
import * as React from 'react'; import * as React from 'react';
import type { Options } from 'scroll-into-view-if-needed'; import type { Options } from 'scroll-into-view-if-needed';
import warning from '../_util/warning'; import warning from '../_util/warning';
import { ValidateMessagesContext } from '../form/context';
import type { RequiredMark } from '../form/Form'; import type { RequiredMark } from '../form/Form';
import type { Locale } from '../locale'; import type { Locale } from '../locale';
import LocaleProvider, { ANT_MARK } from '../locale'; import LocaleProvider, { ANT_MARK } from '../locale';
@ -311,8 +311,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
const validateMessages = React.useMemo( const validateMessages = React.useMemo(
() => () =>
setValues( merge(
{},
defaultLocale.Form?.defaultValidateMessages || {}, defaultLocale.Form?.defaultValidateMessages || {},
memoedConfig.locale?.Form?.defaultValidateMessages || {}, memoedConfig.locale?.Form?.defaultValidateMessages || {},
form?.validateMessages || {}, form?.validateMessages || {},
@ -321,7 +320,11 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
); );
if (Object.keys(validateMessages).length > 0) { if (Object.keys(validateMessages).length > 0) {
childNode = <RcFormProvider validateMessages={validateMessages}>{children}</RcFormProvider>; childNode = (
<ValidateMessagesContext.Provider value={validateMessages}>
{children}
</ValidateMessagesContext.Provider>
);
} }
if (locale) { if (locale) {

View File

@ -12,6 +12,7 @@ const locale: PickerLocale = {
weekPlaceholder: 'Pasirinkite savaitę', weekPlaceholder: 'Pasirinkite savaitę',
rangePlaceholder: ['Pradžios data', 'Pabaigos data'], rangePlaceholder: ['Pradžios data', 'Pabaigos data'],
rangeYearPlaceholder: ['Pradžios metai', 'Pabaigos metai'], rangeYearPlaceholder: ['Pradžios metai', 'Pabaigos metai'],
rangeQuarterPlaceholder: ['Pradžios ketvirtis', 'Pabaigos ketvirtis'],
rangeMonthPlaceholder: ['Pradžios mėnesis', 'Pabaigos mėnesis'], rangeMonthPlaceholder: ['Pradžios mėnesis', 'Pabaigos mėnesis'],
rangeWeekPlaceholder: ['Pradžios savaitė', 'Pabaigos savaitė'], rangeWeekPlaceholder: ['Pradžios savaitė', 'Pabaigos savaitė'],
...CalendarLocale, ...CalendarLocale,

View File

@ -12,7 +12,7 @@ import { SizeContextProvider } from '../config-provider/SizeContext';
import useSize from '../config-provider/hooks/useSize'; import useSize from '../config-provider/hooks/useSize';
import type { ColProps } from '../grid/col'; import type { ColProps } from '../grid/col';
import type { FormContextProps } from './context'; import type { FormContextProps } from './context';
import { FormContext } from './context'; import { FormContext, FormProvider, ValidateMessagesContext } from './context';
import useForm, { type FormInstance } from './hooks/useForm'; import useForm, { type FormInstance } from './hooks/useForm';
import useFormWarning from './hooks/useFormWarning'; import useFormWarning from './hooks/useFormWarning';
import type { FormLabelAlign } from './interface'; import type { FormLabelAlign } from './interface';
@ -67,6 +67,8 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
const mergedSize = useSize(size); const mergedSize = useSize(size);
const contextValidateMessages = React.useContext(ValidateMessagesContext);
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
useFormWarning(props); useFormWarning(props);
@ -158,16 +160,23 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
return wrapSSR( return wrapSSR(
<DisabledContextProvider disabled={disabled}> <DisabledContextProvider disabled={disabled}>
<SizeContextProvider size={mergedSize}> <SizeContextProvider size={mergedSize}>
<FormContext.Provider value={formContextValue}> <FormProvider
<FieldForm {...{
id={name} // This is not list in API, we pass with spread
{...restFormProps} validateMessages: contextValidateMessages,
name={name} }}
onFinishFailed={onInternalFinishFailed} >
form={wrapForm} <FormContext.Provider value={formContextValue}>
className={formClassName} <FieldForm
/> id={name}
</FormContext.Provider> {...restFormProps}
name={name}
onFinishFailed={onInternalFinishFailed}
form={wrapForm}
className={formClassName}
/>
</FormContext.Provider>
</FormProvider>
</SizeContextProvider> </SizeContextProvider>
</DisabledContextProvider>, </DisabledContextProvider>,
); );

View File

@ -1,6 +1,6 @@
import { FormProvider as RcFormProvider } from 'rc-field-form'; import { FormProvider as RcFormProvider } from 'rc-field-form';
import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext'; import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
import type { Meta } from 'rc-field-form/lib/interface'; import type { Meta, ValidateMessages } from 'rc-field-form/lib/interface';
import omit from 'rc-util/lib/omit'; import omit from 'rc-util/lib/omit';
import type { FC, PropsWithChildren, ReactNode } from 'react'; import type { FC, PropsWithChildren, ReactNode } from 'react';
import * as React from 'react'; import * as React from 'react';
@ -92,3 +92,5 @@ export const NoFormStyle: FC<NoFormStyleProps> = ({ children, status, override }
</FormItemInputContext.Provider> </FormItemInputContext.Provider>
); );
}; };
export const ValidateMessagesContext = React.createContext<ValidateMessages | undefined>(undefined);

View File

@ -1,9 +1,8 @@
/* eslint-disable no-template-curly-in-string */ /* eslint-disable no-template-curly-in-string */
import Pagination from 'rc-pagination/lib/locale/lt_LT'; import Pagination from 'rc-pagination/lib/locale/lt_LT';
import type { Locale } from '.';
import Calendar from '../calendar/locale/lt_LT'; import Calendar from '../calendar/locale/lt_LT';
import DatePicker from '../date-picker/locale/lt_LT'; import DatePicker from '../date-picker/locale/lt_LT';
import type { Locale } from '.';
import TimePicker from '../time-picker/locale/lt_LT'; import TimePicker from '../time-picker/locale/lt_LT';
const typeTemplate: string = '${label} neatitinka tipo ${type}'; const typeTemplate: string = '${label} neatitinka tipo ${type}';
@ -14,14 +13,20 @@ const localeValues: Locale = {
DatePicker, DatePicker,
TimePicker, TimePicker,
Calendar, Calendar,
global: {
placeholder: 'Pasirinkite',
},
Table: { Table: {
filterTitle: 'Filtras', filterTitle: 'Filtras',
filterConfirm: 'Gerai', filterConfirm: 'Gerai',
filterReset: 'Atstatyti', filterReset: 'Atstatyti',
filterEmptyText: 'Be filtrų', filterEmptyText: 'Be filtrų',
filterCheckall: 'Pasirinkti visus',
filterSearchPlaceholder: 'Ieškoti filtruose',
emptyText: 'Nėra duomenų', emptyText: 'Nėra duomenų',
selectAll: 'Pasirinkti viską', selectAll: 'Pasirinkti viską',
selectInvert: 'Apversti pasirinkimą', selectInvert: 'Apversti pasirinkimą',
selectNone: 'Išvalyti visus',
selectionAll: 'Rinktis visus', selectionAll: 'Rinktis visus',
sortTitle: 'Rikiavimas', sortTitle: 'Rikiavimas',
expand: 'Išskleisti', expand: 'Išskleisti',
@ -30,6 +35,11 @@ const localeValues: Locale = {
triggerAsc: 'Spustelėkite norėdami rūšiuoti didėjančia tvarka', triggerAsc: 'Spustelėkite norėdami rūšiuoti didėjančia tvarka',
cancelSort: 'Spustelėkite, kad atšauktumėte rūšiavimą', cancelSort: 'Spustelėkite, kad atšauktumėte rūšiavimą',
}, },
Tour: {
Next: 'Kitas',
Previous: 'Ankstesnis',
Finish: 'Baigti',
},
Modal: { Modal: {
okText: 'Taip', okText: 'Taip',
cancelText: 'Atšaukti', cancelText: 'Atšaukti',
@ -45,18 +55,18 @@ const localeValues: Locale = {
itemUnit: 'vnt.', itemUnit: 'vnt.',
itemsUnit: 'vnt.', itemsUnit: 'vnt.',
remove: 'Pašalinti', remove: 'Pašalinti',
selectAll: 'Pasirinkti visus', selectCurrent: 'Pasirinkti dabartinį puslapį',
selectCurrent: 'Pasirinkite dabartinį puslapį',
selectInvert: 'Atkeist pasirinkimą',
removeAll: 'Ištrinti visus duomenis',
removeCurrent: 'Ištrinti dabartinį puslapį', removeCurrent: 'Ištrinti dabartinį puslapį',
selectAll: 'Pasirinkti viską',
removeAll: 'Ištrinti viską',
selectInvert: 'Apversti pasirinkimą',
}, },
Upload: { Upload: {
uploading: 'Gaunami duomenys...', uploading: 'Įkeliami duomenys...',
removeFile: 'Ištrinti failą', removeFile: 'Ištrinti failą',
uploadError: 'Įkeliant įvyko klaida', uploadError: 'Įkeliant įvyko klaida',
previewFile: 'Failo peržiūra', previewFile: 'Failo peržiūra',
downloadFile: 'Įkelti failą', downloadFile: 'Atsisiųsti failą',
}, },
Empty: { Empty: {
description: 'Nėra duomenų', description: 'Nėra duomenų',
@ -74,11 +84,12 @@ const localeValues: Locale = {
back: 'Atgal', back: 'Atgal',
}, },
Form: { Form: {
optional: '(neprivaloma)',
defaultValidateMessages: { defaultValidateMessages: {
default: 'Laukelio klaida ${label}', default: 'Klaida laukelyje ${label}',
required: 'Prašome įvesti ${label}', required: 'Prašome įvesti ${label}',
enum: '${label} turėtu būti vienas iš [${enum}]', enum: '${label} turi būti vienas iš [${enum}]',
whitespace: '${label} negali likti tuščiu', whitespace: '${label} negali likti tuščias',
date: { date: {
format: '${label} neteisingas datos formatas', format: '${label} neteisingas datos formatas',
parse: '${label} negali būti konvertuotas į datą', parse: '${label} negali būti konvertuotas į datą',
@ -101,26 +112,37 @@ const localeValues: Locale = {
}, },
string: { string: {
len: '${label} turi būti ${len} simbolių', len: '${label} turi būti ${len} simbolių',
min: '${label} turi būti ilgesnis nei ${min} simbolių', min: '${label} turi būti bent ${min} simbolių',
max: '${label} turi būti ne trumpesnis ${max} simbolių', max: '${label} turi būti ne ilgesnis nei ${max} simbolių',
range: 'Lauko ${label} reikšmės ribos ${min}-${max} simbolių', range: 'Laukelio ${label} reikšmės ribos ${min}-${max} simbolių',
}, },
number: { number: {
len: '${label} turi būti lygi ${len}', len: '${label} turi būti lygi ${len}',
min: '${label} turi būti lygus arba didesnis ${min}', min: '${label} turi būti lygus arba didesnis už ${min}',
max: '${label} turi būti lygus arba mažesnis ${max}', max: '${label} turi būti lygus arba mažesnis už ${max}',
range: '${label} turi būti tarp ${min}-${max}',
}, },
array: { array: {
len: 'Pasirinktas kiekis ${label} turi būti lygus ${len}', len: 'Pasirinktas kiekis ${label} turi būti lygus ${len}',
min: 'Pasirinktas kiekis ${label} turi būti lygus arba didesnis ${min}', min: 'Pasirinktas kiekis ${label} turi būti bent ${min}',
max: 'Pasirinktas kiekis ${label} turi būti lygus arba mažesnis ${max}', max: 'Pasirinktas kiekis ${label} turi būti ne ilgesnis nei ${max}',
range: 'Pasirinktas kiekis ${label} turi būti tarp ${min} и ${max}', range: 'Pasirinktas ${label} kiekis turi būti tarp ${min}-${max}',
}, },
pattern: { pattern: {
mismatch: '${label} neatitinka modelio ${pattern}', mismatch: '${label} neatitinka modelio ${pattern}',
}, },
}, },
}, },
Image: {
preview: 'Peržiūrėti',
},
QRCode: {
expired: 'QR kodo galiojimas baigėsi',
refresh: 'Atnaujinti',
},
ColorPicker: {
presetEmpty: 'Tuščia',
},
}; };
export default localeValues; export default localeValues;

View File

@ -829,4 +829,20 @@ describe('Modal.confirm triggers callbacks correctly', () => {
expect(document.querySelector(`.ant-modal-content`)).toMatchSnapshot(); expect(document.querySelector(`.ant-modal-content`)).toMatchSnapshot();
}); });
}); });
it('warning getContainer be false', async () => {
resetWarned();
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
Modal.confirm({
getContainer: false,
});
await waitFakeTimer();
expect(warnSpy).toHaveBeenCalledWith(
'Warning: [antd: Modal] Static method not support `getContainer` to be `false` since it do not have context env.',
);
warnSpy.mockRestore();
});
}); });

View File

@ -50,7 +50,13 @@ export default function confirm(config: ModalFuncProps) {
reactUnmount(container); reactUnmount(container);
} }
function render({ okText, cancelText, prefixCls: customizePrefixCls, ...props }: any) { function render({
okText,
cancelText,
prefixCls: customizePrefixCls,
getContainer,
...props
}: any) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
/** /**
@ -67,9 +73,23 @@ export default function confirm(config: ModalFuncProps) {
const iconPrefixCls = getIconPrefixCls(); const iconPrefixCls = getIconPrefixCls();
const theme = getTheme(); const theme = getTheme();
let mergedGetContainer = getContainer;
if (mergedGetContainer === false) {
mergedGetContainer = undefined;
if (process.env.NODE_ENV !== 'production') {
warning(
false,
'Modal',
'Static method not support `getContainer` to be `false` since it do not have context env.',
);
}
}
reactRender( reactRender(
<ConfirmDialog <ConfirmDialog
{...props} {...props}
getContainer={mergedGetContainer}
prefixCls={prefixCls} prefixCls={prefixCls}
rootPrefixCls={rootPrefixCls} rootPrefixCls={rootPrefixCls}
iconPrefixCls={iconPrefixCls} iconPrefixCls={iconPrefixCls}

View File

@ -72,6 +72,7 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
width: 0, width: 0,
margin: `${FIXED_ITEM_MARGIN}px 0`, margin: `${FIXED_ITEM_MARGIN}px 0`,
lineHeight: `${selectItemHeight}px`, lineHeight: `${selectItemHeight}px`,
visibility: 'hidden',
content: '"\\a0"', content: '"\\a0"',
}, },
}, },

View File

@ -316,6 +316,46 @@ Array [
class="ant-space ant-space-horizontal ant-space-align-center" class="ant-space ant-space-horizontal ant-space-align-center"
style="flex-wrap: wrap; margin-bottom: -8px;" style="flex-wrap: wrap; margin-bottom: -8px;"
> >
<div
class="ant-space-item"
style="margin-right: 0px; padding-bottom: 8px;"
>
<span
class="ant-tag ant-tag-processing ant-tag-borderless"
>
processing
</span>
</div>
<div
class="ant-space-item"
style="margin-right: 0px; padding-bottom: 8px;"
>
<span
class="ant-tag ant-tag-success ant-tag-borderless"
>
success
</span>
</div>
<div
class="ant-space-item"
style="margin-right: 0px; padding-bottom: 8px;"
>
<span
class="ant-tag ant-tag-error ant-tag-borderless"
>
error
</span>
</div>
<div
class="ant-space-item"
style="margin-right: 0px; padding-bottom: 8px;"
>
<span
class="ant-tag ant-tag-warning ant-tag-borderless"
>
warning
</span>
</div>
<div <div
class="ant-space-item" class="ant-space-item"
style="margin-right: 0px; padding-bottom: 8px;" style="margin-right: 0px; padding-bottom: 8px;"

View File

@ -316,6 +316,46 @@ Array [
class="ant-space ant-space-horizontal ant-space-align-center" class="ant-space ant-space-horizontal ant-space-align-center"
style="flex-wrap:wrap;margin-bottom:-8px" style="flex-wrap:wrap;margin-bottom:-8px"
> >
<div
class="ant-space-item"
style="margin-right:0;padding-bottom:8px"
>
<span
class="ant-tag ant-tag-processing ant-tag-borderless"
>
processing
</span>
</div>
<div
class="ant-space-item"
style="margin-right:0;padding-bottom:8px"
>
<span
class="ant-tag ant-tag-success ant-tag-borderless"
>
success
</span>
</div>
<div
class="ant-space-item"
style="margin-right:0;padding-bottom:8px"
>
<span
class="ant-tag ant-tag-error ant-tag-borderless"
>
error
</span>
</div>
<div
class="ant-space-item"
style="margin-right:0;padding-bottom:8px"
>
<span
class="ant-tag ant-tag-warning ant-tag-borderless"
>
warning
</span>
</div>
<div <div
class="ant-space-item" class="ant-space-item"
style="margin-right:0;padding-bottom:8px" style="margin-right:0;padding-bottom:8px"

View File

@ -15,6 +15,18 @@ const App: React.FC = () => (
</Space> </Space>
<Divider /> <Divider />
<Space size={[0, 'small']} wrap> <Space size={[0, 'small']} wrap>
<Tag bordered={false} color="processing">
processing
</Tag>
<Tag bordered={false} color="success">
success
</Tag>
<Tag bordered={false} color="error">
error
</Tag>
<Tag bordered={false} color="warning">
warning
</Tag>
<Tag bordered={false} color="magenta"> <Tag bordered={false} color="magenta">
magenta magenta
</Tag> </Tag>

View File

@ -33,6 +33,9 @@ const genTagStatusStyle = (
color: token[`color${cssVariableType}`], color: token[`color${cssVariableType}`],
background: token[`color${capitalizedCssVariableType}Bg`], background: token[`color${capitalizedCssVariableType}Bg`],
borderColor: token[`color${capitalizedCssVariableType}Border`], borderColor: token[`color${capitalizedCssVariableType}Border`],
[`&${token.componentCls}-borderless`]: {
borderColor: 'transparent',
},
}, },
}; };
}; };

View File

@ -1,10 +1,10 @@
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs'; import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import { Keyframes } from '@ant-design/cssinjs'; import { Keyframes } from '@ant-design/cssinjs';
import { genCollapseMotion } from '../../style/motion';
import { getStyle as getCheckboxStyle } from '../../checkbox/style'; import { getStyle as getCheckboxStyle } from '../../checkbox/style';
import { genFocusOutline, resetComponent } from '../../style';
import { genCollapseMotion } from '../../style/motion';
import type { DerivativeToken } from '../../theme/internal'; import type { DerivativeToken } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal'; import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import { genFocusOutline, resetComponent } from '../../style';
// ============================ Keyframes ============================= // ============================ Keyframes =============================
const treeNodeFX = new Keyframes('ant-tree-node-fx-do-not-use', { const treeNodeFX = new Keyframes('ant-tree-node-fx-do-not-use', {
@ -63,16 +63,7 @@ type TreeToken = DerivativeToken & {
}; };
export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject => { export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject => {
const { const { treeCls, treeNodeCls, treeNodePadding, treeTitleHeight } = token;
treeCls,
treeNodeCls,
controlInteractiveSize: checkboxSize,
treeNodePadding,
treeTitleHeight,
} = token;
// Ref: https://github.com/ant-design/ant-design/issues/41564
const checkBoxOffset = (token.lineHeight * token.fontSize) / 2 - checkboxSize / 2;
const treeCheckBoxMarginVertical = (treeTitleHeight - token.fontSizeLG) / 2 - checkBoxOffset;
const treeCheckBoxMarginHorizontal = token.paddingXS; const treeCheckBoxMarginHorizontal = token.paddingXS;
return { return {
@ -269,7 +260,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
[`${treeCls}-checkbox`]: { [`${treeCls}-checkbox`]: {
top: 'initial', top: 'initial',
marginInlineEnd: treeCheckBoxMarginHorizontal, marginInlineEnd: treeCheckBoxMarginHorizontal,
marginBlockStart: treeCheckBoxMarginVertical,
}, },
// >>> Title // >>> Title

View File

@ -62,6 +62,12 @@ Since antd's components are based on react-component, sometimes you may need to
## Development Workflow ## Development Workflow
Before you can start you must run the following command to enable [corepack](https://nodejs.org/api/corepack.html)。
```bash
corepack enable
```
After cloning antd, run `npm install` to fetch its dependencies. Then, you can run several commands: After cloning antd, run `npm install` to fetch its dependencies. Then, you can run several commands:
1. `npm start` runs Ant Design website locally. 1. `npm start` runs Ant Design website locally.

View File

@ -62,6 +62,12 @@ Ant Design 团队会关注所有的 pull request我们会 review 以及合并
## 开发流程 ## 开发流程
在开始之前,请先执行下面的命令启用 [corepack](https://nodejs.org/api/corepack.html)。
```bash
corepack enable
```
在你 clone 了 antd 的代码并且使用 `npm install` 安装完依赖后,你还可以运行下面几个常用的命令: 在你 clone 了 antd 的代码并且使用 `npm install` 安装完依赖后,你还可以运行下面几个常用的命令:
1. `npm start` 在本地运行 Ant Design 的网站。 1. `npm start` 在本地运行 Ant Design 的网站。

View File

@ -1,6 +1,7 @@
{ {
"name": "antd", "name": "antd",
"version": "5.5.1", "version": "5.5.1",
"packageManager": "^npm@9.0.0",
"description": "An enterprise-class UI design language and React components implementation", "description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design", "title": "Ant Design",
"keywords": [ "keywords": [
@ -127,7 +128,7 @@
"rc-dialog": "~9.1.0", "rc-dialog": "~9.1.0",
"rc-drawer": "~6.1.1", "rc-drawer": "~6.1.1",
"rc-dropdown": "~4.1.0", "rc-dropdown": "~4.1.0",
"rc-field-form": "~1.31.0", "rc-field-form": "~1.32.0",
"rc-image": "~5.16.0", "rc-image": "~5.16.0",
"rc-input": "~1.0.4", "rc-input": "~1.0.4",
"rc-input-number": "~7.4.0", "rc-input-number": "~7.4.0",
@ -152,7 +153,7 @@
"rc-tree": "~5.7.4", "rc-tree": "~5.7.4",
"rc-tree-select": "~5.9.0", "rc-tree-select": "~5.9.0",
"rc-upload": "~4.3.0", "rc-upload": "~4.3.0",
"rc-util": "^5.27.0", "rc-util": "^5.32.0",
"scroll-into-view-if-needed": "^3.0.3", "scroll-into-view-if-needed": "^3.0.3",
"throttle-debounce": "^5.0.0" "throttle-debounce": "^5.0.0"
}, },
@ -244,7 +245,7 @@
"jest-environment-jsdom": "^29.0.1", "jest-environment-jsdom": "^29.0.1",
"jest-environment-node": "^29.0.0", "jest-environment-node": "^29.0.0",
"jest-image-snapshot": "^6.0.0", "jest-image-snapshot": "^6.0.0",
"jest-puppeteer": "^8.0.4", "jest-puppeteer": "^9.0.0",
"jquery": "^3.4.1", "jquery": "^3.4.1",
"jsdom": "^22.0.0", "jsdom": "^22.0.0",
"jsonml-to-react-element": "^1.1.11", "jsonml-to-react-element": "^1.1.11",