diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 12cc1a41e..84d4ffa90 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -10,6 +10,13 @@ --- +## 4.2.6 + +- 🐞 Fix Modal component aria-hidden error problem under chrome [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823) +- 🐞 Fix the problem that the built-in input method of Safari automatically fills in the decimal point when inputting Chinese [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918) +- 🐞 Fix InputNumber component disabled style problem [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776) +- 🐞 Fix Select cannot lose focus problem [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819) + ## 4.2.5 - 🐞 Fix Empty component memory leak problem diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index d1e06a065..c9b50d963 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -10,6 +10,13 @@ --- +## 4.2.6 + +- 🐞 修复 Modal 组件在 chrome 下,aria-hidden 报错问题 [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823) +- 🐞 修复 Safari 下自带输入法 input 组件输入中文时,自动填写小数点问题 [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918) +- 🐞 修复 InputNumber 组件 disabled 样式问题 [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776) +- 🐞 修复 Select 无法失焦问题 [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819) + ## 4.2.5 - 🐞 修复 Empty 组件内存泄漏问题 diff --git a/components/icon/index.en-US.md b/components/icon/index.en-US.md index 758950f77..7d753e2c3 100644 --- a/components/icon/index.en-US.md +++ b/components/icon/index.en-US.md @@ -122,6 +122,8 @@ See [iconfont.cn documents](http://iconfont.cn/help/detail?spm=a313x.7781069.199 ### Custom SVG Icon +#### vue cli 3 + You can import SVG icon as an vue component by using `vue cli 3` and [`vue-svg-loader`](https://www.npmjs.com/package/vue-svg-loader). `vue-svg-loader`'s `options` [reference](https://github.com/visualfanatic/vue-svg-loader). ```js @@ -149,6 +151,84 @@ export default defineComponent({ }); ``` +#### Rsbuild + +Rsbuild is a new generation of build tool, official website https://rsbuild.dev/ +Create your own `vue-svg-loader.js` file, which allows you to customize and beautify SVG, and then configure it in `rsbuild.config.ts` + +```js +// vue-svg-loader.js +/* eslint-disable */ +const { optimize } = require('svgo'); +const { version } = require('vue'); +const semverMajor = require('semver/functions/major'); + +module.exports = async function (svg) { + const callback = this.async(); + + try { + ({ data: svg } = await optimize(svg, { + path: this.resourcePath, + js2svg: { + indent: 2, + pretty: true, + }, + plugins: [ + 'convertStyleToAttrs', + 'removeDoctype', + 'removeXMLProcInst', + 'removeComments', + 'removeMetadata', + 'removeTitle', + 'removeDesc', + 'removeStyleElement', + 'removeXMLNS', + 'removeXMLProcInst', + ], + })); + } catch (error) { + callback(error); + return; + } + + if (semverMajor(version) === 2) { + svg = svg.replace('${svg}`); +}; +``` + +```js +// rsbuild.config.ts +/* eslint-disable */ +import { defineConfig } from '@rsbuild/core'; +import { pluginVue } from '@rsbuild/plugin-vue'; + +export default defineConfig({ + tools: { + bundlerChain(chain, { CHAIN_ID }) { + chain.module.rule(CHAIN_ID.RULE.SVG).exclude.add(/\.svg$/); + }, + rspack: { + module: { + rules: [ + { + test: /\.svg$/, + use: ['vue-loader', 'vue-svg-loader'], + }, + ], + }, + resolveLoader: { + alias: { + 'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'), + }, + }, + }, + }, +}); +``` + The following properties are available for the component: | Property | Description | Type | Default | diff --git a/components/icon/index.zh-CN.md b/components/icon/index.zh-CN.md index c8a02d68e..66995e279 100644 --- a/components/icon/index.zh-CN.md +++ b/components/icon/index.zh-CN.md @@ -119,7 +119,9 @@ export default defineComponent({ ### 自定义 SVG 图标 -如果使用 `vue cli 3`,可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。 +#### vue cli 3 + +可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。 ```js // vue.config.js @@ -146,6 +148,88 @@ export default defineComponent({ }); ``` +#### Rsbuild + +Rsbuild 是新一代构建工具,官网 https://rsbuild.dev/ + +自己实现一个 `vue-svg-loader.js` 文件,好处是可以自定义美化 svg,然后在 `rsbuild.config.ts` 中配置: + +```js +// vue-svg-loader.js +/* eslint-disable */ +const { optimize } = require('svgo'); +const { version } = require('vue'); +const semverMajor = require('semver/functions/major'); + +module.exports = async function (svg) { + const callback = this.async(); + + try { + ({ data: svg } = await optimize(svg, { + path: this.resourcePath, + js2svg: { + indent: 2, + pretty: true, + }, + plugins: [ + 'convertStyleToAttrs', + 'removeDoctype', + 'removeXMLProcInst', + 'removeComments', + 'removeMetadata', + 'removeTitle', + 'removeDesc', + 'removeStyleElement', + 'removeXMLNS', + 'removeXMLProcInst', + ], + })); + } catch (error) { + callback(error); + return; + } + + if (semverMajor(version) === 2) { + svg = svg.replace('${svg}`); +}; +``` + +```js +// rsbuild.config.ts +/* eslint-disable */ +import { defineConfig } from '@rsbuild/core'; +import { pluginVue } from '@rsbuild/plugin-vue'; + +export default defineConfig({ + tools: { + bundlerChain(chain, { CHAIN_ID }) { + chain.module + // 先给svg排除默认的规则,方便下面自定义loader + .rule(CHAIN_ID.RULE.SVG) + .exclude.add(/\.svg$/); + }, + rspack: { + module: { + rules: [ + { + test: /\.svg$/, + use: ['vue-loader', 'vue-svg-loader'], + }, + ], + }, + resolveLoader: { + alias: { + 'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'), + }, + }, + }, + }, +}); +``` + `Icon` 中的 `component` 组件的接受的属性如下: | 字段 | 说明 | 类型 | 只读值 | diff --git a/components/input-number/src/InputNumber.tsx b/components/input-number/src/InputNumber.tsx index 811b8eeef..9fa9a7d46 100644 --- a/components/input-number/src/InputNumber.tsx +++ b/components/input-number/src/InputNumber.tsx @@ -395,6 +395,11 @@ export default defineComponent({ } }; + // Solve the issue of the event triggering sequence when entering numbers in chinese input (Safari) + const onBeforeInput = () => { + userTypingRef.value = true; + }; + const onKeyDown: KeyboardEventHandler = event => { const { which } = event; userTypingRef.value = true; @@ -577,6 +582,7 @@ export default defineComponent({ onBlur={onBlur} onCompositionstart={onCompositionStart} onCompositionend={onCompositionEnd} + onBeforeinput={onBeforeInput} /> diff --git a/components/input-number/style/index.tsx b/components/input-number/style/index.tsx index d119e7d66..e363f0772 100644 --- a/components/input-number/style/index.tsx +++ b/components/input-number/style/index.tsx @@ -263,6 +263,10 @@ const genInputNumberStyles: GenerateStyle = (token: InputNumbe [`${componentCls}-handler-wrap`]: { display: 'none', }, + + [`${componentCls}-input`]: { + color: 'inherit', + }, }, [` diff --git a/components/select/__tests__/index.test.js b/components/select/__tests__/index.test.js index e169e107f..46ee2e46f 100644 --- a/components/select/__tests__/index.test.js +++ b/components/select/__tests__/index.test.js @@ -159,6 +159,52 @@ describe('Select', () => { }, 500); }); + it('The select trigger should be blur when the panel is closed.', async () => { + const wrapper = mount( + { + render() { + return ( + ; + }} + /> + ); + }, + }, + { + sync: false, + attachTo: 'body', + }, + ); + await asyncExpect(async () => { + await wrapper.find('.ant-select-selector').trigger('mousedown'); + await wrapper.find('.ant-select-selection-search-input').trigger('focus'); + }); + + await asyncExpect(async () => { + const el = wrapper.find('.ant-select'); + + expect(el.classes()).toContain('ant-select-focused'); + $$('#dropdownRenderInput')[0].focus(); + + expect(el.classes()).toContain('ant-select-focused'); + + document.body.dispatchEvent( + new MouseEvent('mousedown', { + bubbles: true, + cancelable: true, + view: window, + }), + ); + }, 100); + + await asyncExpect(async () => { + const el = wrapper.find('.ant-select'); + expect(el.classes()).not.toContain('ant-select-focused'); + }, 200); + }); + describe('Select Custom Icons', () => { it('should support customized icons', () => { const wrapper = mount({ diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md index 136217e54..4dda321cd 100644 --- a/components/select/index.en-US.md +++ b/components/select/index.en-US.md @@ -63,7 +63,7 @@ Select component to select value from options. | searchValue | The current input "search" text | string | - | | | showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | | | showSearch | Whether select is searchable | boolean | single:false, multiple:true | | -| size | Size of Select input. `default` `large` `small` | string | default | | +| size | Size of Select input. `middle` `large` `small` | string | middle | | | status | Set validation status | 'error' \| 'warning' | - | 3.3.0 | | suffixIcon | The custom suffix icon | VNode \| slot | - | | | tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | | diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md index 7f748d9b5..bb8be2a13 100644 --- a/components/select/index.zh-CN.md +++ b/components/select/index.zh-CN.md @@ -63,7 +63,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*5oPiTqPxGAUAAA | searchValue | 控制搜索文本 | string | - | | | showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | | | showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | | -| size | 选择框大小,可选 `large` `small` | string | default | | +| size | 选择框大小,可选 `middle` `large` `small` | string | middle | | | status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 | | suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | | | tagRender | 自定义 tag 内容 render,仅在 `mode` 为 `multiple` 或 `tags` 时生效 | slot \| (props) => any | - | 3.0 | diff --git a/components/tabs/index.en-US.md b/components/tabs/index.en-US.md index a90408048..fcd1dd31e 100644 --- a/components/tabs/index.en-US.md +++ b/components/tabs/index.en-US.md @@ -24,6 +24,7 @@ Ant Design has 3 types of Tabs for different situations. | --- | --- | --- | --- | --- | | activeKey(v-model) | Current TabPane's key | string | - | | | animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | | +| centered | Whether to display the labels in the center | boolean | false | 3.0 | | destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | | | hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } | | size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | | diff --git a/components/tree/index.en-US.md b/components/tree/index.en-US.md index 42db4c104..80c4991fc 100644 --- a/components/tree/index.en-US.md +++ b/components/tree/index.en-US.md @@ -74,7 +74,7 @@ Almost anything can be represented in a tree structure. Examples include directo | disableCheckbox | Disables the checkbox of the treeNode | boolean | false | | | disabled | Disables the treeNode | boolean | false | | | icon | customize icon. When you pass component, whose render will receive full TreeNode props as component props | slot\|slot-scope | - | | -| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | false | | +| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | - | | | key | Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. P.S.: It must be unique in all of treeNodes of the tree! | string \| number | internal calculated position of treeNode | | | selectable | Set whether the treeNode can be selected | boolean | true | | | style | style | string\|object | - | | diff --git a/components/tree/index.zh-CN.md b/components/tree/index.zh-CN.md index dd0dd79e8..29e282b38 100644 --- a/components/tree/index.zh-CN.md +++ b/components/tree/index.zh-CN.md @@ -75,7 +75,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*1GeUQJPTGUYAAA | disableCheckbox | 禁掉 checkbox | boolean | false | | | disabled | 禁掉响应 | boolean | false | | | icon | 自定义图标。可接收组件,props 为当前节点 props | slot\|slot-scope | - | | -| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | false | | +| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | - | | | key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | | | selectable | 设置节点是否可被选中 | boolean | true | | | style | 节点的 style | string\|object | - | | diff --git a/components/vc-dialog/Content.tsx b/components/vc-dialog/Content.tsx index 82ecda5c1..7c1a5fe60 100644 --- a/components/vc-dialog/Content.tsx +++ b/components/vc-dialog/Content.tsx @@ -5,7 +5,7 @@ import { getTransitionProps } from '../_util/transition'; import dialogPropTypes from './IDialogPropTypes'; import { offset } from './util'; const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' }; - +const entityStyle = { outline: 'none' }; export type ContentRef = { focus: () => void; changeActive: (next: boolean) => void; @@ -28,14 +28,14 @@ export default defineComponent({ const dialogRef = ref(); expose({ focus: () => { - sentinelStartRef.value?.focus(); + sentinelStartRef.value?.focus({ preventScroll: true }); }, changeActive: next => { const { activeElement } = document; if (next && activeElement === sentinelEndRef.value) { - sentinelStartRef.value.focus(); + sentinelStartRef.value.focus({ preventScroll: true }); } else if (!next && activeElement === sentinelStartRef.value) { - sentinelEndRef.value.focus(); + sentinelEndRef.value.focus({ preventScroll: true }); } }, }); @@ -143,9 +143,10 @@ export default defineComponent({ onMousedown={onMousedown} onMouseup={onMouseup} > -