From 5176e2f8834896f603e5e2e903a648bd6de0f79b Mon Sep 17 00:00:00 2001 From: jaaaaavier Date: Mon, 30 Mar 2026 16:37:56 +0200 Subject: [PATCH 1/2] add new property & update behaviour for align --- src/components/popover/Popover.tsx | 18 ++++++++++++++---- .../popover/__test__/Popover.test.tsx | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/components/popover/Popover.tsx b/src/components/popover/Popover.tsx index c9879a8..9eeed68 100644 --- a/src/components/popover/Popover.tsx +++ b/src/components/popover/Popover.tsx @@ -7,6 +7,7 @@ export interface PopoverProps { className?: string; classButton?: string; align?: 'left' | 'right'; + direction?: 'up' | 'down'; } /** @@ -25,12 +26,19 @@ export interface PopoverProps { * * @property {string} [classButton] * - Custom classes for the trigger button. - * + * + * @property {'left' | 'right'} [align='right'] + * - The alignment of the popover panel relative to the trigger button. + * + * @property {'up' | 'down'} [direction='down'] + * - The direction of the popover panel relative to the trigger button. + * * @returns {JSX.Element} * - The rendered Popover component. + * */ -const Popover = ({ childrenButton, panel, className, classButton, align = 'right' }: PopoverProps): JSX.Element => { +const Popover = ({ childrenButton, panel, className, classButton, align = 'right', direction = 'down' }: PopoverProps): JSX.Element => { const [isOpen, setIsOpen] = useState(false); const panelRef = useRef(null); const [showContent, setShowContent] = useState(isOpen); @@ -88,8 +96,10 @@ const Popover = ({ childrenButton, panel, className, classButton, align = 'right
diff --git a/src/components/popover/__test__/Popover.test.tsx b/src/components/popover/__test__/Popover.test.tsx index 09d1dad..cdf1af6 100644 --- a/src/components/popover/__test__/Popover.test.tsx +++ b/src/components/popover/__test__/Popover.test.tsx @@ -123,6 +123,22 @@ describe('Popover', () => { await waitFor(() => expect(getByText('Popover Content')).toBeInTheDocument()); }); + it('applies the correct classes for left alignment', () => { + const { getByText, queryByText } = renderPopover({ align: 'left' }); + fireEvent.click(getByText('Open Popover')); + const leftPanel = queryByText('Popover Content')?.parentElement?.parentElement; + expect(leftPanel).toHaveClass('right-0'); + expect(leftPanel).toHaveClass('origin-top-right'); + }); + + it('applies the correct classes for right alignment', () => { + const { getByText, queryByText } = renderPopover({ align: 'right' }); + fireEvent.click(getByText('Open Popover')); + const rightPanel = queryByText('Popover Content')?.parentElement?.parentElement; + expect(rightPanel).toHaveClass('left-0'); + expect(rightPanel).toHaveClass('origin-top-left'); + }); + it('should call onMouseDown stopPropagation when the button is clicked', () => { const stopPropagationSpy = vi.fn(); const { getByText } = renderPopover(); From a38c6b59b4a3ad16ebb3feaf885276c0969cc8aa Mon Sep 17 00:00:00 2001 From: jaaaaavier Date: Tue, 31 Mar 2026 13:31:02 +0200 Subject: [PATCH 2/2] Update Popover.tsx --- src/components/popover/Popover.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/popover/Popover.tsx b/src/components/popover/Popover.tsx index 9eeed68..ff95e2c 100644 --- a/src/components/popover/Popover.tsx +++ b/src/components/popover/Popover.tsx @@ -10,6 +10,10 @@ export interface PopoverProps { direction?: 'up' | 'down'; } +const originMap: Record<'up' | 'down', Record<'left' | 'right', string>> = { + up: { left: 'origin-bottom-right', right: 'origin-bottom-left' }, + down: { left: 'origin-top-right', right: 'origin-top-left' }, +}; /** * Popover component * @@ -99,7 +103,7 @@ const Popover = ({ childrenButton, panel, className, classButton, align = 'right 'absolute z-50 transform rounded-md border border-gray-10 ' + `${direction === 'up' ? 'bottom-full mb-1' : 'mt-1'} ` + `${align === 'left' ? 'right-0' : 'left-0'} ` + - `${direction === 'up' ? (align === 'left' ? 'origin-bottom-right' : 'origin-bottom-left') : (align === 'left' ? 'origin-top-right' : 'origin-top-left')} ` + + `${originMap[direction][align]} ` + `bg-surface py-1.5 shadow-subtle duration-100 ease-out dark:bg-gray-5 ${transitionOpacity} ${transitionScale}` } >