Skip to content

Commit

Permalink
fix: modal overflow issue (#304)
Browse files Browse the repository at this point in the history
### Description
- The `FocusTrap` component was inserting a `div`. Adding the `asChild` prop + wrapping `Stack` in the ref convertor allows there to be only a single div now. 
- Added `overflowY: "auto"` to `Modal.Body` as default. 
- Added a modal with a lot of content in storybook so we can see if this behavior works as expected.

### Tasks
[KNO-7270](https://linear.app/knock/issue/KNO-7270/[telegraph]-fix-modal-overflow-issue)
  • Loading branch information
kylemcd authored Nov 1, 2024
1 parent 3c5f068 commit 5406a48
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/silly-buses-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@telegraph/modal": patch
---

fix modal overflow issue
128 changes: 128 additions & 0 deletions packages/modal/src/Modal/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,134 @@ export const Modal: Story = {
},
};

export const ScrollingModal: Story = {
render: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [open, setOpen] = React.useState(true);
const Modal = TelegraphModal;
return (
<>
<Button onClick={() => setOpen(true)}>Open Modal</Button>
<Modal.Root open={open} onOpenChange={setOpen} a11yTitle="Modal title">
<Modal.Content>
<Modal.Header>
<Heading as="h2" size="3">
Modal title
</Heading>
<Modal.Close />
</Modal.Header>
<Modal.Body>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
<h1>Modal body</h1>
</Modal.Body>
<Modal.Footer>
<Button variant="outline" size="1">
Cancel
</Button>
<Button color="accent" size="1">
Save
</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
},
};

type NestedModalProps = {
open: boolean;
onOpenChange: (value: boolean) => void;
Expand Down
33 changes: 24 additions & 9 deletions packages/modal/src/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FocusScope } from "@radix-ui/react-focus-scope";
import { useControllableState } from "@radix-ui/react-use-controllable-state";
import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
import { Button } from "@telegraph/button";
import type { Required } from "@telegraph/helpers";
import { RefToTgphRef, type Required } from "@telegraph/helpers";
import type {
PolymorphicProps,
TgphComponentProps,
Expand Down Expand Up @@ -201,12 +201,14 @@ type ContentRef = React.ElementRef<typeof Dialog.Content>;
const Content = React.forwardRef<ContentRef, ContentProps>(
({ children, ...props }, forwardedRef) => {
return (
<FocusScope trapped={true}>
<Dialog.Content ref={forwardedRef} asChild {...props}>
<Stack direction="column" h="full" {...props}>
{children}
</Stack>
</Dialog.Content>
<FocusScope trapped={true} asChild>
<RefToTgphRef>
<Dialog.Content ref={forwardedRef} asChild {...props}>
<Stack direction="column" h="full" {...props}>
{children}
</Stack>
</Dialog.Content>
</RefToTgphRef>
</FocusScope>
);
},
Expand Down Expand Up @@ -234,9 +236,22 @@ const Close = <T extends TgphElement>({
type BodyProps<T extends TgphElement> = PolymorphicProps<T> &
TgphComponentProps<typeof Stack>;

const Body = <T extends TgphElement>({ children, ...props }: BodyProps<T>) => {
const Body = <T extends TgphElement>({
style,
children,
...props
}: BodyProps<T>) => {
return (
<Stack direction="column" px="6" py="4" {...props}>
<Stack
direction="column"
px="6"
py="4"
style={{
overflowY: "auto",
...style,
}}
{...props}
>
{children}
</Stack>
);
Expand Down

0 comments on commit 5406a48

Please sign in to comment.