From 7ac38cb8db55edc2247a9c58378dbc5cb41858d7 Mon Sep 17 00:00:00 2001 From: Eli Black Date: Thu, 6 Feb 2025 17:07:04 +0800 Subject: [PATCH] Allow passing a function to `align`, to dynamically determine the alignment based off of the selected position. --- src/index.d.ts | 6 +++++- src/usePopover.ts | 32 +++++++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 92f4065..4b2f3dc 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -42,7 +42,11 @@ export type PositionTransform = | ((popoverState: PopoverState) => PositionTransformValue); export type PopoverPosition = 'left' | 'right' | 'top' | 'bottom'; -export type PopoverAlign = 'start' | 'center' | 'end'; +export type PopoverAlignValue = 'start' | 'center' | 'end'; + +export type PopoverAlign = + | PopoverAlignValue + | ((popoverPosition: PopoverPosition) => PopoverAlignValue); export type UseArrowContainerProps = { childRect: Rect; diff --git a/src/usePopover.ts b/src/usePopover.ts index 3b7c0d5..22f5e0e 100644 --- a/src/usePopover.ts +++ b/src/usePopover.ts @@ -48,8 +48,8 @@ export const usePopover = ({ const popoverRef = useElementRef({ containerClassName: containerClassName != null && - containerClassName.length > 0 && - containerClassName !== 'react-tiny-popover-container' + containerClassName.length > 0 && + containerClassName !== 'react-tiny-popover-container' ? `react-tiny-popover-container ${containerClassName}` : 'react-tiny-popover-container', containerStyle: POPOVER_STYLE, @@ -74,18 +74,18 @@ export const usePopover = ({ const { top: inputTop, left: inputLeft } = typeof transform === 'function' ? transform({ - childRect, - popoverRect, - parentRect, - boundaryRect, - padding, - align, - nudgedTop: 0, - nudgedLeft: 0, - boundaryInset, - violations: EMPTY_RECT, - hasViolations: false, - }) + childRect, + popoverRect, + parentRect, + boundaryRect, + padding, + align, + nudgedTop: 0, + nudgedLeft: 0, + boundaryInset, + violations: EMPTY_RECT, + hasViolations: false, + }) : transform; const finalLeft = Math.round(parentRect.left + inputLeft - scoutRect.left); @@ -119,13 +119,15 @@ export const usePopover = ({ const isExhausted = positionIndex === positions.length; const position = isExhausted ? positions[0] : positions[positionIndex]; + const calculatedAlign = typeof align === 'function' ? align(position) : align; + const { rect, boundaryViolation } = getNewPopoverRect( { childRect, popoverRect, boundaryRect, position, - align, + align: calculatedAlign, padding, reposition, },