UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

74 lines (73 loc) 2.02 kB
import { ownerDocument, ownerWindow } from '@base-ui-components/utils/owner'; import { getSide } from '@floating-ui/utils'; export const DEFAULT_SIDES = { sideX: 'left', sideY: 'top' }; export const adaptiveOrigin = { name: 'adaptiveOrigin', async fn(state) { const { x: rawX, y: rawY, rects: { floating: floatRect }, elements: { floating }, platform, strategy, placement } = state; const win = ownerWindow(floating); const styles = win.getComputedStyle(floating); const hasTransition = styles.transitionDuration !== '0s' && styles.transitionDuration !== ''; if (!hasTransition) { return { x: rawX, y: rawY, data: DEFAULT_SIDES }; } const offsetParent = await platform.getOffsetParent?.(floating); let offsetDimensions = { width: 0, height: 0 }; // For fixed strategy, prefer visualViewport if available if (strategy === 'fixed' && win?.visualViewport) { offsetDimensions = { width: win.visualViewport.width, height: win.visualViewport.height }; } else if (offsetParent === win) { const doc = ownerDocument(floating); offsetDimensions = { width: doc.documentElement.clientWidth, height: doc.documentElement.clientHeight }; } else if (await platform.isElement?.(offsetParent)) { offsetDimensions = await platform.getDimensions(offsetParent); } const currentSide = getSide(placement); let x = rawX; let y = rawY; if (currentSide === 'left') { x = offsetDimensions.width - (rawX + floatRect.width); } if (currentSide === 'top') { y = offsetDimensions.height - (rawY + floatRect.height); } const sideX = currentSide === 'left' ? 'right' : DEFAULT_SIDES.sideX; const sideY = currentSide === 'top' ? 'bottom' : DEFAULT_SIDES.sideY; return { x, y, data: { sideX, sideY } }; } };