styles(drawer): [drawer] add drawer types (#1318)

This commit is contained in:
jxhhdx 2024-01-24 12:19:28 +08:00 committed by GitHub
parent 301de64902
commit fc10ea4cf6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 134 additions and 85 deletions

View File

@ -1,15 +1,16 @@
import debounce from '../common/deps/debounce' import debounce from '../common/deps/debounce'
import { addClass, removeClass } from '../common/deps/dom' import { addClass, removeClass } from '../common/deps/dom'
import type { IDrawerState, IDrawerProps, IDrawerApi, IDrawerCT, ISharedRenderlessParamUtils } from '@/types'
export const close = export const close =
({ emit, state }) => ({ emit, state }: { emit: ISharedRenderlessParamUtils['emit']; state: IDrawerState }) =>
() => { () => {
state.toggle = false state.toggle = false
emit('close', state) emit('close', state)
} }
export const watchVisible = export const watchVisible =
({ state }) => ({ state }: { state: IDrawerState }) =>
(bool) => { (bool) => {
setTimeout(() => { setTimeout(() => {
state.toggle = bool state.toggle = bool
@ -17,22 +18,22 @@ export const watchVisible =
} }
export const watchToggle = export const watchToggle =
({ emit }) => ({ emit }: { emit: ISharedRenderlessParamUtils['emit'] }) =>
(bool) => { (bool: boolean) => {
setTimeout(() => { setTimeout(() => {
emit('update:visible', bool) emit('update:visible', bool)
}, 0) }, 0)
} }
export const confirm = export const confirm =
({ emit, state }) => ({ emit, state }: { emit: ISharedRenderlessParamUtils['emit']; state: IDrawerState }) =>
() => { () => {
state.toggle = false state.toggle = false
emit('confirm', state) emit('confirm', state)
} }
export const mousedown = export const mousedown =
({ state, vm }) => ({ state, vm }: { vm: ISharedRenderlessParamUtils<IDrawerCT>['vm']; state: IDrawerState }) =>
(event) => { (event) => {
event.preventDefault() event.preventDefault()
@ -44,7 +45,7 @@ export const mousedown =
state.dragEvent.offsetWidth = drawerBox.offsetWidth state.dragEvent.offsetWidth = drawerBox.offsetWidth
} }
export const mousemove = ({ state, props }) => export const mousemove = ({ state, props }: { state: IDrawerState; props: IDrawerProps }) =>
debounce(1, (event) => { debounce(1, (event) => {
if (!state.dragEvent.isDrag) { if (!state.dragEvent.isDrag) {
return return
@ -67,21 +68,21 @@ export const mousemove = ({ state, props }) =>
} else if (placement === 'right') { } else if (placement === 'right') {
state.width = offsetWidth - offsetX state.width = offsetWidth - offsetX
} }
}) }) as Parameters<Document['removeEventListener']>['1']
export const mouseup = export const mouseup =
({ state }) => ({ state }: { state: IDrawerState }) =>
() => { () => {
if (!state.dragEvent.isDrag) { if (!state.dragEvent.isDrag) {
return return
} }
event.preventDefault() ;(event as any).preventDefault()
state.dragEvent.isDrag = false state.dragEvent.isDrag = false
} }
export const addDragEvent = export const addDragEvent =
({ api, vm }) => ({ api, vm }: { api: IDrawerApi; vm: ISharedRenderlessParamUtils<IDrawerCT>['vm'] }) =>
() => { () => {
const el = vm.$refs.dragBar const el = vm.$refs.dragBar
@ -95,7 +96,7 @@ export const addDragEvent =
} }
export const removeDragEvent = export const removeDragEvent =
({ api, vm }) => ({ api, vm }: { api: IDrawerApi; vm: ISharedRenderlessParamUtils<IDrawerCT>['vm'] }) =>
() => { () => {
const el = vm.$refs.dragBar const el = vm.$refs.dragBar
@ -117,8 +118,8 @@ export const hideScrollbar = (lockScrollClass) => () => {
} }
export const watchVisibleNotImmediate = export const watchVisibleNotImmediate =
({ api, props }) => ({ api, props }: { api: IDrawerApi; props: IDrawerProps }) =>
(visible) => { (visible: boolean) => {
if (props.lockScroll) { if (props.lockScroll) {
visible ? api.showScrollbar() : api.hideScrollbar() visible ? api.showScrollbar() : api.hideScrollbar()
} }

View File

@ -12,18 +12,26 @@ import {
hideScrollbar, hideScrollbar,
watchVisibleNotImmediate watchVisibleNotImmediate
} from './index' } from './index'
import type {
IDrawerProps,
IDrawerState,
IDrawerApi,
ISharedRenderlessParamUtils,
ISharedRenderlessFunctionParams,
IDrawerCT
} from '@/types'
export const api = ['state', 'close', 'confirm'] export const api = ['state', 'close', 'confirm']
export const renderless = ( export const renderless = (
props, props: IDrawerProps,
{ reactive, watch, onMounted, onBeforeUnmount, computed }, { reactive, watch, onMounted, onBeforeUnmount, computed }: ISharedRenderlessFunctionParams<null>,
{ emit, vm, mode, constants } { emit, vm, mode, constants }: ISharedRenderlessParamUtils<IDrawerCT>
) => { ) => {
const lockScrollClass = constants.SCROLL_LOCK_CLASS(mode) const lockScrollClass = constants.SCROLL_LOCK_CLASS(mode)
const api = {} const api: Partial<IDrawerApi> = {}
const state = reactive({ const state = reactive<IDrawerState>({
toggle: false, toggle: false,
width: 0, width: 0,
dragEvent: { x: 0, isDrag: false, offsetWidth: 0 }, dragEvent: { x: 0, isDrag: false, offsetWidth: 0 },
@ -37,29 +45,29 @@ export const renderless = (
mousedown: mousedown({ state, vm }), mousedown: mousedown({ state, vm }),
mousemove: mousemove({ state, props }), mousemove: mousemove({ state, props }),
mouseup: mouseup({ state }), mouseup: mouseup({ state }),
addDragEvent: addDragEvent({ api, vm }), addDragEvent: addDragEvent({ api: api as IDrawerApi, vm }),
removeDragEvent: removeDragEvent({ api, vm }), removeDragEvent: removeDragEvent({ api: api as IDrawerApi, vm }),
watchVisible: watchVisible({ state }), watchVisible: watchVisible({ state }),
watchToggle: watchToggle({ emit }), watchToggle: watchToggle({ emit }),
showScrollbar: showScrollbar(lockScrollClass), showScrollbar: showScrollbar(lockScrollClass),
hideScrollbar: hideScrollbar(lockScrollClass), hideScrollbar: hideScrollbar(lockScrollClass),
watchVisibleNotImmediate: watchVisibleNotImmediate({ api, props }) watchVisibleNotImmediate: watchVisibleNotImmediate({ api: api as IDrawerApi, props })
}) })
onMounted(() => { onMounted(() => {
props.dragable && api.addDragEvent() props.dragable && (api as IDrawerApi).addDragEvent()
if (props.lockScroll && props.visible) { if (props.lockScroll && props.visible) {
api.showScrollbar() ;(api as IDrawerApi).showScrollbar()
} }
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
props.dragable && api.removeDragEvent() props.dragable && (api as IDrawerApi).removeDragEvent()
props.lockScroll && api.hideScrollbar() props.lockScroll && (api as IDrawerApi).hideScrollbar()
}) })
watch(() => props.visible, api.watchVisible, { immediate: true }) watch(() => props.visible, (api as IDrawerApi).watchVisible, { immediate: true })
watch(() => state.toggle, api.watchToggle) watch(() => state.toggle, (api as IDrawerApi).watchToggle)
watch( watch(
() => props.width, () => props.width,
() => (state.width = 0) () => (state.width = 0)

View File

@ -0,0 +1,40 @@
import type { ExtractPropTypes, ComputedRef } from 'vue'
import type { drawerProps } from '@/drawer/src'
import type {
close,
watchVisible,
watchToggle,
confirm,
mousedown,
mouseup,
mousemove,
addDragEvent,
removeDragEvent,
showScrollbar,
hideScrollbar,
watchVisibleNotImmediate
} from '../src/drawer'
export interface IDrawerState {
toggle: boolean
width: number
dragEvent: { x: number; isDrag: boolean; offsetWidth: number }
computedWidth: ComputedRef<string>
}
export type IDrawerProps = ExtractPropTypes<typeof drawerProps>
export interface IDrawerApi {
state: IDrawerState
confirm: ReturnType<typeof confirm>
close: ReturnType<typeof close>
mousemove: ReturnType<typeof mousemove>
mouseup: ReturnType<typeof mouseup>
mousedown: ReturnType<typeof mousedown>
addDragEvent: ReturnType<typeof addDragEvent>
removeDragEvent: ReturnType<typeof removeDragEvent>
watchVisible: ReturnType<typeof watchVisible>
watchToggle: ReturnType<typeof watchToggle>
showScrollbar: ReturnType<typeof showScrollbar>
hideScrollbar: ReturnType<typeof hideScrollbar>
watchVisibleNotImmediate: ReturnType<typeof watchVisibleNotImmediate>
}
export type IDrawerCT = ReturnType<typeof drawerProps._constants.default>

View File

@ -2,70 +2,70 @@ import { $props, $prefix, $setup } from '@opentiny/vue-common'
import template from 'virtual-template?pc|mobile-first' import template from 'virtual-template?pc|mobile-first'
const $constants = { const $constants = {
SCROLL_LOCK_CLASS(mode) { SCROLL_LOCK_CLASS(mode: string) {
const scrollLockClasses = { const scrollLockClasses = {
'mobile-first': 'overflow-hidden' 'mobile-first': 'overflow-hidden'
} }
return scrollLockClasses[mode] || '' return (scrollLockClasses[mode] || '') as string
}
}
export const drawerProps = {
...$props,
_constants: {
type: Object,
default: () => $constants
},
visible: {
type: Boolean,
default: false
},
customClass: [String, Object, Array],
placement: {
type: String,
default: 'right'
},
width: {
type: String,
default: '500px'
},
title: String,
showClose: {
type: Boolean,
default: true
},
showHeader: {
type: Boolean,
default: true
},
showFooter: {
type: Boolean,
default: false
},
mask: {
type: Boolean,
default: true
},
maskClosable: {
type: Boolean,
default: true
},
dragable: Boolean,
lockScroll: {
type: Boolean,
default: true
},
flex: {
type: Boolean,
default: false
},
zIndex: {
type: Number,
default: 2000
} }
} }
export default { export default {
name: $prefix + 'Drawer', name: $prefix + 'Drawer',
props: { props: drawerProps,
...$props,
_constants: {
type: Object,
default: () => $constants
},
visible: {
type: Boolean,
default: false
},
customClass: [String, Object, Array],
placement: {
type: String,
default: 'right'
},
width: {
type: String,
default: '500px'
},
title: String,
showClose: {
type: Boolean,
default: true
},
showHeader: {
type: Boolean,
default: true
},
showFooter: {
type: Boolean,
default: false
},
mask: {
type: Boolean,
default: true
},
maskClosable: {
type: Boolean,
default: true
},
dragable: Boolean,
lockScroll: {
type: Boolean,
default: true
},
flex: {
type: Boolean,
default: false
},
zIndex: {
type: Number,
default: 2000
}
},
setup(props, context) { setup(props, context) {
return $setup({ props, context, template }) return $setup({ props, context, template })
} }