Skip to content

Commit

Permalink
Add portals (Drawer, Menu, Tooltip) (#230)
Browse files Browse the repository at this point in the history
* build(deps): upgrade dependencies

* fix: add portals to drawer, modal, and tooltip
  • Loading branch information
coopbri authored Jan 30, 2024
1 parent 8671b32 commit bebbadd
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 57 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-cooks-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@animareflection/ui": patch
---

Add `Portal` to `Drawer`, `Modal`, and `Tooltip` to fix render overlay issues
Binary file modified bun.lockb
Binary file not shown.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.11.10",
"@types/react": "^18.2.48",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"concurrently": "^8.2.2",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
Expand All @@ -101,7 +101,7 @@
"eslint-plugin-unused-imports": "^3.0.0",
"framer-motion": "^11.0.3",
"http-server": "^14.1.1",
"husky": "^9.0.6",
"husky": "^9.0.7",
"jsonfile": "^6.1.0",
"lint-staged": "^15.2.0",
"next": "^14.1.0",
Expand Down
44 changes: 25 additions & 19 deletions src/components/core/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Portal } from "@ark-ui/react";
import { FiX as CloseIcon } from "react-icons/fi";

import Icon from "components/core/Icon/Icon";
Expand All @@ -17,13 +18,15 @@ import type {
PrimitiveDrawerContentProps,
} from "components/primitives";
import type { DrawerVariantProps } from "generated/panda/recipes";
import type { ReactNode } from "react";
import type { ReactNode, RefObject } from "react";

export interface Props extends PrimitiveDrawerProps, DrawerVariantProps {
trigger?: ReactNode;
title?: string;
description?: string;
contentProps?: PrimitiveDrawerContentProps;
/** Portal container ref to mount to. */
containerRef?: RefObject<HTMLElement>;
}

/**
Expand All @@ -37,6 +40,7 @@ const Drawer = ({
title,
description,
contentProps,
containerRef,
...rest
}: Props) => (
<PrimitiveDrawer lazyMount unmountOnExit {...rest}>
Expand All @@ -46,28 +50,30 @@ const Drawer = ({
<PrimitiveDrawerTrigger asChild>{trigger}</PrimitiveDrawerTrigger>
)}

<PrimitiveDrawerBackdrop />
<Portal container={containerRef}>
<PrimitiveDrawerBackdrop />

<PrimitiveDrawerPositioner>
<PrimitiveDrawerContent {...contentProps}>
{title && <PrimitiveDrawerTitle>{title}</PrimitiveDrawerTitle>}
<PrimitiveDrawerPositioner>
<PrimitiveDrawerContent {...contentProps}>
{title && <PrimitiveDrawerTitle>{title}</PrimitiveDrawerTitle>}

{description && (
<PrimitiveDrawerDescription>
{description}
</PrimitiveDrawerDescription>
)}
{description && (
<PrimitiveDrawerDescription>
{description}
</PrimitiveDrawerDescription>
)}

{/* forward nested context/state if utilized, otherwise directly render children */}
{typeof children === "function" ? children(ctx) : children}
{/* forward nested context/state if utilized, otherwise directly render children */}
{typeof children === "function" ? children(ctx) : children}

<PrimitiveDrawerCloseTrigger>
<Icon>
<CloseIcon />
</Icon>
</PrimitiveDrawerCloseTrigger>
</PrimitiveDrawerContent>
</PrimitiveDrawerPositioner>
<PrimitiveDrawerCloseTrigger>
<Icon>
<CloseIcon />
</Icon>
</PrimitiveDrawerCloseTrigger>
</PrimitiveDrawerContent>
</PrimitiveDrawerPositioner>
</Portal>
</>
)}
</PrimitiveDrawer>
Expand Down
52 changes: 32 additions & 20 deletions src/components/core/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Portal } from "@ark-ui/react";
import { FiX as CloseIcon } from "react-icons/fi";

import Icon from "components/core/Icon/Icon";
Expand All @@ -13,49 +14,60 @@ import {
} from "components/primitives";

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;
/** Portal container ref to mount to. */
containerRef?: RefObject<HTMLElement>;
}

