mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 11:10:01 +08:00
Merge branch 'master' into feature-merge-master
This commit is contained in:
commit
43541cb6d9
@ -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 (
|
||||
|
@ -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"
|
||||
|
@ -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`
|
||||
|
@ -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`
|
||||
|
@ -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 =====================
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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 };
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user