hongluan-ui
Version:
Hongluan Component Library for Vue 3
1 lines • 12.9 kB
Source Map (JSON)
{"version":3,"file":"dropdown.mjs","sources":["../../../../../../packages/components/dropdown/src/dropdown.vue"],"sourcesContent":["<template>\n <div :class=\"[namespace + '-dropdown', disabled ? 'is-disabled' : '']\">\n <hl-tooltip\n ref=\"popperRef\"\n :role=\"role\"\n :effect=\"effect\"\n :offset=\"popperOffset\"\n :fallback-placements=\"['bottom', 'top']\"\n :popper-options=\"popperOptions\"\n :gpu-acceleration=\"false\"\n :hide-after=\"trigger === 'hover' ? hideTimeout : 0\"\n :manual-mode=\"true\"\n :placement=\"placement\"\n :popper-class=\"[`${namespace}-dropdown-popper`, popperClass]\"\n :reference-element=\"referenceElementRef?.$el\"\n :trigger=\"trigger\"\n :trigger-keys=\"triggerKeys\"\n :trigger-target-el=\"contentRef\"\n :show-after=\"trigger === 'hover' ? showTimeout : 0\"\n :stop-popper-mouse-event=\"false\"\n :virtual-ref=\"triggeringElementRef\"\n :virtual-triggering=\"!!split\"\n :disabled=\"disabled\"\n :teleported=\"compatTeleported\"\n transition=\"dropdown\"\n :show-arrow=\"false\"\n persistent\n @before-show=\"handleBeforeShowTooltip\"\n @show=\"handleShowTooltip\"\n @before-hide=\"handleBeforeHideTooltip\"\n >\n <template #content>\n <hl-scrollbar ref=\"scrollbar\" :wrap-style=\"wrapStyle\" tag=\"div\" view-class=\"dropdown-list\">\n <hl-roving-focus-group\n :loop=\"loop\"\n :current-tab-id=\"currentTabId\"\n orientation=\"horizontal\"\n @current-tab-id-change=\"handleCurrentTabIdChange\"\n @entry-focus=\"handleEntryFocus\"\n >\n <hl-dropdown-collection>\n <slot name=\"dropdown\"></slot>\n </hl-dropdown-collection>\n </hl-roving-focus-group>\n </hl-scrollbar>\n </template>\n <template v-if=\"!split\" #default>\n <hl-only-child\n :id=\"triggerId\"\n ref=\"triggeringElementRef\"\n role=\"button\"\n :tabindex=\"tabindex\"\n >\n <slot name=\"default\"></slot>\n </hl-only-child>\n </template>\n </hl-tooltip>\n <template v-if=\"split\">\n <hl-group :class=\"dropdownTriggerKls\" class=\"dropdown-button\">\n <template v-if=\"split === 'button'\">\n <hl-button\n ref=\"referenceElementRef\"\n v-bind=\"buttonProps\"\n :size=\"dropdownSize\"\n :type=\"type\"\n :disabled=\"disabled\"\n :tabindex=\"tabindex\"\n @click=\"handlerMainButtonClick\"\n >\n <slot name=\"default\"></slot>\n </hl-button>\n <hl-button\n :id=\"triggerId\"\n ref=\"triggeringElementRef\"\n v-bind=\"buttonProps\"\n role=\"button\"\n class=\"caret-button\"\n :class=\"type ? 'is-active' : ''\"\n :size=\"dropdownSize\"\n :type=\"type\"\n :disabled=\"disabled\"\n :tabindex=\"tabindex\"\n :aria-label=\"t('hl.dropdown.toggleDropdown')\"\n equal\n >\n <span class=\"caret\"></span>\n </hl-button>\n </template>\n <template v-else-if=\"split === 'link'\">\n <span\n ref=\"referenceElementRef\"\n :class=\"['text-' + type, dropdownSize, disabled ? 'is-disabled' : '']\"\n style=\"cursor:pointer;\"\n @click=\"() => !disabled && handlerMainButtonClick()\"\n >\n <slot name=\"default\"></slot>\n </span>\n <span\n ref=\"triggeringElementRef\"\n :class=\"['text-' + type, dropdownSize, disabled ? 'is-disabled' : '', 'caret']\"\n style=\"cursor:pointer;\"\n ></span>\n </template>\n </hl-group>\n </template>\n </div>\n</template>\n<script lang=\"ts\">\nimport {\n computed,\n onBeforeUnmount,\n defineComponent,\n getCurrentInstance,\n provide,\n ref,\n toRef,\n unref,\n watch,\n} from 'vue'\nimport HlButton from '@hongluan-ui/components/button'\nimport HlTooltip from '@hongluan-ui/components/tooltip'\nimport HlGroup from '@hongluan-ui/components/group'\nimport HlScrollbar from '@hongluan-ui/components/scrollbar'\nimport HlRovingFocusGroup from '@hongluan-ui/components/roving-focus-group'\nimport { HlOnlyChild } from '@hongluan-ui/components/slot'\nimport { useDeprecateAppendToBody } from '@hongluan-ui/components/popper'\nimport { addUnit, ensureArray } from '@hongluan-ui/utils'\nimport { EVENT_CODE } from '@hongluan-ui/constants'\nimport { useNamespace, useConsistentProp, useLocale, useId } from '@hongluan-ui/hooks'\nimport { HlCollection as HlDropdownCollection, dropdownProps } from './dropdown'\nimport { DROPDOWN_INJECTION_KEY } from './tokens'\n\nimport type { CSSProperties } from 'vue'\n\nexport default defineComponent({\n name: 'Dropdown',\n components: {\n HlButton,\n HlGroup,\n HlScrollbar,\n HlOnlyChild,\n HlDropdownCollection,\n HlTooltip,\n HlRovingFocusGroup,\n },\n props: dropdownProps,\n emits: ['visible-change', 'click', 'command'],\n setup(props, { emit }) {\n const _instance = getCurrentInstance()\n const { namespace } = useNamespace()\n const { t } = useLocale()\n\n const triggeringElementRef = ref()\n const referenceElementRef = ref()\n const popperRef = ref<InstanceType<typeof HlTooltip> | null>(null)\n const contentRef = ref<HTMLElement | null>(null)\n const scrollbar = ref(null)\n const currentTabId = ref<string | null>(null)\n const isUsingKeyboard = ref(false)\n const triggerKeys = [EVENT_CODE.enter, EVENT_CODE.space, EVENT_CODE.down]\n\n const { compatTeleported } = useDeprecateAppendToBody(\n 'Dropdown',\n 'popperAppendToBody',\n )\n const wrapStyle = computed<CSSProperties>(() => ({\n maxHeight: addUnit(props.maxHeight),\n }))\n const dropdownTriggerKls = computed(() => [dropdownSize.value])\n const trigger = computed(() => ensureArray(props.trigger))\n\n\n const defaultTriggerId = useId().value\n const triggerId = computed<string>(() => props.id || defaultTriggerId)\n\n // The goal of this code is to focus on the tooltip triggering element when it is hovered.\n // This is a temporary fix for where closing the dropdown through pointerleave event focuses on a\n // completely different element. For a permanent solution, remove all calls to any \"element.focus()\"\n // that are triggered through pointer enter/leave events.\n watch(\n [triggeringElementRef, trigger],\n ([triggeringElement, trigger], [prevTriggeringElement]) => {\n if (prevTriggeringElement?.$el?.removeEventListener) {\n prevTriggeringElement.$el.removeEventListener(\n 'pointerenter',\n onAutofocusTriggerEnter,\n )\n }\n if (triggeringElement?.$el?.removeEventListener) {\n triggeringElement.$el.removeEventListener(\n 'pointerenter',\n onAutofocusTriggerEnter,\n )\n }\n if (\n triggeringElement?.$el?.addEventListener &&\n trigger.includes('hover')\n ) {\n triggeringElement.$el.addEventListener(\n 'pointerenter',\n onAutofocusTriggerEnter,\n )\n }\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n if (triggeringElementRef.value?.$el?.removeEventListener) {\n triggeringElementRef.value.$el.removeEventListener(\n 'pointerenter',\n onAutofocusTriggerEnter,\n )\n }\n })\n\n function handleClick() {\n handleClose()\n }\n\n function handleClose() {\n popperRef.value?.onClose()\n }\n\n function handleOpen() {\n popperRef.value?.onOpen()\n }\n\n const { size: dropdownSize } = useConsistentProp()\n\n function commandHandler(...args: any[]) {\n emit('command', ...args)\n }\n\n function onAutofocusTriggerEnter() {\n triggeringElementRef.value?.$el?.focus()\n }\n\n function onItemEnter() {\n // NOOP for now\n }\n\n function onItemLeave() {\n const contentEl = unref(contentRef)\n\n trigger.value.includes('hover') && contentEl?.focus()\n currentTabId.value = null\n }\n\n function handleCurrentTabIdChange(id: string) {\n currentTabId.value = id\n }\n\n function handleEntryFocus(e: Event) {\n if (!isUsingKeyboard.value) {\n e.preventDefault()\n e.stopImmediatePropagation()\n }\n }\n\n function handleBeforeShowTooltip() {\n emit('visible-change', true)\n }\n function handleShowTooltip(event?: Event) {\n if (event?.type === 'keydown') {\n contentRef.value.focus()\n }\n }\n function handleBeforeHideTooltip() {\n emit('visible-change', false)\n }\n\n provide(DROPDOWN_INJECTION_KEY, {\n contentRef,\n role: computed(() => props.role),\n triggerId,\n isUsingKeyboard,\n onItemEnter,\n onItemLeave,\n })\n\n provide('hlDropdown', {\n instance: _instance,\n dropdownSize,\n handleClick,\n commandHandler,\n trigger: toRef(props, 'trigger'),\n hideOnClick: toRef(props, 'hideOnClick'),\n })\n\n const onFocusAfterTrapped = (e: Event) => {\n e.preventDefault()\n contentRef.value?.focus?.({\n preventScroll: true,\n })\n }\n\n const handlerMainButtonClick = (event: MouseEvent) => {\n emit('click', event)\n }\n\n return {\n t,\n namespace,\n scrollbar,\n wrapStyle,\n dropdownTriggerKls,\n dropdownSize,\n triggerId,\n triggerKeys,\n currentTabId,\n compatTeleported,\n handleCurrentTabIdChange,\n handlerMainButtonClick,\n handleEntryFocus,\n handleClose,\n handleOpen,\n handleBeforeShowTooltip,\n handleShowTooltip,\n handleBeforeHideTooltip,\n onFocusAfterTrapped,\n popperRef,\n contentRef,\n triggeringElementRef,\n referenceElementRef,\n }\n },\n})\n</script>\n"],"names":["HlOnlyChild","HlDropdownCollection","ensureArray","_openBlock"],"mappings":"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"}