fix: use open, remove visible
parent
1b51e6ffb3
commit
37b5d02b6d
|
@ -59,6 +59,7 @@ jspm_packages/
|
||||||
dist
|
dist
|
||||||
lib
|
lib
|
||||||
es
|
es
|
||||||
|
/locale
|
||||||
_site
|
_site
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
@ -78,5 +79,8 @@ report.html
|
||||||
|
|
||||||
site/src/router/demoRoutes.js
|
site/src/router/demoRoutes.js
|
||||||
|
|
||||||
|
components/version/version.ts
|
||||||
components/version/version.tsx
|
components/version/version.tsx
|
||||||
|
components/version/token.json
|
||||||
|
components/version/token-meta.json
|
||||||
~component-api.json
|
~component-api.json
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// import hash from '@emotion/hash';
|
import hash from '@emotion/hash';
|
||||||
import type * as CSS from 'csstype';
|
import type * as CSS from 'csstype';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import unitless from '@emotion/unitless';
|
import unitless from '@emotion/unitless';
|
||||||
|
@ -10,22 +10,22 @@ import type { Linter } from '../linters';
|
||||||
import { contentQuotesLinter, hashedAnimationLinter } from '../linters';
|
import { contentQuotesLinter, hashedAnimationLinter } from '../linters';
|
||||||
import type { HashPriority } from '../StyleContext';
|
import type { HashPriority } from '../StyleContext';
|
||||||
import {
|
import {
|
||||||
// useStyleInject,
|
useStyleInject,
|
||||||
// ATTR_DEV_CACHE_PATH,
|
ATTR_DEV_CACHE_PATH,
|
||||||
ATTR_MARK,
|
ATTR_MARK,
|
||||||
ATTR_TOKEN,
|
ATTR_TOKEN,
|
||||||
// CSS_IN_JS_INSTANCE,
|
CSS_IN_JS_INSTANCE,
|
||||||
// CSS_IN_JS_INSTANCE_ID,
|
CSS_IN_JS_INSTANCE_ID,
|
||||||
} from '../StyleContext';
|
} from '../StyleContext';
|
||||||
import { supportLayer } from '../util';
|
import { supportLayer } from '../util';
|
||||||
// import useGlobalCache from './useGlobalCache';
|
import useGlobalCache from './useGlobalCache';
|
||||||
// import canUseDom from '../../canUseDom';
|
import canUseDom from '../../canUseDom';
|
||||||
// import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
// import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import type { VueNode } from '../../type';
|
import type { VueNode } from '../../type';
|
||||||
|
|
||||||
// const isClientSide = canUseDom();
|
const isClientSide = canUseDom();
|
||||||
|
|
||||||
const SKIP_CHECK = '_skip_check_';
|
const SKIP_CHECK = '_skip_check_';
|
||||||
|
|
||||||
|
@ -275,9 +275,9 @@ export const parseStyle = (
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// == Register ==
|
// == Register ==
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// function uniqueHash(path: (string | number)[], styleStr: string) {
|
function uniqueHash(path: (string | number)[], styleStr: string) {
|
||||||
// return hash(`${path.join('%')}${styleStr}`);
|
return hash(`${path.join('%')}${styleStr}`);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// function Empty() {
|
// function Empty() {
|
||||||
// return null;
|
// return null;
|
||||||
|
@ -287,90 +287,88 @@ export const parseStyle = (
|
||||||
* Register a style to the global style sheet.
|
* Register a style to the global style sheet.
|
||||||
*/
|
*/
|
||||||
export default function useStyleRegister(
|
export default function useStyleRegister(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
info: Ref<{
|
||||||
_info: Ref<{
|
|
||||||
theme: Theme<any, any>;
|
theme: Theme<any, any>;
|
||||||
token: any;
|
token: any;
|
||||||
path: string[];
|
path: string[];
|
||||||
hashId?: string;
|
hashId?: string;
|
||||||
layer?: string;
|
layer?: string;
|
||||||
}>,
|
}>,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
styleFn: () => CSSInterpolation,
|
||||||
_styleFn: () => CSSInterpolation,
|
|
||||||
) {
|
) {
|
||||||
// const styleContext = useStyleInject();
|
const styleContext = useStyleInject();
|
||||||
|
|
||||||
// const tokenKey = computed(() => info.value.token._tokenKey as string);
|
const tokenKey = computed(() => info.value.token._tokenKey as string);
|
||||||
|
|
||||||
// const fullPath = computed(() => [tokenKey.value, ...info.value.path]);
|
const fullPath = computed(() => [tokenKey.value, ...info.value.path]);
|
||||||
|
|
||||||
// Check if need insert style
|
// Check if need insert style
|
||||||
// let isMergedClientSide = isClientSide;
|
let isMergedClientSide = isClientSide;
|
||||||
// if (process.env.NODE_ENV !== 'production' && styleContext.mock !== undefined) {
|
if (process.env.NODE_ENV !== 'production' && styleContext.mock !== undefined) {
|
||||||
// isMergedClientSide = styleContext.mock === 'client';
|
isMergedClientSide = styleContext.mock === 'client';
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const [cacheStyle[0], cacheStyle[1], cacheStyle[2]]
|
// const [cacheStyle[0], cacheStyle[1], cacheStyle[2]]
|
||||||
// const cacheStyle = useGlobalCache(
|
useGlobalCache(
|
||||||
// 'style',
|
'style',
|
||||||
// fullPath,
|
fullPath,
|
||||||
// // Create cache if needed
|
// Create cache if needed
|
||||||
// () => {
|
() => {
|
||||||
// const styleObj = styleFn();
|
const styleObj = styleFn();
|
||||||
// const { hashPriority, container, transformers, linters } = styleContext;
|
const { hashPriority, container, transformers, linters } = styleContext;
|
||||||
// const { path, hashId, layer } = info.value;
|
const { path, hashId, layer } = info.value;
|
||||||
// const [parsedStyle, effectStyle] = parseStyle(styleObj, {
|
const [parsedStyle, effectStyle] = parseStyle(styleObj, {
|
||||||
// hashId,
|
hashId,
|
||||||
// hashPriority,
|
hashPriority,
|
||||||
// layer,
|
layer,
|
||||||
// path: path.join('-'),
|
path: path.join('-'),
|
||||||
// transformers,
|
transformers,
|
||||||
// linters,
|
linters,
|
||||||
// });
|
});
|
||||||
// const styleStr = normalizeStyle(parsedStyle);
|
const styleStr = normalizeStyle(parsedStyle);
|
||||||
// const styleId = uniqueHash(fullPath.value, styleStr);
|
const styleId = uniqueHash(fullPath.value, styleStr);
|
||||||
|
|
||||||
// if (isMergedClientSide) {
|
if (isMergedClientSide) {
|
||||||
// const style = updateCSS(styleStr, styleId, {
|
const style = updateCSS(styleStr, styleId, {
|
||||||
// mark: ATTR_MARK,
|
mark: ATTR_MARK,
|
||||||
// prepend: 'queue',
|
prepend: 'queue',
|
||||||
// attachTo: container,
|
attachTo: container,
|
||||||
// });
|
});
|
||||||
|
|
||||||
// (style as any)[CSS_IN_JS_INSTANCE] = CSS_IN_JS_INSTANCE_ID;
|
(style as any)[CSS_IN_JS_INSTANCE] = CSS_IN_JS_INSTANCE_ID;
|
||||||
|
|
||||||
// // Used for `useCacheToken` to remove on batch when token removed
|
// Used for `useCacheToken` to remove on batch when token removed
|
||||||
// style.setAttribute(ATTR_TOKEN, tokenKey.value);
|
style.setAttribute(ATTR_TOKEN, tokenKey.value);
|
||||||
|
|
||||||
// // Dev usage to find which cache path made this easily
|
// Dev usage to find which cache path made this easily
|
||||||
// if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
// style.setAttribute(ATTR_DEV_CACHE_PATH, fullPath.value.join('|'));
|
style.setAttribute(ATTR_DEV_CACHE_PATH, fullPath.value.join('|'));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Inject client side effect style
|
// Inject client side effect style
|
||||||
// Object.keys(effectStyle).forEach(effectKey => {
|
Object.keys(effectStyle).forEach(effectKey => {
|
||||||
// if (!globalEffectStyleKeys.has(effectKey)) {
|
if (!globalEffectStyleKeys.has(effectKey)) {
|
||||||
// globalEffectStyleKeys.add(effectKey);
|
globalEffectStyleKeys.add(effectKey);
|
||||||
|
|
||||||
// // Inject
|
// Inject
|
||||||
// updateCSS(normalizeStyle(effectStyle[effectKey]), `_effect-${effectKey}`, {
|
updateCSS(normalizeStyle(effectStyle[effectKey]), `_effect-${effectKey}`, {
|
||||||
// mark: ATTR_MARK,
|
mark: ATTR_MARK,
|
||||||
// prepend: 'queue',
|
prepend: 'queue',
|
||||||
// attachTo: container,
|
attachTo: container,
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return [styleStr, tokenKey.value, styleId];
|
return [styleStr, tokenKey.value, styleId];
|
||||||
// },
|
},
|
||||||
// // Remove cache if no need
|
// Remove cache if no need
|
||||||
// ([, , styleId], fromHMR) => {
|
([, , styleId], fromHMR) => {
|
||||||
// if ((fromHMR || styleContext.autoClear) && isClientSide) {
|
if ((fromHMR || styleContext.autoClear) && isClientSide) {
|
||||||
// removeCSS(styleId, { mark: ATTR_MARK });
|
removeCSS(styleId, { mark: ATTR_MARK });
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// );
|
);
|
||||||
|
|
||||||
return (node: VueNode) => {
|
return (node: VueNode) => {
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -111,15 +111,15 @@ const Affix = defineComponent({
|
||||||
status: AffixStatus.None,
|
status: AffixStatus.None,
|
||||||
} as AffixState;
|
} as AffixState;
|
||||||
const targetRect = getTargetRect(targetNode);
|
const targetRect = getTargetRect(targetNode);
|
||||||
const placeholderReact = getTargetRect(placeholderNode.value as HTMLElement);
|
const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement);
|
||||||
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop.value);
|
const fixedTop = getFixedTop(placeholderRect, targetRect, offsetTop.value);
|
||||||
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom.value);
|
const fixedBottom = getFixedBottom(placeholderRect, targetRect, offsetBottom.value);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
placeholderReact.top === 0 &&
|
placeholderRect.top === 0 &&
|
||||||
placeholderReact.left === 0 &&
|
placeholderRect.left === 0 &&
|
||||||
placeholderReact.width === 0 &&
|
placeholderRect.width === 0 &&
|
||||||
placeholderReact.height === 0
|
placeholderRect.height === 0
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ Components which support rtl direction are listed here, you can toggle the direc
|
||||||
<a-divider orientation="left">Modal example</a-divider>
|
<a-divider orientation="left">Modal example</a-divider>
|
||||||
<div>
|
<div>
|
||||||
<a-button type="primary" @click="showModal">Open Modal</a-button>
|
<a-button type="primary" @click="showModal">Open Modal</a-button>
|
||||||
<a-modal v-model:visible="state.modalVisible" title="پنچره ساده">
|
<a-modal v-model:open="state.modalVisible" title="پنچره ساده">
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
|
|
|
@ -54,7 +54,7 @@ Components which need localization support are listed here, you can toggle the l
|
||||||
<div class="example">
|
<div class="example">
|
||||||
<a-table :data-source="[]" :columns="columns" />
|
<a-table :data-source="[]" :columns="columns" />
|
||||||
</div>
|
</div>
|
||||||
<a-modal v-model:visible="visible" title="Locale Modal">
|
<a-modal v-model:open="visible" title="Locale Modal">
|
||||||
<p>Locale Modal</p>
|
<p>Locale Modal</p>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,6 +29,10 @@ import type { InputStatus } from '../../_util/statusUtils';
|
||||||
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
|
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
|
||||||
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
|
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
|
||||||
|
|
||||||
|
type RangeShowTimeObject<DateType> = Omit<SharedTimeProps<DateType>, 'defaultValue'> & {
|
||||||
|
defaultValue?: DateType[];
|
||||||
|
};
|
||||||
|
|
||||||
function commonProps<DateType = any>() {
|
function commonProps<DateType = any>() {
|
||||||
return {
|
return {
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -205,6 +209,7 @@ function rangePickerProps<DateType>() {
|
||||||
format: String,
|
format: String,
|
||||||
renderExtraFooter: functionType<() => VueNode>(),
|
renderExtraFooter: functionType<() => VueNode>(),
|
||||||
separator: { type: String },
|
separator: { type: String },
|
||||||
|
showTime: someType<boolean | RangeShowTimeObject<DateType>>([Boolean, Object]),
|
||||||
ranges:
|
ranges:
|
||||||
objectType<
|
objectType<
|
||||||
Record<
|
Record<
|
||||||
|
@ -250,6 +255,7 @@ export interface RangePickerProps<DateType> {
|
||||||
format?: string;
|
format?: string;
|
||||||
renderExtraFooter?: () => VueNode;
|
renderExtraFooter?: () => VueNode;
|
||||||
separator?: string;
|
separator?: string;
|
||||||
|
showTime?: boolean | RangeShowTimeObject<DateType>;
|
||||||
ranges?: Record<
|
ranges?: Record<
|
||||||
string,
|
string,
|
||||||
Exclude<RangeValue<DateType>, null> | (() => Exclude<RangeValue<DateType>, null>)
|
Exclude<RangeValue<DateType>, null> | (() => Exclude<RangeValue<DateType>, null>)
|
||||||
|
|
|
@ -17,7 +17,7 @@ The default is to close the menu when you click on menu items, this feature can
|
||||||
</docs>
|
</docs>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-dropdown v-model:visible="visible">
|
<a-dropdown v-model:open="visible">
|
||||||
<a class="ant-dropdown-link" @click.prevent>
|
<a class="ant-dropdown-link" @click.prevent>
|
||||||
Hover me
|
Hover me
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useInjectFormItemPrefix } from './context';
|
import { useInjectFormItemPrefix } from './context';
|
||||||
import type { VueNode } from '../_util/type';
|
import type { VueNode } from '../_util/type';
|
||||||
import { computed, defineComponent, ref, Transition, watch } from 'vue';
|
import { computed, defineComponent, ref, Transition, watch, TransitionGroup } from 'vue';
|
||||||
import { getTransitionGroupProps, getTransitionProps, TransitionGroup } from '../_util/transition';
|
import { getTransitionGroupProps, getTransitionProps } from '../_util/transition';
|
||||||
|
|
||||||
import collapseMotion from '../_util/collapseMotion';
|
import collapseMotion from '../_util/collapseMotion';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
@ -37,19 +37,15 @@ export default defineComponent({
|
||||||
`${prefixCls.value}-show-help-item`,
|
`${prefixCls.value}-show-help-item`,
|
||||||
colMItem,
|
colMItem,
|
||||||
);
|
);
|
||||||
|
(transitionGroupProps as any).role = 'alert';
|
||||||
|
(transitionGroupProps as any).class = [hashId.value, baseClassName.value, attrs.class];
|
||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
{...getTransitionProps(`${prefixCls.value}-show-help`)}
|
{...getTransitionProps(`${prefixCls.value}-show-help`)}
|
||||||
onAfterEnter={() => props.onErrorVisibleChanged(true)}
|
onAfterEnter={() => props.onErrorVisibleChanged(true)}
|
||||||
onAfterLeave={() => props.onErrorVisibleChanged(false)}
|
onAfterLeave={() => props.onErrorVisibleChanged(false)}
|
||||||
>
|
>
|
||||||
<TransitionGroup
|
<TransitionGroup {...transitionGroupProps} tag="div" v-show={!!props.errors?.length}>
|
||||||
{...transitionGroupProps}
|
|
||||||
tag="div"
|
|
||||||
role="alert"
|
|
||||||
v-show={!!props.errors?.length}
|
|
||||||
class={[hashId.value, baseClassName.value, attrs.class]}
|
|
||||||
>
|
|
||||||
{props.errors?.map((error: any, index: number) => (
|
{props.errors?.map((error: any, index: number) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
|
|
|
@ -52,7 +52,7 @@ In this case, submit button is in the Modal which is out of Form. You can use `f
|
||||||
<a-button html-type="button" style="margin: 0 8px" @click="visible = true">Add User</a-button>
|
<a-button html-type="button" style="margin: 0 8px" @click="visible = true">Add User</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-modal v-model:visible="visible" title="Basic Drawer" @ok="onOk">
|
<a-modal v-model:open="visible" title="Basic Drawer" @ok="onOk">
|
||||||
<a-form ref="modalFormRef" :model="modalFormState" layout="vertical" name="userForm">
|
<a-form ref="modalFormRef" :model="modalFormState" layout="vertical" name="userForm">
|
||||||
<a-form-item name="name" label="User Name" :rules="[{ required: true }]">
|
<a-form-item name="name" label="User Name" :rules="[{ required: true }]">
|
||||||
<a-input v-model:value="modalFormState.name" />
|
<a-input v-model:value="modalFormState.name" />
|
||||||
|
|
|
@ -19,7 +19,7 @@ When user visit a page with a list of items, and want to create a new item. The
|
||||||
<div>
|
<div>
|
||||||
<a-button type="primary" @click="visible = true">New Collection</a-button>
|
<a-button type="primary" @click="visible = true">New Collection</a-button>
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
v-model:open="visible"
|
||||||
title="Create a new collection"
|
title="Create a new collection"
|
||||||
ok-text="Create"
|
ok-text="Create"
|
||||||
cancel-text="Cancel"
|
cancel-text="Cancel"
|
||||||
|
|
|
@ -36,7 +36,7 @@ Set label width by labelCol.style
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="Activity form">
|
<a-form-item label="Activity form">
|
||||||
<a-input v-model:value="formState.desc" type="textarea" />
|
<a-textarea v-model:value="formState.desc" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
||||||
<a-button type="primary" @click="onSubmit">Create</a-button>
|
<a-button type="primary" @click="onSubmit">Create</a-button>
|
||||||
|
|
|
@ -44,21 +44,41 @@ Use the single file method to recursively generate menus.
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, ref, PropType } from 'vue';
|
||||||
import {
|
import {
|
||||||
MenuFoldOutlined,
|
MenuFoldOutlined,
|
||||||
MenuUnfoldOutlined,
|
MenuUnfoldOutlined,
|
||||||
PieChartOutlined,
|
PieChartOutlined,
|
||||||
MailOutlined,
|
MailOutlined,
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
const list = [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
title: 'Option 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
title: 'Navigation 2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '2.1',
|
||||||
|
title: 'Navigation 3',
|
||||||
|
children: [{ key: '2.1.1', title: 'Option 2.1.1' }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
// you can rewrite it to a single file component, if not, you should config vue alias to vue/dist/vue.esm-bundler.js
|
// you can rewrite it to a single file component, if not, you should config vue alias to vue/dist/vue.esm-bundler.js
|
||||||
const SubMenu = {
|
const SubMenu = defineComponent({
|
||||||
name: 'SubMenu',
|
name: 'SubMenu',
|
||||||
|
components: {
|
||||||
|
PieChartOutlined,
|
||||||
|
MailOutlined,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
menuInfo: {
|
menuInfo: {
|
||||||
type: Object,
|
type: Object as PropType<(typeof list)[number]>,
|
||||||
default: () => ({}),
|
default: () => ({} as (typeof list)[number]),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
|
@ -80,28 +100,8 @@ const SubMenu = {
|
||||||
</template>
|
</template>
|
||||||
</a-sub-menu>
|
</a-sub-menu>
|
||||||
`,
|
`,
|
||||||
components: {
|
});
|
||||||
PieChartOutlined,
|
|
||||||
MailOutlined,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const list = [
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
title: 'Option 1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
title: 'Navigation 2',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
key: '2.1',
|
|
||||||
title: 'Navigation 3',
|
|
||||||
children: [{ key: '2.1.1', title: 'Option 2.1.1' }],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
'sub-menu': SubMenu,
|
'sub-menu': SubMenu,
|
||||||
|
|
|
@ -198,7 +198,7 @@ export default defineComponent({
|
||||||
tooltipProps.title = null;
|
tooltipProps.title = null;
|
||||||
// Reset `visible` to fix control mode tooltip display not correct
|
// Reset `visible` to fix control mode tooltip display not correct
|
||||||
// ref: https://github.com/ant-design/ant-design/issues/16742
|
// ref: https://github.com/ant-design/ant-design/issues/16742
|
||||||
tooltipProps.visible = false;
|
tooltipProps.open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================ Render ============================
|
// ============================ Render ============================
|
||||||
|
|
|
@ -20,10 +20,10 @@ Make it pop up under some conditions.
|
||||||
<div>
|
<div>
|
||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
title="Are you sure delete this task?"
|
title="Are you sure delete this task?"
|
||||||
:visible="visible"
|
:open="visible"
|
||||||
ok-text="Yes"
|
ok-text="Yes"
|
||||||
cancel-text="No"
|
cancel-text="No"
|
||||||
@visibleChange="handleVisibleChange"
|
@openChange="handleVisibleChange"
|
||||||
@confirm="confirm"
|
@confirm="confirm"
|
||||||
@cancel="cancel"
|
@cancel="cancel"
|
||||||
>
|
>
|
||||||
|
|
|
@ -21,6 +21,7 @@ import omit from '../_util/omit';
|
||||||
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
||||||
import ActionButton from '../_util/ActionButton';
|
import ActionButton from '../_util/ActionButton';
|
||||||
import usePopconfirmStyle from './style';
|
import usePopconfirmStyle from './style';
|
||||||
|
import warning from '../_util/warning';
|
||||||
|
|
||||||
export const popconfirmProps = () => ({
|
export const popconfirmProps = () => ({
|
||||||
...abstractTooltipProps(),
|
...abstractTooltipProps(),
|
||||||
|
@ -67,6 +68,11 @@ const Popconfirm = defineComponent({
|
||||||
// emits: ['update:open', 'visibleChange'],
|
// emits: ['update:open', 'visibleChange'],
|
||||||
setup(props: PopconfirmProps, { slots, emit, expose, attrs }) {
|
setup(props: PopconfirmProps, { slots, emit, expose, attrs }) {
|
||||||
const rootRef = ref();
|
const rootRef = ref();
|
||||||
|
warning(
|
||||||
|
props.visible === undefined,
|
||||||
|
'Popconfirm',
|
||||||
|
`\`visible\` will be removed in next major version, please use \`open\` instead.`,
|
||||||
|
);
|
||||||
expose({
|
expose({
|
||||||
getPopupDomNode: () => {
|
getPopupDomNode: () => {
|
||||||
return rootRef.value?.getPopupDomNode?.();
|
return rootRef.value?.getPopupDomNode?.();
|
||||||
|
|
|
@ -16,7 +16,7 @@ Use `visible` prop to control the display of the card.
|
||||||
|
|
||||||
</docs>
|
</docs>
|
||||||
<template>
|
<template>
|
||||||
<a-popover v-model:visible="visible" title="Title" trigger="click">
|
<a-popover v-model:open="visible" title="Title" trigger="click">
|
||||||
<template #content>
|
<template #content>
|
||||||
<a @click="hide">Close</a>
|
<a @click="hide">Close</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -20,18 +20,13 @@ The following example shows how to create a popover which can be hovered and cli
|
||||||
style="width: 500px"
|
style="width: 500px"
|
||||||
title="Hover title"
|
title="Hover title"
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
:visible="hovered"
|
:open="hovered"
|
||||||
@visibleChange="handleHoverChange"
|
@openChange="handleHoverChange"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div>This is hover content.</div>
|
<div>This is hover content.</div>
|
||||||
</template>
|
</template>
|
||||||
<a-popover
|
<a-popover title="Click title" trigger="click" :open="clicked" @openChange="handleClickChange">
|
||||||
title="Click title"
|
|
||||||
trigger="click"
|
|
||||||
:visible="clicked"
|
|
||||||
@visibleChange="handleClickChange"
|
|
||||||
>
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<div>
|
<div>
|
||||||
<div>This is click content.</div>
|
<div>This is click content.</div>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { getTransitionName } from '../_util/transition';
|
||||||
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
|
import warning from '../_util/warning';
|
||||||
|
|
||||||
export const popoverProps = () => ({
|
export const popoverProps = () => ({
|
||||||
...abstractTooltipProps(),
|
...abstractTooltipProps(),
|
||||||
|
@ -33,7 +34,11 @@ const Popover = defineComponent({
|
||||||
}),
|
}),
|
||||||
setup(props, { expose, slots, attrs }) {
|
setup(props, { expose, slots, attrs }) {
|
||||||
const tooltipRef = ref();
|
const tooltipRef = ref();
|
||||||
|
warning(
|
||||||
|
props.visible === undefined,
|
||||||
|
'popover',
|
||||||
|
`\`visible\` will be removed in next major version, please use \`open\` instead.`,
|
||||||
|
);
|
||||||
expose({
|
expose({
|
||||||
getPopupDomNode: () => {
|
getPopupDomNode: () => {
|
||||||
return tooltipRef.value?.getPopupDomNode?.();
|
return tooltipRef.value?.getPopupDomNode?.();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import useConfigInject from '../../config-provider/hooks/useConfigInject';
|
||||||
import { initDefaultProps } from '../../_util/props-util';
|
import { initDefaultProps } from '../../_util/props-util';
|
||||||
import useStyle from '../style';
|
import useStyle from '../style';
|
||||||
import type { VueNode } from '../../_util/type';
|
import type { VueNode } from '../../_util/type';
|
||||||
import { someType, arrayType, booleanType, stringType } from '../../_util/type';
|
import { functionType, someType, arrayType, booleanType, stringType } from '../../_util/type';
|
||||||
import type { ChangeEvent } from '../../_util/EventInterface';
|
import type { ChangeEvent } from '../../_util/EventInterface';
|
||||||
import MotionThumb from './MotionThumb';
|
import MotionThumb from './MotionThumb';
|
||||||
export type SegmentedValue = string | number;
|
export type SegmentedValue = string | number;
|
||||||
|
@ -46,14 +46,29 @@ export const segmentedProps = () => {
|
||||||
size: stringType<segmentedSize>(),
|
size: stringType<segmentedSize>(),
|
||||||
value: { ...someType<SegmentedValue>([String, Number]), required: true },
|
value: { ...someType<SegmentedValue>([String, Number]), required: true },
|
||||||
motionName: String,
|
motionName: String,
|
||||||
|
onChange: functionType<(val: SegmentedValue) => void>(),
|
||||||
|
'onUpdate:value': functionType<(val: SegmentedValue) => void>(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type SegmentedProps = Partial<ExtractPropTypes<ReturnType<typeof segmentedProps>>>;
|
export type SegmentedProps = Partial<ExtractPropTypes<ReturnType<typeof segmentedProps>>>;
|
||||||
|
|
||||||
const SegmentedOption: FunctionalComponent<
|
const SegmentedOption: FunctionalComponent<
|
||||||
SegmentedOption & { prefixCls: string; checked: boolean }
|
SegmentedOption & {
|
||||||
> = (props, { slots, emit, attrs }) => {
|
prefixCls: string;
|
||||||
const { value, disabled, payload, title, prefixCls, label = slots.label, checked } = props;
|
checked: boolean;
|
||||||
|
onChange: (_event: ChangeEvent, val: SegmentedValue) => void;
|
||||||
|
}
|
||||||
|
> = (props, { slots, emit }) => {
|
||||||
|
const {
|
||||||
|
value,
|
||||||
|
disabled,
|
||||||
|
payload,
|
||||||
|
title,
|
||||||
|
prefixCls,
|
||||||
|
label = slots.label,
|
||||||
|
checked,
|
||||||
|
className,
|
||||||
|
} = props;
|
||||||
const handleChange = (event: InputEvent) => {
|
const handleChange = (event: InputEvent) => {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return;
|
return;
|
||||||
|
@ -68,7 +83,7 @@ const SegmentedOption: FunctionalComponent<
|
||||||
{
|
{
|
||||||
[`${prefixCls}-item-disabled`]: disabled,
|
[`${prefixCls}-item-disabled`]: disabled,
|
||||||
},
|
},
|
||||||
attrs.class,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
@ -100,7 +115,6 @@ export default defineComponent({
|
||||||
options: [],
|
options: [],
|
||||||
motionName: 'thumb-motion',
|
motionName: 'thumb-motion',
|
||||||
}),
|
}),
|
||||||
emits: ['change', 'update:value'],
|
|
||||||
slots: ['label'],
|
slots: ['label'],
|
||||||
setup(props, { emit, slots, attrs }) {
|
setup(props, { emit, slots, attrs }) {
|
||||||
const { prefixCls, direction, size } = useConfigInject('segmented', props);
|
const { prefixCls, direction, size } = useConfigInject('segmented', props);
|
||||||
|
@ -154,13 +168,13 @@ export default defineComponent({
|
||||||
<SegmentedOption
|
<SegmentedOption
|
||||||
key={segmentedOption.value}
|
key={segmentedOption.value}
|
||||||
prefixCls={pre}
|
prefixCls={pre}
|
||||||
class={classNames(segmentedOption.className, `${pre}-item`, {
|
|
||||||
[`${pre}-item-selected`]:
|
|
||||||
segmentedOption.value === props.value && !thumbShow.value,
|
|
||||||
})}
|
|
||||||
checked={segmentedOption.value === props.value}
|
checked={segmentedOption.value === props.value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
{...segmentedOption}
|
{...segmentedOption}
|
||||||
|
className={classNames(segmentedOption.className, `${pre}-item`, {
|
||||||
|
[`${pre}-item-selected`]:
|
||||||
|
segmentedOption.value === props.value && !thumbShow.value,
|
||||||
|
})}
|
||||||
disabled={!!props.disabled || !!segmentedOption.disabled}
|
disabled={!!props.disabled || !!segmentedOption.disabled}
|
||||||
v-slots={slots}
|
v-slots={slots}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -18,7 +18,7 @@ Wrap
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-space :size="[8, 16]" wrap>
|
<a-space :size="[8, 16]" wrap>
|
||||||
<template v-for="index in 20" :key="index">
|
<template v-for="_i in 20" :key="_i">
|
||||||
<a-button>Button</a-button>
|
<a-button>Button</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
|
|
@ -160,9 +160,9 @@ export default defineComponent({
|
||||||
<Dropdown
|
<Dropdown
|
||||||
prefixCls={dropdownPrefix}
|
prefixCls={dropdownPrefix}
|
||||||
trigger={['hover']}
|
trigger={['hover']}
|
||||||
open={open.value}
|
visible={open.value}
|
||||||
transitionName={moreTransitionName}
|
transitionName={moreTransitionName}
|
||||||
onOpenChange={setOpen}
|
onVisibleChange={setOpen}
|
||||||
overlayClassName={overlayClassName}
|
overlayClassName={overlayClassName}
|
||||||
mouseEnterDelay={0.1}
|
mouseEnterDelay={0.1}
|
||||||
mouseLeaveDelay={0.1}
|
mouseLeaveDelay={0.1}
|
||||||
|
|
|
@ -5,20 +5,20 @@ import mountTest from '../../../tests/shared/mountTest';
|
||||||
|
|
||||||
describe('Tooltip', () => {
|
describe('Tooltip', () => {
|
||||||
mountTest(Tooltip);
|
mountTest(Tooltip);
|
||||||
it('check `onVisibleChange` arguments', async () => {
|
it('check `onOpenChange` arguments', async () => {
|
||||||
const onVisibleChange = jest.fn();
|
const onOpenChange = jest.fn();
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
{
|
{
|
||||||
props: ['title', 'visible'],
|
props: ['title', 'open'],
|
||||||
render() {
|
render() {
|
||||||
const props = {
|
const props = {
|
||||||
title: this.title || '',
|
title: this.title || '',
|
||||||
mouseEnterDelay: 0,
|
mouseEnterDelay: 0,
|
||||||
mouseLeaveDelay: 0,
|
mouseLeaveDelay: 0,
|
||||||
onVisibleChange,
|
onOpenChange,
|
||||||
};
|
};
|
||||||
if (this.visible !== undefined) {
|
if (this.open !== undefined) {
|
||||||
props.visible = this.visible;
|
props.open = this.open;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Tooltip ref="tooltip" {...props}>
|
<Tooltip ref="tooltip" {...props}>
|
||||||
|
@ -38,15 +38,15 @@ describe('Tooltip', () => {
|
||||||
div.dispatchEvent(new MouseEvent('mouseenter'));
|
div.dispatchEvent(new MouseEvent('mouseenter'));
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
expect(onOpenChange).not.toHaveBeenCalled();
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
div.dispatchEvent(new MouseEvent('mouseleave'));
|
div.dispatchEvent(new MouseEvent('mouseleave'));
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
expect(onOpenChange).not.toHaveBeenCalled();
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
// update `title` value.
|
// update `title` value.
|
||||||
|
@ -56,35 +56,35 @@ describe('Tooltip', () => {
|
||||||
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
|
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(true);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(true);
|
||||||
}, 0);
|
}, 0);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
|
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
expect(onOpenChange).toHaveBeenLastCalledWith(false);
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
// add `visible` props.
|
// add `open` props.
|
||||||
wrapper.setProps({ visible: false });
|
wrapper.setProps({ open: false });
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
|
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
// always trigger onVisibleChange
|
// always trigger onOpenChange
|
||||||
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
|
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
|
||||||
lastCount = onVisibleChange.mock.calls.length;
|
lastCount = onOpenChange.mock.calls.length;
|
||||||
});
|
});
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange.mock.calls.length).toBe(lastCount); // no change with lastCount
|
expect(onOpenChange.mock.calls.length).toBe(lastCount); // no change with lastCount
|
||||||
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
|
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,7 @@ After users upload picture, the thumbnail will be shown in list. The upload butt
|
||||||
<div style="margin-top: 8px">Upload</div>
|
<div style="margin-top: 8px">Upload</div>
|
||||||
</div>
|
</div>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<a-modal :visible="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
<a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
||||||
<img alt="example" style="width: 100%" :src="previewImage" />
|
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import type { ExtractPropTypes, PropType } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import type { SizeType } from '../config-provider';
|
import type { SizeType } from '../config-provider';
|
||||||
import type { VueNode } from '../_util/type';
|
import type { VueNode } from '../_util/type';
|
||||||
|
import { stringType } from '../_util/type';
|
||||||
import type {
|
import type {
|
||||||
ChangeEventHandler,
|
ChangeEventHandler,
|
||||||
CompositionEventHandler,
|
CompositionEventHandler,
|
||||||
|
@ -54,33 +55,30 @@ export const inputProps = () => ({
|
||||||
type: [String, Number] as PropType<string | number>,
|
type: [String, Number] as PropType<string | number>,
|
||||||
},
|
},
|
||||||
autocomplete: String,
|
autocomplete: String,
|
||||||
type: {
|
type: stringType<
|
||||||
type: String as PropType<
|
| 'button'
|
||||||
| 'button'
|
| 'checkbox'
|
||||||
| 'checkbox'
|
| 'color'
|
||||||
| 'color'
|
| 'date'
|
||||||
| 'date'
|
| 'datetime-local'
|
||||||
| 'datetime-local'
|
| 'email'
|
||||||
| 'email'
|
| 'file'
|
||||||
| 'file'
|
| 'hidden'
|
||||||
| 'hidden'
|
| 'image'
|
||||||
| 'image'
|
| 'month'
|
||||||
| 'month'
|
| 'number'
|
||||||
| 'number'
|
| 'password'
|
||||||
| 'password'
|
| 'radio'
|
||||||
| 'radio'
|
| 'range'
|
||||||
| 'range'
|
| 'reset'
|
||||||
| 'reset'
|
| 'search'
|
||||||
| 'search'
|
| 'submit'
|
||||||
| 'submit'
|
| 'tel'
|
||||||
| 'tel'
|
| 'text'
|
||||||
| 'text'
|
| 'time'
|
||||||
| 'time'
|
| 'url'
|
||||||
| 'url'
|
| 'week'
|
||||||
| 'week'
|
>('text'),
|
||||||
>,
|
|
||||||
default: 'text',
|
|
||||||
},
|
|
||||||
name: String,
|
name: String,
|
||||||
size: { type: String as PropType<SizeType> },
|
size: { type: String as PropType<SizeType> },
|
||||||
autofocus: { type: Boolean, default: undefined },
|
autofocus: { type: Boolean, default: undefined },
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<a-modal v-model:visible="visible" title="成为赞助商" @ok="visible = false">
|
<a-modal v-model:open="visible" title="成为赞助商" @ok="visible = false">
|
||||||
如果您有品牌推广、活动推广、招聘推广、社区合作等需求,欢迎联系我们,成为赞助商。
|
如果您有品牌推广、活动推广、招聘推广、社区合作等需求,欢迎联系我们,成为赞助商。
|
||||||
<br />
|
<br />
|
||||||
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面。
|
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面。
|
||||||
|
|
|
@ -389,6 +389,12 @@ export default {
|
||||||
type: 'Layout',
|
type: 'Layout',
|
||||||
title: 'Space',
|
title: 'Space',
|
||||||
},
|
},
|
||||||
|
segmented: {
|
||||||
|
category: 'Components',
|
||||||
|
subtitle: '分段控制器',
|
||||||
|
type: 'Data Display',
|
||||||
|
title: 'Segmented',
|
||||||
|
},
|
||||||
// colorPicker: {
|
// colorPicker: {
|
||||||
// category: 'Components',
|
// category: 'Components',
|
||||||
// subtitle: '取色器',
|
// subtitle: '取色器',
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<CloseOutlined class="close-icon" @click="visibleAlertBanner = false" />
|
<CloseOutlined class="close-icon" @click="visibleAlertBanner = false" />
|
||||||
</div>
|
</div>
|
||||||
<a-popover
|
<a-popover
|
||||||
v-model:visible="menuVisible"
|
v-model:open="menuVisible"
|
||||||
overlay-class-name="popover-menu"
|
overlay-class-name="popover-menu"
|
||||||
placement="bottomRight"
|
placement="bottomRight"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
|
|
Loading…
Reference in New Issue