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

[cdk: overlay] add cdk overlay #113

Closed
1 task done
LaamGinghong opened this issue Jan 5, 2021 · 7 comments · Fixed by #176 or #178
Closed
1 task done

[cdk: overlay] add cdk overlay #113

LaamGinghong opened this issue Jan 5, 2021 · 7 comments · Fixed by #176 or #178
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@LaamGinghong
Copy link
Contributor

LaamGinghong commented Jan 5, 2021

[cdk: overlay] add cdk overlay

  • I have searched the issues of this repository and believe that this is not a duplicate.

对外暴露一个函数,允许调用方调用函数来创建一个浮层,且允许调用方还合适的范围内对浮层进行自定义。

特性

  • 通过函数可以创建浮层并返回该浮层对应的实例;

  • 调用方可以通过函数返回的浮层实例,对视图进行绑定;

  • 调用方可以通过返回的实例,控制浮层的初始化、显示、隐藏和销毁;

  • 浮层的滚动策略有四种:

    • close :滚动时自动关闭浮层;
    • reposition :默认行为,滚动时重新定位。
  • 浮层定位依赖于 @popperjs/core

  • cdk会对外抛出以下事件,需要调用方在使用时将事件绑定到视图上,使得cdk可以对浮层行为进行控制:

    • OverlayTriggerEvents
      • onClick
      • onMouseEnter
      • onMouseLeave
      • onFocus
      • onBlur
    • OverlayPopperEvents
      • onMouseEnter
      • onMouseLeave

    注意:Trigger返回的事件与调用方传入 trigger 的值相关。

API

overlay

import type { Options, Placement } from '@popperjs/core'
import type { ComponentPublicInstance, ComputedRef, Ref } from 'vue'

declare type Nullable<T> = T | null

type OverlayScrollStrategy = 'close' | 'reposition'
type OverlayTrigger = 'click' | 'hover' | 'focus'
type RefElement = Nullable<HTMLElement>
type VueElement = Nullable<ComponentPublicInstance | HTMLElement>

interface OverlayTriggerEvents {
  onClick?: (event: Event) => void
  onMouseEnter?: (event: Event) => void
  onMouseLeave?: (event: Event) => void
  onFocus?: (event: Event) => void
  onBlur?: (event: Event) => void
}

interface OverlayPopperEvents {
  onMouseEnter: () => void
  onMouseLeave: () => void
}

interface OverlayOptions {
  /* The class name of the overlay container. */
  className?: string
  /**
   * Control the visibility of the overlay
   */
  visible?: boolean
  /* Scroll strategy for overlay */
  scrollStrategy: OverlayScrollStrategy
  /* Disable the overlay */
  disable?: boolean
  /**
   * The distance between the arrow and the starting point at both ends.
   *Acting when the overlay uses border-radius.
   */
  arrowOffset?: number
  /* Whether to show arrow. */
  showArrow?: boolean
  /* Alignment of floating layer. */
  placement: Placement
  /**
   * The options of popper.
   * Used when ConnectOverlayOptions cannot meet the demand.
   * Priority is higher than ConnectOverlayOptions.
   */
  popperOptions?: Partial<Options>
  /* Trigger method. */
  trigger: OverlayTrigger
  /* Whether to allow the mouse to enter the overlay. */
  allowEnter?: boolean
  /**
   * Overlay offset.
   * [Horizontal axis offset, vertical axis offset]
   */
  offset: [number, number]
  /**
   * The delay of hiding overlay.
   * Send false if you don't need it.
   */
  hideDelay: number | false
  /**
   * The delay of showing overlay.
   * Send false if you don't need it.
   */
  showDelay: number | false
}

