Merge branch 'master' into feature-merge-master

This commit is contained in:
MadCcc 2023-01-10 17:43:13 +08:00
commit 43541cb6d9
13 changed files with 91 additions and 161 deletions

View File

@ -25,7 +25,12 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
const visibleDemos = showDebug ? items : items.filter((item) => !item.previewerProps.debug);
const filteredItems = visibleDemos.map((item) => ({
...item,
previewerProps: { ...item.previewerProps, expand: expandAll },
previewerProps: {
...item.previewerProps,
expand: expandAll,
// always override debug property, because dumi will hide debug demo in production
debug: false,
},
}));
return (

View File

@ -2,7 +2,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
import { useLocation } from 'dumi';
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
import classNames from 'classnames';
import { Col, Modal, Popover, Row, Select, Typography } from 'antd';
import { Col, Modal, Popover, Row, Select } from 'antd';
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
import { ClassNames, css } from '@emotion/react';
import * as utils from '../../utils';
@ -24,17 +24,6 @@ const { Option } = Select;
const antdVersion: string = packageJson.version;
const locales = {
cn: {
title: '🎉🎉🎉 Ant Design 5.0 发布! 🎉🎉🎉',
ok: '知道了',
},
en: {
title: '🎉🎉🎉 Ant Design 5.0 is released! 🎉🎉🎉',
ok: 'Got it',
},
};
const useStyle = () => {
const { token } = useSiteToken();
const searchIconColor = '#ced4d9';
@ -120,7 +109,6 @@ const useStyle = () => {
};
};
const V5_NOTIFICATION = 'antd@4.0.0-notification-sent';
const SHOULD_OPEN_ANT_DESIGN_MIRROR_MODAL = 'ANT_DESIGN_DO_NOT_OPEN_MIRROR_MODAL';
function disableAntdMirrorModal() {
@ -140,33 +128,7 @@ interface HeaderState {
// ================================= Header =================================
const Header: React.FC = () => {
const [isClient, setIsClient] = React.useState(false);
const [locale, lang] = useLocale(locales);
const { token } = useSiteToken();
const [notify, setNotify] = React.useState<null | boolean>(null);
// ========================= 发布通知 开始 =========================
React.useEffect(() => {
if (utils.isLocalStorageNameSupported()) {
// 大版本发布后全局弹窗提示
// 1. 点击『知道了』之后不再提示
// 2. 超过截止日期后不再提示
if (
localStorage.getItem(V5_NOTIFICATION) !== 'true' &&
Date.now() < new Date('2022/12/31').getTime()
) {
setNotify(true);
return;
}
}
setNotify(false);
}, []);
function onClose() {
setNotify(false);
localStorage.setItem(V5_NOTIFICATION, 'true');
}
// ========================= 发布通知 结束 =========================
const [, lang] = useLocale();
const themeConfig = getThemeConfig();
const [headerState, setHeaderState] = useState<HeaderState>({
@ -322,60 +284,20 @@ const Header: React.FC = () => {
/>
);
let menu: (React.ReactElement | null)[] = [
let menu: React.ReactNode[] = [
navigationNode,
<Popover
<Select
key="version"
open={!!notify}
title={locale?.title}
content={
<Typography style={{ marginTop: token.marginXS }}>
{lang === 'cn' ? (
<>
<div>
{' '}
<Typography.Link
target="_blank"
href="https://github.com/ant-design/ant-design/issues/38463"
>
GitHub Issue
</Typography.Link>{' '}
</div>
<div> v4 </div>
</>
) : (
<>
<div>
If you find any official site problem. Please feel free to report on{' '}
<Typography.Link
target="_blank"
href="https://github.com/ant-design/ant-design/issues/38463"
>
GitHub Issue
</Typography.Link>
.
</div>
<p>Click above Select to switch to v4 docs.</p>
</>
)}
</Typography>
}
className="version"
size="small"
defaultValue={antdVersion}
onChange={handleVersionChange}
dropdownStyle={getDropdownStyle}
dropdownMatchSelectWidth={false}
getPopupContainer={(trigger) => trigger.parentNode}
>
<Select
key="version"
className="version"
size="small"
defaultValue={antdVersion}
onChange={handleVersionChange}
dropdownStyle={getDropdownStyle}
dropdownMatchSelectWidth={false}
getPopupContainer={(trigger) => trigger.parentNode}
onClick={onClose}
>
{versionOptions}
</Select>
</Popover>,
{versionOptions}
</Select>,
<More key="more" {...sharedProps} />,
<SwitchBtn
key="lang"

View File

@ -15,6 +15,14 @@ timeline: true
---
## 5.1.4
`2023-1-9`
- 🐞 Fix missing locale file. [#40116](https://github.com/ant-design/ant-design/pull/40116)
- 🐞 Fix Cascader dropdown `placement` in RTL mode. [#40109](https://github.com/ant-design/ant-design/pull/40109) [@3hson](https://github.com/3hson)
- 🐞 Fix animation flicking in some components. [react-component/motion#39](https://github.com/react-component/motion/pull/39)
## 5.1.3
`2023-1-9`

View File

@ -15,6 +15,14 @@ timeline: true
---
## 5.1.4
`2023-1-9`
- 🐞 修复 locale 文件丢失的问题。[#40116](https://github.com/ant-design/ant-design/pull/40116)
- 🐞 修复 Cascader 组件 RTL 模式中下拉菜单位置问题。[#40109](https://github.com/ant-design/ant-design/pull/40109) [@3hson](https://github.com/3hson)
- 🐞 修复部分组件动画闪烁的问题。[react-component/motion#39](https://github.com/react-component/motion/pull/39)
## 5.1.3
`2023-1-9`

View File

@ -272,9 +272,7 @@ const Cascader = React.forwardRef((props: CascaderProps<any>, ref: React.Ref<Cas
if (placement !== undefined) {
return placement;
}
return direction === 'rtl'
? ('bottomRight' as SelectCommonPlacement)
: ('bottomLeft' as SelectCommonPlacement);
return isRtl ? 'bottomRight' : 'bottomLeft';
};
// ==================== Render =====================

View File

@ -104,7 +104,8 @@ We added a `createFromIconfontCN` function to help developer use their own icons
> This method is specified for [iconfont.cn](http://iconfont.cn/).
```js
```jsx
import React from 'react';
import { createFromIconfontCN } from '@ant-design/icons';
const MyIcon = createFromIconfontCN({
@ -133,7 +134,8 @@ You can import SVG icon as a react component by using `webpack` and [`@svgr/webp
```js
// webpack.config.js
{
module.exports = {
// ... other config
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
@ -147,7 +149,7 @@ You can import SVG icon as a react component by using `webpack` and [`@svgr/webp
},
},
],
}
};
```
```jsx

View File

@ -99,7 +99,8 @@ getTwoToneColor(); // #eb2f96
`3.9.0` 之后,我们提供了一个 `createFromIconfontCN` 方法,方便开发者调用在 [iconfont.cn](http://iconfont.cn/) 上自行管理的图标。
```js
```jsx
import React from 'react';
import { createFromIconfontCN } from '@ant-design/icons';
const MyIcon = createFromIconfontCN({
@ -128,7 +129,8 @@ options 的配置项如下:
```js
// webpack.config.js
{
module.exports = {
// ... other config
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
@ -142,7 +144,7 @@ options 的配置项如下:
},
},
],
}
};
```
```jsx

View File

@ -2,7 +2,7 @@ import React from 'react';
import Watermark from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { render, waitFor } from '../../../tests/utils';
import { render, waitFor, waitFakeTimer } from '../../../tests/utils';
describe('Watermark', () => {
mountTest(Watermark);
@ -67,6 +67,7 @@ describe('Watermark', () => {
it('MutationObserver should work properly', async () => {
const { container } = render(<Watermark className="watermark" content="MutationObserver" />);
const target = container.querySelector<HTMLDivElement>('.watermark div');
await waitFakeTimer();
target?.remove();
await waitFor(() => expect(target).toBeTruthy());
expect(container).toMatchSnapshot();
@ -77,6 +78,7 @@ describe('Watermark', () => {
<Watermark offset={[-200, -200]} className="watermark" content="MutationObserver" />,
);
const target = container.querySelector<HTMLDivElement>('.watermark div');
await waitFakeTimer();
target?.setAttribute('style', '');
await waitFor(() => expect(target).toBeTruthy());
expect(container).toMatchSnapshot();

View File

@ -1,6 +1,6 @@
import React, { useEffect, useRef } from 'react';
import useMutationObserver from './useMutationObserver';
import { getStyleStr, getPixelRatio, rotateWatermark } from './utils';
import MutateObserver from '@rc-component/mutate-observer';
import { getStyleStr, getPixelRatio, rotateWatermark, reRendering } from './utils';
/**
* Base size of the canvas, 1 for parallel layout and 2 for alternate layout
@ -96,7 +96,7 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
const containerRef = useRef<HTMLDivElement>(null);
const watermarkRef = useRef<HTMLDivElement>();
const { createObserver, destroyObserver, reRendering } = useMutationObserver();
const stopObservation = useRef(false);
const destroyWatermark = () => {
if (watermarkRef.current) {
@ -107,7 +107,7 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
const appendWatermark = (base64Url: string, markWidth: number) => {
if (containerRef.current && watermarkRef.current) {
destroyObserver();
stopObservation.current = true;
watermarkRef.current.setAttribute(
'style',
getStyleStr({
@ -117,14 +117,9 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
}),
);
containerRef.current?.append(watermarkRef.current);
createObserver(containerRef.current, (mutations) => {
mutations.forEach((mutation) => {
if (reRendering(mutation, watermarkRef.current)) {
destroyWatermark();
// eslint-disable-next-line @typescript-eslint/no-use-before-define
renderWatermark();
}
});
// Delayed execution
setTimeout(() => {
stopObservation.current = false;
});
}
};
@ -221,6 +216,18 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
}
};
const onMutate = (mutations: MutationRecord[]) => {
if (stopObservation.current) {
return;
}
mutations.forEach((mutation) => {
if (reRendering(mutation, watermarkRef.current)) {
destroyWatermark();
renderWatermark();
}
});
};
useEffect(renderWatermark, [
rotate,
zIndex,
@ -240,9 +247,11 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
]);
return (
<div ref={containerRef} className={className} style={{ position: 'relative', ...style }}>
{children}
</div>
<MutateObserver onMutate={onMutate}>
<div ref={containerRef} className={className} style={{ position: 'relative', ...style }}>
{children}
</div>
</MutateObserver>
);
};

View File

@ -1,42 +0,0 @@
import { useEffect, useRef } from 'react';
export default function useMutationObserver() {
const instance = useRef<MutationObserver>();
const destroyObserver = () => {
if (instance.current) {
instance.current.takeRecords();
instance.current.disconnect();
instance.current = undefined;
}
};
const createObserver = (target: Node, callback: MutationCallback) => {
if (MutationObserver) {
destroyObserver();
instance.current = new MutationObserver(callback);
instance.current.observe(target, {
childList: true,
subtree: true,
attributeFilter: ['style', 'class'],
});
}
};
useEffect(() => destroyObserver, []);
const reRendering = (mutation: MutationRecord, watermarkElement?: HTMLElement) => {
let flag = false;
// Whether to delete the watermark node
if (mutation.removedNodes.length) {
flag = Array.from(mutation.removedNodes).some((node) => node === watermarkElement);
}
// Whether the watermark dom property value has been modified
if (mutation.type === 'attributes' && mutation.target === watermarkElement) {
flag = true;
}
return flag;
};
return { createObserver, destroyObserver, reRendering };
}

View File

@ -25,3 +25,17 @@ export function rotateWatermark(
ctx.rotate((Math.PI / 180) * Number(rotate));
ctx.translate(-rotateX, -rotateY);
}
/** Whether to re-render the watermark */
export const reRendering = (mutation: MutationRecord, watermarkElement?: HTMLElement) => {
let flag = false;
// Whether to delete the watermark node
if (mutation.removedNodes.length) {
flag = Array.from(mutation.removedNodes).some((node) => node === watermarkElement);
}
// Whether the watermark dom property value has been modified
if (mutation.type === 'attributes' && mutation.target === watermarkElement) {
flag = true;
}
return flag;
};

View File

@ -1,6 +1,6 @@
{
"name": "antd",
"version": "5.1.3",
"version": "5.1.4",
"description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design",
"keywords": [
@ -113,6 +113,7 @@
"@ant-design/react-slick": "~1.0.0",
"@babel/runtime": "^7.18.3",
"@ctrl/tinycolor": "^3.4.0",
"@rc-component/mutate-observer": "^1.0.0",
"@rc-component/tour": "~1.4.0",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.2.0",
@ -155,7 +156,7 @@
"throttle-debounce": "^5.0.0"
},
"devDependencies": {
"@ant-design/tools": "^17.0.0-alpha.5",
"@ant-design/tools": "^17.0.0-alpha.7",
"@babel/eslint-plugin": "^7.19.1",
"@emotion/babel-preset-css-prop": "^11.10.0",
"@emotion/css": "^11.10.5",

View File

@ -27,6 +27,7 @@ const DEPRECIATED_VERSION = {
'5.0.6': ['https://github.com/ant-design/ant-design/issues/39807'],
'5.1.0': ['https://github.com/react-component/drawer/pull/370'],
'5.1.2': ['https://github.com/ant-design/ant-design/issues/39949'],
'5.1.3': ['https://github.com/ant-design/ant-design/issues/40113'],
};
function matchDeprecated(version) {