fix: use open, remove visible

pull/6293/head^2
tangjinzhou 2023-02-23 11:58:23 +08:00
parent 1b51e6ffb3
commit 37b5d02b6d
27 changed files with 232 additions and 204 deletions

4
.gitignore vendored
View File

@ -59,6 +59,7 @@ jspm_packages/
dist
lib
es
/locale
_site
yarn.lock
package-lock.json
@ -78,5 +79,8 @@ report.html
site/src/router/demoRoutes.js
components/version/version.ts
components/version/version.tsx
components/version/token.json
components/version/token-meta.json
~component-api.json

View File

@ -1,4 +1,4 @@
// import hash from '@emotion/hash';
import hash from '@emotion/hash';
import type * as CSS from 'csstype';
// @ts-ignore
import unitless from '@emotion/unitless';
@ -10,22 +10,22 @@ import type { Linter } from '../linters';
import { contentQuotesLinter, hashedAnimationLinter } from '../linters';
import type { HashPriority } from '../StyleContext';
import {
// useStyleInject,
// ATTR_DEV_CACHE_PATH,
useStyleInject,
ATTR_DEV_CACHE_PATH,
ATTR_MARK,
ATTR_TOKEN,
// CSS_IN_JS_INSTANCE,
// CSS_IN_JS_INSTANCE_ID,
CSS_IN_JS_INSTANCE,
CSS_IN_JS_INSTANCE_ID,
} from '../StyleContext';
import { supportLayer } from '../util';
// import useGlobalCache from './useGlobalCache';
// import canUseDom from '../../canUseDom';
// import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
import useGlobalCache from './useGlobalCache';
import canUseDom from '../../canUseDom';
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
import type { Ref } from 'vue';
// import { computed } from 'vue';
import { computed } from 'vue';
import type { VueNode } from '../../type';
// const isClientSide = canUseDom();
const isClientSide = canUseDom();
const SKIP_CHECK = '_skip_check_';
@ -275,9 +275,9 @@ export const parseStyle = (
// ============================================================================
// == Register ==
// ============================================================================
// function uniqueHash(path: (string | number)[], styleStr: string) {
// return hash(`${path.join('%')}${styleStr}`);
// }
function uniqueHash(path: (string | number)[], styleStr: string) {
return hash(`${path.join('%')}${styleStr}`);
}
// function Empty() {
// return null;
@ -287,90 +287,88 @@ export const parseStyle = (
* Register a style to the global style sheet.
*/
export default function useStyleRegister(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_info: Ref<{
info: Ref<{
theme: Theme<any, any>;
token: any;
path: string[];
hashId?: 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
// let isMergedClientSide = isClientSide;
// if (process.env.NODE_ENV !== 'production' && styleContext.mock !== undefined) {
// isMergedClientSide = styleContext.mock === 'client';
// }
let isMergedClientSide = isClientSide;
if (process.env.NODE_ENV !== 'production' && styleContext.mock !== undefined) {
isMergedClientSide = styleContext.mock === 'client';
}
// const [cacheStyle[0], cacheStyle[1], cacheStyle[2]]
// const cacheStyle = useGlobalCache(
// 'style',
// fullPath,
// // Create cache if needed
// () => {
// const styleObj = styleFn();
// const { hashPriority, container, transformers, linters } = styleContext;
// const { path, hashId, layer } = info.value;
// const [parsedStyle, effectStyle] = parseStyle(styleObj, {
// hashId,
// hashPriority,
// layer,
// path: path.join('-'),
// transformers,
// linters,
// });
// const styleStr = normalizeStyle(parsedStyle);
// const styleId = uniqueHash(fullPath.value, styleStr);
useGlobalCache(
'style',
fullPath,
// Create cache if needed
() => {
const styleObj = styleFn();
const { hashPriority, container, transformers, linters } = styleContext;
const { path, hashId, layer } = info.value;
const [parsedStyle, effectStyle] = parseStyle(styleObj, {
hashId,
hashPriority,
layer,
path: path.join('-'),
transformers,
linters,
});
const styleStr = normalizeStyle(parsedStyle);
const styleId = uniqueHash(fullPath.value, styleStr);
// if (isMergedClientSide) {
// const style = updateCSS(styleStr, styleId, {
// mark: ATTR_MARK,
// prepend: 'queue',
// attachTo: container,
// });
if (isMergedClientSide) {
const style = updateCSS(styleStr, styleId, {
mark: ATTR_MARK,
prepend: 'queue',
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
// style.setAttribute(ATTR_TOKEN, tokenKey.value);
// Used for `useCacheToken` to remove on batch when token removed
style.setAttribute(ATTR_TOKEN, tokenKey.value);
// // Dev usage to find which cache path made this easily
// if (process.env.NODE_ENV !== 'production') {
// style.setAttribute(ATTR_DEV_CACHE_PATH, fullPath.value.join('|'));
// }
// Dev usage to find which cache path made this easily
if (process.env.NODE_ENV !== 'production') {
style.setAttribute(ATTR_DEV_CACHE_PATH, fullPath.value.join('|'));
}
// // Inject client side effect style
// Object.keys(effectStyle).forEach(effectKey => {
// if (!globalEffectStyleKeys.has(effectKey)) {
// globalEffectStyleKeys.add(effectKey);
// Inject client side effect style
Object.keys(effectStyle).forEach(effectKey => {
if (!globalEffectStyleKeys.has(effectKey)) {
globalEffectStyleKeys.add(effectKey);
// // Inject
// updateCSS(normalizeStyle(effectStyle[effectKey]), `_effect-${effectKey}`, {
// mark: ATTR_MARK,
// prepend: 'queue',
// attachTo: container,
// });
// }
// });
// }
// Inject
updateCSS(normalizeStyle(effectStyle[effectKey]), `_effect-${effectKey}`, {
mark: ATTR_MARK,
prepend: 'queue',
attachTo: container,
});
}
});
}
// return [styleStr, tokenKey.value, styleId];
// },
// // Remove cache if no need
// ([, , styleId], fromHMR) => {
// if ((fromHMR || styleContext.autoClear) && isClientSide) {
// removeCSS(styleId, { mark: ATTR_MARK });
// }
// },
// );
return [styleStr, tokenKey.value, styleId];
},
// Remove cache if no need
([, , styleId], fromHMR) => {
if ((fromHMR || styleContext.autoClear) && isClientSide) {
removeCSS(styleId, { mark: ATTR_MARK });
}
},
);
return (node: VueNode) => {
return node;

View File

@ -111,15 +111,15 @@ const Affix = defineComponent({
status: AffixStatus.None,
} as AffixState;
const targetRect = getTargetRect(targetNode);
const placeholderReact = getTargetRect(placeholderNode.value as HTMLElement);
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop.value);
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom.value);
const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement);
const fixedTop = getFixedTop(placeholderRect, targetRect, offsetTop.value);
const fixedBottom = getFixedBottom(placeholderRect, targetRect, offsetBottom.value);
if (
placeholderReact.top === 0 &&
placeholderReact.left === 0 &&
placeholderReact.width === 0 &&
placeholderReact.height === 0
placeholderRect.top === 0 &&
placeholderRect.left === 0 &&
placeholderRect.width === 0 &&
placeholderRect.height === 0
) {
return;
}

View File

@ -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>
<div>
<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>

View File

@ -54,7 +54,7 @@ Components which need localization support are listed here, you can toggle the l
<div class="example">
<a-table :data-source="[]" :columns="columns" />
</div>
<a-modal v-model:visible="visible" title="Locale Modal">
<a-modal v-model:open="visible" title="Locale Modal">
<p>Locale Modal</p>
</a-modal>
</div>

View File

@ -29,6 +29,10 @@ import type { InputStatus } from '../../_util/statusUtils';
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
type RangeShowTimeObject<DateType> = Omit<SharedTimeProps<DateType>, 'defaultValue'> & {
defaultValue?: DateType[];
};
function commonProps<DateType = any>() {
return {
id: String,
@ -205,6 +209,7 @@ function rangePickerProps<DateType>() {
format: String,
renderExtraFooter: functionType<() => VueNode>(),
separator: { type: String },
showTime: someType<boolean | RangeShowTimeObject<DateType>>([Boolean, Object]),
ranges:
objectType<
Record<
@ -250,6 +255,7 @@ export interface RangePickerProps<DateType> {
format?: string;
renderExtraFooter?: () => VueNode;
separator?: string;
showTime?: boolean | RangeShowTimeObject<DateType>;
ranges?: Record<
string,
Exclude<RangeValue<DateType>, null> | (() => Exclude<RangeValue<DateType>, null>)

View File

@ -17,7 +17,7 @@ The default is to close the menu when you click on menu items, this feature can
</docs>
<template>
<a-dropdown v-model:visible="visible">
<a-dropdown v-model:open="visible">
<a class="ant-dropdown-link" @click.prevent>
Hover me
<DownOutlined />

View File

@ -1,7 +1,7 @@
import { useInjectFormItemPrefix } from './context';
import type { VueNode } from '../_util/type';
import { computed, defineComponent, ref, Transition, watch } from 'vue';
import { getTransitionGroupProps, getTransitionProps, TransitionGroup } from '../_util/transition';
import { computed, defineComponent, ref, Transition, watch, TransitionGroup } from 'vue';
import { getTransitionGroupProps, getTransitionProps } from '../_util/transition';
import collapseMotion from '../_util/collapseMotion';
import useStyle from './style';
@ -37,19 +37,15 @@ export default defineComponent({
`${prefixCls.value}-show-help-item`,
colMItem,
);
(transitionGroupProps as any).role = 'alert';
(transitionGroupProps as any).class = [hashId.value, baseClassName.value, attrs.class];
return (
<Transition
{...getTransitionProps(`${prefixCls.value}-show-help`)}
onAfterEnter={() => props.onErrorVisibleChanged(true)}
onAfterLeave={() => props.onErrorVisibleChanged(false)}
>
<TransitionGroup
{...transitionGroupProps}
tag="div"
role="alert"
v-show={!!props.errors?.length}
class={[hashId.value, baseClassName.value, attrs.class]}
>
<TransitionGroup {...transitionGroupProps} tag="div" v-show={!!props.errors?.length}>
{props.errors?.map((error: any, index: number) => (
<div
key={index}

View File

@ -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-form-item>
</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-item name="name" label="User Name" :rules="[{ required: true }]">
<a-input v-model:value="modalFormState.name" />

View File

@ -19,7 +19,7 @@ When user visit a page with a list of items, and want to create a new item. The
<div>
<a-button type="primary" @click="visible = true">New Collection</a-button>
<a-modal
v-model:visible="visible"
v-model:open="visible"
title="Create a new collection"
ok-text="Create"
cancel-text="Cancel"

View File

@ -36,7 +36,7 @@ Set label width by labelCol.style
</a-radio-group>
</a-form-item>
<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 :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">Create</a-button>

View File

@ -44,21 +44,41 @@ Use the single file method to recursively generate menus.
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { defineComponent, ref, PropType } from 'vue';
import {
MenuFoldOutlined,
MenuUnfoldOutlined,
PieChartOutlined,
MailOutlined,
} 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
const SubMenu = {
const SubMenu = defineComponent({
name: 'SubMenu',
components: {
PieChartOutlined,
MailOutlined,
},
props: {
menuInfo: {
type: Object,
default: () => ({}),
type: Object as PropType<(typeof list)[number]>,
default: () => ({} as (typeof list)[number]),
},
},
template: `
@ -80,28 +100,8 @@ const SubMenu = {
</template>
</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({
components: {
'sub-menu': SubMenu,

View File

@ -198,7 +198,7 @@ export default defineComponent({
tooltipProps.title = null;
// Reset `visible` to fix control mode tooltip display not correct
// ref: https://github.com/ant-design/ant-design/issues/16742
tooltipProps.visible = false;
tooltipProps.open = false;
}
// ============================ Render ============================

View File

@ -20,10 +20,10 @@ Make it pop up under some conditions.
<div>
<a-popconfirm
title="Are you sure delete this task?"
:visible="visible"
:open="visible"
ok-text="Yes"
cancel-text="No"
@visibleChange="handleVisibleChange"
@openChange="handleVisibleChange"
@confirm="confirm"
@cancel="cancel"
>

View File

@ -21,6 +21,7 @@ import omit from '../_util/omit';
import { tooltipDefaultProps } from '../tooltip/Tooltip';
import ActionButton from '../_util/ActionButton';
import usePopconfirmStyle from './style';
import warning from '../_util/warning';
export const popconfirmProps = () => ({
...abstractTooltipProps(),
@ -67,6 +68,11 @@ const Popconfirm = defineComponent({
// emits: ['update:open', 'visibleChange'],
setup(props: PopconfirmProps, { slots, emit, expose, attrs }) {
const rootRef = ref();
warning(
props.visible === undefined,
'Popconfirm',
`\`visible\` will be removed in next major version, please use \`open\` instead.`,
);
expose({
getPopupDomNode: () => {
return rootRef.value?.getPopupDomNode?.();

View File

@ -16,7 +16,7 @@ Use `visible` prop to control the display of the card.
</docs>
<template>
<a-popover v-model:visible="visible" title="Title" trigger="click">
<a-popover v-model:open="visible" title="Title" trigger="click">
<template #content>
<a @click="hide">Close</a>
</template>

View File

@ -20,18 +20,13 @@ The following example shows how to create a popover which can be hovered and cli
style="width: 500px"
title="Hover title"
trigger="hover"
:visible="hovered"
@visibleChange="handleHoverChange"
:open="hovered"
@openChange="handleHoverChange"
>
<template #content>
<div>This is hover content.</div>
</template>
<a-popover
title="Click title"
trigger="click"
:visible="clicked"
@visibleChange="handleClickChange"
>
<a-popover title="Click title" trigger="click" :open="clicked" @openChange="handleClickChange">
<template #content>
<div>
<div>This is click content.</div>

View File

@ -10,6 +10,7 @@ import { getTransitionName } from '../_util/transition';
import { tooltipDefaultProps } from '../tooltip/Tooltip';
import useStyle from './style';
import classNames from '../_util/classNames';
import warning from '../_util/warning';
export const popoverProps = () => ({
...abstractTooltipProps(),
@ -33,7 +34,11 @@ const Popover = defineComponent({
}),
setup(props, { expose, slots, attrs }) {
const tooltipRef = ref();
warning(
props.visible === undefined,
'popover',
`\`visible\` will be removed in next major version, please use \`open\` instead.`,
);
expose({
getPopupDomNode: () => {
return tooltipRef.value?.getPopupDomNode?.();

View File

@ -5,7 +5,7 @@ import useConfigInject from '../../config-provider/hooks/useConfigInject';
import { initDefaultProps } from '../../_util/props-util';
import useStyle from '../style';
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 MotionThumb from './MotionThumb';
export type SegmentedValue = string | number;
@ -46,14 +46,29 @@ export const segmentedProps = () => {
size: stringType<segmentedSize>(),
value: { ...someType<SegmentedValue>([String, Number]), required: true },
motionName: String,
onChange: functionType<(val: SegmentedValue) => void>(),
'onUpdate:value': functionType<(val: SegmentedValue) => void>(),
};
};
export type SegmentedProps = Partial<ExtractPropTypes<ReturnType<typeof segmentedProps>>>;
const SegmentedOption: FunctionalComponent<
SegmentedOption & { prefixCls: string; checked: boolean }
> = (props, { slots, emit, attrs }) => {
const { value, disabled, payload, title, prefixCls, label = slots.label, checked } = props;
SegmentedOption & {
prefixCls: string;
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) => {
if (disabled) {
return;
@ -68,7 +83,7 @@ const SegmentedOption: FunctionalComponent<
{
[`${prefixCls}-item-disabled`]: disabled,
},
attrs.class,
className,
)}
>
<input
@ -100,7 +115,6 @@ export default defineComponent({
options: [],
motionName: 'thumb-motion',
}),
emits: ['change', 'update:value'],
slots: ['label'],
setup(props, { emit, slots, attrs }) {
const { prefixCls, direction, size } = useConfigInject('segmented', props);
@ -154,13 +168,13 @@ export default defineComponent({
<SegmentedOption
key={segmentedOption.value}
prefixCls={pre}
class={classNames(segmentedOption.className, `${pre}-item`, {
[`${pre}-item-selected`]:
segmentedOption.value === props.value && !thumbShow.value,
})}
checked={segmentedOption.value === props.value}
onChange={handleChange}
{...segmentedOption}
className={classNames(segmentedOption.className, `${pre}-item`, {
[`${pre}-item-selected`]:
segmentedOption.value === props.value && !thumbShow.value,
})}
disabled={!!props.disabled || !!segmentedOption.disabled}
v-slots={slots}
/>

View File

@ -18,7 +18,7 @@ Wrap
<template>
<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>
</template>
</a-space>

View File

@ -160,9 +160,9 @@ export default defineComponent({
<Dropdown
prefixCls={dropdownPrefix}
trigger={['hover']}
open={open.value}
visible={open.value}
transitionName={moreTransitionName}
onOpenChange={setOpen}
onVisibleChange={setOpen}
overlayClassName={overlayClassName}
mouseEnterDelay={0.1}
mouseLeaveDelay={0.1}

View File

@ -5,20 +5,20 @@ import mountTest from '../../../tests/shared/mountTest';
describe('Tooltip', () => {
mountTest(Tooltip);
it('check `onVisibleChange` arguments', async () => {
const onVisibleChange = jest.fn();
it('check `onOpenChange` arguments', async () => {
const onOpenChange = jest.fn();
const wrapper = mount(
{
props: ['title', 'visible'],
props: ['title', 'open'],
render() {
const props = {
title: this.title || '',
mouseEnterDelay: 0,
mouseLeaveDelay: 0,
onVisibleChange,
onOpenChange,
};
if (this.visible !== undefined) {
props.visible = this.visible;
if (this.open !== undefined) {
props.open = this.open;
}
return (
<Tooltip ref="tooltip" {...props}>
@ -38,15 +38,15 @@ describe('Tooltip', () => {
div.dispatchEvent(new MouseEvent('mouseenter'));
});
await asyncExpect(() => {
expect(onVisibleChange).not.toHaveBeenCalled();
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
expect(onOpenChange).not.toHaveBeenCalled();
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
});
await asyncExpect(() => {
div.dispatchEvent(new MouseEvent('mouseleave'));
});
await asyncExpect(() => {
expect(onVisibleChange).not.toHaveBeenCalled();
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
expect(onOpenChange).not.toHaveBeenCalled();
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
});
await asyncExpect(() => {
// update `title` value.
@ -56,35 +56,35 @@ describe('Tooltip', () => {
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
});
await asyncExpect(() => {
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
expect(wrapper.vm.$refs.tooltip.visible).toBe(true);
expect(onOpenChange).toHaveBeenLastCalledWith(true);
expect(wrapper.vm.$refs.tooltip.open).toBe(true);
}, 0);
await asyncExpect(() => {
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
});
await asyncExpect(() => {
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
expect(onOpenChange).toHaveBeenLastCalledWith(false);
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
});
await asyncExpect(() => {
// add `visible` props.
wrapper.setProps({ visible: false });
// add `open` props.
wrapper.setProps({ open: false });
});
await asyncExpect(() => {
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseenter'));
});
await asyncExpect(() => {
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
expect(onOpenChange).toHaveBeenLastCalledWith(true);
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
});
await asyncExpect(() => {
// always trigger onVisibleChange
// always trigger onOpenChange
document.getElementById('hello').dispatchEvent(new MouseEvent('mouseleave'));
lastCount = onVisibleChange.mock.calls.length;
lastCount = onOpenChange.mock.calls.length;
});
await asyncExpect(() => {
expect(onVisibleChange.mock.calls.length).toBe(lastCount); // no change with lastCount
expect(wrapper.vm.$refs.tooltip.visible).toBe(false);
expect(onOpenChange.mock.calls.length).toBe(lastCount); // no change with lastCount
expect(wrapper.vm.$refs.tooltip.open).toBe(false);
});
});
});

View File

@ -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>
</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" />
</a-modal>
</div>

View File

@ -2,6 +2,7 @@ import type { ExtractPropTypes, PropType } from 'vue';
import PropTypes from '../_util/vue-types';
import type { SizeType } from '../config-provider';
import type { VueNode } from '../_util/type';
import { stringType } from '../_util/type';
import type {
ChangeEventHandler,
CompositionEventHandler,
@ -54,33 +55,30 @@ export const inputProps = () => ({
type: [String, Number] as PropType<string | number>,
},
autocomplete: String,
type: {
type: String as PropType<
| 'button'
| 'checkbox'
| 'color'
| 'date'
| 'datetime-local'
| 'email'
| 'file'
| 'hidden'
| 'image'
| 'month'
| 'number'
| 'password'
| 'radio'
| 'range'
| 'reset'
| 'search'
| 'submit'
| 'tel'
| 'text'
| 'time'
| 'url'
| 'week'
>,
default: 'text',
},
type: stringType<
| 'button'
| 'checkbox'
| 'color'
| 'date'
| 'datetime-local'
| 'email'
| 'file'
| 'hidden'
| 'image'
| 'month'
| 'number'
| 'password'
| 'radio'
| 'range'
| 'reset'
| 'search'
| 'submit'
| 'tel'
| 'text'
| 'time'
| 'url'
| 'week'
>('text'),
name: String,
size: { type: String as PropType<SizeType> },
autofocus: { type: Boolean, default: undefined },

View File

@ -22,7 +22,7 @@
</li>
</ul>
</div>
<a-modal v-model:visible="visible" title="成为赞助商" @ok="visible = false">
<a-modal v-model:open="visible" title="成为赞助商" @ok="visible = false">
如果您有品牌推广活动推广招聘推广社区合作等需求欢迎联系我们成为赞助商
<br />
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面

View File

@ -389,6 +389,12 @@ export default {
type: 'Layout',
title: 'Space',
},
segmented: {
category: 'Components',
subtitle: '分段控制器',
type: 'Data Display',
title: 'Segmented',
},
// colorPicker: {
// category: 'Components',
// subtitle: '取色器',

View File

@ -23,7 +23,7 @@
<CloseOutlined class="close-icon" @click="visibleAlertBanner = false" />
</div>
<a-popover
v-model:visible="menuVisible"
v-model:open="menuVisible"
overlay-class-name="popover-menu"
placement="bottomRight"
trigger="click"