interface OverlayInstance {
  /**
   * Initialize the overlay.
   * The life cycle of the overlay will enter mounted.
   */
  initialize: () => void
  /**
   * Show the overlay.
   * The style of the overlay container will be set to block.
   */
  show: () => void
  /**
   * Hide the overlay.
   * The style of the overlay container will be set to none.
   */
  hide: () => void
  /**
   * Destroy the overlay.
   * The life cycle of the overlay will enter beforeDestroy.
   * To show the overlay again, please recreate.
   */
  destroy: () => void
  /**
   * TODO
   * The unique id of the overlay.
   * Provide subsequent components with markings for the specified overlay treatment.
   */
  overlayId: string
  /**
   * The display status of the current overlay.
   * Control by visible and disable.
   */
  visibility: ComputedRef<boolean>
  /**
   * The truth DOM node of the overlay.
   * The caller needs to bind the variable to the view.
   */
  overlayRef: Ref<RefElement>
  /**
   * Update overlay.
   * If the overlay has not been initialized, the overlay will be initialized first, otherwise the overlay will be update directly.
   * @param options
   */
  update: (options: Partial<OverlayOptions>) => void
 /**
   * The truth DOM node of the arrow.
   * If showArrow is false, we won't return arrowRef.
   * The caller needs to bind the variable to the view.
   */
  arrowRef?: Ref<RefElement>
  /**
   * The truth DOM node of the trigger.
   * The caller needs to bind the variable to the view.
   */
  triggerRef: Ref<VueElement>
  /**
   * Manually bind to the event on the trigger.
   */
  triggerEvents: OverlayTriggerEvents
  /**
   * Manually bind to events on the overlay.
   */
  overlayEvents: OverlayPopperEvents
}

Portal

Props

名称 说明 类型 备注
disable 禁止传送 boolean
target 传送位置 HTMLElement | string 传入类型是字符串时,会首先判断body下是否存在以该字符串为class name的元素,如果存在会直接使用该元素,否则会创建对应的元素作为容器。

Slots

名称 说明 备注
default 需要被传送的内容 -

DEMO

<template>
  <ix-button ref="triggerRef" @click="triggerEvents.onClick">Click</ix-button>
  <teleport to="body">
    <div ref="overlayRef" @mouseenter="overlayEvents.onMouseEnter()" @mouseleave="overlayEvents.onMouseLeave()">
      tooltip
    </div>
  </teleport>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import { useOverlay } from '@idux/cdk/overlay'

export default defineComponent({
  name: 'Basic',
  setup() {
    const { initialize, overlayRef, triggerRef, triggerEvents, overlayEvents } = useOverlay({
      visible: false,
      trigger: 'click',
      placement: 'bottom',
      offset: [0, 0],
      showDelay: false,
      hideDelay: 1000,
      allowEnter: true,
    })
    onMounted(initialize)

    return { overlayRef, triggerRef, triggerEvents, overlayEvents }
  },
})
</script>
@LaamGinghong LaamGinghong added the enhancement New feature or request label Jan 5, 2021
@danranVm danranVm added this to the v1.0.0 milestone Jan 5, 2021
@danranVm
Copy link
Member

danranVm commented Jan 5, 2021

@coolyuantao @danranVm 负责此组件的 review, API 设计完成后请 @ 他们

@danranVm danranVm mentioned this issue Jan 5, 2021
95 tasks
@LaamGinghong
Copy link
Contributor Author

@coolyuantao @danranVm 请review API

@coolyuantao
Copy link
Member

coolyuantao commented Jan 19, 2021

@danranVm 讨论后一些结论,一起看下吧

  1. popperRef, arrowRef, triggerRef 这三个现在不清楚怎么用
  2. popperInstance 这个实例建议不要给用户了,理论上封装好后,这个是不需要用户知道的
  3. visibility 这个readonly吧
  4. overlayId 这个可以不给用户
  5. arrowOffset 这个应该是离自身浮动层的偏移吧?而不是 trigger 的才对吧
  6. class -> className
  7. offset 这个是相对trigger的偏移,建议支持[x, y]的形式
  8. gpuAcceleration 这个就不用了吧,全部使用 transform 有何不可

@LaamGinghong
Copy link
Contributor Author

@danranVm @coolyuantao 请重新Review API

@coolyuantao
Copy link
Member

  1. 那个浮层里又有浮层的,要不要放CDK里管理?
  2. arrowRef 这个放在内部管理,用户可以不管这个,showArrow 已经可以控制这个了

@coolyuantao
Copy link
Member

还有另外一个需求: show, hide 需要支持动画,比如渐变消失等

LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Jan 30, 2021
@LaamGinghong
Copy link
Contributor Author

@coolyuantao @danranVm 请重新review API

LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Jan 30, 2021
LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Jan 31, 2021
LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Feb 4, 2021
LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Feb 5, 2021
LaamGinghong added a commit to LaamGinghong/idux that referenced this issue Feb 5, 2021
danranVm pushed a commit that referenced this issue Feb 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
3 participants