Skip to content

Commit

Permalink
Optional Portal Targets (#147)
Browse files Browse the repository at this point in the history
* feat(tooltip): add option target ref for portal

* feat(drawer): add option target ref for portal

* feat(flyout): add optional target ref for portal

* feat(menu): add optional target ref for portal

* feat(modal): add optional target ref for portal

* ci(changesets): add changesets for portal target component changes
  • Loading branch information
hobbescodes authored Oct 4, 2023
1 parent fafcc31 commit a5c5bf6
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-meals-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@animareflection/ui": minor
---

Add `targetRef` prop for all components that use `Portal`
6 changes: 4 additions & 2 deletions src/components/core/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ import type {
PrimitiveDrawerContentProps,
} from "components/primitives";
import type { DrawerVariantProps } from "generated/panda/recipes";
import type { ReactNode } from "react";
import type { RefObject, ReactNode } from "react";

export interface Props extends PrimitiveDrawerProps, DrawerVariantProps {
trigger?: ReactNode;
title?: string;
description?: string;
contentProps?: PrimitiveDrawerContentProps;
targetRef?: RefObject<HTMLElement>;
}

/**
Expand All @@ -39,6 +40,7 @@ const Drawer = ({
title,
description,
contentProps,
targetRef,
...rest
}: Props) => {
const classNames = drawer({ placement });
Expand All @@ -57,7 +59,7 @@ const Drawer = ({
</PrimitiveDrawerTrigger>
)}

<Portal>
<Portal target={targetRef}>
<PrimitiveDrawerBackdrop className={classNames.backdrop} />
<PrimitiveDrawerContainer className={classNames.container}>
<PrimitiveDrawerContent
Expand Down
14 changes: 11 additions & 3 deletions src/components/core/Flyout/Flyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,27 @@ import type {
PrimitiveFlyoutProps,
PrimitiveFlyoutTriggerProps,
} from "components/primitives";
import type { ReactNode } from "react";
import type { RefObject, ReactNode } from "react";

export interface Props extends PrimitiveFlyoutProps {
trigger?: ReactNode;
title?: ReactNode;
children: ReactNode;
triggerProps?: PrimitiveFlyoutTriggerProps;
targetRef?: RefObject<HTMLElement>;
}

/**
* Core UI flyout.
*/
const Flyout = ({ trigger, title, children, triggerProps, ...rest }: Props) => {
const Flyout = ({
trigger,
title,
children,
triggerProps,
targetRef,
...rest
}: Props) => {
const [isOpen, setIsOpen] = useState<boolean>(false);

const classNames = flyout();
Expand All @@ -59,7 +67,7 @@ const Flyout = ({ trigger, title, children, triggerProps, ...rest }: Props) => {
</PrimitiveFlyoutTrigger>
)}

<Portal>
<Portal target={targetRef}>
<PrimitiveFlyoutPositioner className={classNames.positioner}>
<PrimitiveFlyoutContent className={classNames.content}>
<PrimitiveFlyoutArrow className={classNames.arrow}>
Expand Down
6 changes: 4 additions & 2 deletions src/components/core/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type {
ButtonVariantProps,
MenuVariantProps,
} from "generated/panda/recipes";
import type { ReactElement, ReactNode } from "react";
import type { ReactElement, ReactNode, RefObject } from "react";

export interface MenuItemRecord {
id: string;
Expand All @@ -40,6 +40,7 @@ export interface Props extends PrimitiveMenuProps, MenuVariantProps {
triggerItem?: ReactNode;
triggerVariant?: ButtonVariantProps["variant"];
groups?: MenuItemGroupRecord[];
targetRef?: RefObject<HTMLElement>;
}

/**
Expand All @@ -52,6 +53,7 @@ const Menu = ({
triggerVariant,
groups,
size,
targetRef,
...rest
}: Props) => {
const classNames = menu({ size });
Expand Down Expand Up @@ -79,7 +81,7 @@ const Menu = ({
{triggerItem}
</PrimitiveMenuTriggerItem>
)}
<Portal>
<Portal target={targetRef}>
<PrimitiveMenuPositioner className={classNames.positioner}>
<PrimitiveMenuContent className={classNames.content}>
{groups?.map(({ id, label, separator, items }) => (
Expand Down
14 changes: 11 additions & 3 deletions src/components/core/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ import { modal } from "generated/panda/recipes";
import { useIsMounted } from "lib/hooks";

import type { PrimitiveModalProps } from "components/primitives";
import type { ReactNode } from "react";
import type { ReactNode, RefObject } from "react";

export interface Props extends PrimitiveModalProps {
trigger?: ReactNode;
title?: string;
description?: string;
targetRef?: RefObject<HTMLElement>;
}

/**
* Core UI modal.
*/
const Modal = ({ children, trigger, title, description, ...rest }: Props) => {
const Modal = ({
children,
trigger,
title,
description,
targetRef,
...rest
}: Props) => {
const classNames = modal();

const isMounted = useIsMounted();
Expand All @@ -44,7 +52,7 @@ const Modal = ({ children, trigger, title, description, ...rest }: Props) => {
</PrimitiveModalTrigger>
)}

<Portal>
<Portal target={targetRef}>
<PrimitiveModalBackdrop className={classNames.backdrop} />
<PrimitiveModalContainer className={classNames.container}>
<PrimitiveModalContent
Expand Down
6 changes: 4 additions & 2 deletions src/components/core/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import { useIsMounted } from "lib/hooks";
import type { PrimitiveTooltipProps } from "components/primitives";
import type { TooltipVariantProps } from "generated/panda/recipes";
import type { JsxStyleProps } from "generated/panda/types";
import type { ReactNode } from "react";
import type { ReactNode, RefObject } from "react";

export interface Props extends PrimitiveTooltipProps, TooltipVariantProps {
trigger?: ReactNode;
tooltipContent: ReactNode;
bgColor?: JsxStyleProps["bgColor"];
arrow?: boolean;
targetRef?: RefObject<HTMLElement>;
}

/**
Expand All @@ -34,6 +35,7 @@ const Tooltip = ({
bgColor = "bg.default",
variant,
arrow = true,
targetRef,
...rest
}: Props) => {
const isMounted = useIsMounted();
Expand All @@ -52,7 +54,7 @@ const Tooltip = ({
</PrimitiveTooltipTrigger>
)}

<Portal>
<Portal target={targetRef}>
<PrimitiveTooltipPositioner className={classNames.positioner}>
{isOpen && (
<>
Expand Down

1 comment on commit a5c5bf6

@vercel
Copy link

@vercel vercel bot commented on a5c5bf6 Oct 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ui-studio – ./

ui-studio-git-master-animareflection.vercel.app
ui-studio-animareflection.vercel.app

Please sign in to comment.