-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cdk:popper): migrate popperjs to floating-ui (#1191)
BREAKING CHANGE: modifiers is now changed to middlewares BREAKING CHANGE: forceUpdate is now removed BREAKING CHANGE: onFirstUpdate is now removed
- Loading branch information
Showing
27 changed files
with
516 additions
and
322 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { PopperOptions } from '../types' | ||
|
||
import { type ComputedRef, computed } from 'vue' | ||
|
||
import { defaultDelay } from './useOptions' | ||
|
||
export function useDelay(options: Required<PopperOptions>): ComputedRef<{ show: number; hide: number }> { | ||
const convertDelay = (delay: number | [number | null, number | null]) => { | ||
if (Array.isArray(delay)) { | ||
const [show, hide] = delay | ||
return { show: show ?? defaultDelay, hide: hide ?? defaultDelay } | ||
} | ||
return { show: delay, hide: delay } | ||
} | ||
|
||
return computed(() => convertDelay(options.delay)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { PopperElement } from '../types' | ||
|
||
import { type Ref, watch } from 'vue' | ||
|
||
import { type ComputePositionConfig, type ComputePositionReturn, autoUpdate, computePosition } from '@floating-ui/dom' | ||
|
||
import { convertElement } from '@idux/cdk/utils' | ||
|
||
export interface Instance { | ||
update: () => Promise<void> | ||
destroy: () => void | ||
} | ||
|
||
export function useInstance( | ||
triggerRef: Ref<PopperElement | undefined>, | ||
popperRef: Ref<PopperElement | undefined>, | ||
options: Ref<ComputePositionConfig>, | ||
): Instance { | ||
const updatePopperPosition = (state: ComputePositionReturn) => { | ||
const popperEl = convertElement(popperRef.value) | ||
const { x, y, strategy } = state | ||
|
||
if (popperEl) { | ||
Object.assign(popperEl.style, { | ||
position: strategy, | ||
left: `${x}px`, | ||
top: `${y}px`, | ||
}) | ||
} | ||
} | ||
|
||
const update = async () => { | ||
const triggerEl = convertElement(triggerRef.value) | ||
const popperEl = convertElement(popperRef.value) | ||
|
||
if (!triggerEl || !popperEl) { | ||
return | ||
} | ||
|
||
const state = await computePosition(triggerEl, popperEl, options.value) | ||
state && updatePopperPosition(state) | ||
} | ||
|
||
let cleanUpHandler: (() => void) | null = null | ||
const initialize = () => { | ||
const triggerEl = convertElement(triggerRef.value) | ||
const popperEl = convertElement(popperRef.value) | ||
if (!triggerEl || !popperEl) { | ||
return | ||
} | ||
|
||
cleanUpHandler?.() | ||
|
||
Object.assign(popperEl.style, { | ||
position: 'absolute', | ||
left: 0, | ||
top: 0, | ||
}) | ||
|
||
cleanUpHandler = autoUpdate(triggerEl, popperEl, () => { | ||
update() | ||
}) | ||
} | ||
|
||
const watchStopHandlers = [ | ||
watch([triggerRef, popperRef], initialize, { immediate: true }), | ||
watch(options, update, { immediate: true }), | ||
] | ||
const destroy = () => { | ||
watchStopHandlers.forEach(handler => handler()) | ||
cleanUpHandler?.() | ||
} | ||
|
||
return { | ||
update, | ||
destroy, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { PopperOptions } from '../types' | ||
|
||
import { type ComputedRef, computed, reactive, watch } from 'vue' | ||
|
||
import { isEqual } from 'lodash-es' | ||
|
||
export const defaultDelay = 0 | ||
|
||
export function usePopperOptions(options: PopperOptions): { | ||
popperOptions: Required<PopperOptions> | ||
updateOptions: (options: PopperOptions) => void | ||
} { | ||
const popperOptions = reactive<Required<PopperOptions>>({ | ||
allowEnter: options.allowEnter ?? true, | ||
autoAdjust: options.autoAdjust ?? true, | ||
delay: options.delay ?? defaultDelay, | ||
disabled: options.disabled ?? false, | ||
offset: options.offset ?? [0, 0], | ||
placement: options.placement ?? 'top', | ||
trigger: options.trigger ?? 'hover', | ||
visible: options.visible ?? false, | ||
strategy: options.strategy ?? 'absolute', | ||
middlewares: options.middlewares ?? [], | ||
}) | ||
const updateOptions = (options: PopperOptions) => { | ||
Object.entries(options).forEach(([key, value]) => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
if (value !== undefined && !isEqual(value, (popperOptions as any)[key])) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
;(popperOptions as any)[key] = value | ||
} | ||
}) | ||
} | ||
|
||
watch(options, _options => { | ||
updateOptions(_options) | ||
}) | ||
|
||
return { | ||
popperOptions, | ||
updateOptions, | ||
} | ||
} | ||
|
||
export type BaseOptions = Pick< | ||
Required<PopperOptions>, | ||
'placement' | 'strategy' | 'middlewares' | 'offset' | 'autoAdjust' | ||
> | ||
|
||
export function useBaseOptions(options: Required<PopperOptions>): ComputedRef<BaseOptions> { | ||
return computed(() => { | ||
const { placement, strategy, middlewares, offset, autoAdjust } = options | ||
return { placement, strategy, middlewares, offset, autoAdjust } | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { PopperOptions, PopperPlacement } from '../types' | ||
|
||
import { type ComputedRef, computed, ref, watch } from 'vue' | ||
|
||
export function usePlacement(options: Required<PopperOptions>): { | ||
placement: ComputedRef<PopperPlacement> | ||
updatePlacement: (value: PopperPlacement) => void | ||
} { | ||
const _placement = ref(options.placement) | ||
|
||
const updatePlacement = (value: PopperPlacement) => { | ||
_placement.value = value | ||
} | ||
|
||
watch(() => options.placement, updatePlacement) | ||
|
||
const placement = computed(() => _placement.value) | ||
|
||
return { placement, updatePlacement } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { PopperEvents, PopperOptions } from '../types' | ||
|
||
import { type ComputedRef, computed } from 'vue' | ||
|
||
import { NoopObject } from '@idux/cdk/utils' | ||
|
||
export function usePopperEvents( | ||
baseOptions: Required<PopperOptions>, | ||
eventOptions: { show(): void; hide(): void }, | ||
): ComputedRef<PopperEvents> { | ||
const { show, hide } = eventOptions | ||
|
||
const onMouseenter = () => show() | ||
const onMouseleave = () => hide() | ||
|
||
const eventsMap = { | ||
click: NoopObject, | ||
focus: NoopObject, | ||
hover: { onMouseenter, onMouseleave }, | ||
contextmenu: NoopObject, | ||
manual: NoopObject, | ||
} | ||
|
||
return computed(() => (baseOptions.allowEnter ? eventsMap[baseOptions.trigger] : NoopObject)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* @license | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
export function useTimer(): { setTimer: (action: () => void, delay: number) => void; clearTimer: () => void } { | ||
let timer: number | null = null | ||
|
||
const setTimer = (action: () => void, delay: number) => { | ||
if (timer) { | ||
clearTimeout(timer) | ||
} | ||
timer = setTimeout(action, delay) | ||
} | ||
|
||
const clearTimer = () => { | ||
if (timer) { | ||
clearTimeout(timer) | ||
timer = null | ||
} | ||
} | ||
|
||
return { setTimer, clearTimer } | ||
} |
Oops, something went wrong.