* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { guid } from '@opentiny/utils'
import type {
IDropdownState,
IDropdownApi,
IDropdownProps,
IDropdownRenderlessParamUtils,
ISharedRenderlessParamHooks
} from '@/types'
import {
watchVisible,
watchFocusing,
show,
hide,
handleClick,
handleTriggerKeyDown,
handleItemKeyDown,
resetTabindex,
removeTabindex,
initAria,
initEvent,
handleMenuItemClick,
handleMainButtonClick,
triggerElmFocus,
initDomOperation,
mounted,
beforeDistory,
clickOutside,
toggleFocus
} from './index'
export const api = ['state', 'handleMainButtonClick', 'hide', 'show', 'initDomOperation', 'handleClick', 'clickOutside']
export const renderless = (
props: IDropdownProps,
{ reactive, watch, provide, onMounted, computed, onBeforeUnmount }: ISharedRenderlessParamHooks,
{ emit, parent, broadcast, vm, nextTick, mode, designConfig, useBreakpoint }: IDropdownRenderlessParamUtils
): IDropdownApi => {
const api = {} as IDropdownApi
const { current } = useBreakpoint()
const state: IDropdownState = reactive({
current,
visible: false,
timeout: null,
focusing: false,
menuItems: [],
menuItemsArray: [],
triggerElm: null,
dropdownElm: null,
listId: `dropdown-menu-${guid()}`,
showIcon: props.showIcon,
showSelfIcon: props.showSelfIcon,
designConfig,
trigger: computed(() => {
return props.trigger || designConfig?.props?.trigger || 'hover'
}),
visibleIsBoolean: computed(() => typeof props.visible === 'boolean')
})
provide('dropdownVm', vm)
Object.assign(api, {
state,
watchVisible: watchVisible({ broadcast, emit, nextTick }),
watchFocusing: watchFocusing(parent),
show: show({ props, state, emit }),
hide: hide({ api, props, state, emit }),
mounted: mounted({ api, vm, state, broadcast, props }),
handleClick: handleClick({ api, props, state, emit }),
handleTriggerKeyDown: handleTriggerKeyDown({ api, state }),
handleItemKeyDown: handleItemKeyDown({ api, props, state, emit }),
resetTabindex: resetTabindex(api),
removeTabindex: removeTabindex(state),
initAria: initAria({ state, props }),
initEvent: initEvent({ api, props, state, vm, mode }),
handleMenuItemClick: handleMenuItemClick({ props, state, emit }),
handleMainButtonClick: handleMainButtonClick({ api, emit }),
triggerElmFocus: triggerElmFocus(state),
initDomOperation: initDomOperation({ api, state, vm }),
beforeDistory: beforeDistory({ vm, api, state }),
clickOutside: clickOutside({ props, api }),
toggleFocusOnTrue: toggleFocus({ state, value: true }),
toggleFocusOnFalse: toggleFocus({ state, value: false })
})
if (typeof props.visible === 'boolean') {
watch(() => props.visible, api.watchVisible)
} else {
watch(() => state.visible, api.watchVisible)
}
watch(() => state.focusing, api.watchFocusing)
onMounted(api.mounted)
onBeforeUnmount(api.beforeDistory)
return api
}