Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(components): [popover] switch to script-setup syntax #8273

Merged
merged 1 commit into from Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/components/popover/__tests__/directive.test.ts
Expand Up @@ -2,7 +2,7 @@ import { nextTick, ref } from 'vue'
import { afterEach, describe, expect, test } from 'vitest'
import makeMount from '@element-plus/test-utils/make-mount'
import { rAF } from '@element-plus/test-utils/tick'
import Popover from '../src/index.vue'
import Popover from '../src/popover.vue'
import PopoverDirective, { VPopover } from '../src/directive'

const AXIOM = 'Rem is the best girl'
Expand Down
2 changes: 1 addition & 1 deletion packages/components/popover/__tests__/popover.test.ts
Expand Up @@ -4,7 +4,7 @@ import { POPPER_CONTAINER_SELECTOR, useZIndex } from '@element-plus/hooks'
import makeMount from '@element-plus/test-utils/make-mount'
import { rAF } from '@element-plus/test-utils/tick'
import { ElPopperTrigger } from '@element-plus/components/popper'
import Popover from '../src/index.vue'
import Popover from '../src/popover.vue'

const AXIOM = 'Rem is the best girl'

Expand Down
36 changes: 12 additions & 24 deletions packages/components/popover/index.ts
@@ -1,28 +1,16 @@
import Popover from './src/index.vue'
import PopoverDirective, { VPopover } from './src/directive'

import type { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils'
import { withInstall, withInstallDirective } from '@element-plus/utils'

Popover.install = (app: App): void => {
app.component(Popover.name, Popover)
}
;(PopoverDirective as SFCWithInstall<typeof PopoverDirective>).install = (
app: App
) => {
app.directive(VPopover, PopoverDirective)
}

const _PopoverDirective = PopoverDirective as SFCWithInstall<
typeof PopoverDirective
>
import Popover from './src/popover.vue'
import PopoverDirective, { VPopover } from './src/directive'

Popover.directive = _PopoverDirective
export const ElPopoverDirective = withInstallDirective(
PopoverDirective,
VPopover
)

const _Popover = Popover as any as SFCWithInstall<typeof Popover> & {
directive: typeof _PopoverDirective
}
export const ElPopover = withInstall(Popover, {
directive: ElPopoverDirective,
})
export default ElPopover

export default _Popover
export const ElPopover = _Popover
export const ElPopoverDirective = _PopoverDirective
export * from './src/popover'
5 changes: 2 additions & 3 deletions packages/components/popover/src/directive.ts
@@ -1,9 +1,8 @@
import type ElPopover from './index.vue'
import type { DirectiveBinding, ObjectDirective } from 'vue'
import type { PopoverInstance } from './popover'

const attachEvents = (el: HTMLElement, binding: DirectiveBinding) => {
const popperComponent: InstanceType<typeof ElPopover> =
binding.arg || binding.value
const popperComponent: PopoverInstance = binding.arg || binding.value
const popover = popperComponent?.popperRef
if (popover) {
popover.triggerRef = el
Expand Down
136 changes: 0 additions & 136 deletions packages/components/popover/src/index.vue

This file was deleted.

18 changes: 16 additions & 2 deletions packages/components/popover/src/popover.ts
@@ -1,11 +1,13 @@
import { buildProps } from '@element-plus/utils'
import { buildProps, isBoolean } from '@element-plus/utils'
import {
useTooltipContentProps,
useTooltipTriggerProps,
} from '@element-plus/components/tooltip'
import { dropdownProps } from '@element-plus/components/dropdown'
import type { ExtractPropTypes } from 'vue'
import type Popover from './popover.vue'

export const usePopoverProps = buildProps({
export const popoverProps = buildProps({
trigger: useTooltipTriggerProps.trigger,
placement: dropdownProps.placement,
disabled: useTooltipTriggerProps.disabled,
Expand Down Expand Up @@ -56,3 +58,15 @@ export const usePopoverProps = buildProps({
default: true,
},
} as const)
export type PopoverProps = ExtractPropTypes<typeof popoverProps>

export const popoverEmits = {
'update:visible': (value: boolean) => isBoolean(value),
'before-enter': () => true,
'before-leave': () => true,
'after-enter': () => true,
'after-leave': () => true,
}
export type PopoverEmits = typeof popoverEmits

export type PopoverInstance = InstanceType<typeof Popover>
109 changes: 109 additions & 0 deletions packages/components/popover/src/popover.vue
@@ -0,0 +1,109 @@
<template>
<el-tooltip
ref="tooltipRef"
v-bind="$attrs"
:trigger="trigger"
:placement="placement"
:disabled="disabled"
:visible="visible"
:transition="transition"
:popper-options="popperOptions"
:tabindex="tabindex"
:content="content"
:offset="offset"
:show-after="showAfter"
:hide-after="hideAfter"
:auto-close="autoClose"
:show-arrow="showArrow"
:aria-label="title"
:effect="effect"
:enterable="enterable"
:popper-class="kls"
:popper-style="style"
:teleported="teleported"
:persistent="persistent"
:gpu-acceleration="gpuAcceleration"
@before-show="beforeEnter"
@before-hide="beforeLeave"
@show="afterEnter"
@hide="afterLeave"
>
<template v-if="$slots.reference">
<slot name="reference" />
</template>

<template #content>
<div v-if="title" :class="ns.e('title')" role="title">
{{ title }}
</div>
<slot>
{{ content }}
</slot>
</template>
</el-tooltip>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue'
import { ElTooltip } from '@element-plus/components/tooltip'
import { addUnit } from '@element-plus/utils'
import { useNamespace } from '@element-plus/hooks'
import { popoverEmits, popoverProps } from './popover'
import type { TooltipInstance } from '@element-plus/components/tooltip'

defineOptions({
name: 'ElPopover',
})

const props = defineProps(popoverProps)
const emit = defineEmits(popoverEmits)

const ns = useNamespace('popover')
const tooltipRef = ref<TooltipInstance>()
const popperRef = computed(() => {
return unref(tooltipRef)?.popperRef
})

const style = computed(() => {
return [
{
width: addUnit(props.width),
},
props.popperStyle!,
]
})

const kls = computed(() => {
return [ns.b(), props.popperClass!, { [ns.m('plain')]: !!props.content }]
})

const gpuAcceleration = computed(() => {
return props.transition === 'el-fade-in-linear'
})

const hide = () => {
tooltipRef.value?.hide()
}

const beforeEnter = () => {
emit('before-enter')
}
const beforeLeave = () => {
emit('before-leave')
}

const afterEnter = () => {
emit('after-enter')
}

const afterLeave = () => {
emit('update:visible', false)
emit('after-leave')
}

defineExpose({
/** @description popper ref */
popperRef,
/** @description hide popover */
hide,
})
</script>
8 changes: 8 additions & 0 deletions packages/utils/vue/install.ts
Expand Up @@ -30,6 +30,14 @@ export const withInstallFunction = <T>(fn: T, name: string) => {
return fn as SFCInstallWithContext<T>
}

export const withInstallDirective = <T>(directive: T, name: string) => {
;(directive as SFCWithInstall<T>).install = (app: App): void => {
app.directive(name, directive)
}

return directive as SFCWithInstall<T>
}

export const withNoopInstall = <T>(component: T) => {
;(component as SFCWithInstall<T>).install = NOOP

Expand Down