diff --git a/.dumi/theme/builtins/Palette/index.tsx b/.dumi/theme/builtins/Palette/index.tsx index b94369dd0b0a..4dacea1bc6ba 100644 --- a/.dumi/theme/builtins/Palette/index.tsx +++ b/.dumi/theme/builtins/Palette/index.tsx @@ -1,4 +1,3 @@ -// @ts-ignore import Palette from '../../common/Color/Palette'; export default Palette; diff --git a/.dumi/theme/builtins/Previewer/fromDumiProps.tsx b/.dumi/theme/builtins/Previewer/fromDumiProps.tsx index f00d5872f591..435a9035f629 100644 --- a/.dumi/theme/builtins/Previewer/fromDumiProps.tsx +++ b/.dumi/theme/builtins/Previewer/fromDumiProps.tsx @@ -3,7 +3,6 @@ import React, { useEffect, useState } from 'react'; import JsonML from 'jsonml.js/lib/utils'; // @ts-ignore import toReactComponent from 'jsonml-to-react-element'; -// @ts-ignore import Prism from 'prismjs'; import { useLocation, useIntl, type IPreviewerProps } from 'dumi'; import { ping } from '../../utils'; diff --git a/.dumi/theme/common/BrowserFrame.jsx b/.dumi/theme/common/BrowserFrame.jsx deleted file mode 100644 index 642e372890fb..000000000000 --- a/.dumi/theme/common/BrowserFrame.jsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -const BrowserFrame = ({ children }) =>
{children}
; - -export default BrowserFrame; diff --git a/.dumi/theme/common/BrowserFrame.tsx b/.dumi/theme/common/BrowserFrame.tsx new file mode 100644 index 000000000000..385a23cf4100 --- /dev/null +++ b/.dumi/theme/common/BrowserFrame.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const BrowserFrame: React.FC<{ children?: React.ReactNode }> = ({ children }) => ( +
{children}
+); + +export default BrowserFrame; diff --git a/.dumi/theme/common/CodePenIcon.jsx b/.dumi/theme/common/CodePenIcon.tsx similarity index 91% rename from .dumi/theme/common/CodePenIcon.jsx rename to .dumi/theme/common/CodePenIcon.tsx index cda997597eff..63ecd3d36655 100644 --- a/.dumi/theme/common/CodePenIcon.jsx +++ b/.dumi/theme/common/CodePenIcon.tsx @@ -1,12 +1,14 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const SVGIcon = () => ( +const SVGIcon: React.FC = () => ( ); -const CodePenIcon = (props) => ; +const CodePenIcon: React.FC<{ className?: string }> = (props) => ( + +); export default CodePenIcon; diff --git a/.dumi/theme/common/CodePreview.jsx b/.dumi/theme/common/CodePreview.tsx similarity index 52% rename from .dumi/theme/common/CodePreview.jsx rename to .dumi/theme/common/CodePreview.tsx index 3624ec0fbb14..1f399a122163 100644 --- a/.dumi/theme/common/CodePreview.jsx +++ b/.dumi/theme/common/CodePreview.tsx @@ -8,31 +8,25 @@ const LANGS = { jsx: 'JavaScript', }; -const CodePreview = ({ toReactComponent, codes, onCodeTypeChange }) => { +interface CodePreviewProps { + codes?: Record; + toReactComponent?: (node: any) => React.ReactNode; + onCodeTypeChange?: (activeKey: string) => void; +} + +const CodePreview: React.FC = ({ toReactComponent, codes, onCodeTypeChange }) => { const langList = Object.keys(codes).sort().reverse(); - let content; + let content: React.ReactNode; if (langList.length === 1) { - content = toReactComponent([ - 'pre', - { - lang: langList[0], - highlighted: codes[langList[0]], - }, - ]); + content = toReactComponent(['pre', { lang: langList[0], highlighted: codes[langList[0]] }]); } else { content = ( {langList.map((lang) => ( - {toReactComponent([ - 'pre', - { - lang, - highlighted: codes[lang], - }, - ])} + {toReactComponent(['pre', { lang, highlighted: codes[lang] }])} ))} diff --git a/.dumi/theme/common/CodeSandboxIcon.jsx b/.dumi/theme/common/CodeSandboxIcon.tsx similarity index 76% rename from .dumi/theme/common/CodeSandboxIcon.jsx rename to .dumi/theme/common/CodeSandboxIcon.tsx index 96ac3f53803e..24162f03be3f 100644 --- a/.dumi/theme/common/CodeSandboxIcon.jsx +++ b/.dumi/theme/common/CodeSandboxIcon.tsx @@ -1,12 +1,14 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const SVGIcon = () => ( +const SVGIcon: React.FC = () => ( ); -const CodeSandboxIcon = (props) => ; +const CodeSandboxIcon: React.FC<{ className?: string }> = (props) => ( + +); export default CodeSandboxIcon; diff --git a/.dumi/theme/common/Color/ColorBlock.jsx b/.dumi/theme/common/Color/ColorBlock.tsx similarity index 80% rename from .dumi/theme/common/Color/ColorBlock.jsx rename to .dumi/theme/common/Color/ColorBlock.tsx index 282c6a6ca03f..aa981b763ba9 100644 --- a/.dumi/theme/common/Color/ColorBlock.jsx +++ b/.dumi/theme/common/Color/ColorBlock.tsx @@ -2,7 +2,13 @@ import React, { Component } from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import { message } from 'antd'; -export default class ColorBlock extends Component { +interface ColorBlockProps { + color: string; + index: number; + dark?: boolean; +} + +class ColorBlock extends Component { getTextStyle() { const { color, index, dark } = this.props; const colorMap = { @@ -25,7 +31,7 @@ export default class ColorBlock extends Component { render() { const { color, index } = this.props; return ( - +
color-{index} {color.toLowerCase()} @@ -34,3 +40,5 @@ export default class ColorBlock extends Component { ); } } + +export default ColorBlock; diff --git a/.dumi/theme/common/Color/ColorPaletteTool.jsx b/.dumi/theme/common/Color/ColorPaletteTool.tsx similarity index 73% rename from .dumi/theme/common/Color/ColorPaletteTool.jsx rename to .dumi/theme/common/Color/ColorPaletteTool.tsx index 8a1936e1cde8..78cbe310a019 100644 --- a/.dumi/theme/common/Color/ColorPaletteTool.jsx +++ b/.dumi/theme/common/Color/ColorPaletteTool.tsx @@ -1,3 +1,4 @@ +import type { ChangeEvent } from 'react'; import React, { Component } from 'react'; import { FormattedMessage } from 'dumi'; import ColorPicker from './ColorPicker'; @@ -6,18 +7,17 @@ import ColorPatterns from './ColorPatterns'; const primaryMinSaturation = 70; // 主色推荐最小饱和度 const primaryMinBrightness = 70; // 主色推荐最小亮度 -export default class ColorPaletteTool extends Component { +class ColorPaletteTool extends Component { state = { primaryColor: '#1890ff', primaryColorInstance: null, }; - handleChangeColor = (e, color) => { - const value = e.target ? e.target.value : e; - this.setState({ - primaryColor: value, - primaryColorInstance: color, - }); + handleChangeColor = (e: string | ChangeEvent, color: { hex: string }) => { + const value = (e as ChangeEvent).target + ? (e as ChangeEvent).target.value + : e; + this.setState({ primaryColor: value, primaryColorInstance: color }); }; renderColorValidation() { @@ -45,12 +45,10 @@ export default class ColorPaletteTool extends Component {
-
- -
+
{ColorPatterns({ color: primaryColor })}
- + {primaryColor} {this.renderColorValidation()} @@ -59,3 +57,5 @@ export default class ColorPaletteTool extends Component { ); } } + +export default ColorPaletteTool; diff --git a/.dumi/theme/common/Color/ColorPaletteToolDark.jsx b/.dumi/theme/common/Color/ColorPaletteToolDark.tsx similarity index 77% rename from .dumi/theme/common/Color/ColorPaletteToolDark.jsx rename to .dumi/theme/common/Color/ColorPaletteToolDark.tsx index 2559b1afee24..fdcf68e6fdea 100644 --- a/.dumi/theme/common/Color/ColorPaletteToolDark.jsx +++ b/.dumi/theme/common/Color/ColorPaletteToolDark.tsx @@ -1,3 +1,4 @@ +import type { ChangeEvent } from 'react'; import React, { Component } from 'react'; import { FormattedMessage } from 'dumi'; import { Row, Col } from 'antd'; @@ -7,26 +8,25 @@ import ColorPatterns from './ColorPatterns'; const primaryMinSaturation = 70; // 主色推荐最小饱和度 const primaryMinBrightness = 70; // 主色推荐最小亮度 -export default class ColorPaletteTool extends Component { +class ColorPaletteTool extends Component { state = { primaryColor: '#1890ff', backgroundColor: '#141414', primaryColorInstance: null, }; - handleChangeColor = (e, color) => { - const value = e.target ? e.target.value : e; - this.setState({ - primaryColor: value, - primaryColorInstance: color, - }); + handleChangeColor = (e: string | ChangeEvent, color: { hex: string }) => { + const value = (e as ChangeEvent).target + ? (e as ChangeEvent).target.value + : e; + this.setState({ primaryColor: value, primaryColorInstance: color }); }; - handleChangeBackgroundColor = (e) => { - const value = e.target ? e.target.value : e; - this.setState({ - backgroundColor: value, - }); + handleChangeBackgroundColor = (e: string | ChangeEvent) => { + const value = (e as ChangeEvent).target + ? (e as ChangeEvent).target.value + : e; + this.setState({ backgroundColor: value }); }; renderColorValidation() { @@ -56,7 +56,7 @@ export default class ColorPaletteTool extends Component { return (
- + {ColorPatterns({ color: primaryColor, dark: true, backgroundColor })}
@@ -67,11 +67,7 @@ export default class ColorPaletteTool extends Component { - + {primaryColor} @@ -87,7 +83,6 @@ export default class ColorPaletteTool extends Component { @@ -105,3 +100,5 @@ export default class ColorPaletteTool extends Component { ); } } + +export default ColorPaletteTool; diff --git a/.dumi/theme/common/Color/ColorPalettes.jsx b/.dumi/theme/common/Color/ColorPalettes.jsx deleted file mode 100644 index f7411668d6e9..000000000000 --- a/.dumi/theme/common/Color/ColorPalettes.jsx +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import cls from 'classnames'; -import Palette from './Palette'; - -const ColorPalettes = (props) => { - const { dark } = props; - - const colors = [ - { - name: 'red', - english: 'Dust Red', - chinese: '薄暮', - description: '斗志、奔放', - }, - { - name: 'volcano', - english: 'Volcano', - chinese: '火山', - description: '醒目、澎湃', - }, - { - name: 'orange', - english: 'Sunset Orange', - chinese: '日暮', - description: '温暖、欢快', - }, - { - name: 'gold', - english: 'Calendula Gold', - chinese: '金盏花', - description: '活力、积极', - }, - { - name: 'yellow', - english: 'Sunrise Yellow', - chinese: '日出', - description: '出生、阳光', - }, - { - name: 'lime', - english: 'Lime', - chinese: '青柠', - description: '自然、生机', - }, - { - name: 'green', - english: 'Polar Green', - chinese: '极光绿', - description: '健康、创新', - }, - { - name: 'cyan', - english: 'Cyan', - chinese: '明青', - description: '希望、坚强', - }, - { - name: 'blue', - english: 'Daybreak Blue', - chinese: '拂晓蓝', - description: '包容、科技、普惠', - }, - { - name: 'geekblue', - english: 'Geek Blue', - chinese: '极客蓝', - description: '探索、钻研', - }, - { - name: 'purple', - english: 'Golden Purple', - chinese: '酱紫', - description: '优雅、浪漫', - }, - { - name: 'magenta', - english: 'Magenta', - chinese: '法式洋红', - description: '明快、感性', - }, - ]; - const colorCls = cls('color-palettes', { - 'color-palettes-dark': !!dark, - }); - return ( -
- {colors.map((color) => ( - - ))} -
- ); -}; - -export default ColorPalettes; diff --git a/.dumi/theme/common/Color/ColorPalettes.tsx b/.dumi/theme/common/Color/ColorPalettes.tsx new file mode 100644 index 000000000000..b380e3f60da9 --- /dev/null +++ b/.dumi/theme/common/Color/ColorPalettes.tsx @@ -0,0 +1,94 @@ +import React from 'react'; +import cls from 'classnames'; +import Palette from './Palette'; + +const colors = [ + { + name: 'red', + english: 'Dust Red', + chinese: '薄暮', + description: '斗志、奔放', + }, + { + name: 'volcano', + english: 'Volcano', + chinese: '火山', + description: '醒目、澎湃', + }, + { + name: 'orange', + english: 'Sunset Orange', + chinese: '日暮', + description: '温暖、欢快', + }, + { + name: 'gold', + english: 'Calendula Gold', + chinese: '金盏花', + description: '活力、积极', + }, + { + name: 'yellow', + english: 'Sunrise Yellow', + chinese: '日出', + description: '出生、阳光', + }, + { + name: 'lime', + english: 'Lime', + chinese: '青柠', + description: '自然、生机', + }, + { + name: 'green', + english: 'Polar Green', + chinese: '极光绿', + description: '健康、创新', + }, + { + name: 'cyan', + english: 'Cyan', + chinese: '明青', + description: '希望、坚强', + }, + { + name: 'blue', + english: 'Daybreak Blue', + chinese: '拂晓蓝', + description: '包容、科技、普惠', + }, + { + name: 'geekblue', + english: 'Geek Blue', + chinese: '极客蓝', + description: '探索、钻研', + }, + { + name: 'purple', + english: 'Golden Purple', + chinese: '酱紫', + description: '优雅、浪漫', + }, + { + name: 'magenta', + english: 'Magenta', + chinese: '法式洋红', + description: '明快、感性', + }, +]; + +const ColorPalettes: React.FC<{ dark?: boolean }> = (props) => { + const { dark } = props; + const colorCls = cls('color-palettes', { + 'color-palettes-dark': !!dark, + }); + return ( +
+ {colors.map((color) => ( + + ))} +
+ ); +}; + +export default ColorPalettes; diff --git a/.dumi/theme/common/Color/ColorPatterns.jsx b/.dumi/theme/common/Color/ColorPatterns.tsx similarity index 63% rename from .dumi/theme/common/Color/ColorPatterns.jsx rename to .dumi/theme/common/Color/ColorPatterns.tsx index 6989b2021545..d40d88a0c997 100644 --- a/.dumi/theme/common/Color/ColorPatterns.jsx +++ b/.dumi/theme/common/Color/ColorPatterns.tsx @@ -3,9 +3,17 @@ import { generate } from '@ant-design/colors'; import uniq from 'lodash/uniq'; import ColorBlock from './ColorBlock'; -export default function ColorPatterns({ color, dark, backgroundColor }) { +interface ColorPatternsProps { + color?: string; + dark?: boolean; + backgroundColor?: string; +} + +const ColorPatterns = ({ color, dark, backgroundColor }: ColorPatternsProps) => { const colors = generate(color, dark ? { theme: 'dark', backgroundColor } : {}); return uniq(colors).map((colorString, i) => ( )); -} +}; + +export default ColorPatterns; diff --git a/.dumi/theme/common/Color/ColorPicker.tsx b/.dumi/theme/common/Color/ColorPicker.tsx index 5e7fe77f5ba6..e6b5d928713c 100644 --- a/.dumi/theme/common/Color/ColorPicker.tsx +++ b/.dumi/theme/common/Color/ColorPicker.tsx @@ -5,11 +5,11 @@ const noop = () => {}; interface ColorPickerProps { color?: string; - small: boolean; - position: string; + small?: boolean; + position?: string; presetColors?: string[]; - onChange: (hex: string, color: { hex: string }) => void; - onChangeComplete: (hex: string) => void; + onChange?: (hex: string, color: { hex: string }) => void; + onChangeComplete?: (hex: string) => void; } export default class ColorPicker extends Component { diff --git a/.dumi/theme/common/Color/ColorStyle.tsx b/.dumi/theme/common/Color/ColorStyle.tsx index 58ebe6d3aba7..9de6c08de0a2 100644 --- a/.dumi/theme/common/Color/ColorStyle.tsx +++ b/.dumi/theme/common/Color/ColorStyle.tsx @@ -48,89 +48,89 @@ ${makeGrayPalette(index + 1)} return ( ); }; diff --git a/.dumi/theme/common/Color/Palette.jsx b/.dumi/theme/common/Color/Palette.tsx similarity index 83% rename from .dumi/theme/common/Color/Palette.jsx rename to .dumi/theme/common/Color/Palette.tsx index 5b35b6a36595..3f5f6246534f 100644 --- a/.dumi/theme/common/Color/Palette.jsx +++ b/.dumi/theme/common/Color/Palette.tsx @@ -3,7 +3,7 @@ import { message } from 'antd'; import CopyToClipboard from 'react-copy-to-clipboard'; import { presetDarkPalettes } from '@ant-design/colors'; -const rgbToHex = (rgbString) => { +const rgbToHex = (rgbString: string): string => { const rgb = rgbString.match(/\d+/g); let r = parseInt(rgb[0], 10).toString(16); let g = parseInt(rgb[1], 10).toString(16); @@ -14,10 +14,21 @@ const rgbToHex = (rgbString) => { return `#${r}${g}${b}`; }; -export default class Palette extends React.Component { +interface PaletteProps { + showTitle?: boolean; + direction?: 'horizontal' | 'vertical'; + dark?: boolean; + color?: any; +} + +class Palette extends React.Component { + hexColors: Record; + + colorNodes: Record; + componentDidMount() { this.hexColors = {}; - Object.keys(this.colorNodes).forEach((key) => { + Object.keys(this.colorNodes || {}).forEach((key) => { const computedColor = getComputedStyle(this.colorNodes[key])['background-color']; if (computedColor.includes('rgba')) { this.hexColors[key] = computedColor; @@ -34,10 +45,10 @@ export default class Palette extends React.Component { showTitle, direction, dark, - color: { name, description, english, chinese, count = 10 }, + color: { name, description, english, chinese, count } = { name: 'gray', count: 13 }, } = this.props; const className = direction === 'horizontal' ? 'color-palette-horizontal' : 'color-palette'; - const colors = []; + const colors: React.ReactNode[] = []; const colorName = `${english} / ${chinese}`; const colorPaletteMap = { dark: ['#fff', 'unset'], @@ -88,6 +99,4 @@ export default class Palette extends React.Component { } } -Palette.defaultProps = { - color: { name: 'gray', count: 13 }, -}; +export default Palette; diff --git a/.dumi/theme/common/ExternalLinkIcon.jsx b/.dumi/theme/common/ExternalLinkIcon.tsx similarity index 79% rename from .dumi/theme/common/ExternalLinkIcon.jsx rename to .dumi/theme/common/ExternalLinkIcon.tsx index a0429db503cd..f193d6a69559 100644 --- a/.dumi/theme/common/ExternalLinkIcon.jsx +++ b/.dumi/theme/common/ExternalLinkIcon.tsx @@ -1,13 +1,15 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const SVGIcon = ({ color = 'currentColor' }) => ( +const SVGIcon: React.FC<{ color?: string }> = ({ color = 'currentColor' }) => ( ); -const ExternalLinkIcon = (props) => ; +const ExternalLinkIcon: React.FC<{ className?: string }> = (props) => ( + +); export default ExternalLinkIcon; diff --git a/.dumi/theme/common/PrevAndNext.tsx b/.dumi/theme/common/PrevAndNext.tsx index 1a36a40a0dfb..4752705ee6d4 100644 --- a/.dumi/theme/common/PrevAndNext.tsx +++ b/.dumi/theme/common/PrevAndNext.tsx @@ -96,7 +96,7 @@ const flattenMenu = (menuItems: MenuProps['items']): MenuProps['items'] | null = return null; }; -const PrevAndNext = () => { +const PrevAndNext: React.FC = () => { const styles = useStyle(); const [menuItems, selectedKey] = useMenu({ diff --git a/.dumi/theme/common/RiddleIcon.jsx b/.dumi/theme/common/RiddleIcon.tsx similarity index 94% rename from .dumi/theme/common/RiddleIcon.jsx rename to .dumi/theme/common/RiddleIcon.tsx index e8efd77dc585..2c46a2415233 100644 --- a/.dumi/theme/common/RiddleIcon.jsx +++ b/.dumi/theme/common/RiddleIcon.tsx @@ -1,12 +1,14 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const SVGIcon = () => ( +const SVGIcon: React.FC = () => ( ); -const RiddleIcon = (props) => ; +const RiddleIcon: React.FC<{ className?: string }> = (props) => ( + +); export default RiddleIcon; diff --git a/.dumi/theme/common/ThemeSwitch/ThemeIcon.tsx b/.dumi/theme/common/ThemeSwitch/ThemeIcon.tsx index cbf413a5d3ee..724f5a8c84e7 100644 --- a/.dumi/theme/common/ThemeSwitch/ThemeIcon.tsx +++ b/.dumi/theme/common/ThemeSwitch/ThemeIcon.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const ThemeIcon = (props: any) => { +const ThemeIcon: React.FC<{ className?: string }> = (props) => { const SVGIcon = React.useCallback( () => ( diff --git a/.dumi/theme/common/ThemeSwitch/index.tsx b/.dumi/theme/common/ThemeSwitch/index.tsx index fe461cbbc558..c39092cb5060 100644 --- a/.dumi/theme/common/ThemeSwitch/index.tsx +++ b/.dumi/theme/common/ThemeSwitch/index.tsx @@ -1,4 +1,3 @@ -import type { FC } from 'react'; import React from 'react'; import { FloatButton, theme } from 'antd'; import { DarkTheme, Light, CompactTheme } from 'antd-token-previewer/es/icons'; @@ -11,7 +10,7 @@ export type ThemeSwitchProps = { onChange: (value: typeof defaultAlgorithm[]) => void; }; -const ThemeSwitch: FC = ({ value, onChange }) => { +const ThemeSwitch: React.FC = ({ value, onChange }) => { const handleLightSwitch = () => { let newValue = [...value]; if (value.includes(darkAlgorithm)) { diff --git a/.dumi/theme/slots/Footer/AdditionalInfo.tsx b/.dumi/theme/slots/Footer/AdditionalInfo.tsx index 09ee7516b585..a0a204e2e549 100644 --- a/.dumi/theme/slots/Footer/AdditionalInfo.tsx +++ b/.dumi/theme/slots/Footer/AdditionalInfo.tsx @@ -35,15 +35,15 @@ export default function InfoNewVersion() { updateCSS( ` :where(.${whereCls}) { - width: 93px !important; + content: "__CHECK__"; } `, whereCls, ); // Check style - const { width } = getComputedStyle(p); - setSupportWhere(String(width) === '93px'); + const { content } = getComputedStyle(p); + setSupportWhere(String(content).includes('CHECK')); return () => { document.body.removeChild(p); diff --git a/.dumi/theme/slots/Footer/index.tsx b/.dumi/theme/slots/Footer/index.tsx index c54c7ef3eeb5..0d8c8666200b 100644 --- a/.dumi/theme/slots/Footer/index.tsx +++ b/.dumi/theme/slots/Footer/index.tsx @@ -15,7 +15,6 @@ import { TwitterOutlined, UsergroupAddOutlined, ZhihuOutlined, - YuqueFilled, } from '@ant-design/icons'; import { css } from '@emotion/react'; import { TinyColor } from '@ctrl/tinycolor'; @@ -154,7 +153,7 @@ const Footer = () => { }, { title: , - url: 'https://ant-design.gitee.io/', + url: 'https://ant-design.antgroup.com', }, ], }; @@ -181,19 +180,24 @@ const Footer = () => { openExternal: true, }, { - icon: , + icon: ( + yuque + ), title: , url: 'https://yuque.com/ant-design/ant-design', openExternal: true, }, { - icon: , + icon: , title: , url: 'https://www.zhihu.com/column/c_1564262000561106944', openExternal: true, }, { - icon: , + icon: , title: , url: 'http://zhuanlan.zhihu.com/xtech', openExternal: true, diff --git a/.eslintrc.js b/.eslintrc.js index 2b8af60c8823..12628ed2b150 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -25,7 +25,7 @@ module.exports = { }, }, parser: '@typescript-eslint/parser', - plugins: ['react', 'babel', 'jest', '@typescript-eslint', 'react-hooks', 'unicorn', 'markdown'], + plugins: ['react', '@babel', 'jest', '@typescript-eslint', 'react-hooks', 'unicorn', 'markdown'], // https://github.com/typescript-eslint/typescript-eslint/issues/46#issuecomment-470486034 overrides: [ { @@ -67,6 +67,11 @@ module.exports = { }, rules: { indent: 0, + '@babel/new-cap': 0, + '@babel/no-invalid-this': 0, + '@babel/no-unused-expressions': 2, + '@babel/object-curly-spacing': 0, + '@babel/semi': 2, 'default-case': 0, 'eol-last': 0, 'no-console': 0, diff --git a/.github/workflows/compressed-size.yml b/.github/workflows/compressed-size.yml deleted file mode 100644 index 34f234d3ebeb..000000000000 --- a/.github/workflows/compressed-size.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: 📦 Compressed Size - -on: - pull_request: - types: [opened, synchronize] - -# Cancel prev CI if new commit come -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - compressed-size: - permissions: - contents: read # for actions/checkout to fetch code - pull-requests: write # for preactjs/compressed-size-action to create PR comments - runs-on: ubuntu-latest - env: - CI_JOB_NUMBER: 1 - - steps: - - uses: actions/checkout@v3 - - uses: preactjs/compressed-size-action@v2 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - pattern: "./dist/**/*.min.{js,css}" - build-script: "dist:esbuild-no-dup-check" - clean-script: "clean-lockfiles" diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml index ed8009427cb0..bcce41cd74eb 100644 --- a/.github/workflows/size-limit.yml +++ b/.github/workflows/size-limit.yml @@ -1,4 +1,4 @@ -name: 📦 Compressed Size(size-limit) +name: 📦 Size Limit on: pull_request: @@ -13,19 +13,50 @@ permissions: contents: read jobs: - compressed-size: + size: permissions: - contents: read # for actions/checkout to fetch code - pull-requests: write # for preactjs/compressed-size-action to create PR comments + contents: read + pull-requests: write runs-on: ubuntu-latest env: CI_JOB_NUMBER: 1 steps: - - uses: actions/checkout@v3 - - uses: andresz1/size-limit-action@v1 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - pattern: "./dist/**/*.min.{js,css}" - build-script: "dist:esbuild-no-dup-check" - clean-script: "clean-lockfiles" + - name: checkout + uses: actions/checkout@v3 + + - name: cache package-lock.json + uses: actions/cache@v3 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: create package-lock.json + run: npm i --package-lock-only --ignore-scripts + + - name: hack for single file + run: | + if [ ! -d "package-temp-dir" ]; then + mkdir package-temp-dir + fi + cp package-lock.json package-temp-dir + + - name: cache node_modules + id: node_modules_cache_id + uses: actions/cache@v3 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: install + if: steps.node_modules_cache_id.outputs.cache-hit != 'true' + run: npm ci + + - name: size-limit + uses: ant-design/size-limit-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + build_script: dist + skip_step: install + env: + NODE_OPTIONS: --max_old_space_size=4096 diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 42aad221a1b5..b49dd92b5384 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -15,6 +15,26 @@ timeline: true --- +## 5.0.4 + +`2022-12-05` + +- Modal + - 🐞 Fix Modal with long content exceed the panel. [#39249](https://github.com/ant-design/ant-design/pull/39249) [@MuxinFeng](https://github.com/MuxinFeng) + - 🐞 Fix Modal.info content width when without icon. [#39047](https://github.com/ant-design/ant-design/pull/39047) [@owjs3901](https://github.com/owjs3901) +- 🐞 Fix Tree config `checkable` and `blockNode` not makes `title` stretch issue. [#39209](https://github.com/ant-design/ant-design/pull/39209) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 Fix Dropdown sub menu missing motion. [#39235](https://github.com/ant-design/ant-design/pull/39235) +- 💄 Fix RangePicker time panel padding style. [#39228](https://github.com/ant-design/ant-design/pull/39228) +- 🐞 Fix Card action button round style. [#39210](https://github.com/ant-design/ant-design/pull/39210) [@muxin](https://github.com/muxin) +- 🐞 Fix Badge wave effect color not follow `color`. [#39182](https://github.com/ant-design/ant-design/pull/39182) [@li-jia-nan](https://github.com/li-jia-nan) +- 🐞 Fix Radio disabled status check style. [#39165](https://github.com/ant-design/ant-design/pull/39165) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 Fixed TextArea count style when `resize` is not `none`. [#39121](https://github.com/ant-design/ant-design/pull/39121) [@51wangping](https://github.com/51wangping) +- 🐞 Fix Transfer clicking the checkbox position cannot be unchecked and onSelectChange is triggered twice. [#39078](https://github.com/ant-design/ant-design/pull/39078) [@edc-hui](https://github.com/edc-hui) +- 🐞 Fix Steps set `size="small"` with progress not fully display. [#39100](https://github.com/ant-design/ant-design/pull/39100) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 Fix Form horizontal layout with `xs` responsive config not work. [#39130](https://github.com/ant-design/ant-design/pull/39130) +- 🐞 Fix message position not correct in RTL. [#39248](https://github.com/ant-design/ant-design/pull/39248) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 Fix Switch only set with `checkedChildren` or `unCheckedChildren` content not display. [#39262](https://github.com/ant-design/ant-design/pull/39262) + ## 5.0.3 `2022-11-30` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 4572e406b628..1dbbd177ee97 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,26 @@ timeline: true --- +## 5.0.4 + +`2022-12-05` + +- Modal + - 🐞 修复 Modal 文字内容过多会超出框体的样式问题。[#39249](https://github.com/ant-design/ant-design/pull/39249) [@MuxinFeng](https://github.com/MuxinFeng) + - 🐞 修复 Modal.info 没有图标时,内容宽度不正确的问题。[#39047](https://github.com/ant-design/ant-design/pull/39047) [@owjs3901](https://github.com/owjs3901) +- 🐞 修复 Tree `checkable` 与 `blockNode` 配合时,`title` 元素不拉伸的问题。[#39209](https://github.com/ant-design/ant-design/pull/39209) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 修复 Dropdown 二级菜单丢失动画的问题。[#39235](https://github.com/ant-design/ant-design/pull/39235) +- 💄 修复 RangePicker 内时间面板的 padding 样式。[#39228](https://github.com/ant-design/ant-design/pull/39228) +- 🐞 修复 Card 的按钮组圆角样式。[#39210](https://github.com/ant-design/ant-design/pull/39210) [@muxin](https://github.com/muxin) +- 🐞 修复了 Badge 自定义颜色的时候,波纹的颜色不会跟着小圆点颜色发生变化的问题。[#39182](https://github.com/ant-design/ant-design/pull/39182) [@li-jia-nan](https://github.com/li-jia-nan) +- 🐞 修复 Radio 禁用状态选中样式。[#39165](https://github.com/ant-design/ant-design/pull/39165) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 修复 TextArea `resize` 不是 `none` 时计数文字的样式问题。[#39121](https://github.com/ant-design/ant-design/pull/39121) [@51wangping](https://github.com/51wangping) +- 🐞 修复 Transfer 组件 点击复选框位置不可以取消选中,并触发了两次 onSelectChange 问题。[#39078](https://github.com/ant-design/ant-design/pull/39078) [@edc-hui](https://github.com/edc-hui) +- 🐞 修复 Steps `size="small"` 第一项带有进度时,进度条显示不全的问题。[#39100](https://github.com/ant-design/ant-design/pull/39100) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 修复 Form 水平布局下 `xs` 的响应式布局不生效的问题。[#39130](https://github.com/ant-design/ant-design/pull/39130) +- 🐞 修复 message 在 RTL 下位置不正确的问题。[#39248](https://github.com/ant-design/ant-design/pull/39248) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 修复 Switch 在只设置 `checkedChildren` 或 `unCheckedChildren` 时,其内容不会显示的问题。[#39262](https://github.com/ant-design/ant-design/pull/39262) + ## 5.0.3 `2022-11-30` diff --git a/components/__tests__/__snapshots__/index.test.ts.snap b/components/__tests__/__snapshots__/index.test.ts.snap index 740ef46f1fa8..a0b933818ac3 100644 --- a/components/__tests__/__snapshots__/index.test.ts.snap +++ b/components/__tests__/__snapshots__/index.test.ts.snap @@ -5,6 +5,7 @@ exports[`antd exports modules correctly 1`] = ` "Affix", "Alert", "Anchor", + "App", "AutoComplete", "Avatar", "BackTop", @@ -40,6 +41,7 @@ exports[`antd exports modules correctly 1`] = ` "Popconfirm", "Popover", "Progress", + "QRCode", "Radio", "Rate", "Result", diff --git a/components/anchor/Anchor.tsx b/components/anchor/Anchor.tsx index e555e5445f2f..6ca13b070134 100644 --- a/components/anchor/Anchor.tsx +++ b/components/anchor/Anchor.tsx @@ -97,7 +97,7 @@ export interface AntAnchor { activeLink: string | null; scrollTo: (link: string) => void; onClick?: ( - e: React.MouseEvent, + e: React.MouseEvent, link: { title: React.ReactNode; href: string }, ) => void; } diff --git a/components/anchor/AnchorLink.tsx b/components/anchor/AnchorLink.tsx index 5e7c4aa611f8..0ea729e0bd07 100644 --- a/components/anchor/AnchorLink.tsx +++ b/components/anchor/AnchorLink.tsx @@ -31,7 +31,7 @@ const AnchorLink: React.FC = (props) => { }; }, [href, registerLink, unregisterLink]); - const handleClick = (e: React.MouseEvent) => { + const handleClick = (e: React.MouseEvent) => { onClick?.(e, { title, href }); scrollTo?.(href); }; diff --git a/components/anchor/index.en-US.md b/components/anchor/index.en-US.md index 2b9942364a42..5c2d64c898ee 100644 --- a/components/anchor/index.en-US.md +++ b/components/anchor/index.en-US.md @@ -44,7 +44,7 @@ For displaying anchor hyperlinks on page and jumping between them. | showInkInFixed | Whether show ink-balls when `affix={false}` | boolean | false | | | targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | - | | | onChange | Listening for anchor link change | (currentActiveLink: string) => void | | | -| onClick | Set the handler to handle `click` event | function(e: Event, link: Object) | - | | +| onClick | Set the handler to handle `click` event | (e: MouseEvent, link: object) => void | - | | | items | Data configuration option content, support nesting through children | { href, title, target, children }\[] | - | | ### Link Props diff --git a/components/anchor/index.zh-CN.md b/components/anchor/index.zh-CN.md index f020e06aab19..c07fc8e13d0a 100644 --- a/components/anchor/index.zh-CN.md +++ b/components/anchor/index.zh-CN.md @@ -45,7 +45,7 @@ group: | showInkInFixed | `affix={false}` 时是否显示小圆点 | boolean | false | | | targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | - | | | onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | - | | -| onClick | `click` 事件的 handler | function(e: Event, link: Object) | - | | +| onClick | `click` 事件的 handler | (e: MouseEvent, link: object) => void | - | | | items | 数据化配置选项内容,支持通过 children 嵌套 | { href, title, target, children }\[] | - | | ### Link Props diff --git a/components/app/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/app/__tests__/__snapshots__/demo-extend.test.ts.snap new file mode 100644 index 000000000000..a405386610f1 --- /dev/null +++ b/components/app/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./components/app/demo/message.tsx extend context correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/app/demo/modal.tsx extend context correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/app/demo/notification.tsx extend context correctly 1`] = ` +
+ +
+`; diff --git a/components/app/__tests__/__snapshots__/demo.test.ts.snap b/components/app/__tests__/__snapshots__/demo.test.ts.snap new file mode 100644 index 000000000000..c8a98f5162f7 --- /dev/null +++ b/components/app/__tests__/__snapshots__/demo.test.ts.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./components/app/demo/message.tsx correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/app/demo/modal.tsx correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/app/demo/notification.tsx correctly 1`] = ` +
+ +
+`; diff --git a/components/app/__tests__/__snapshots__/index.test.tsx.snap b/components/app/__tests__/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000000..9d7d65275a4e --- /dev/null +++ b/components/app/__tests__/__snapshots__/index.test.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`App rtl render component should be rendered correctly in RTL direction 1`] = ` +
+`; + +exports[`App single 1`] = ` +
+
+ Hello World +
+
+`; diff --git a/components/app/__tests__/demo-extend.test.ts b/components/app/__tests__/demo-extend.test.ts new file mode 100644 index 000000000000..6ef0a0d13da1 --- /dev/null +++ b/components/app/__tests__/demo-extend.test.ts @@ -0,0 +1,3 @@ +import { extendTest } from '../../../tests/shared/demoTest'; + +extendTest('app'); diff --git a/components/app/__tests__/demo.test.ts b/components/app/__tests__/demo.test.ts new file mode 100644 index 000000000000..fbcb9a76c9d6 --- /dev/null +++ b/components/app/__tests__/demo.test.ts @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest'; + +demoTest('app'); diff --git a/components/app/__tests__/image.test.ts b/components/app/__tests__/image.test.ts new file mode 100644 index 000000000000..8d3a08346d67 --- /dev/null +++ b/components/app/__tests__/image.test.ts @@ -0,0 +1,5 @@ +import { imageDemoTest } from '../../../tests/shared/imageTest'; + +describe('app', () => { + imageDemoTest('app'); +}); diff --git a/components/app/__tests__/index.test.tsx b/components/app/__tests__/index.test.tsx new file mode 100644 index 000000000000..3ea627cc9cc2 --- /dev/null +++ b/components/app/__tests__/index.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import App from '..'; +import mountTest from '../../../tests/shared/mountTest'; +import rtlTest from '../../../tests/shared/rtlTest'; +import { render } from '../../../tests/utils'; + +describe('App', () => { + mountTest(App); + rtlTest(App); + + it('single', () => { + // Sub page + const MyPage = () => { + const { message } = App.useApp(); + React.useEffect(() => { + message.success('Good!'); + }, [message]); + + return
Hello World
; + }; + + // Entry component + const MyApp = () => ( + + + + ); + + const { getByText, container } = render(); + expect(getByText('Hello World')).toBeTruthy(); + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/components/app/context.ts b/components/app/context.ts new file mode 100644 index 000000000000..823ae1ed7a96 --- /dev/null +++ b/components/app/context.ts @@ -0,0 +1,19 @@ +import React from 'react'; +import type { MessageInstance } from '../message/interface'; +import type { NotificationInstance } from '../notification/interface'; +import type { ModalStaticFunctions } from '../modal/confirm'; + +type ModalType = Omit; +export interface useAppProps { + message: MessageInstance; + notification: NotificationInstance; + modal: ModalType; +} + +const AppContext = React.createContext({ + message: {} as MessageInstance, + notification: {} as NotificationInstance, + modal: {} as ModalType, +}); + +export default AppContext; diff --git a/components/app/demo/message.md b/components/app/demo/message.md new file mode 100644 index 000000000000..499640422814 --- /dev/null +++ b/components/app/demo/message.md @@ -0,0 +1,7 @@ +## zh-CN + +获取 `message` 静态方法. + +## en-US + +Static method for `message`. diff --git a/components/app/demo/message.tsx b/components/app/demo/message.tsx new file mode 100644 index 000000000000..71ecffd5b978 --- /dev/null +++ b/components/app/demo/message.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { App, Button } from 'antd'; + +// Sub page +const MyPage = () => { + const { message } = App.useApp(); + + const showMessage = () => { + message.success('Success!'); + }; + + return ( + + ); +}; + +// Entry component +export default () => ( + + + +); diff --git a/components/app/demo/modal.md b/components/app/demo/modal.md new file mode 100644 index 000000000000..f07f87c7c8da --- /dev/null +++ b/components/app/demo/modal.md @@ -0,0 +1,7 @@ +## zh-CN + +获取 `modal` 静态方法. + +## en-US + +Static method for `modal`. diff --git a/components/app/demo/modal.tsx b/components/app/demo/modal.tsx new file mode 100644 index 000000000000..3fe95c848d39 --- /dev/null +++ b/components/app/demo/modal.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { App, Button } from 'antd'; + +// Sub page +const MyPage = () => { + const { modal } = App.useApp(); + + const showModal = () => { + modal.warning({ + title: 'This is a warning message', + content: 'some messages...some messages...', + }); + }; + + return ( + + ); +}; + +// Entry component +export default () => ( + + + +); diff --git a/components/app/demo/notification.md b/components/app/demo/notification.md new file mode 100644 index 000000000000..28fa841aaba4 --- /dev/null +++ b/components/app/demo/notification.md @@ -0,0 +1,7 @@ +## zh-CN + +获取 `notification` 静态方法. + +## en-US + +Static method for `notification`. diff --git a/components/app/demo/notification.tsx b/components/app/demo/notification.tsx new file mode 100644 index 000000000000..fe8613a7f4b6 --- /dev/null +++ b/components/app/demo/notification.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { App, Button } from 'antd'; + +// Sub page +const MyPage = () => { + const { notification } = App.useApp(); + + const showNotification = () => { + notification.info({ + message: `Notification topLeft`, + description: 'Hello, Ant Design!!', + placement: 'topLeft', + }); + }; + + return ( + + ); +}; + +// Entry component +export default () => ( + + + +); diff --git a/components/app/index.en-US.md b/components/app/index.en-US.md new file mode 100644 index 000000000000..691985be42f5 --- /dev/null +++ b/components/app/index.en-US.md @@ -0,0 +1,46 @@ +--- +category: Components +group: Other +title: App +cover: https://gw.alipayobjects.com/zos/bmw-prod/cc3fcbfa-bf5b-4c8c-8a3d-c3f8388c75e8.svg +demo: + cols: 2 +--- + +New App Component which provide global style & static function replacement. + +## When To Use + +Static function in React 18 concurrent mode will not well support. In v5, we recommend to use hooks for the static replacement. But it will make user manual work on define this. + +## Examples + + +message +notification +modal + +## How to use + +```tsx +import React from 'react'; +import { App } from 'antd'; + +const MyPage: React.FC = () => { + const { message, notification, modal } = App.useApp(); + message.success('Good!'); + notification.info({ message: 'Good' }); + modal.warning({ title: 'Good' }); + // .... + // other message, notification, modal static function + return
Hello word
; +}; + +const MyApp: React.FC = () => ( + + + +); + +export default MyApp; +``` diff --git a/components/app/index.tsx b/components/app/index.tsx new file mode 100644 index 000000000000..5b9a10c7a2f1 --- /dev/null +++ b/components/app/index.tsx @@ -0,0 +1,59 @@ +import React, { useContext } from 'react'; +import type { ReactNode } from 'react'; +import classNames from 'classnames'; +import type { ConfigConsumerProps } from '../config-provider'; +import { ConfigContext } from '../config-provider'; +import useStyle from './style'; +import useMessage from '../message/useMessage'; +import useNotification from '../notification/useNotification'; +import useModal from '../modal/useModal'; +import AppContext from './context'; +import type { useAppProps } from './context'; + +export type AppProps = { + className?: string; + prefixCls?: string; + children?: ReactNode; +}; + +const useApp = () => React.useContext(AppContext); + +const App: React.FC & { useApp: () => useAppProps } = (props) => { + const { prefixCls: customizePrefixCls, children, className } = props; + const { getPrefixCls } = useContext(ConfigContext); + const prefixCls = getPrefixCls('app', customizePrefixCls); + const [wrapSSR, hashId] = useStyle(prefixCls); + const customClassName = classNames(hashId, prefixCls, className); + + const [messageApi, messageContextHolder] = useMessage(); + const [notificationApi, notificationContextHolder] = useNotification(); + const [ModalApi, ModalContextHolder] = useModal(); + + const memoizedContextValue = React.useMemo( + () => ({ + message: messageApi, + notification: notificationApi, + modal: ModalApi, + }), + [messageApi, notificationApi, ModalApi], + ); + + return wrapSSR( + +
+ {ModalContextHolder} + {messageContextHolder} + {notificationContextHolder} + {children} +
+
, + ); +}; + +if (process.env.NODE_ENV !== 'production') { + App.displayName = 'App'; +} + +App.useApp = useApp; + +export default App; diff --git a/components/app/index.zh-CN.md b/components/app/index.zh-CN.md new file mode 100644 index 000000000000..32777ab6cbb7 --- /dev/null +++ b/components/app/index.zh-CN.md @@ -0,0 +1,48 @@ +--- +category: Components +subtitle: 包裹组件 +group: 其他 +title: App +cover: https://gw.alipayobjects.com/zos/bmw-prod/cc3fcbfa-bf5b-4c8c-8a3d-c3f8388c75e8.svg +demo: + cols: 2 +--- + +新的包裹组件,提供重置样式和提供消费上下文的默认环境。 + +## 何时使用 + +- 提供可消费 React context 的 `message.xxx`、`Modal.xxx`、`notification.xxx` 的静态方法,可以简化 useMessage 等方法需要手动植入 `contextHolder` 的问题。 +- 提供基于 `.ant-app` 的默认重置样式,解决原生元素没有 antd 规范样式的问题。 + +## 代码演示 + + +message +notification +modal + +## How to use + +```tsx +import React from 'react'; +import { App } from 'antd'; + +const MyPage: React.FC = () => { + const { message, notification, modal } = App.useApp(); + message.success('Good!'); + notification.info({ message: 'Good' }); + modal.warning({ title: 'Good' }); + // .... + // other message, notification, modal static function + return
Hello word
; +}; + +const MyApp: React.FC = () => ( + + + +); + +export default MyApp; +``` diff --git a/components/app/style/index.tsx b/components/app/style/index.tsx new file mode 100644 index 000000000000..700aa8098b80 --- /dev/null +++ b/components/app/style/index.tsx @@ -0,0 +1,22 @@ +import type { FullToken, GenerateStyle } from '../../theme/internal'; +import { genComponentStyleHook } from '../../theme/internal'; + +export type ComponentToken = {}; + +interface AppToken extends FullToken<'App'> {} + +// =============================== Base =============================== +const genBaseStyle: GenerateStyle = (token) => { + const { componentCls, colorText, fontSize, lineHeight, fontFamily } = token; + return { + [componentCls]: { + color: colorText, + fontSize, + lineHeight, + fontFamily, + }, + }; +}; + +// ============================== Export ============================== +export default genComponentStyleHook('App', (token) => [genBaseStyle(token)]); diff --git a/components/auto-complete/index.en-US.md b/components/auto-complete/index.en-US.md index 11ae2e245fc9..9d47a6e8e2e7 100644 --- a/components/auto-complete/index.en-US.md +++ b/components/auto-complete/index.en-US.md @@ -78,29 +78,3 @@ The differences with Select are: Please use `onChange` to manage control state. `onSearch` is used for searching input which is not the same as `onChange`. Besides, clicking on the option will not trigger the `onSearch` event. Related issue: [#18230](https://github.com/ant-design/ant-design/issues/18230) [#17916](https://github.com/ant-design/ant-design/issues/17916) - -### Part of the api in v3 are not available in v4? - -AutoComplete is an Input component that supports auto complete tips. As such, it should not support props like `labelInValue` that affect value display. In v3, the AutoComplete implementation can not handle the case where the `value` and `label` are identical. v4 not longer support `label` as the value input. - -Besides, to unify the API, `dataSource` is replaced with `options`. You can migrate with the following change: - -#### v3 - -```tsx -dataSource = ['light', 'bamboo']; -// or -dataSource = [ - { value: 'light', text: 'Light' }, - { value: 'bamboo', text: 'Bamboo' }, -]; -``` - -#### v4 - -```tsx -options = [ - { value: 'light', label: 'Light' }, - { value: 'bamboo', label: 'Bamboo' }, -]; -``` diff --git a/components/auto-complete/index.zh-CN.md b/components/auto-complete/index.zh-CN.md index 2c1ffee0462d..01a078e5bcf4 100644 --- a/components/auto-complete/index.zh-CN.md +++ b/components/auto-complete/index.zh-CN.md @@ -80,29 +80,3 @@ demo: 请使用 `onChange` 进行受控管理。`onSearch` 触发于搜索输入,与 `onChange` 时机不同。此外,点选选项时也不会触发 `onSearch` 事件。 相关 issue:[#18230](https://github.com/ant-design/ant-design/issues/18230) [#17916](https://github.com/ant-design/ant-design/issues/17916) - -### v3 的部分属性为何在 v4 中没有了? - -AutoComplete 组件是一个支持自动提示的 Input 组件,因而其不具有 `labelInValue` 等影响 value 展示的属性。在 v3 版本,AutoComplete 实现存在输入值如果遇到 `value` 与 `label` 相同时无法映射的问题。 v4 中不再支持 `label` 为值的输入形态。 - -此外为了统一 API,`dataSource` 改为 `options` 你可以如下转换: - -#### v3 - -```tsx -dataSource = ['light', 'bamboo']; -// or -dataSource = [ - { value: 'light', text: 'Light' }, - { value: 'bamboo', text: 'Bamboo' }, -]; -``` - -#### v4 - -```tsx -options = [ - { value: 'light', label: 'Light' }, - { value: 'bamboo', label: 'Bamboo' }, -]; -``` diff --git a/components/breadcrumb/index.en-US.md b/components/breadcrumb/index.en-US.md index 9b6afe9c2e81..614cc6d1daba 100644 --- a/components/breadcrumb/index.en-US.md +++ b/components/breadcrumb/index.en-US.md @@ -15,36 +15,6 @@ A breadcrumb displays the current location within a hierarchy. It allows going b - When you need to inform the user of where they are. - When the user may need to navigate back to a higher level. -### Usage upgrade after 4.24.0 - - - -```jsx -// works when >=4.24.0, recommended ✅ -const items = [ - { label: 'item 1', key: 'item-1' }, // remember to pass the key prop - { label: 'item 2', key: 'item-2' }, -]; -return ( - - Ant Design - -); - -// works when <4.24.0, deprecated when >=4.24.0 🙅🏻‍♀️ -const menu = ( - - item 1 - item 2 - -); -return ( - - Ant Design - -); -``` - ## Examples diff --git a/components/breadcrumb/index.zh-CN.md b/components/breadcrumb/index.zh-CN.md index 295b6c7e64cb..420b0e697f9a 100644 --- a/components/breadcrumb/index.zh-CN.md +++ b/components/breadcrumb/index.zh-CN.md @@ -16,36 +16,6 @@ demo: - 当需要告知用户『你在哪里』时; - 当需要向上导航的功能时。 -### 4.24.0 用法升级 - - - -```jsx -// >=4.24.0 可用,推荐的写法 ✅ -const items = [ - { label: '菜单项一', key: 'item-1' }, // 菜单项务必填写 key - { label: '菜单项二', key: 'item-2' }, -]; -return ( - - Ant Design - -); - -// <4.24.0 可用,>=4.24.0 时不推荐 🙅🏻‍♀️ -const menu = ( - - 菜单项一 - 菜单项二 - -); -return ( - - Ant Design - -); -``` - ## 代码演示 diff --git a/components/button/index.zh-CN.md b/components/button/index.zh-CN.md index a0e4a0ca7360..70532ceb5de4 100644 --- a/components/button/index.zh-CN.md +++ b/components/button/index.zh-CN.md @@ -59,7 +59,7 @@ group: | --- | --- | --- | --- | --- | | block | 将按钮宽度调整为其父宽度的选项 | boolean | false | | | danger | 设置危险按钮 | boolean | false | | -| disabled | 按钮失效状态 | boolean | false | | +| disabled | 设置按钮失效状态 | boolean | false | | | ghost | 幽灵属性,使按钮背景透明 | boolean | false | | | href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 | string | - | | | htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | | diff --git a/components/button/style/index.tsx b/components/button/style/index.tsx index 077e7ec35f35..03a807c30f2a 100644 --- a/components/button/style/index.tsx +++ b/components/button/style/index.tsx @@ -50,7 +50,7 @@ const genSharedButtonStyle: GenerateStyle = (token): CSS ...genFocusStyle(token), }, - ...genCompactItemStyle(token, componentCls), + ...genCompactItemStyle(token, componentCls, { focus: false }), ...genCompactItemVerticalStyle(token, componentCls), // make `btn-icon-only` not too narrow @@ -62,14 +62,14 @@ const genSharedButtonStyle: GenerateStyle = (token): CSS '&:not([disabled]) + &:not([disabled])': { position: 'relative', - '&:after': { + '&:before': { position: 'absolute', top: -token.lineWidth, insetInlineStart: -token.lineWidth, display: 'inline-block', width: token.lineWidth, height: `calc(100% + ${token.lineWidth * 2}px)`, - backgroundColor: token.colorPrimaryBorder, + backgroundColor: token.colorPrimaryHover, content: '""', }, }, @@ -80,14 +80,14 @@ const genSharedButtonStyle: GenerateStyle = (token): CSS '&:not([disabled]) + &:not([disabled])': { position: 'relative', - '&:after': { + '&:before': { position: 'absolute', top: -token.lineWidth, insetInlineStart: -token.lineWidth, display: 'inline-block', width: `calc(100% + ${token.lineWidth * 2}px)`, height: token.lineWidth, - backgroundColor: token.colorPrimaryBorder, + backgroundColor: token.colorPrimaryHover, content: '""', }, }, diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index 8c086114e16a..a3efedfdea5f 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -13,7 +13,6 @@ import type { import RcCascader from 'rc-cascader'; import omit from 'rc-util/lib/omit'; import * as React from 'react'; -import { useContext } from 'react'; import { ConfigContext } from '../config-provider'; import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; import DisabledContext from '../config-provider/DisabledContext'; @@ -158,7 +157,7 @@ const Cascader = React.forwardRef((props: CascaderProps, ref: React.Ref, ref: React.Ref { const { getPrefixCls, direction } = React.useContext(ConfigContext); const checkboxGroup = React.useContext(GroupContext); - const { isFormItemInput } = useContext(FormItemInputContext); - const contextDisabled = useContext(DisabledContext); + const { isFormItemInput } = React.useContext(FormItemInputContext); + const contextDisabled = React.useContext(DisabledContext); const mergedDisabled = (checkboxGroup?.disabled || disabled) ?? contextDisabled; const prevValue = React.useRef(restProps.value); diff --git a/components/checkbox/index.en-US.md b/components/checkbox/index.en-US.md index 853a32647d92..947328a2586c 100644 --- a/components/checkbox/index.en-US.md +++ b/components/checkbox/index.en-US.md @@ -38,17 +38,17 @@ Checkbox component. | defaultChecked | Specifies the initial state: whether or not the checkbox is selected | boolean | false | | | disabled | If disable checkbox | boolean | false | | | indeterminate | The indeterminate checked state of checkbox | boolean | false | | -| onChange | The callback function that is triggered when the state changes | function(e:Event) | - | | +| onChange | The callback function that is triggered when the state changes | function(e: CheckboxChangeEvent) | - | | #### Checkbox Group | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| defaultValue | Default selected value | string\[] | \[] | | +| defaultValue | Default selected value | (string \| number)\[] | \[] | | | disabled | If disable all checkboxes | boolean | false | | | name | The `name` property of all `input[type="checkbox"]` children | string | - | | | options | Specifies options | string\[] \| number\[] \| Option\[] | \[] | | -| value | Used for setting the currently selected value | string\[] | \[] | | +| value | Used for setting the currently selected value | (string \| number)\[] | \[] | | | onChange | The callback function that is triggered when the state changes | function(checkedValue) | - | | ### Methods diff --git a/components/checkbox/index.zh-CN.md b/components/checkbox/index.zh-CN.md index c96cb86c0817..c0ceaf5101d5 100644 --- a/components/checkbox/index.zh-CN.md +++ b/components/checkbox/index.zh-CN.md @@ -32,24 +32,24 @@ demo: #### Checkbox -| 参数 | 说明 | 类型 | 默认值 | 版本 | -| -------------- | --------------------------------------- | ----------------- | ------ | ---- | -| autoFocus | 自动获取焦点 | boolean | false | | -| checked | 指定当前是否选中 | boolean | false | | -| defaultChecked | 初始是否选中 | boolean | false | | -| disabled | 失效状态 | boolean | false | | -| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | | -| onChange | 变化时的回调函数 | function(e:Event) | - | | +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| --- | --- | --- | --- | --- | +| autoFocus | 自动获取焦点 | boolean | false | | +| checked | 指定当前是否选中 | boolean | false | | +| defaultChecked | 初始是否选中 | boolean | false | | +| disabled | 失效状态 | boolean | false | | +| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | | +| onChange | 变化时的回调函数 | function(e: CheckboxChangeEvent) | - | | #### Checkbox Group | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| defaultValue | 默认选中的选项 | string\[] | \[] | | +| defaultValue | 默认选中的选项 | (string \| number)\[] | \[] | | | disabled | 整组失效 | boolean | false | | | name | CheckboxGroup 下所有 `input[type="checkbox"]` 的 `name` 属性 | string | - | | | options | 指定可选项 | string\[] \| number\[] \| Option\[] | \[] | | -| value | 指定选中的选项 | string\[] | \[] | | +| value | 指定选中的选项 | (string \| number)\[] | \[] | | | onChange | 变化时的回调函数 | function(checkedValue) | - | | ##### Option diff --git a/components/config-provider/__tests__/__snapshots__/components.test.tsx.snap b/components/config-provider/__tests__/__snapshots__/components.test.tsx.snap index ff54c0429e9f..78438a96bc86 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.tsx.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.tsx.snap @@ -20960,57 +20960,61 @@ exports[`ConfigProvider components Popconfirm configProvider 1`] = ` role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21047,59 +21051,63 @@ exports[`ConfigProvider components Popconfirm configProvider componentDisabled 1 role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21136,57 +21144,61 @@ exports[`ConfigProvider components Popconfirm configProvider componentSize large role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21223,57 +21235,61 @@ exports[`ConfigProvider components Popconfirm configProvider componentSize middl role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21310,57 +21326,61 @@ exports[`ConfigProvider components Popconfirm configProvider virtual and dropdow role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21397,57 +21417,61 @@ exports[`ConfigProvider components Popconfirm normal 1`] = ` role="tooltip" >
- - + + - +
+
-
-
- - + + +
@@ -21484,57 +21508,61 @@ exports[`ConfigProvider components Popconfirm prefixCls 1`] = ` role="tooltip" >
- - + + - +
+
-
-
- - + + +
diff --git a/components/date-picker/style/index.tsx b/components/date-picker/style/index.tsx index d4857963a7db..56d90c1206cb 100644 --- a/components/date-picker/style/index.tsx +++ b/components/date-picker/style/index.tsx @@ -531,14 +531,14 @@ export const genPanelStyle = (token: SharedPickerToken): CSSObject => { [`&-date-panel ${componentCls}-cell-in-view${componentCls}-cell-in-range${componentCls}-cell-range-hover-start ${pickerCellInnerCls}::after`]: { - insetInlineEnd: (pickerPanelCellWidth - pickerPanelCellHeight) / 2, + insetInlineEnd: -(pickerPanelCellWidth - pickerPanelCellHeight) / 2, insetInlineStart: 0, }, [`&-date-panel ${componentCls}-cell-in-view${componentCls}-cell-in-range${componentCls}-cell-range-hover-end ${pickerCellInnerCls}::after`]: { insetInlineEnd: 0, - insetInlineStart: (pickerPanelCellWidth - pickerPanelCellHeight) / 2, + insetInlineStart: -(pickerPanelCellWidth - pickerPanelCellHeight) / 2, }, // Hover with range start & end @@ -974,7 +974,9 @@ const genPickerStyle: GenerateStyle = (token) => { transition: `border ${motionDurationMid}, box-shadow ${motionDurationMid}`, // Space.Compact - ...genCompactItemStyle(token, componentCls, '', `${componentCls}-focused`), + ...genCompactItemStyle(token, componentCls, { + focusElCls: `${componentCls}-focused`, + }), '&:hover, &-focused': { ...genHoverStyle(token), diff --git a/components/divider/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/divider/__tests__/__snapshots__/demo-extend.test.ts.snap index aa54fa2d5f8e..563b0ba86959 100644 --- a/components/divider/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/divider/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -33,6 +33,21 @@ Array [ role="separator" style="height:60px;border-color:#7cb305" />, +
+ +
, ] `; diff --git a/components/divider/__tests__/__snapshots__/demo.test.ts.snap b/components/divider/__tests__/__snapshots__/demo.test.ts.snap index 8af60aeef21c..72e62c427198 100644 --- a/components/divider/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/divider/__tests__/__snapshots__/demo.test.ts.snap @@ -33,6 +33,21 @@ Array [ role="separator" style="height:60px;border-color:#7cb305" />, +
+ +
, ] `; diff --git a/components/divider/demo/customize-style.tsx b/components/divider/demo/customize-style.tsx index d537eb0b547e..29621bb49838 100644 --- a/components/divider/demo/customize-style.tsx +++ b/components/divider/demo/customize-style.tsx @@ -10,6 +10,12 @@ const App: React.FC = () => ( + +
+ + Text + +
); diff --git a/components/divider/style/index.tsx b/components/divider/style/index.tsx index 118cfaabfd4f..ae8beabca275 100644 --- a/components/divider/style/index.tsx +++ b/components/divider/style/index.tsx @@ -45,6 +45,7 @@ const genSharedDividerStyle: GenerateStyle = (token): CSSObject => '&-horizontal&-with-text': { display: 'flex', + alignItems: 'center', margin: `${token.dividerHorizontalWithTextGutterMargin}px 0`, color: token.colorTextHeading, fontWeight: 500, @@ -55,7 +56,6 @@ const genSharedDividerStyle: GenerateStyle = (token): CSSObject => '&::before, &::after': { position: 'relative', - top: '50%', width: '50%', borderBlockStart: `${lineWidth}px solid transparent`, // Chrome not accept `inherit` in `border-top` @@ -68,24 +68,20 @@ const genSharedDividerStyle: GenerateStyle = (token): CSSObject => '&-horizontal&-with-text-left': { '&::before': { - top: '50%', width: '5%', }, '&::after': { - top: '50%', width: '95%', }, }, '&-horizontal&-with-text-right': { '&::before': { - top: '50%', width: '95%', }, '&::after': { - top: '50%', width: '5%', }, }, diff --git a/components/dropdown/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/dropdown/__tests__/__snapshots__/demo-extend.test.ts.snap index d96817e743e1..76a267831456 100644 --- a/components/dropdown/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/dropdown/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -3351,324 +3351,6 @@ Array [ ] `; -exports[`renders ./components/dropdown/demo/deprecated.tsx extend context correctly 1`] = ` -Array [ - -
-
- Hover me -
-
- - - -
-
-
, -
-
- - @@ -25754,22 +25770,177 @@ exports[`Locale Provider should display the text as by 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+
+
+ + +
+
+
+ + + + + + 0 + элем. + + +
+
-
-
-
-
- - - - - - 0 - элем. - - -
- -
-
- - -
+
+ + +
@@ -30857,60 +30877,64 @@ exports[`Locale Provider should display the text as ca 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -35960,60 +35984,64 @@ exports[`Locale Provider should display the text as cs 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -41063,22 +41091,177 @@ exports[`Locale Provider should display the text as da 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + element + + +
+
-
-
-
-
- - - - - - 0 - element - - -
- -
-
- - -
+
+ + +
@@ -46166,60 +46198,64 @@ exports[`Locale Provider should display the text as de 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -51269,60 +51305,64 @@ exports[`Locale Provider should display the text as el 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -56372,22 +56412,177 @@ exports[`Locale Provider should display the text as en 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + item + + +
+
-
-
-
-
- - - - - - 0 - item - - -
- -
-
- - -
+
+ + +
@@ -61475,60 +61519,64 @@ exports[`Locale Provider should display the text as en-gb 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -66578,60 +66626,64 @@ exports[`Locale Provider should display the text as es 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -71681,22 +71733,177 @@ exports[`Locale Provider should display the text as et 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + kogus + + +
+
-
-
-
-
- - - - - - 0 - kogus - - -
- -
-
- - -
+
+ + +
@@ -73653,7 +73709,7 @@ exports[`Locale Provider should display the text as fa 1`] = ` tabindex="-1" type="button" > - سپتامبر + آذر +
-
- - -
@@ -77337,9 +77397,9 @@ exports[`Locale Provider should display the text as fa 1`] = ` - سپتامبر + آذر
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -86990,22 +87054,177 @@ exports[`Locale Provider should display the text as fr 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + élément + + +
+
-
-
-
-
- - - - - - 0 - élément - - -
- -
-
- - -
+
+ + +
@@ -92093,60 +92161,64 @@ exports[`Locale Provider should display the text as fr 2`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -97196,60 +97268,64 @@ exports[`Locale Provider should display the text as fr 3`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -102299,22 +102375,177 @@ exports[`Locale Provider should display the text as ga 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + item + + +
+
-
-
-
-
- - - - - - 0 - item - - -
- -
-
- - -
+
+ + +
@@ -107402,60 +107482,64 @@ exports[`Locale Provider should display the text as gl 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -112505,60 +112589,64 @@ exports[`Locale Provider should display the text as he 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -117608,22 +117696,177 @@ exports[`Locale Provider should display the text as hi 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + तत्त्व + + +
+
-
-
-
-
- - - - - - 0 - तत्त्व - - -
- -
-
- - -
+
+ + +
@@ -122711,60 +122803,64 @@ exports[`Locale Provider should display the text as hr 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -127814,60 +127910,64 @@ exports[`Locale Provider should display the text as hu 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -132917,22 +133017,177 @@ exports[`Locale Provider should display the text as hy-am 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + պարագան + + +
+
-
-
-
-
- - - - - - 0 - պարագան - - -
- -
-
- - -
+
+ + +
@@ -138020,60 +138124,64 @@ exports[`Locale Provider should display the text as id 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -143123,60 +143231,64 @@ exports[`Locale Provider should display the text as is 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -148226,22 +148338,177 @@ exports[`Locale Provider should display the text as it 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + elemento + + +
+
-
-
-
-
- - - - - - 0 - elemento - - -
- -
-
- - -
+
+ + +
@@ -153329,60 +153445,64 @@ exports[`Locale Provider should display the text as ja 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -158432,60 +158552,64 @@ exports[`Locale Provider should display the text as ka 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -163535,22 +163659,177 @@ exports[`Locale Provider should display the text as kk 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + элемент. + + +
+
-
-
-
-
- - - - - - 0 - элемент. - - -
- -
-
- - -
+
+ + +
@@ -168638,60 +168766,64 @@ exports[`Locale Provider should display the text as km 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -173739,60 +173871,64 @@ exports[`Locale Provider should display the text as kn 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -178842,22 +178978,177 @@ exports[`Locale Provider should display the text as ko 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + 개 + + +
+
-
-
-
-
- - - - - - 0 - 개 - - -
- -
-
- - -
+
+ + +
@@ -183945,60 +184085,64 @@ exports[`Locale Provider should display the text as ku 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -189048,60 +189192,64 @@ exports[`Locale Provider should display the text as ku-iq 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -194151,22 +194299,177 @@ exports[`Locale Provider should display the text as lt 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + vnt. + + +
+
-
-
-
-
- - - - - - 0 - vnt. - - -
- -
-
- - -
+
+ + +
@@ -199254,60 +199406,64 @@ exports[`Locale Provider should display the text as lv 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -204357,60 +204513,64 @@ exports[`Locale Provider should display the text as mk 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -209460,22 +209620,177 @@ exports[`Locale Provider should display the text as ml 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + ഇനം + + +
+
-
-
-
-
- - - - - - 0 - ഇനം - - -
- -
-
- - -
+
+ + +
@@ -214563,60 +214727,64 @@ exports[`Locale Provider should display the text as mn-mn 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -219666,60 +219834,64 @@ exports[`Locale Provider should display the text as ms-my 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -224769,22 +224941,177 @@ exports[`Locale Provider should display the text as nb 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + element + + +
+
-
-
-
-
- - - - - - 0 - element - - -
- -
-
- - -
+
+ + +
@@ -229872,60 +230048,64 @@ exports[`Locale Provider should display the text as ne-np 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -234975,60 +235155,64 @@ exports[`Locale Provider should display the text as nl 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -240078,22 +240262,177 @@ exports[`Locale Provider should display the text as nl-be 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + item + + +
+
-
-
-
-
- - - - - - 0 - item - - -
- -
-
- - -
+
+ + +
@@ -245181,60 +245369,64 @@ exports[`Locale Provider should display the text as pl 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -250284,60 +250476,64 @@ exports[`Locale Provider should display the text as pt 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -255387,22 +255583,177 @@ exports[`Locale Provider should display the text as pt-br 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + item + + +
+
-
-
-
-
- - - - - - 0 - item - - -
- -
-
- - -
+
+ + +
@@ -260490,60 +260690,64 @@ exports[`Locale Provider should display the text as ro 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -265593,60 +265797,64 @@ exports[`Locale Provider should display the text as ru 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -270696,22 +270904,177 @@ exports[`Locale Provider should display the text as si 1`] = ` role="tooltip" >
+
+ + + + + +
+ Question? +
+
+
+ + +
+
+
+ + + + +
+
+
+ + + + + + 0 + අථකය + + +
+
-
-
-
-
- - - - - - 0 - අථකය - - -
- -
-
- - -
+
+ + +
@@ -275799,60 +276011,64 @@ exports[`Locale Provider should display the text as sk 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -280902,60 +281118,64 @@ exports[`Locale Provider should display the text as sl 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -286005,60 +286225,64 @@ exports[`Locale Provider should display the text as sr 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -291108,60 +291332,64 @@ exports[`Locale Provider should display the text as sv 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -296211,60 +296439,64 @@ exports[`Locale Provider should display the text as ta 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -301314,60 +301546,64 @@ exports[`Locale Provider should display the text as th 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -306417,60 +306653,64 @@ exports[`Locale Provider should display the text as tk 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -311520,60 +311760,64 @@ exports[`Locale Provider should display the text as tr 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -316623,60 +316867,64 @@ exports[`Locale Provider should display the text as uk 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -321726,60 +321974,64 @@ exports[`Locale Provider should display the text as ur 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -326829,60 +327081,64 @@ exports[`Locale Provider should display the text as vi 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -328444,7 +328700,7 @@ exports[`Locale Provider should display the text as vi 1`] = ` type="button" > - Huỷ + Hủy @@ -331932,60 +332188,64 @@ exports[`Locale Provider should display the text as zh-cn 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -337035,60 +337295,64 @@ exports[`Locale Provider should display the text as zh-hk 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
@@ -342138,60 +342402,64 @@ exports[`Locale Provider should display the text as zh-tw 1`] = ` role="tooltip" >
- - + + + - +
+ Question? +
+
- Question? + +
-
- - -
diff --git a/components/locale-provider/index.tsx b/components/locale-provider/index.tsx index 3691222058d7..1c937030227f 100644 --- a/components/locale-provider/index.tsx +++ b/components/locale-provider/index.tsx @@ -46,6 +46,10 @@ export interface Locale { Image?: { preview: string; }; + QRCode?: { + expired: string; + refresh: string; + }; } export interface LocaleProviderProps { diff --git a/components/locale/en_US.tsx b/components/locale/en_US.tsx index 4b87557341e5..080e2ebcd9d2 100644 --- a/components/locale/en_US.tsx +++ b/components/locale/en_US.tsx @@ -136,6 +136,10 @@ const localeValues: Locale = { Image: { preview: 'Preview', }, + QRCode: { + expired: 'QRCode is expired', + refresh: 'click refresh', + }, }; export default localeValues; diff --git a/components/locale/he_IL.tsx b/components/locale/he_IL.tsx index c0fc9a6f87da..739dbb716acc 100644 --- a/components/locale/he_IL.tsx +++ b/components/locale/he_IL.tsx @@ -25,9 +25,9 @@ const localeValues: Locale = { selectionAll: 'בחר את כל הנתונים', sortTitle: 'מיון', expand: 'הרחב שורה', - collapse: 'צמצם שורהw', - triggerDesc: 'לחץ על מיון לפי סדר יורד', - triggerAsc: 'לחץ על מיון לפי סדר עולה', + collapse: 'צמצם שורה', + triggerDesc: 'לחץ למיון לפי סדר יורד', + triggerAsc: 'לחץ למיון לפי סדר עולה', cancelSort: 'לחץ כדי לבטל את המיון', }, Modal: { diff --git a/components/locale/vi_VN.tsx b/components/locale/vi_VN.tsx index 369686728af2..c7669b4447f2 100644 --- a/components/locale/vi_VN.tsx +++ b/components/locale/vi_VN.tsx @@ -11,20 +11,20 @@ const localeValues: Locale = { TimePicker, Calendar, Table: { - filterTitle: 'Bộ ', - filterConfirm: 'OK', - filterReset: 'Tạo Lại', - selectAll: 'Chọn Tất Cả', - selectInvert: 'Chọn Ngược Lại', + filterTitle: 'Bộ lọc', + filterConfirm: 'Đồng ý', + filterReset: 'Bỏ lọc', + selectAll: 'Chọn tất cả', + selectInvert: 'Chọn ngược lại', }, Modal: { - okText: 'OK', - cancelText: 'Huỷ', + okText: 'Đồng ý', + cancelText: 'Hủy', justOkText: 'OK', }, Popconfirm: { - okText: 'OK', - cancelText: 'Huỷ', + okText: 'Đồng ý', + cancelText: 'Hủy', }, Transfer: { titles: ['', ''], @@ -36,7 +36,7 @@ const localeValues: Locale = { uploading: 'Đang tải lên...', removeFile: 'Gỡ bỏ tập tin', uploadError: 'Lỗi tải lên', - previewFile: 'Xem thử tập tin', + previewFile: 'Xem trước tập tin', downloadFile: 'Tải tập tin', }, Empty: { diff --git a/components/locale/zh_CN.tsx b/components/locale/zh_CN.tsx index 6d155dde0aec..ea97e256bfa6 100644 --- a/components/locale/zh_CN.tsx +++ b/components/locale/zh_CN.tsx @@ -136,6 +136,10 @@ const localeValues: Locale = { Image: { preview: '预览', }, + QRCode: { + expired: '二维码过期', + refresh: '点击刷新', + }, }; export default localeValues; diff --git a/components/mentions/demo/render-panel.tsx b/components/mentions/demo/render-panel.tsx index 65199d789ee4..d8add045b9d3 100644 --- a/components/mentions/demo/render-panel.tsx +++ b/components/mentions/demo/render-panel.tsx @@ -12,10 +12,10 @@ const options = [ value: 'zombieJ', label: 'zombieJ', }, -] +]; const App: React.FC = () => ( - + ); export default App; diff --git a/components/mentions/index.en-US.md b/components/mentions/index.en-US.md index 638e0e5bdbcc..8d607c0b34cc 100644 --- a/components/mentions/index.en-US.md +++ b/components/mentions/index.en-US.md @@ -68,7 +68,7 @@ return ; | onResize | The callback function that is triggered when textarea resize | function({ width, height }) | - | | | onSearch | Trigger when prefix hit | (text: string, prefix: string) => void | - | | | onSelect | Trigger when user select the option | (option: OptionProps, prefix: string) => void | - | | -| options | Option Configuration | [Options](#Option) | \[] | 5.1.0 | +| options | Option Configuration | [Options](#Option) | \[] | 5.1.0 | ### Mention methods @@ -79,6 +79,7 @@ return ; ### Option + | Property | Description | Type | Default | | --- | --- | --- | --- | | label | Title of the option | React.ReactNode | - | diff --git a/components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap index 72c92344ba9a..64222338f213 100644 --- a/components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1,274 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/menu/demo/deprecated.tsx extend context correctly 1`] = ` -Array [ - , - , -] -`; - -exports[`renders ./components/popconfirm/demo/placement.tsx extend context correctly 1`] = ` -
-
- -
-
-
-
- -
-
- Delete the task + Are you sure to delete this task?
+
, +] +`; + +exports[`renders ./components/popconfirm/demo/placement.tsx extend context correctly 1`] = ` +
+
@@ -627,64 +555,68 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
@@ -696,7 +628,7 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre type="button" > - TR + Top
@@ -719,64 +651,164 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task +
+
+ +
+
+
+
+
+ + +
+
+
+
+ +
+
@@ -815,64 +847,68 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
@@ -907,64 +943,68 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
@@ -999,64 +1039,68 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
@@ -1095,64 +1139,164 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task +
+
+ +
+ + + + + + +
+
+
+
+ +
+
@@ -1164,7 +1308,7 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre type="button" > - Right + RB
@@ -1187,76 +1331,84 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
+ +
@@ -1279,80 +1431,80 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
- -
@@ -1375,64 +1527,68 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
@@ -1444,7 +1600,7 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre type="button" > - Bottom + BR
@@ -1467,96 +1623,109 @@ exports[`renders ./components/popconfirm/demo/placement.tsx extend context corre role="tooltip" >
- - + + - +
+ Are you sure to delete this task? +
+
- Are you sure to delete this task? + Delete the task
-
-
- Delete the task -
-
- - + + +
- , +
+
- - BR - - -
+ +
+
-
-
+ , +] `; -exports[`renders ./components/popconfirm/demo/promise.tsx extend context correctly 1`] = ` +exports[`renders ./components/popconfirm/demo/render-panel.tsx extend context correctly 1`] = ` Array [ - , -
+ +
+
, +
+
+
+
@@ -1819,65 +2059,64 @@ Array [ role="tooltip" >
- - + + + - +
+ Are you OK? +
+
- Are you OK? + +
-
- Does this look good? -
-
- - -
diff --git a/components/popconfirm/__tests__/__snapshots__/demo.test.ts.snap b/components/popconfirm/__tests__/__snapshots__/demo.test.ts.snap index 9fcc2be36da8..90dd6ef5b8fa 100644 --- a/components/popconfirm/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/popconfirm/__tests__/__snapshots__/demo.test.ts.snap @@ -214,64 +214,68 @@ Array [ role="tooltip" >
- - + + - +
+ Are you OK? +
+
- Are you OK? + Does this look good?
-
-
- Does this look good? -
-
- - + + +
@@ -293,64 +297,227 @@ Array [ role="tooltip" >
- - + + - +
+ Are you OK? +
+
- Are you OK? + Does this look good? +
+
+ +
+ + + + , +] +`; + +exports[`renders ./components/popconfirm/demo/wireframe.tsx correctly 1`] = ` +Array [ +
+
+
+ +
+
, +
+
+
+
diff --git a/components/popconfirm/__tests__/__snapshots__/index.test.tsx.snap b/components/popconfirm/__tests__/__snapshots__/index.test.tsx.snap index a2f125ceb489..316c4e743529 100644 --- a/components/popconfirm/__tests__/__snapshots__/index.test.tsx.snap +++ b/components/popconfirm/__tests__/__snapshots__/index.test.tsx.snap @@ -2,8 +2,8 @@ exports[`Popconfirm rtl render component should be rendered correctly in RTL direction 1`] = ``; -exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"
"`; +exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"
"`; -exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"
"`; +exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"
"`; -exports[`Popconfirm shows content for render functions 1`] = `"
"`; +exports[`Popconfirm shows content for render functions 1`] = `"
"`; diff --git a/components/popconfirm/demo/wireframe.md b/components/popconfirm/demo/wireframe.md new file mode 100644 index 000000000000..5dfe42d65559 --- /dev/null +++ b/components/popconfirm/demo/wireframe.md @@ -0,0 +1,7 @@ +## zh-CN + +线框风格。 + +## en-US + +Wireframe style. diff --git a/components/popconfirm/demo/wireframe.tsx b/components/popconfirm/demo/wireframe.tsx new file mode 100644 index 000000000000..1c6202f00a99 --- /dev/null +++ b/components/popconfirm/demo/wireframe.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { ConfigProvider, Popconfirm } from 'antd'; + +const { _InternalPanelDoNotUseOrYouWillBeFired: InternalPopconfirm } = Popconfirm; + +const App: React.FC = () => ( + + + + +); + +export default App; diff --git a/components/popconfirm/index.en-US.md b/components/popconfirm/index.en-US.md index 36290d5d3784..738676f0de87 100644 --- a/components/popconfirm/index.en-US.md +++ b/components/popconfirm/index.en-US.md @@ -26,6 +26,7 @@ The difference with the `confirm` modal dialog is that it's more lightweight tha Asynchronously close Asynchronously close on Promise _InternalPanelDoNotUseOrYouWillBeFired +Wireframe ## API diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 3c64fc60f4f3..b33085e00ef0 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -3,6 +3,7 @@ import classNames from 'classnames'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import KeyCode from 'rc-util/lib/KeyCode'; import * as React from 'react'; +import omit from 'rc-util/lib/omit'; import type { ButtonProps, LegacyButtonType } from '../button/button'; import { ConfigContext } from '../config-provider'; import Popover from '../popover'; @@ -10,7 +11,6 @@ import type { AbstractTooltipProps } from '../tooltip'; import type { RenderFunction } from '../_util/getRenderPropValue'; import { cloneElement } from '../_util/reactNode'; import PurePanel, { Overlay } from './PurePanel'; - import usePopconfirmStyle from './style'; export interface PopconfirmProps extends AbstractTooltipProps { @@ -95,14 +95,14 @@ const Popconfirm = React.forwardRef((props, ref) => { return wrapSSR( 异步关闭 基于 Promise 的异步关闭 _InternalPanelDoNotUseOrYouWillBeFired +线框风格 ## API diff --git a/components/popover/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/popover/__tests__/__snapshots__/demo-extend.test.ts.snap index 26071b35cb93..61409fa7d067 100644 --- a/components/popover/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/popover/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1130,3 +1130,76 @@ exports[`renders ./components/popover/demo/triggerType.tsx extend context correc
`; + +exports[`renders ./components/popover/demo/wireframe.tsx extend context correctly 1`] = ` +Array [ +
+
+
+ +
+
, +
+
+
+ +
+
, +] +`; diff --git a/components/popover/__tests__/__snapshots__/demo.test.ts.snap b/components/popover/__tests__/__snapshots__/demo.test.ts.snap index 454226edea1b..746b1d070cd2 100644 --- a/components/popover/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/popover/__tests__/__snapshots__/demo.test.ts.snap @@ -274,3 +274,76 @@ exports[`renders ./components/popover/demo/triggerType.tsx correctly 1`] = `
`; + +exports[`renders ./components/popover/demo/wireframe.tsx correctly 1`] = ` +Array [ +
+
+
+ +
+
, +
+
+
+ +
+
, +] +`; diff --git a/components/popover/demo/wireframe.md b/components/popover/demo/wireframe.md new file mode 100644 index 000000000000..da41370eba12 --- /dev/null +++ b/components/popover/demo/wireframe.md @@ -0,0 +1,7 @@ +## zh-CN + +线框样式。 + +## en-US + +Wireframe style. diff --git a/components/popover/demo/wireframe.tsx b/components/popover/demo/wireframe.tsx new file mode 100644 index 000000000000..c8cd85cef752 --- /dev/null +++ b/components/popover/demo/wireframe.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { ConfigProvider, Popover } from 'antd'; + +const { _InternalPanelDoNotUseOrYouWillBeFired: InternalPopover } = Popover; + +const content = ( +
+

Content

+

Content

+
+); + +const App: React.FC = () => ( + + + + +); + +export default App; diff --git a/components/popover/index.en-US.md b/components/popover/index.en-US.md index 2eb08f0101dc..f39cdc7518db 100644 --- a/components/popover/index.en-US.md +++ b/components/popover/index.en-US.md @@ -25,6 +25,7 @@ Comparing with `Tooltip`, besides information `Popover` card can also provide ac Arrow pointing Hover with click popover _InternalPanelDoNotUseOrYouWillBeFired +Wireframe ## API diff --git a/components/popover/index.tsx b/components/popover/index.tsx index b655890d2456..8112324070f7 100644 --- a/components/popover/index.tsx +++ b/components/popover/index.tsx @@ -13,8 +13,6 @@ import useStyle from './style'; export interface PopoverProps extends AbstractTooltipProps { title?: React.ReactNode | RenderFunction; content?: React.ReactNode | RenderFunction; - /** @internal Used For Popconfirm. Safe to remove. */ - _overlay?: React.ReactNode; } interface OverlayPorps { @@ -41,7 +39,6 @@ const Popover = React.forwardRef((props, ref) => { title, content, overlayClassName, - _overlay, placement = 'top', trigger = 'hover', mouseEnterDelay = 0.1, @@ -68,7 +65,7 @@ const Popover = React.forwardRef((props, ref) => { prefixCls={prefixCls} overlayClassName={overlayCls} ref={ref} - overlay={_overlay || } + overlay={} transitionName={getTransitionName(rootPrefixCls, 'zoom-big', otherProps.transitionName)} data-popover-inject />, diff --git a/components/popover/index.zh-CN.md b/components/popover/index.zh-CN.md index be19d9dd83f6..a0ae1def96c3 100644 --- a/components/popover/index.zh-CN.md +++ b/components/popover/index.zh-CN.md @@ -26,6 +26,7 @@ demo: 箭头指向 悬停点击弹出窗口 _InternalPanelDoNotUseOrYouWillBeFired +线框风格 ## API diff --git a/components/popover/style/index.tsx b/components/popover/style/index.tsx index 6f5f250bc761..26d811b94f3e 100644 --- a/components/popover/style/index.tsx +++ b/components/popover/style/index.tsx @@ -36,7 +36,11 @@ const genBaseStyle: GenerateStyle = (token) => { ...resetComponent(token), position: 'absolute', top: 0, - insetInlineStart: 0, + // use `left` to fix https://github.com/ant-design/ant-design/issues/39195 + left: { + _skip_check_: true, + value: 0, + }, zIndex: zIndexPopup, fontWeight: 'normal', whiteSpace: 'normal', diff --git a/components/qrcode/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/qrcode/__tests__/__snapshots__/demo-extend.test.ts.snap new file mode 100644 index 000000000000..74af4d455c9e --- /dev/null +++ b/components/qrcode/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -0,0 +1,403 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./components/qrcode/demo/Popover.tsx extend context correctly 1`] = ` +Array [ + icon, +
+
+
+
+ +
+ +
+
+
, +] +`; + +exports[`renders ./components/qrcode/demo/base.tsx extend context correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/qrcode/demo/customColor.tsx extend context correctly 1`] = ` +
+
+
+ +
+
+
+
+ +
+
+
+`; + +exports[`renders ./components/qrcode/demo/customSize.tsx extend context correctly 1`] = ` +Array [ +
+ + +
, +
+ + +
, +] +`; + +exports[`renders ./components/qrcode/demo/download.tsx extend context correctly 1`] = ` +
+
+ +
+ +
+`; + +exports[`renders ./components/qrcode/demo/errorlevel.tsx extend context correctly 1`] = ` +Array [ +
+ +
, +
+
+ + + + +
+
, +] +`; + +exports[`renders ./components/qrcode/demo/icon.tsx extend context correctly 1`] = ` +
+ + +
+`; + +exports[`renders ./components/qrcode/demo/status.tsx extend context correctly 1`] = ` +
+
+
+
+
+ + + + + + +
+
+ +
+
+
+
+
+

+ QRCode is expired +

+ +
+ +
+
+
+`; diff --git a/components/qrcode/__tests__/__snapshots__/demo.test.ts.snap b/components/qrcode/__tests__/__snapshots__/demo.test.ts.snap new file mode 100644 index 000000000000..51e8a82e7078 --- /dev/null +++ b/components/qrcode/__tests__/__snapshots__/demo.test.ts.snap @@ -0,0 +1,363 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./components/qrcode/demo/Popover.tsx correctly 1`] = ` +icon +`; + +exports[`renders ./components/qrcode/demo/base.tsx correctly 1`] = ` +
+ +
+`; + +exports[`renders ./components/qrcode/demo/customColor.tsx correctly 1`] = ` +
+
+
+ +
+
+
+
+ +
+
+
+`; + +exports[`renders ./components/qrcode/demo/customSize.tsx correctly 1`] = ` +Array [ +
+ + +
, +
+ + +
, +] +`; + +exports[`renders ./components/qrcode/demo/download.tsx correctly 1`] = ` +
+
+ +
+ +
+`; + +exports[`renders ./components/qrcode/demo/errorlevel.tsx correctly 1`] = ` +Array [ +
+ +
, +
+
+ + + + +
+
, +] +`; + +exports[`renders ./components/qrcode/demo/icon.tsx correctly 1`] = ` +
+ + +
+`; + +exports[`renders ./components/qrcode/demo/status.tsx correctly 1`] = ` +
+
+
+
+
+ + + + + + +
+
+ +
+
+
+
+
+

+ QRCode is expired +

+ +
+ +
+
+
+`; diff --git a/components/qrcode/__tests__/__snapshots__/index.test.tsx.snap b/components/qrcode/__tests__/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000000..6dcb91c4b332 --- /dev/null +++ b/components/qrcode/__tests__/__snapshots__/index.test.tsx.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`QRCode test rtl render component should be rendered correctly in RTL direction 1`] = `null`; + +exports[`QRCode test should correct render 1`] = ` +
+
+ +
+
+`; + +exports[`QRCode test should render \`null\` and console Error when value not exist 1`] = `null`; diff --git a/components/qrcode/__tests__/demo-extend.test.ts b/components/qrcode/__tests__/demo-extend.test.ts new file mode 100644 index 000000000000..79dea1e4faf5 --- /dev/null +++ b/components/qrcode/__tests__/demo-extend.test.ts @@ -0,0 +1,3 @@ +import { extendTest } from '../../../tests/shared/demoTest'; + +extendTest('qrcode'); diff --git a/components/qrcode/__tests__/demo.test.ts b/components/qrcode/__tests__/demo.test.ts new file mode 100644 index 000000000000..1cb1d77dd4fd --- /dev/null +++ b/components/qrcode/__tests__/demo.test.ts @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest'; + +demoTest('qrcode'); diff --git a/components/qrcode/__tests__/image.test.ts b/components/qrcode/__tests__/image.test.ts new file mode 100644 index 000000000000..df82d405e561 --- /dev/null +++ b/components/qrcode/__tests__/image.test.ts @@ -0,0 +1,5 @@ +import { imageDemoTest } from '../../../tests/shared/imageTest'; + +describe('QRCode image', () => { + imageDemoTest('qrcode'); +}); diff --git a/components/qrcode/__tests__/index.test.tsx b/components/qrcode/__tests__/index.test.tsx new file mode 100644 index 000000000000..8cd91d3ce0d0 --- /dev/null +++ b/components/qrcode/__tests__/index.test.tsx @@ -0,0 +1,91 @@ +import React, { useState } from 'react'; +import QRCode from '..'; +import mountTest from '../../../tests/shared/mountTest'; +import rtlTest from '../../../tests/shared/rtlTest'; +import { fireEvent, render } from '../../../tests/utils'; +import type { QRCodeProps } from '../interface'; + +describe('QRCode test', () => { + mountTest(QRCode); + rtlTest(QRCode); + + it('should correct render', () => { + const { container } = render(); + expect( + container + ?.querySelector('.ant-qrcode') + ?.querySelector('canvas'), + ).toBeTruthy(); + expect(container).toMatchSnapshot(); + }); + + it('should render `null` and console Error when value not exist', () => { + const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const { container } = render(); + expect(container.firstChild).toBe(null); + expect(container.firstChild).toMatchSnapshot(); + expect(errSpy).toHaveBeenCalledWith('Warning: [antd: QRCode] need to receive `value` props'); + errSpy.mockRestore(); + }); + + it('support custom icon', () => { + const { container } = render(); + expect( + container + ?.querySelector('.ant-qrcode') + ?.querySelector('img'), + ).toBeTruthy(); + }); + + it('support custom size', () => { + const { container } = render(); + const wapper = container.querySelector('.ant-qrcode'); + expect(wapper?.style?.width).toBe('100px'); + expect(wapper?.style?.height).toBe('100px'); + }); + + it('support refresh', () => { + const refresh = jest.fn(); + const { container } = render(); + fireEvent.click( + container + ?.querySelector('.ant-qrcode') + ?.querySelector('button.ant-btn-link')!, + ); + expect(refresh).toHaveBeenCalled(); + }); + + it('support loading', () => { + const Demo: React.FC = () => { + const [status, setStatus] = useState('active'); + return ( + <> + + + + ); + }; + const { container } = render(); + expect(container.querySelector('.ant-spin-spinning')).toBeFalsy(); + fireEvent.click(container?.querySelector('button')!); + expect(container.querySelector('.ant-spin-spinning')).toBeTruthy(); + }); + + it('support bordered', () => { + const { container } = render(); + expect(container?.querySelector('.ant-qrcode')).toHaveClass( + 'ant-qrcode-borderless', + ); + }); + + it('should console Error when icon exist && errorLevel is `L`', () => { + const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + render(); + expect(errSpy).toHaveBeenCalledWith( + 'Warning: [antd: QRCode] ErrorLevel `L` is not recommended to be used with `icon`, for scanning result would be affected by low level.', + ); + errSpy.mockRestore(); + }); +}); diff --git a/components/qrcode/demo/Popover.md b/components/qrcode/demo/Popover.md new file mode 100644 index 000000000000..48c076f08cf6 --- /dev/null +++ b/components/qrcode/demo/Popover.md @@ -0,0 +1,7 @@ +## zh-CN + +带气泡卡片的例子。 + +## en-US + +With Popover. diff --git a/components/qrcode/demo/Popover.tsx b/components/qrcode/demo/Popover.tsx new file mode 100644 index 000000000000..342e1505d402 --- /dev/null +++ b/components/qrcode/demo/Popover.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { QRCode, Popover } from 'antd'; + +const src = 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg'; + +const App: React.FC = () => ( + }> + icon + +); + +export default App; diff --git a/components/qrcode/demo/base.md b/components/qrcode/demo/base.md new file mode 100644 index 000000000000..d7c5bd3ef03d --- /dev/null +++ b/components/qrcode/demo/base.md @@ -0,0 +1,7 @@ +## zh-CN + +基本用法。 + +## en-US + +Basic Usage. diff --git a/components/qrcode/demo/base.tsx b/components/qrcode/demo/base.tsx new file mode 100644 index 000000000000..5092f0f86e1a --- /dev/null +++ b/components/qrcode/demo/base.tsx @@ -0,0 +1,6 @@ +import React from 'react'; +import { QRCode } from 'antd'; + +const App: React.FC = () => ; + +export default App; diff --git a/components/qrcode/demo/customColor.md b/components/qrcode/demo/customColor.md new file mode 100644 index 000000000000..f6824980303d --- /dev/null +++ b/components/qrcode/demo/customColor.md @@ -0,0 +1,7 @@ +## zh-CN + +通过设置 `color` 自定义二维码颜色,通过设置 `style` 自定义背景颜色。 + +## en-US + +Custom Color. diff --git a/components/qrcode/demo/customColor.tsx b/components/qrcode/demo/customColor.tsx new file mode 100644 index 000000000000..8b6118461439 --- /dev/null +++ b/components/qrcode/demo/customColor.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { QRCode, Space, theme } from 'antd'; + +const { useToken } = theme; + +const App: React.FC = () => { + const { token } = useToken(); + return ( + + + + + ); +}; + +export default App; diff --git a/components/qrcode/demo/customSize.md b/components/qrcode/demo/customSize.md new file mode 100644 index 000000000000..08e60002d8c3 --- /dev/null +++ b/components/qrcode/demo/customSize.md @@ -0,0 +1,7 @@ +## zh-CN + +自定义尺寸 + +## en-US + +Custom Size. diff --git a/components/qrcode/demo/customSize.tsx b/components/qrcode/demo/customSize.tsx new file mode 100644 index 000000000000..d1ee8f6fa9fe --- /dev/null +++ b/components/qrcode/demo/customSize.tsx @@ -0,0 +1,49 @@ +import React, { useState } from 'react'; +import { MinusOutlined, PlusOutlined } from '@ant-design/icons'; +import { QRCode, Button } from 'antd'; + +const App: React.FC = () => { + const [size, setSize] = useState(160); + + const increase = () => { + setSize((prevSize) => { + const newSize = prevSize + 10; + if (newSize > 300) { + return 300; + } + return newSize; + }); + }; + + const decline = () => { + setSize((prevSize) => { + const newSize = prevSize - 10; + if (newSize < 48) { + return 48; + } + return newSize; + }); + }; + + return ( + <> + + + + + + + ); +}; + +export default App; diff --git a/components/qrcode/demo/download.md b/components/qrcode/demo/download.md new file mode 100644 index 000000000000..9967cf7fa2f1 --- /dev/null +++ b/components/qrcode/demo/download.md @@ -0,0 +1,7 @@ +## zh-CN + +下载二维码的简单实现。 + +## en-US + +A way to download QRCode. diff --git a/components/qrcode/demo/download.tsx b/components/qrcode/demo/download.tsx new file mode 100644 index 000000000000..c66ce361cc65 --- /dev/null +++ b/components/qrcode/demo/download.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QRCode, Button } from 'antd'; + +const downloadQRCode = () => { + const canvas = document.getElementById('myqrcode')?.querySelector('canvas'); + if (canvas) { + const url = canvas.toDataURL(); + const a = document.createElement('a'); + a.download = 'QRCode.png'; + a.href = url; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + } +}; + +const App: React.FC = () => ( +
+ + +
+); + +export default App; diff --git a/components/qrcode/demo/errorlevel.md b/components/qrcode/demo/errorlevel.md new file mode 100644 index 000000000000..1df7f09c4606 --- /dev/null +++ b/components/qrcode/demo/errorlevel.md @@ -0,0 +1,7 @@ +## zh-CN + +通过设置 errorLevel 调整不同的容错等级。 + +## en-US + +set Error Level. diff --git a/components/qrcode/demo/errorlevel.tsx b/components/qrcode/demo/errorlevel.tsx new file mode 100644 index 000000000000..0995a120a10f --- /dev/null +++ b/components/qrcode/demo/errorlevel.tsx @@ -0,0 +1,19 @@ +import React, { useState } from 'react'; +import type { QRCodeProps } from 'antd'; +import { Segmented, QRCode } from 'antd'; + +const App: React.FC = () => { + const [level, setLevel] = useState('L'); + return ( + <> + + + + ); +}; + +export default App; diff --git a/components/qrcode/demo/icon.md b/components/qrcode/demo/icon.md new file mode 100644 index 000000000000..05a34f1d8cb6 --- /dev/null +++ b/components/qrcode/demo/icon.md @@ -0,0 +1,7 @@ +## zh-CN + +带 Icon 的二维码。 + +## en-US + +QRCode with Icon. diff --git a/components/qrcode/demo/icon.tsx b/components/qrcode/demo/icon.tsx new file mode 100644 index 000000000000..5b251c49f69d --- /dev/null +++ b/components/qrcode/demo/icon.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { QRCode } from 'antd'; + +const App: React.FC = () => ( + +); + +export default App; diff --git a/components/qrcode/demo/status.md b/components/qrcode/demo/status.md new file mode 100644 index 000000000000..bc25a6993a3d --- /dev/null +++ b/components/qrcode/demo/status.md @@ -0,0 +1,7 @@ +## zh-CN + +可以通过 `status` 的值控制二维码的状态。 + +## en-US + +The status can be controlled by the value `status`. diff --git a/components/qrcode/demo/status.tsx b/components/qrcode/demo/status.tsx new file mode 100644 index 000000000000..3f0a57bca60c --- /dev/null +++ b/components/qrcode/demo/status.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { QRCode, Space } from 'antd'; + +const App: React.FC = () => ( + + + console.log('refresh')} /> + +); + +export default App; diff --git a/components/qrcode/index.en-US.md b/components/qrcode/index.en-US.md new file mode 100644 index 000000000000..63c2df1a6c3d --- /dev/null +++ b/components/qrcode/index.en-US.md @@ -0,0 +1,56 @@ +--- +category: Components +title: QRCode +cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*cJopQrf0ncwAAAAAAAAAAAAADrJ8AQ/original +demo: + cols: 2 +group: + title: Data Display + order: 5 +--- + +Components that can convert links into QR codes, and support custom color and logo. Available since `antd@5.1.0`. + + + +## When To Use + +Used when the link needs to be converted into a QR Code. + +## Examples + + +base +With Icon +other statu +Custom Size +Custom Color +Download QRCode +Error Level +Advanced Usage + +## API + +> This component is available since `antd@5.1.0` + +| Property | Description | Type | Default | +| :-- | :-- | :-- | :-- | +| value | scanned link | string | - | +| icon | include image url (only image link are supported) | string | - | +| size | QRCode size | number | 128 | +| iconSize | include image size | number | 32 | +| color | QRCode Color | string | `#000` | +| bordered | Whether has border style | boolean | `true` | +| errorLevel | Error Code Level | `'L' \| 'M' \| 'Q' \| 'H' ` | `M` | +| status | QRCode statu | `active \| expired \| loading ` | `active` | +| onRefresh | callback | `() => void` | - | + +## FAQ + +### About QRCode ErrorLevel + +The ErrorLevel means that the QR code can be scanned normally after being blocked, and the maximum area that can be blocked is the error correction rate. + +Generally, the QR code is divided into 4 error correction levels: Level `L` can correct about `7%` errors, Level `M` can correct about `15%` errors, Level `Q` can correct about `25%` errors, and Level `H` can correct about `30%` errors. When the content encoding of the QR code carries less information, in other words, when the value link is short, set different error correction levels, and the generated image will not change. + +> For more information, see the: [https://www.qrcode.com/en/about/error_correction](https://www.qrcode.com/en/about/error_correction.html) diff --git a/components/qrcode/index.tsx b/components/qrcode/index.tsx new file mode 100644 index 000000000000..b47d7da9288f --- /dev/null +++ b/components/qrcode/index.tsx @@ -0,0 +1,100 @@ +import React, { useMemo, useContext } from 'react'; +import { QRCodeCanvas } from 'qrcode.react'; +import classNames from 'classnames'; +import { ReloadOutlined } from '@ant-design/icons'; +import { ConfigContext } from '../config-provider'; +import LocaleReceiver from '../locale-provider/LocaleReceiver'; +import type { ConfigConsumerProps } from '../config-provider'; +import type { QRCodeProps, QRPropsCanvas } from './interface'; +import warning from '../_util/warning'; +import useStyle from './style/index'; +import Spin from '../spin'; +import Button from '../button'; +import theme from '../theme'; + +const { useToken } = theme; + +const QRCode: React.FC = (props) => { + const { + value, + icon = '', + size = 160, + iconSize = 40, + color = '#000', + errorLevel = 'M', + status = 'active', + bordered = true, + onRefresh, + style, + className, + prefixCls: customizePrefixCls, + } = props; + const { getPrefixCls } = useContext(ConfigContext); + const prefixCls = getPrefixCls('qrcode', customizePrefixCls); + const [wrapSSR, hashId] = useStyle(prefixCls); + const { token } = useToken(); + const qrCodeProps = useMemo(() => { + const imageSettings: QRCodeProps['imageSettings'] = { + src: icon, + x: undefined, + y: undefined, + height: iconSize, + width: iconSize, + excavate: true, + }; + return { + value, + size: size - (token.paddingSM + token.lineWidth) * 2, + level: errorLevel, + bgColor: 'transparent', + fgColor: color, + imageSettings: icon ? imageSettings : undefined, + }; + }, [errorLevel, color, icon, iconSize, size, value]); + + if (!value) { + if (process.env.NODE_ENV !== 'production') { + warning(false, 'QRCode', 'need to receive `value` props'); + } + return null; + } + + if (process.env.NODE_ENV !== 'production') { + warning( + !(icon && errorLevel === 'L'), + 'QRCode', + 'ErrorLevel `L` is not recommended to be used with `icon`, for scanning result would be affected by low level.', + ); + } + + const cls = classNames(prefixCls, className, hashId, { + [`${prefixCls}-borderless`]: !bordered, + }); + + return wrapSSR( + + {(locale) => ( +
+ {status !== 'active' && ( +
+ {status === 'loading' && } + {status === 'expired' && ( + <> +

{locale.expired}

+ {typeof onRefresh === 'function' && ( + + )} + + )} +
+ )} + +
+ )} +
, + ); +}; + +export default QRCode; diff --git a/components/qrcode/index.zh-CN.md b/components/qrcode/index.zh-CN.md new file mode 100644 index 000000000000..16d2d7402545 --- /dev/null +++ b/components/qrcode/index.zh-CN.md @@ -0,0 +1,57 @@ +--- +category: Components +subtitle: 二维码 +title: QRCode +cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*cJopQrf0ncwAAAAAAAAAAAAADrJ8AQ/original +demo: + cols: 2 +group: + title: 数据展示 + order: 5 +--- + +能够将链接转换生成二维码的组件,支持自定义配色和 Logo 配置,自 `antd@5.1.0` 版本开始提供该组件。 + + + +## 何时使用 + +当需要将链接转换成为二维码时使用。 + +## 代码演示 + + +基本使用 +带 Icon 的例子 +不同的状态 +自定义尺寸 +自定义颜色 +下载二维码 +纠错比例 +高级用法 + +## API + +> 自 `antd@5.1.0` 版本开始提供该组件。 + +| 参数 | 说明 | 类型 | 默认值 | +| :-- | :-- | :-- | :-- | +| value | 扫描后的地址 | string | - | +| icon | 二维码中图片的地址(目前只支持图片地址) | string | - | +| size | 二维码大小 | number | 160 | +| iconSize | 二维码中图片的大小 | number | 40 | +| color | 二维码颜色 | string | `#000` | +| bordered | 是否有边框 | boolean | `true` | +| errorLevel | 二维码纠错等级 | `'L' \| 'M' \| 'Q' \| 'H' ` | `M` | +| status | 二维码状态 | `active \| expired \| loading ` | `active` | +| onRefresh | 点击"点击刷新"的回调 | `() => void` | - | + +## FAQ + +### 关于二维码纠错等级 + +纠错等级也叫纠错率,就是指二维码可以被遮挡后还能正常扫描,而这个能被遮挡的最大面积就是纠错率。 + +通常情况下二维码分为 4 个纠错级别:`L级` 可纠正约 `7%` 错误、`M级` 可纠正约 `15%` 错误、`Q级` 可纠正约 `25%` 错误、`H级` 可纠正约`30%` 错误。并不是所有位置都可以缺损,像最明显的三个角上的方框,直接影响初始定位。中间零散的部分是内容编码,可以容忍缺损。当二维码的内容编码携带信息比较少的时候,也就是链接比较短的时候,设置不同的纠错等级,生成的图片不会发生变化。 + +> 有关更多信息,可参阅相关资料:[https://www.qrcode.com/zh/about/error_correction](https://www.qrcode.com/zh/about/error_correction.html) diff --git a/components/qrcode/interface.ts b/components/qrcode/interface.ts new file mode 100644 index 000000000000..bebeeacd78aa --- /dev/null +++ b/components/qrcode/interface.ts @@ -0,0 +1,32 @@ +import type { CSSProperties } from 'react'; + +interface ImageSettings { + src: string; + height: number; + width: number; + excavate: boolean; + x?: number; + y?: number; +} + +interface QRProps { + value: string; + size?: number; + color?: string; + style?: CSSProperties; + includeMargin?: boolean; + imageSettings?: ImageSettings; +} + +export type QRPropsCanvas = QRProps & React.CanvasHTMLAttributes; + +export interface QRCodeProps extends QRProps { + className?: string; + prefixCls?: string; + icon?: string; + iconSize?: number; + bordered?: boolean; + errorLevel?: 'L' | 'M' | 'Q' | 'H'; + status?: 'active' | 'expired' | 'loading'; + onRefresh?: () => void; +} diff --git a/components/qrcode/style/index.ts b/components/qrcode/style/index.ts new file mode 100644 index 000000000000..0cb4e323d740 --- /dev/null +++ b/components/qrcode/style/index.ts @@ -0,0 +1,59 @@ +import type { FullToken, GenerateStyle } from '../../theme/internal'; +import { mergeToken, genComponentStyleHook } from '../../theme/internal'; +import { resetComponent } from '../../style'; + +export interface ComponentToken {} + +interface QRCodeToken extends FullToken<'QRCode'> { + QRCodeMaskBackgroundColor: string; +} + +const genQRCodeStyle: GenerateStyle = (token) => { + const { componentCls } = token; + return { + [componentCls]: { + ...resetComponent(token), + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + padding: token.paddingSM, + borderRadius: token.borderRadiusLG, + border: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`, + position: 'relative', + width: '100%', + height: '100%', + overflow: 'hidden', + [`& > ${componentCls}-mask`]: { + position: 'absolute', + insetBlockStart: 0, + insetInlineStart: 0, + zIndex: 10, + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + width: '100%', + height: '100%', + color: token.colorText, + lineHeight: token.lineHeight, + background: token.QRCodeMaskBackgroundColor, + textAlign: 'center', + }, + '&-icon': { + marginBlockEnd: token.marginXS, + fontSize: token.controlHeight, + }, + }, + [`${componentCls}-borderless`]: { + borderColor: 'transparent', + }, + }; +}; + +export default genComponentStyleHook<'QRCode'>('QRCode', (token) => + genQRCodeStyle( + mergeToken(token, { + QRCodeMaskBackgroundColor: 'rgba(255, 255, 255, 0.96)', + }), + ), +); diff --git a/components/radio/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/radio/__tests__/__snapshots__/demo-extend.test.ts.snap index 9058853ae15e..f04a2c2bbaad 100644 --- a/components/radio/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/radio/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1372,3 +1372,175 @@ Array [
, ] `; + +exports[`renders ./components/radio/demo/wireframe.tsx extend context correctly 1`] = ` +Array [ +
+ + + + +
, +
, +
+ + + + +
, +] +`; diff --git a/components/radio/__tests__/__snapshots__/demo.test.ts.snap b/components/radio/__tests__/__snapshots__/demo.test.ts.snap index 1329b6fd0ce5..dba0a7465448 100644 --- a/components/radio/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/radio/__tests__/__snapshots__/demo.test.ts.snap @@ -1372,3 +1372,175 @@ Array [
, ] `; + +exports[`renders ./components/radio/demo/wireframe.tsx correctly 1`] = ` +Array [ +
+ + + + +
, +
, +
+ + + + +
, +] +`; diff --git a/components/radio/demo/wireframe.md b/components/radio/demo/wireframe.md new file mode 100644 index 000000000000..5dfe42d65559 --- /dev/null +++ b/components/radio/demo/wireframe.md @@ -0,0 +1,7 @@ +## zh-CN + +线框风格。 + +## en-US + +Wireframe style. diff --git a/components/radio/demo/wireframe.tsx b/components/radio/demo/wireframe.tsx new file mode 100644 index 000000000000..00c1581e779b --- /dev/null +++ b/components/radio/demo/wireframe.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { ConfigProvider, Radio } from 'antd'; + +const App: React.FC = () => ( + + + A + B + C + D + +
+ + A + B + C + D + +
+); + +export default App; diff --git a/components/radio/index.en-US.md b/components/radio/index.en-US.md index 6055c61c0cc1..9743901483ec 100644 --- a/components/radio/index.en-US.md +++ b/components/radio/index.en-US.md @@ -26,7 +26,8 @@ Radio. Radio.Group with name Size Solid radio button -测试 Badge 的样式 +Badge style +Wireframe ## API diff --git a/components/radio/index.zh-CN.md b/components/radio/index.zh-CN.md index c86d251da49b..40eb8a145873 100644 --- a/components/radio/index.zh-CN.md +++ b/components/radio/index.zh-CN.md @@ -27,7 +27,8 @@ demo: 单选组合 - 配合 name 使用 大小 填底的按钮样式 -Badge style +测试 Badge 的样式 +线框风格 ## API diff --git a/components/radio/radio.tsx b/components/radio/radio.tsx index c4a8bf02fc45..85629d0af29f 100644 --- a/components/radio/radio.tsx +++ b/components/radio/radio.tsx @@ -2,7 +2,6 @@ import classNames from 'classnames'; import RcCheckbox from 'rc-checkbox'; import { composeRef } from 'rc-util/lib/ref'; import * as React from 'react'; -import { useContext } from 'react'; import { ConfigContext } from '../config-provider'; import DisabledContext from '../config-provider/DisabledContext'; import { FormItemInputContext } from '../form/context'; @@ -19,7 +18,7 @@ const InternalRadio: React.ForwardRefRenderFunction = ( const { getPrefixCls, direction } = React.useContext(ConfigContext); const innerRef = React.useRef(); const mergedRef = composeRef(ref, innerRef); - const { isFormItemInput } = useContext(FormItemInputContext); + const { isFormItemInput } = React.useContext(FormItemInputContext); warning(!('optionType' in props), 'Radio', '`optionType` is only support in Radio.Group.'); diff --git a/components/select/index.tsx b/components/select/index.tsx index e4928cca74ed..32dec3676fc3 100755 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -7,7 +7,6 @@ import type { OptionProps } from 'rc-select/lib/Option'; import type { BaseOptionType, DefaultOptionType } from 'rc-select/lib/Select'; import omit from 'rc-util/lib/omit'; import * as React from 'react'; -import { useContext } from 'react'; import { ConfigContext } from '../config-provider'; import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; import DisabledContext from '../config-provider/DisabledContext'; @@ -125,7 +124,7 @@ const InternalSelect = = (token) => { width: '100%', }, // Space.Compact - ...genCompactItemStyle( - token, - componentCls, - `${componentCls}-selector`, - `${componentCls}-focused`, - ), + ...genCompactItemStyle(token, componentCls, { + borderElCls: `${componentCls}-selector`, + focusElCls: `${componentCls}-focused`, + }), }, }, diff --git a/components/select/style/single.tsx b/components/select/style/single.tsx index 988a4f550e2d..dad8aea78f84 100644 --- a/components/select/style/single.tsx +++ b/components/select/style/single.tsx @@ -165,7 +165,6 @@ export default function genSingleStyle(token: SelectToken): CSSInterpolation { // With arrow should provides `padding-right` to show the arrow [`&${componentCls}-show-arrow ${componentCls}-selection-search`]: { - insetInlineStart: 'auto', insetInlineEnd: inputPaddingHorizontalSM + token.fontSize * 1.5, }, diff --git a/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap index d0311c2e7157..a1e5c8d479fb 100644 --- a/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -259,60 +259,64 @@ exports[`renders ./components/space/demo/base.tsx extend context correctly 1`] = role="tooltip" >
- - + + + - +
+ Are you sure delete this task? +
+
- Are you sure delete this task? + +
-
- - -
@@ -14477,60 +14481,64 @@ exports[`renders ./components/space/demo/debug.tsx extend context correctly 1`] role="tooltip" >
- - + + + - +
+ Are you sure delete this task? +
+
- Are you sure delete this task? + +
-
- - -
@@ -14576,60 +14584,64 @@ exports[`renders ./components/space/demo/debug.tsx extend context correctly 1`] role="tooltip" >
- - + + + - +
+ Are you sure delete this task? +
+
- Are you sure delete this task? + +
-
- - -
diff --git a/components/steps/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/steps/__tests__/__snapshots__/demo-extend.test.ts.snap index ad38b92a37ea..57a2c6e2ef11 100644 --- a/components/steps/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/steps/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -528,139 +528,6 @@ exports[`renders ./components/steps/demo/customized-progress-dot.tsx extend cont `; -exports[`renders ./components/steps/demo/deprecated.tsx extend context correctly 1`] = ` -
-
-
-
-
- - - - - -
-
-
- Finished -
-
- This is a description. -
-
-
-
-
-
-
-
- - 2 - -
-
-
- In Progress -
- Left 00:00:08 -
-
-
- This is a description. -
-
-
-
-
-
-
-
- - 3 - -
-
-
- Waiting -
-
- This is a description. -
-
-
-
-
-`; - exports[`renders ./components/steps/demo/error.tsx extend context correctly 1`] = `
`; + +exports[`renders ./components/steps/demo/wireframe.tsx extend context correctly 1`] = ` +
+
+
+
+
+ + + + + +
+
+
+ Finished +
+
+ This is a description. +
+
+
+
+
+
+
+
+ + 2 + +
+
+
+ In Progress +
+ Left 00:00:08 +
+
+
+ This is a description. +
+
+
+
+
+
+
+
+ + 3 + +
+
+
+ Waiting +
+
+ This is a description. +
+
+
+
+
+`; diff --git a/components/steps/__tests__/__snapshots__/demo.test.ts.snap b/components/steps/__tests__/__snapshots__/demo.test.ts.snap index 0f2c4bb839e2..f1fa3caf3c5d 100644 --- a/components/steps/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/steps/__tests__/__snapshots__/demo.test.ts.snap @@ -384,139 +384,6 @@ exports[`renders ./components/steps/demo/customized-progress-dot.tsx correctly 1
`; -exports[`renders ./components/steps/demo/deprecated.tsx correctly 1`] = ` -
-
-
-
-
- - - - - -
-
-
- Finished -
-
- This is a description. -
-
-
-
-
-
-
-
- - 2 - -
-
-
- In Progress -
- Left 00:00:08 -
-
-
- This is a description. -
-
-
-
-
-
-
-
- - 3 - -
-
-
- Waiting -
-
- This is a description. -
-
-
-
-
-`; - exports[`renders ./components/steps/demo/error.tsx correctly 1`] = `
`; + +exports[`renders ./components/steps/demo/wireframe.tsx correctly 1`] = ` +
+
+
+
+
+ + + + + +
+
+
+ Finished +
+
+ This is a description. +
+
+
+
+
+
+
+
+ + 2 + +
+
+
+ In Progress +
+ Left 00:00:08 +
+
+
+ This is a description. +
+
+
+
+
+
+
+
+ + 3 + +
+
+
+ Waiting +
+
+ This is a description. +
+
+
+
+
+`; diff --git a/components/steps/demo/deprecated.md b/components/steps/demo/deprecated.md deleted file mode 100644 index b31206f35781..000000000000 --- a/components/steps/demo/deprecated.md +++ /dev/null @@ -1,7 +0,0 @@ -## zh-CN - -简单的步骤条。 - -## en-US - -The most basic step bar. diff --git a/components/steps/demo/deprecated.tsx b/components/steps/demo/deprecated.tsx deleted file mode 100644 index 30b1237ce24c..000000000000 --- a/components/steps/demo/deprecated.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { Steps } from 'antd'; - -const { Step } = Steps; -const description = 'This is a description.'; -const App: React.FC = () => ( - - - - - -); - -export default App; diff --git a/components/steps/demo/wireframe.md b/components/steps/demo/wireframe.md new file mode 100644 index 000000000000..5dfe42d65559 --- /dev/null +++ b/components/steps/demo/wireframe.md @@ -0,0 +1,7 @@ +## zh-CN + +线框风格。 + +## en-US + +Wireframe style. diff --git a/components/steps/demo/wireframe.tsx b/components/steps/demo/wireframe.tsx new file mode 100644 index 000000000000..ef4281aeecd6 --- /dev/null +++ b/components/steps/demo/wireframe.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { ConfigProvider, Steps } from 'antd'; + +const description = 'This is a description.'; +const App: React.FC = () => ( + + + +); + +export default App; diff --git a/components/steps/index.en-US.md b/components/steps/index.en-US.md index fbb8aefb8260..c9e5df795818 100644 --- a/components/steps/index.en-US.md +++ b/components/steps/index.en-US.md @@ -11,27 +11,9 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*677sTqCpE3wAAAAAAA When a given task is complicated or has a certain sequence in the series of subtasks, we can decompose it into several steps to make things easier. -### Usage upgrade after 4.24.0 - - - -```jsx -// works when >=4.24.0, recommended ✅ -const items = [{ title: 'first step' }, { title: 'second step' }, { title: 'third step' }]; -return ; - -// works when <4.24.0, deprecated when >=4.24.0 🙅🏻‍♀️ - - - - -; -``` - ## Examples -Basic (deprecated syntactic sugar) Basic Mini version With icon @@ -49,6 +31,7 @@ return ; Progress Debug Steps inside Steps Inline Steps +Wireframe ## API diff --git a/components/steps/index.zh-CN.md b/components/steps/index.zh-CN.md index ef9025c01642..da5d632b86eb 100644 --- a/components/steps/index.zh-CN.md +++ b/components/steps/index.zh-CN.md @@ -12,27 +12,9 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*677sTqCpE3wAAAAAAA 当任务复杂或者存在先后关系时,将其分解成一系列步骤,从而简化任务。 -### 4.24.0 用法升级 - - - -```jsx -// >=4.24.0 可用,推荐的写法 ✅ -const items = [{ title: '第一步' }, { title: '第二步' }, { title: '第三步' }]; -return ; - -// <4.24.0 可用,>=4.24.0 时不推荐 🙅🏻‍♀️ - - - - -; -``` - ## 代码演示 -基本用法 (废弃的语法糖) 基本用法 迷你版 带图标的步骤条 @@ -50,6 +32,7 @@ return ; Progress Debug Steps 嵌套 Steps 内联步骤 +线框风格 ## API diff --git a/components/style/compact-item.tsx b/components/style/compact-item.tsx index 8165934c8cb1..236c79391363 100644 --- a/components/style/compact-item.tsx +++ b/components/style/compact-item.tsx @@ -2,26 +2,40 @@ import type { CSSObject } from '@ant-design/cssinjs'; import type { DerivativeToken } from '../theme/internal'; +interface CompactItemOptions { + focus?: boolean; + /** + * Some component borders are implemented on child elements + * like `Select` + */ + borderElCls?: string; + /** + * Some components have special `focus` className especially with popovers + * like `Select` and `DatePicker` + */ + focusElCls?: string; +} + // handle border collapse -function compactItemBorder( - token: DerivativeToken, - borderedItemCls?: string, - popoverFocusedCls?: string, -): CSSObject { - const childCombinator = borderedItemCls ? '> *' : ''; +function compactItemBorder(token: DerivativeToken, options: CompactItemOptions): CSSObject { + const childCombinator = options.borderElCls ? '> *' : ''; + const hoverEffects = ['hover', options.focus ? 'focus' : null, 'active'] + .filter(Boolean) + .map((n) => `&:${n} ${childCombinator}`) + .join(','); return { '&-item:not(&-last-item)': { marginInlineEnd: -token.lineWidth, }, '&-item': { - [`&:hover ${childCombinator}, &:focus ${childCombinator}, &:active ${childCombinator}`]: { + [hoverEffects]: { zIndex: 2, }, - ...(popoverFocusedCls + ...(options.focusElCls ? { - [`&${popoverFocusedCls}`]: { + [`&${options.focusElCls}`]: { zIndex: 2, }, } @@ -35,8 +49,8 @@ function compactItemBorder( } // handle border-radius -function compactItemBorderRadius(prefixCls: string, borderedElementCls?: string): CSSObject { - const childCombinator = borderedElementCls ? `> ${borderedElementCls}` : ''; +function compactItemBorderRadius(prefixCls: string, options: CompactItemOptions): CSSObject { + const childCombinator = options.borderElCls ? `> ${options.borderElCls}` : ''; return { [`&-item:not(&-first-item):not(&-last-item) ${childCombinator}`]: { @@ -64,18 +78,12 @@ function compactItemBorderRadius(prefixCls: string, borderedElementCls?: string) export function genCompactItemStyle( token: DerivativeToken, prefixCls: string, - /** Some component borders are implemented on child elements like `Select` */ - borderedElementCls?: string, - /** - * Some components have special `focus` className especially with popovers like `Select` and - * `DatePicker` - */ - popoverFocusedCls?: string, + options: CompactItemOptions = { focus: true }, ): CSSObject { return { '&-compact': { - ...compactItemBorder(token, borderedElementCls, popoverFocusedCls), - ...compactItemBorderRadius(prefixCls, borderedElementCls), + ...compactItemBorder(token, options), + ...compactItemBorderRadius(prefixCls, options), }, }; } diff --git a/components/style/index.tsx b/components/style/index.tsx index 743ac86d504e..bcac9ee92a15 100644 --- a/components/style/index.tsx +++ b/components/style/index.tsx @@ -103,15 +103,11 @@ export const genLinkStyle = (token: DerivativeToken): CSSObject => ({ }, }); -export const genCommonStyle = (token: DerivativeToken, componentPrefixCls: string): CSSObject => { - const { fontFamily, fontSize } = token; - +export const genCommonStyle = (componentPrefixCls: string): CSSObject => { const rootPrefixSelector = `[class^="${componentPrefixCls}"], [class*=" ${componentPrefixCls}"]`; return { [rootPrefixSelector]: { - fontFamily, - fontSize, boxSizing: 'border-box', '&::before, &::after': { diff --git a/components/switch/style/index.tsx b/components/switch/style/index.tsx index 2a5018ebb24a..d712357854cb 100644 --- a/components/switch/style/index.tsx +++ b/components/switch/style/index.tsx @@ -182,6 +182,7 @@ const genSwitchInnerStyle: GenerateStyle = (token) => { display: 'block', overflow: 'hidden', borderRadius: 100, + height: '100%', [`${switchInnerCls}-checked, ${switchInnerCls}-unchecked`]: { display: 'block', diff --git a/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap index fe7fab85c7a0..ca17e1a3ccf9 100644 --- a/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/table/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -4834,60 +4834,64 @@ exports[`renders ./components/table/demo/edit-cell.tsx extend context correctly role="tooltip" >
- - + + - +
+ Sure to delete? +
+
- Sure to delete? + +
-
- - -
@@ -4945,60 +4949,64 @@ exports[`renders ./components/table/demo/edit-cell.tsx extend context correctly role="tooltip" >
- - + + - +
+ Sure to delete? +
+
- Sure to delete? + +
-
- - -
diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index bb6d1e3b5d14..0bbd952097cf 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -329,12 +329,6 @@ return ; return
record.uid} />; ``` -## Migrate to v4 - -Table removes `onRowClick`, `onRowDoubleClick`, `onRowMouseEnter`, `onRowMouseLeave` and some other api which is already deprecated in v3. If you only use api listing in official document, that's OK. - -Besides, the breaking change is changing `dataIndex` from nest string path like `user.age` to string array path like `['user', 'age']`. This help to resolve developer should additional work on the field which contains `.`. - ## FAQ ### How to hide pagination when single page or no data? diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 0f8291b64450..3c00afd16616 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -332,12 +332,6 @@ return
; return
record.uid} />; ``` -## 从 v3 升级到 v4 - -Table 移除了在 v3 中废弃的 `onRowClick`、`onRowDoubleClick`、`onRowMouseEnter`、`onRowMouseLeave` 等方法。如果你使用的 api 为文档中列举的 api,那你不用担心会丢失功能。 - -此外,比较重大的改动为 `dataIndex` 从支持路径嵌套如 `user.age` 改成了数组路径如 `['user', 'age']`。以解决过去属性名带 `.` 需要额外的数据转化问题。 - ## FAQ ### 如何在没有数据或只有一页数据时隐藏分页栏 diff --git a/components/tabs/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/tabs/__tests__/__snapshots__/demo-extend.test.ts.snap index 0e982660b3d6..d98ee9bd52f8 100644 --- a/components/tabs/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/tabs/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1197,136 +1197,6 @@ exports[`renders ./components/tabs/demo/custom-tab-bar-node.tsx extend context c `; -exports[`renders ./components/tabs/demo/deprecated.tsx extend context correctly 1`] = ` -
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
- -
-
-
    - -
-
-
-
-
-
- Content of Tab Pane 1 -
-
-
-
-`; - exports[`renders ./components/tabs/demo/disabled.tsx extend context correctly 1`] = `
`; -exports[`renders ./components/tabs/demo/deprecated.tsx correctly 1`] = ` -
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
- -
-
-
-
-
- Content of Tab Pane 1 -
-
-
-
-`; - exports[`renders ./components/tabs/demo/disabled.tsx correctly 1`] = `
( - - - Content of Tab Pane 1 - - - Content of Tab Pane 2 - - - Content of Tab Pane 3 - - -); - -export default App; diff --git a/components/tabs/index.en-US.md b/components/tabs/index.en-US.md index 19bd2ba6d86c..bc88b0bb1eb7 100644 --- a/components/tabs/index.en-US.md +++ b/components/tabs/index.en-US.md @@ -15,33 +15,9 @@ Ant Design has 3 types of Tabs for different situations. - Normal Tabs: for functional aspects of a page. - [Radio.Button](/components/radio/#components-radio-demo-radiobutton): for secondary tabs. -### Usage upgrade after 4.23.0 - - - -```jsx -// works when >=4.23.0, recommended ✅ -const items = [ - { label: 'Tab 1', key: 'item-1', children: 'Content 1' }, // remember to pass the key prop - { label: 'Tab 2', key: 'item-2', children: 'Content 2' }, -]; -return ; - -// works when <4.23.0, deprecated when >=4.23.0 🙅🏻‍♀️ - - - Content 1 - - - Content 2 - -; -``` - ## Examples -Basic usage (deprecated syntactic sugar) Basic Disabled Centered diff --git a/components/tabs/index.zh-CN.md b/components/tabs/index.zh-CN.md index b725aff8a5a8..2f74cc02c681 100644 --- a/components/tabs/index.zh-CN.md +++ b/components/tabs/index.zh-CN.md @@ -18,33 +18,9 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。 - 既可用于容器顶部,也可用于容器内部,是最通用的 Tabs。 - [Radio.Button](/components/radio/#components-radio-demo-radiobutton) 可作为更次级的页签来使用。 -### 4.23.0 用法升级 - - - -```jsx -// >=4.23.0 可用,推荐的写法 ✅ -const items = [ - { label: '项目 1', key: 'item-1', children: '内容 1' }, // 务必填写 key - { label: '项目 2', key: 'item-2', children: '内容 2' }, -]; -return ; - -// <4.23.0 可用,>=4.23.0 时不推荐 🙅🏻‍♀️ - - - 内容 1 - - - 内容 2 - -; -``` - ## 代码演示 -基础用法(废弃的语法糖) 基本 禁用 居中 diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index 2e4a427f56b3..02678f801ef2 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -46,6 +46,8 @@ import type { ComponentToken as TransferComponentToken } from '../../transfer/st import type { ComponentToken as TypographyComponentToken } from '../../typography/style'; import type { ComponentToken as UploadComponentToken } from '../../upload/style'; import type { ComponentToken as TourComponentToken } from '../../tour/style'; +import type { ComponentToken as QRCodeComponentToken } from '../../qrcode/style'; +import type { ComponentToken as AppComponentToken } from '../../app/style'; export interface ComponentTokenMap { Affix?: {}; @@ -108,4 +110,6 @@ export interface ComponentTokenMap { Space?: SpaceComponentToken; Progress?: ProgressComponentToken; Tour?: TourComponentToken; + QRCode?: QRCodeComponentToken; + App?: AppComponentToken; } diff --git a/components/theme/themes/seed.ts b/components/theme/themes/seed.ts index 032bded2b731..2abdf240e85a 100644 --- a/components/theme/themes/seed.ts +++ b/components/theme/themes/seed.ts @@ -43,14 +43,14 @@ const seedToken: SeedToken = { // Motion motionUnit: 0.1, motionBase: 0, - motionEaseOutCirc: `cubic-bezier(0.08, 0.82, 0.17, 1)`, - motionEaseInOutCirc: `cubic-bezier(0.78, 0.14, 0.15, 0.86)`, + motionEaseOutCirc: 'cubic-bezier(0.08, 0.82, 0.17, 1)', + motionEaseInOutCirc: 'cubic-bezier(0.78, 0.14, 0.15, 0.86)', motionEaseOut: 'cubic-bezier(0.215, 0.61, 0.355, 1)', - motionEaseInOut: `cubic-bezier(0.645, 0.045, 0.355, 1)`, - motionEaseOutBack: `cubic-bezier(0.12, 0.4, 0.29, 1.46)`, - motionEaseInBack: `cubic-bezier(0.71, -0.46, 0.88, 0.6)`, - motionEaseInQuint: `cubic-bezier(0.645, 0.045, 0.355, 1)`, - motionEaseOutQuint: `cubic-bezier(0.23, 1, 0.32, 1)`, + motionEaseInOut: 'cubic-bezier(0.645, 0.045, 0.355, 1)', + motionEaseOutBack: 'cubic-bezier(0.12, 0.4, 0.29, 1.46)', + motionEaseInBack: 'cubic-bezier(0.71, -0.46, 0.88, 0.6)', + motionEaseInQuint: 'cubic-bezier(0.645, 0.045, 0.355, 1)', + motionEaseOutQuint: 'cubic-bezier(0.23, 1, 0.32, 1)', // Radius borderRadius: 6, diff --git a/components/theme/util/alias.ts b/components/theme/util/alias.ts index 0a45b6db69ff..fee69167ce3c 100644 --- a/components/theme/util/alias.ts +++ b/components/theme/util/alias.ts @@ -175,7 +175,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken screenXXLMin: screenXXL, // FIXME: component box-shadow, should be removed - boxShadowPopoverArrow: `3px 3px 7px rgba(0, 0, 0, 0.1)`, + boxShadowPopoverArrow: '3px 3px 7px rgba(0, 0, 0, 0.1)', boxShadowCard: ` 0 1px 2px -2px ${new TinyColor('rgba(0, 0, 0, 0.16)').toRgbString()}, 0 3px 6px 0 ${new TinyColor('rgba(0, 0, 0, 0.12)').toRgbString()}, @@ -201,10 +201,10 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken 0 -3px 6px -4px rgba(0, 0, 0, 0.12), 0 -9px 28px 8px rgba(0, 0, 0, 0.05) `, - boxShadowTabsOverflowLeft: `inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)`, - boxShadowTabsOverflowRight: `inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)`, - boxShadowTabsOverflowTop: `inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)`, - boxShadowTabsOverflowBottom: `inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)`, + boxShadowTabsOverflowLeft: 'inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)', + boxShadowTabsOverflowRight: 'inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)', + boxShadowTabsOverflowTop: 'inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)', + boxShadowTabsOverflowBottom: 'inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)', // Override AliasToken ...overrideTokens, diff --git a/components/theme/util/genComponentStyleHook.ts b/components/theme/util/genComponentStyleHook.ts index db2bd218bbd9..7b5d172fbc47 100644 --- a/components/theme/util/genComponentStyleHook.ts +++ b/components/theme/util/genComponentStyleHook.ts @@ -87,7 +87,7 @@ export default function genComponentStyleHook `; + +exports[`renders ./components/timeline/demo/wireframe.tsx extend context correctly 1`] = ` +
    +
  • +
    +
    +
    + Create a services site 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Solve initial network problems 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Technical testing 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Network problems being solved 2015-09-01 +
    +
  • +
+`; diff --git a/components/timeline/__tests__/__snapshots__/demo.test.ts.snap b/components/timeline/__tests__/__snapshots__/demo.test.ts.snap index 666716ca13db..19421493d424 100644 --- a/components/timeline/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/timeline/__tests__/__snapshots__/demo.test.ts.snap @@ -804,3 +804,70 @@ exports[`renders ./components/timeline/demo/right.tsx correctly 1`] = ` `; + +exports[`renders ./components/timeline/demo/wireframe.tsx correctly 1`] = ` +
    +
  • +
    +
    +
    + Create a services site 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Solve initial network problems 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Technical testing 2015-09-01 +
    +
  • +
  • +
    +
    +
    + Network problems being solved 2015-09-01 +
    +
  • +
+`; diff --git a/components/timeline/demo/wireframe.md b/components/timeline/demo/wireframe.md new file mode 100644 index 000000000000..2153d9000cb7 --- /dev/null +++ b/components/timeline/demo/wireframe.md @@ -0,0 +1,7 @@ +## zh-CN + +线框风格。 + +## en-US + +Wireframe. diff --git a/components/timeline/demo/wireframe.tsx b/components/timeline/demo/wireframe.tsx new file mode 100644 index 000000000000..e5b80493beed --- /dev/null +++ b/components/timeline/demo/wireframe.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { ConfigProvider, Timeline } from 'antd'; + +const App: React.FC = () => ( + + + Create a services site 2015-09-01 + Solve initial network problems 2015-09-01 + Technical testing 2015-09-01 + Network problems being solved 2015-09-01 + + +); + +export default App; diff --git a/components/timeline/index.en-US.md b/components/timeline/index.en-US.md index 5b890a8a3915..67359349d4f2 100644 --- a/components/timeline/index.en-US.md +++ b/components/timeline/index.en-US.md @@ -24,6 +24,7 @@ Vertical display timeline. Custom Right alternate Label +Wireframe ## API diff --git a/components/timeline/index.zh-CN.md b/components/timeline/index.zh-CN.md index ddf9f5426b65..476a9030ccc3 100644 --- a/components/timeline/index.zh-CN.md +++ b/components/timeline/index.zh-CN.md @@ -25,6 +25,7 @@ demo: 自定义时间轴点 右侧时间轴点 标签 +线框风格 ## API diff --git a/components/tour/style/index.tsx b/components/tour/style/index.tsx index 3a892c226160..c32d4d93fc55 100644 --- a/components/tour/style/index.tsx +++ b/components/tour/style/index.tsx @@ -209,12 +209,12 @@ const genBaseStyle: GenerateStyle = (token) => { // =========== Limit left and right placement radius ============== [[ - `&-placement-left`, - `&-placement-leftTop`, - `&-placement-leftBottom`, - `&-placement-right`, - `&-placement-rightTop`, - `&-placement-rightBottom`, + '&-placement-left', + '&-placement-leftTop', + '&-placement-leftBottom', + '&-placement-right', + '&-placement-rightTop', + '&-placement-rightBottom', ].join(',')]: { [`${componentCls}-inner`]: { borderRadius: diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx index e1df7a9979ad..492548bd4a70 100644 --- a/components/tree-select/index.tsx +++ b/components/tree-select/index.tsx @@ -5,7 +5,6 @@ import RcTreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode } from 'rc-tr import type { BaseOptionType, DefaultOptionType } from 'rc-tree-select/lib/TreeSelect'; import omit from 'rc-util/lib/omit'; import * as React from 'react'; -import { useContext } from 'react'; import { ConfigContext } from '../config-provider'; import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; import DisabledContext from '../config-provider/DisabledContext'; @@ -143,7 +142,7 @@ const InternalTreeSelect = `; +exports[`renders ./components/tree/demo/block-node.tsx extend context correctly 1`] = ` +
+
+ +
+ +`; + exports[`renders ./components/tree/demo/customized-icon.tsx extend context correctly 1`] = `
`; +exports[`renders ./components/tree/demo/block-node.tsx correctly 1`] = ` +
+
+ +
+ +`; + exports[`renders ./components/tree/demo/customized-icon.tsx correctly 1`] = `
( + +); + +export default App; diff --git a/components/tree/index.en-US.md b/components/tree/index.en-US.md index 9a2552db428a..b7670b893cbb 100644 --- a/components/tree/index.en-US.md +++ b/components/tree/index.en-US.md @@ -28,6 +28,7 @@ Almost anything can be represented in a tree structure. Examples include directo Virtual scroll Drag Debug Big data +Block Node ## API diff --git a/components/tree/index.zh-CN.md b/components/tree/index.zh-CN.md index 4ffb334ce301..20e2a5db92b2 100644 --- a/components/tree/index.zh-CN.md +++ b/components/tree/index.zh-CN.md @@ -29,6 +29,7 @@ demo: 虚拟滚动 Drag Debug 大数据 +占据整行 ## API diff --git a/components/tree/style/index.tsx b/components/tree/style/index.tsx index efeaa32ed42f..df0a92bca33a 100644 --- a/components/tree/style/index.tsx +++ b/components/tree/style/index.tsx @@ -265,10 +265,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject => // >>> Title // add `${treeCls}-checkbox + span` to cover checkbox `${checkboxCls} + span` - [` - ${treeCls}-node-content-wrapper, - ${treeCls}-checkbox + span - `]: { + [`${treeCls}-node-content-wrapper, ${treeCls}-checkbox + span`]: { position: 'relative', zIndex: 'auto', minHeight: treeTitleHeight, diff --git a/docs/react/migration-v5.en-US.md b/docs/react/migration-v5.en-US.md index 0981b2bcb519..7ba8c47be2f2 100644 --- a/docs/react/migration-v5.en-US.md +++ b/docs/react/migration-v5.en-US.md @@ -164,6 +164,27 @@ Use git to save your code and install latest version: npm install --save antd@5.x ``` +You can manually check the code one by one against the above list for modification. In addition, we also provide a codemod cli tool [@ant-design/codemod-v5](https://github.com/ant-design/codemod-v5) To help you quickly upgrade to v5. + +Before running codemod cli, please submit your local code changes. + +```shell +# Run directly through npx +npx -p @ant-design/codemod-v5 antd5-codemod src + +# Or run directly through pnpm +pnpm --package=@ant-design/codemod-v5 dlx antd5-codemod src +``` + + + +> Note that codemod cannot cover all scenarios, and it is recommended to check for incompatible changes one by one. + +### less migration + If you using antd less variables, you can use compatible package to covert it into v4 less variables and use less-loader to inject them: ```js diff --git a/docs/react/migration-v5.zh-CN.md b/docs/react/migration-v5.zh-CN.md index c31c0e35c79e..c7be2d73186d 100644 --- a/docs/react/migration-v5.zh-CN.md +++ b/docs/react/migration-v5.zh-CN.md @@ -156,6 +156,25 @@ title: 从 v4 到 v5 npm install --save antd@5.x ``` +你可以手动对照上面的列表逐条检查代码进行修改,另外,我们也提供了一个 codemod cli 工具 [@ant-design/codemod-v5](https://github.com/ant-design/codemod-v5) 以帮助你快速升级到 v5 版本。 + +在运行 codemod cli 前,请先提交你的本地代码修改。 + +```shell +# 使用 npx 直接运行 +npx -p @ant-design/codemod-v5 antd5-codemod src + +# 或者使用 pnpm 直接运行 +pnpm --package=@ant-design/codemod-v5 dlx antd5-codemod src +``` + + + +> 注意 codemod 不能涵盖所有场景,建议还是要按不兼容的变化逐条排查。 + ### less 迁移 如果你使用到了 antd 的 less 变量,通过兼容包将 v5 变量转译成 v4 版本,并通过 less-loader 注入: diff --git a/package.json b/package.json index b492e7a83b86..467dcc38ecd2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.0.3", + "version": "5.0.4", "description": "An enterprise-class UI design language and React components implementation", "title": "Ant Design", "keywords": [ @@ -120,6 +120,7 @@ "copy-to-clipboard": "^3.2.0", "dayjs": "^1.11.1", "lodash": "^4.17.21", + "qrcode.react": "^3.1.0", "rc-cascader": "~3.7.0", "rc-checkbox": "~2.3.0", "rc-collapse": "~3.4.2", @@ -145,7 +146,7 @@ "rc-steps": "~6.0.0-alpha.2", "rc-switch": "~4.0.0", "rc-table": "~7.26.0", - "rc-tabs": "~12.4.1", + "rc-tabs": "~12.4.2", "rc-textarea": "~0.4.5", "rc-tooltip": "~5.2.0", "rc-tree": "~5.7.0", @@ -153,20 +154,21 @@ "rc-trigger": "^5.2.10", "rc-upload": "~4.3.0", "rc-util": "^5.25.2", - "scroll-into-view-if-needed": "^2.2.25", + "scroll-into-view-if-needed": "^3.0.3", "shallowequal": "^1.1.0" }, "devDependencies": { "@ant-design/bisheng-plugin": "^3.3.0-alpha.4", "@ant-design/hitu": "^0.0.0-alpha.13", "@ant-design/tools": "^16.1.0-alpha.2", + "@babel/eslint-plugin": "^7.19.1", "@docsearch/css": "^3.0.0", "@emotion/babel-preset-css-prop": "^11.10.0", "@emotion/css": "^11.10.5", "@emotion/react": "^11.10.4", "@emotion/server": "^11.4.0", "@qixian.cs/github-contributors-list": "^1.0.3", - "@size-limit/file": "^8.0.0", + "@size-limit/file": "^8.1.0", "@stackblitz/sdk": "^1.3.0", "@testing-library/dom": "^8.17.1", "@testing-library/jest-dom": "^5.16.3", @@ -179,6 +181,7 @@ "@types/jest-image-snapshot": "^5.1.0", "@types/jquery": "^3.5.14", "@types/lodash": "^4.14.139", + "@types/prismjs": "^1.26.0", "@types/puppeteer": "^7.0.4", "@types/qs": "^6.9.7", "@types/react": "^18.0.0", @@ -214,7 +217,6 @@ "eslint-config-airbnb": "^19.0.0", "eslint-config-prettier": "^8.0.0", "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-babel": "^5.3.0", "eslint-plugin-compat": "^4.0.0", "eslint-plugin-import": "^2.21.1", "eslint-plugin-jest": "^27.0.1", @@ -273,7 +275,6 @@ "react-draggable": "^4.4.3", "react-fast-marquee": "^1.2.1", "react-github-button": "^0.1.11", - "react-helmet-async": "~1.3.0", "react-highlight-words": "^0.18.0", "react-infinite-scroll-component": "^6.1.0", "react-resizable": "^3.0.1", @@ -284,21 +285,16 @@ "remark-cli": "^11.0.0", "remark-lint": "^9.0.0", "remark-preset-lint-recommended": "^6.0.0", - "remove-files-webpack-plugin": "1.5.0", - "rimraf": "^3.0.0", "rome": "^10.0.1", - "scrollama": "^3.0.0", "semver": "^7.3.5", "simple-git": "^3.0.0", - "size-limit": "^8.0.0", + "size-limit": "^8.1.0", "stylelint": "^14.9.0", "stylelint-config-prettier": "^9.0.2", "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^29.0.0", "stylelint-declaration-block-no-ignored-properties": "^2.1.0", - "stylelint-order": "^5.0.0", "sylvanas": "^0.6.1", - "theme-switcher": "^1.0.2", "ts-node": "^10.8.2", "typedoc": "^0.23.21", "typescript": "~4.9.3", @@ -316,13 +312,17 @@ "size-limit": [ { "path": "./dist/antd.min.js", - "limit": "375 kB" + "limit": "381 KiB" + }, + { + "path": "./dist/antd-with-locales.min.js", + "limit": "435 KiB" } ], "bundlesize": [ { "path": "./dist/antd.min.js", - "maxSize": "377.5 kB" + "maxSize": "381 kB" } ], "tnpm": { diff --git a/tests/__snapshots__/index.test.ts.snap b/tests/__snapshots__/index.test.ts.snap index b867fa54bcd4..abcb505f0bf0 100644 --- a/tests/__snapshots__/index.test.ts.snap +++ b/tests/__snapshots__/index.test.ts.snap @@ -5,6 +5,7 @@ exports[`antd dist files exports modules correctly 1`] = ` "Affix", "Alert", "Anchor", + "App", "AutoComplete", "Avatar", "BackTop", @@ -40,6 +41,7 @@ exports[`antd dist files exports modules correctly 1`] = ` "Popconfirm", "Popover", "Progress", + "QRCode", "Radio", "Rate", "Result", diff --git a/tests/shared/imageTest.tsx b/tests/shared/imageTest.tsx index 777a3f6044d0..317872e1907d 100644 --- a/tests/shared/imageTest.tsx +++ b/tests/shared/imageTest.tsx @@ -7,6 +7,7 @@ import glob from 'glob'; import { configureToMatchImageSnapshot } from 'jest-image-snapshot'; import MockDate from 'mockdate'; import ReactDOMServer from 'react-dom/server'; +import { App } from '../../components'; const toMatchImageSnapshot = configureToMatchImageSnapshot({ customSnapshotsDir: `${process.cwd()}/imageSnapshots`, @@ -34,9 +35,14 @@ export default function imageTest(component: React.ReactElement) { await page.addStyleTag({ path: `${process.cwd()}/dist/reset.css` }); const cache = createCache(); - const html = ReactDOMServer.renderToString( - {component}, + + const element = ( + + {component} + ); + + const html = ReactDOMServer.renderToString(element); const styleStr = extractStyle(cache); await page.evaluate( diff --git a/tests/utils.tsx b/tests/utils.tsx index e1da0ba22393..a7245965db99 100644 --- a/tests/utils.tsx +++ b/tests/utils.tsx @@ -32,8 +32,6 @@ export const sleep = async (timeout = 0) => { const customRender = (ui: ReactElement, options?: Omit) => render(ui, { wrapper: StrictMode, ...options }); -export * from '@testing-library/react'; - export function renderHook(func: () => T): { result: React.RefObject } { const result = React.createRef();