/**
* Modal.
*
* **NOTE:** by default, the component is rendered lazily and unmounted on exit due to `lazyMount` and `unmountOnExit` being specified. To override these behaviors, pass `lazyMount={false}` and/or `unmountOnExit={false}`.
*/
const Modal = ({ children, trigger, title, description, ...rest }: Props) => (
const Modal = ({
children,
trigger,
title,
description,
containerRef,
...rest
}: Props) => (
<PrimitiveModal lazyMount unmountOnExit {...rest}>
{(ctx) => (
<>
{trigger && (
<PrimitiveModalTrigger asChild>{trigger}</PrimitiveModalTrigger>
)}

<PrimitiveModalBackdrop />
<Portal container={containerRef}>
<PrimitiveModalBackdrop />

<PrimitiveModalPositioner>
<PrimitiveModalContent>
{title && <PrimitiveModalTitle>{title}</PrimitiveModalTitle>}
<PrimitiveModalPositioner>
<PrimitiveModalContent>
{title && <PrimitiveModalTitle>{title}</PrimitiveModalTitle>}

{description && (
<PrimitiveModalDescription>
{description}
</PrimitiveModalDescription>
)}
{description && (
<PrimitiveModalDescription>
{description}
</PrimitiveModalDescription>
)}

{/* forward nested context/state if utilized, otherwise directly render children */}
{typeof children === "function" ? children(ctx) : children}
{/* forward nested context/state if utilized, otherwise directly render children */}
{typeof children === "function" ? children(ctx) : children}

<PrimitiveModalCloseTrigger>
<Icon>
<CloseIcon />
</Icon>
</PrimitiveModalCloseTrigger>
</PrimitiveModalContent>
</PrimitiveModalPositioner>
<PrimitiveModalCloseTrigger>
<Icon>
<CloseIcon />
</Icon>
</PrimitiveModalCloseTrigger>
</PrimitiveModalContent>
</PrimitiveModalPositioner>
</Portal>
</>
)}
</PrimitiveModal>
Expand Down
37 changes: 22 additions & 15 deletions src/components/core/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Portal } from "@ark-ui/react";

import {
PrimitiveTooltip,
PrimitiveTooltipArrow,
Expand All @@ -13,14 +15,16 @@ import type {
} 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;
contentProps?: PrimitiveTooltipContentProps;
/** Portal container ref to mount to. */
containerRef?: RefObject<HTMLElement>;
}

/**
Expand All @@ -34,6 +38,7 @@ const Tooltip = ({
bgColor = "bg.default",
arrow = true,
contentProps,
containerRef,
...rest
}: Props) => (
<PrimitiveTooltip openDelay={openDelay} closeDelay={closeDelay} {...rest}>
Expand All @@ -43,21 +48,23 @@ const Tooltip = ({
<PrimitiveTooltipTrigger asChild>{trigger}</PrimitiveTooltipTrigger>
)}

<PrimitiveTooltipPositioner>
{isOpen && (
<>
{arrow && (
<PrimitiveTooltipArrow bgColor={bgColor}>
<PrimitiveTooltipArrowTip />
</PrimitiveTooltipArrow>
)}
<Portal container={containerRef}>
<PrimitiveTooltipPositioner>
{isOpen && (
<>
{arrow && (
<PrimitiveTooltipArrow bgColor={bgColor}>
<PrimitiveTooltipArrowTip />
</PrimitiveTooltipArrow>
)}

<PrimitiveTooltipContent bgColor={bgColor} {...contentProps}>
{tooltipContent}
</PrimitiveTooltipContent>
</>
)}
</PrimitiveTooltipPositioner>
<PrimitiveTooltipContent bgColor={bgColor} {...contentProps}>
{tooltipContent}
</PrimitiveTooltipContent>
</>
)}
</PrimitiveTooltipPositioner>
</Portal>
</>
)}
</PrimitiveTooltip>
Expand Down

0 comments on commit bebbadd

Please sign in to comment.