Merge branch 'vueComponent:main' into main
commit
e49f063866
|
@ -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
|
## 4.2.5
|
||||||
|
|
||||||
- 🐞 Fix Empty component memory leak problem
|
- 🐞 Fix Empty component memory leak problem
|
||||||
|
|
|
@ -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
|
## 4.2.5
|
||||||
|
|
||||||
- 🐞 修复 Empty 组件内存泄漏问题
|
- 🐞 修复 Empty 组件内存泄漏问题
|
||||||
|
|
|
@ -122,6 +122,8 @@ See [iconfont.cn documents](http://iconfont.cn/help/detail?spm=a313x.7781069.199
|
||||||
|
|
||||||
### Custom SVG Icon
|
### 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).
|
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
|
```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', '<svg v-on="$listeners"');
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, `<template>${svg}</template>`);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```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:
|
The following properties are available for the component:
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
|
|
|
@ -119,7 +119,9 @@ export default defineComponent({
|
||||||
|
|
||||||
### 自定义 SVG 图标
|
### 自定义 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
|
```js
|
||||||
// vue.config.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', '<svg v-on="$listeners"');
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, `<template>${svg}</template>`);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```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` 组件的接受的属性如下:
|
`Icon` 中的 `component` 组件的接受的属性如下:
|
||||||
|
|
||||||
| 字段 | 说明 | 类型 | 只读值 |
|
| 字段 | 说明 | 类型 | 只读值 |
|
||||||
|
|
|
@ -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 onKeyDown: KeyboardEventHandler = event => {
|
||||||
const { which } = event;
|
const { which } = event;
|
||||||
userTypingRef.value = true;
|
userTypingRef.value = true;
|
||||||
|
@ -577,6 +582,7 @@ export default defineComponent({
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
onCompositionstart={onCompositionStart}
|
onCompositionstart={onCompositionStart}
|
||||||
onCompositionend={onCompositionEnd}
|
onCompositionend={onCompositionEnd}
|
||||||
|
onBeforeinput={onBeforeInput}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -263,6 +263,10 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
|
||||||
[`${componentCls}-handler-wrap`]: {
|
[`${componentCls}-handler-wrap`]: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-input`]: {
|
||||||
|
color: 'inherit',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
[`
|
[`
|
||||||
|
|
|
@ -159,6 +159,52 @@ describe('Select', () => {
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('The select trigger should be blur when the panel is closed.', async () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
{
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
dropdownRender={() => {
|
||||||
|
return <input id="dropdownRenderInput" />;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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', () => {
|
describe('Select Custom Icons', () => {
|
||||||
it('should support customized icons', () => {
|
it('should support customized icons', () => {
|
||||||
const wrapper = mount({
|
const wrapper = mount({
|
||||||
|
|
|
@ -63,7 +63,7 @@ Select component to select value from options.
|
||||||
| searchValue | The current input "search" text | string | - | |
|
| searchValue | The current input "search" text | string | - | |
|
||||||
| showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | |
|
| showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | |
|
||||||
| showSearch | Whether select is searchable | boolean | single:false, multiple:true | |
|
| 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 |
|
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
|
||||||
| suffixIcon | The custom suffix icon | VNode \| slot | - | |
|
| suffixIcon | The custom suffix icon | VNode \| slot | - | |
|
||||||
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | |
|
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | |
|
||||||
|
|
|
@ -63,7 +63,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*5oPiTqPxGAUAAA
|
||||||
| searchValue | 控制搜索文本 | string | - | |
|
| searchValue | 控制搜索文本 | string | - | |
|
||||||
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
|
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
|
||||||
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
|
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
|
||||||
| size | 选择框大小,可选 `large` `small` | string | default | |
|
| size | 选择框大小,可选 `middle` `large` `small` | string | middle | |
|
||||||
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
|
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
|
||||||
| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | |
|
| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | |
|
||||||
| tagRender | 自定义 tag 内容 render,仅在 `mode` 为 `multiple` 或 `tags` 时生效 | slot \| (props) => any | - | 3.0 |
|
| tagRender | 自定义 tag 内容 render,仅在 `mode` 为 `multiple` 或 `tags` 时生效 | slot \| (props) => any | - | 3.0 |
|
||||||
|
|
|
@ -24,6 +24,7 @@ Ant Design has 3 types of Tabs for different situations.
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| activeKey(v-model) | Current TabPane's key | string | - | |
|
| 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"` | |
|
| 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 | |
|
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
|
||||||
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | 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` | |
|
| size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | |
|
||||||
|
|
|
@ -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 | |
|
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | |
|
||||||
| disabled | Disables 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 | - | |
|
| 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 | |
|
| 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 | |
|
| selectable | Set whether the treeNode can be selected | boolean | true | |
|
||||||
| style | style | string\|object | - | |
|
| style | style | string\|object | - | |
|
||||||
|
|
|
@ -75,7 +75,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*1GeUQJPTGUYAAA
|
||||||
| disableCheckbox | 禁掉 checkbox | boolean | false | |
|
| disableCheckbox | 禁掉 checkbox | boolean | false | |
|
||||||
| disabled | 禁掉响应 | boolean | false | |
|
| disabled | 禁掉响应 | boolean | false | |
|
||||||
| icon | 自定义图标。可接收组件,props 为当前节点 props | slot\|slot-scope | - | |
|
| icon | 自定义图标。可接收组件,props 为当前节点 props | slot\|slot-scope | - | |
|
||||||
| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | false | |
|
| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | - | |
|
||||||
| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | |
|
| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | |
|
||||||
| selectable | 设置节点是否可被选中 | boolean | true | |
|
| selectable | 设置节点是否可被选中 | boolean | true | |
|
||||||
| style | 节点的 style | string\|object | - | |
|
| style | 节点的 style | string\|object | - | |
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { getTransitionProps } from '../_util/transition';
|
||||||
import dialogPropTypes from './IDialogPropTypes';
|
import dialogPropTypes from './IDialogPropTypes';
|
||||||
import { offset } from './util';
|
import { offset } from './util';
|
||||||
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
|
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
|
||||||
|
const entityStyle = { outline: 'none' };
|
||||||
export type ContentRef = {
|
export type ContentRef = {
|
||||||
focus: () => void;
|
focus: () => void;
|
||||||
changeActive: (next: boolean) => void;
|
changeActive: (next: boolean) => void;
|
||||||
|
@ -28,14 +28,14 @@ export default defineComponent({
|
||||||
const dialogRef = ref<HTMLDivElement>();
|
const dialogRef = ref<HTMLDivElement>();
|
||||||
expose({
|
expose({
|
||||||
focus: () => {
|
focus: () => {
|
||||||
sentinelStartRef.value?.focus();
|
sentinelStartRef.value?.focus({ preventScroll: true });
|
||||||
},
|
},
|
||||||
changeActive: next => {
|
changeActive: next => {
|
||||||
const { activeElement } = document;
|
const { activeElement } = document;
|
||||||
if (next && activeElement === sentinelEndRef.value) {
|
if (next && activeElement === sentinelEndRef.value) {
|
||||||
sentinelStartRef.value.focus();
|
sentinelStartRef.value.focus({ preventScroll: true });
|
||||||
} else if (!next && activeElement === sentinelStartRef.value) {
|
} else if (!next && activeElement === sentinelStartRef.value) {
|
||||||
sentinelEndRef.value.focus();
|
sentinelEndRef.value.focus({ preventScroll: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -143,9 +143,10 @@ export default defineComponent({
|
||||||
onMousedown={onMousedown}
|
onMousedown={onMousedown}
|
||||||
onMouseup={onMouseup}
|
onMouseup={onMouseup}
|
||||||
>
|
>
|
||||||
<div tabindex={0} ref={sentinelStartRef} style={sentinelStyle} aria-hidden="true" />
|
<div tabindex={0} ref={sentinelStartRef} style={entityStyle}>
|
||||||
{modalRender ? modalRender({ originVNode: content }) : content}
|
{modalRender ? modalRender({ originVNode: content }) : content}
|
||||||
<div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} aria-hidden="true" />
|
</div>
|
||||||
|
<div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
|
@ -343,6 +343,14 @@ export default defineComponent({
|
||||||
if (mergedOpen.value !== nextOpen && !props.disabled) {
|
if (mergedOpen.value !== nextOpen && !props.disabled) {
|
||||||
setInnerOpen(nextOpen);
|
setInnerOpen(nextOpen);
|
||||||
props.onDropdownVisibleChange && props.onDropdownVisibleChange(nextOpen);
|
props.onDropdownVisibleChange && props.onDropdownVisibleChange(nextOpen);
|
||||||
|
|
||||||
|
if (!nextOpen && popupFocused.value) {
|
||||||
|
popupFocused.value = false;
|
||||||
|
setMockFocused(false, () => {
|
||||||
|
focusRef.value = false;
|
||||||
|
blurRef.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ export default defineComponent({
|
||||||
ref={alignRef}
|
ref={alignRef}
|
||||||
monitorWindowResize
|
monitorWindowResize
|
||||||
disabled={alignDisabled.value}
|
disabled={alignDisabled.value}
|
||||||
align={align}
|
align={align as any}
|
||||||
onAlign={onInternalAlign}
|
onAlign={onInternalAlign}
|
||||||
v-slots={{
|
v-slots={{
|
||||||
default: () => (
|
default: () => (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ant-design-vue",
|
"name": "ant-design-vue",
|
||||||
"version": "4.2.5",
|
"version": "4.2.6",
|
||||||
"title": "Ant Design Vue",
|
"title": "Ant Design Vue",
|
||||||
"description": "An enterprise-class UI design language and Vue-based implementation",
|
"description": "An enterprise-class UI design language and Vue-based implementation",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
|
@ -2,10 +2,11 @@ import type { InputProps } from 'ant-design-vue';
|
||||||
import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue';
|
import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue';
|
||||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import { defineComponent, watchEffect, watch, computed, toRefs, ref } from 'vue';
|
import { defineComponent, watchEffect, computed, toRefs, ref } from 'vue';
|
||||||
import { HexColorPicker, RgbaColorPicker } from '../vue-colorful';
|
import { HexColorPicker, RgbaColorPicker } from '../vue-colorful';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import makeStyle from './utils/makeStyle';
|
import makeStyle from './utils/makeStyle';
|
||||||
|
import type { ValueType } from 'ant-design-vue/es/input-number/src/utils/MiniDecimal';
|
||||||
|
|
||||||
const { useToken } = theme;
|
const { useToken } = theme;
|
||||||
|
|
||||||
|
@ -168,24 +169,42 @@ const RgbColorInput = defineComponent({
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { value, alpha } = toRefs(props);
|
const { value, alpha } = toRefs(props);
|
||||||
|
|
||||||
watch(value, val => {
|
const handleChange = (val: ValueType, key: 'r' | 'g' | 'b' | 'a') => {
|
||||||
props.onChange(val);
|
value.value[key] = val;
|
||||||
});
|
props.onChange(value.value);
|
||||||
|
};
|
||||||
return () => {
|
return () => {
|
||||||
return (
|
return (
|
||||||
<div class="color-panel-rgba-input">
|
<div class="color-panel-rgba-input">
|
||||||
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}>
|
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}>
|
||||||
<div class="color-panel-rgba-input-part">
|
<div class="color-panel-rgba-input-part">
|
||||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.r, 'value']} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={255}
|
||||||
|
size="small"
|
||||||
|
value={value.value.r}
|
||||||
|
onChange={val => handleChange(val, 'r')}
|
||||||
|
/>
|
||||||
<div class="color-panel-mode-title">R</div>
|
<div class="color-panel-mode-title">R</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="color-panel-rgba-input-part">
|
<div class="color-panel-rgba-input-part">
|
||||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.g, 'value']} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={255}
|
||||||
|
size="small"
|
||||||
|
value={value.value.g}
|
||||||
|
onChange={val => handleChange(val, 'g')}
|
||||||
|
/>
|
||||||
<div class="color-panel-mode-title">G</div>
|
<div class="color-panel-mode-title">G</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="color-panel-rgba-input-part">
|
<div class="color-panel-rgba-input-part">
|
||||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.b, 'value']} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={255}
|
||||||
|
size="small"
|
||||||
|
value={value.value.b}
|
||||||
|
onChange={val => handleChange(val, 'b')}
|
||||||
|
/>
|
||||||
<div class="color-panel-mode-title">B</div>
|
<div class="color-panel-mode-title">B</div>
|
||||||
</div>
|
</div>
|
||||||
{alpha.value && (
|
{alpha.value && (
|
||||||
|
@ -195,7 +214,8 @@ const RgbColorInput = defineComponent({
|
||||||
max={1}
|
max={1}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
size="small"
|
size="small"
|
||||||
v-model={[value.value.a, 'value']}
|
value={value.value.a}
|
||||||
|
onChange={val => handleChange(val, 'a')}
|
||||||
/>
|
/>
|
||||||
<div class="color-panel-mode-title">A</div>
|
<div class="color-panel-mode-title">A</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue