mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
types(DropdownMenu): use tsx (#8167)
This commit is contained in:
parent
6c89575946
commit
8568c02e0b
@ -1,8 +1,14 @@
|
|||||||
import { reactive, Teleport } from 'vue';
|
import {
|
||||||
|
reactive,
|
||||||
|
Teleport,
|
||||||
|
PropType,
|
||||||
|
TeleportProps,
|
||||||
|
CSSProperties,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { createNamespace, UnknownProp } from '../utils';
|
import { createNamespace, UnknownProp } from '../utils';
|
||||||
import { DROPDOWN_KEY } from '../dropdown-menu';
|
import { DROPDOWN_KEY, DropdownMenuProvide } from '../dropdown-menu';
|
||||||
|
|
||||||
// Composition
|
// Composition
|
||||||
import { useParent } from '@vant/use';
|
import { useParent } from '@vant/use';
|
||||||
@ -15,15 +21,21 @@ import Popup from '../popup';
|
|||||||
|
|
||||||
const [createComponent, bem] = createNamespace('dropdown-item');
|
const [createComponent, bem] = createNamespace('dropdown-item');
|
||||||
|
|
||||||
|
export type DropdownItemOption = {
|
||||||
|
text: string;
|
||||||
|
icon?: string;
|
||||||
|
value: number | string;
|
||||||
|
};
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
title: String,
|
title: String,
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
teleport: [String, Object],
|
teleport: [String, Object] as PropType<TeleportProps['to']>,
|
||||||
modelValue: UnknownProp,
|
modelValue: UnknownProp,
|
||||||
titleClass: UnknownProp,
|
titleClass: UnknownProp,
|
||||||
options: {
|
options: {
|
||||||
type: Array,
|
type: Array as PropType<DropdownItemOption[]>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
lazyRender: {
|
lazyRender: {
|
||||||
@ -41,9 +53,19 @@ export default createComponent({
|
|||||||
showWrapper: false,
|
showWrapper: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { parent } = useParent(DROPDOWN_KEY);
|
const { parent } = useParent<DropdownMenuProvide>(DROPDOWN_KEY);
|
||||||
|
|
||||||
const createEmitter = (eventName) => () => emit(eventName);
|
if (!parent) {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
console.error(
|
||||||
|
'[Vant] DropdownItem must be a child component of DropdownMenu.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createEmitter = (eventName: 'open' | 'close' | 'opened') => () =>
|
||||||
|
emit(eventName);
|
||||||
const onOpen = createEmitter('open');
|
const onOpen = createEmitter('open');
|
||||||
const onClose = createEmitter('close');
|
const onClose = createEmitter('close');
|
||||||
const onOpened = createEmitter('opened');
|
const onOpened = createEmitter('opened');
|
||||||
@ -53,14 +75,17 @@ export default createComponent({
|
|||||||
emit('closed');
|
emit('closed');
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClickWrapper = (event) => {
|
const onClickWrapper = (event: MouseEvent) => {
|
||||||
// prevent being identified as clicking outside and closed when using teleport
|
// prevent being identified as clicking outside and closed when using teleport
|
||||||
if (props.teleport) {
|
if (props.teleport) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggle = (show = !state.showPopup, options = {}) => {
|
const toggle = (
|
||||||
|
show = !state.showPopup,
|
||||||
|
options: { immediate?: boolean } = {}
|
||||||
|
) => {
|
||||||
if (show === state.showPopup) {
|
if (show === state.showPopup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -89,7 +114,7 @@ export default createComponent({
|
|||||||
return match.length ? match[0].text : '';
|
return match.length ? match[0].text : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderOption = (option) => {
|
const renderOption = (option: DropdownItemOption) => {
|
||||||
const { activeColor } = parent.props;
|
const { activeColor } = parent.props;
|
||||||
const active = option.value === props.modelValue;
|
const active = option.value === props.modelValue;
|
||||||
|
|
||||||
@ -129,7 +154,10 @@ export default createComponent({
|
|||||||
closeOnClickOverlay,
|
closeOnClickOverlay,
|
||||||
} = parent.props;
|
} = parent.props;
|
||||||
|
|
||||||
const style = { zIndex };
|
const style: CSSProperties = {
|
||||||
|
zIndex: zIndex !== undefined ? +zIndex : undefined,
|
||||||
|
};
|
||||||
|
|
||||||
if (direction === 'down') {
|
if (direction === 'down') {
|
||||||
style.top = `${offset.value}px`;
|
style.top = `${offset.value}px`;
|
||||||
} else {
|
} else {
|
@ -1,7 +1,7 @@
|
|||||||
import { ref, computed } from 'vue';
|
import { ref, computed, PropType, CSSProperties, Ref } from 'vue';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { createNamespace, isDef } from '../utils';
|
import { isDef, ComponentInstance, createNamespace } from '../utils';
|
||||||
|
|
||||||
// Composition
|
// Composition
|
||||||
import {
|
import {
|
||||||
@ -16,6 +16,20 @@ const [createComponent, bem] = createNamespace('dropdown-menu');
|
|||||||
|
|
||||||
export const DROPDOWN_KEY = 'vanDropdownMenu';
|
export const DROPDOWN_KEY = 'vanDropdownMenu';
|
||||||
|
|
||||||
|
export type DropdownMenuDirection = 'up' | 'down';
|
||||||
|
|
||||||
|
export type DropdownMenuProvide = {
|
||||||
|
props: {
|
||||||
|
zIndex?: number | string;
|
||||||
|
overlay: boolean;
|
||||||
|
duration: number | string;
|
||||||
|
direction: DropdownMenuDirection;
|
||||||
|
activeColor?: string;
|
||||||
|
closeOnClickOverlay: boolean;
|
||||||
|
};
|
||||||
|
offset: Ref<number>;
|
||||||
|
};
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
zIndex: [Number, String],
|
zIndex: [Number, String],
|
||||||
@ -29,7 +43,7 @@ export default createComponent({
|
|||||||
default: 0.2,
|
default: 0.2,
|
||||||
},
|
},
|
||||||
direction: {
|
direction: {
|
||||||
type: String,
|
type: String as PropType<DropdownMenuDirection>,
|
||||||
default: 'down',
|
default: 'down',
|
||||||
},
|
},
|
||||||
closeOnClickOutside: {
|
closeOnClickOutside: {
|
||||||
@ -43,11 +57,13 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const root = ref();
|
const root = ref<HTMLElement>();
|
||||||
|
const barRef = ref<HTMLElement>();
|
||||||
const offset = ref(0);
|
const offset = ref(0);
|
||||||
const barRef = ref();
|
|
||||||
|
|
||||||
const { children, linkChildren } = useChildren(DROPDOWN_KEY);
|
const { children, linkChildren } = useChildren<ComponentInstance>(
|
||||||
|
DROPDOWN_KEY
|
||||||
|
);
|
||||||
const scrollParent = useScrollParent(root);
|
const scrollParent = useScrollParent(root);
|
||||||
|
|
||||||
const opened = computed(() =>
|
const opened = computed(() =>
|
||||||
@ -57,8 +73,8 @@ export default createComponent({
|
|||||||
const barStyle = computed(() => {
|
const barStyle = computed(() => {
|
||||||
if (opened.value && isDef(props.zIndex)) {
|
if (opened.value && isDef(props.zIndex)) {
|
||||||
return {
|
return {
|
||||||
zIndex: 1 + props.zIndex,
|
zIndex: +props.zIndex + 1,
|
||||||
};
|
} as CSSProperties;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +103,7 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleItem = (active) => {
|
const toggleItem = (active: number) => {
|
||||||
children.forEach((item, index) => {
|
children.forEach((item, index) => {
|
||||||
if (index === active) {
|
if (index === active) {
|
||||||
updateOffset();
|
updateOffset();
|
||||||
@ -98,7 +114,7 @@ export default createComponent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderTitle = (item, index) => {
|
const renderTitle = (item: ComponentInstance, index: number) => {
|
||||||
const { showPopup } = item.state;
|
const { showPopup } = item.state;
|
||||||
const { disabled, titleClass } = item;
|
const { disabled, titleClass } = item;
|
||||||
|
|
3
src/vue-tsx-shim.d.ts
vendored
3
src/vue-tsx-shim.d.ts
vendored
@ -10,12 +10,15 @@ declare module 'vue' {
|
|||||||
// see: https://github.com/vuejs/vue-next/issues/1553
|
// see: https://github.com/vuejs/vue-next/issues/1553
|
||||||
// https://github.com/vuejs/vue-next/issues/3029
|
// https://github.com/vuejs/vue-next/issues/3029
|
||||||
onBlur?: EventHandler;
|
onBlur?: EventHandler;
|
||||||
|
onOpen?: EventHandler;
|
||||||
onEdit?: EventHandler;
|
onEdit?: EventHandler;
|
||||||
|
onClose?: EventHandler;
|
||||||
onFocus?: EventHandler;
|
onFocus?: EventHandler;
|
||||||
onInput?: EventHandler;
|
onInput?: EventHandler;
|
||||||
onClick?: EventHandler;
|
onClick?: EventHandler;
|
||||||
onPress?: EventHandler;
|
onPress?: EventHandler;
|
||||||
onCancel?: EventHandler;
|
onCancel?: EventHandler;
|
||||||
|
onOpened?: EventHandler;
|
||||||
onClosed?: EventHandler;
|
onClosed?: EventHandler;
|
||||||
onChange?: EventHandler;
|
onChange?: EventHandler;
|
||||||
onSubmit?: EventHandler;
|
onSubmit?: EventHandler;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user