Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions packages/components/src/Modal/Modal.rebuilt.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,37 @@
z-index: var(--elevation-modal);
width: 100%;
max-width: var(--modal--width);
max-height: calc(100dvh - 2 * var(--space-base));
box-shadow: var(--modal--shadow);
margin: auto;
padding: var(--space-small);
border: var(--border-base) solid var(--color-border);
border-radius: var(--radius-base);
outline: none;
overflow: hidden;
background-color: var(--color-surface);
flex: 0 0 auto;
}

.modal:focus-visible {
box-shadow: var(--shadow-focus);
}

.modalBody {
max-height: inherit;
padding: var(--space-small);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't mind if we just removed this. if I'm understanding it right, this is the padding that used to be on .modal

however, that padding doesn't make sense. it's extra padding that we don't need.

I'll double check I'm understanding it right though.

Copy link
Contributor

Choose a reason for hiding this comment

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

actually it's fine. even though I don't like it, it has nothing to do with these changes. we can keep it equivalent for the time being and address it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ideally this should be the overall padding of the modal and eventually we don't set margin on header, body, and actions separately.

Copy link
Contributor

Choose a reason for hiding this comment

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

true. we need to either commit to the individual pieces providing the padding, or do that.

I have never understood our current state that is a mixture of everything 😵

  • padding on Header, and Actions
  • no padding on the main content
  • extra padding on the entire thing

overflow-y: auto;
}

/* Adjust `Content` and `Tab` components public padding to match the modal */

.modal > * {
.modalBody > * {
--public-content--padding: var(--modal--padding);
--public-tab--inset: var(--modal--padding-horizontal);
}

/* Remove the nested `Content` components public padding */

.modal > * > * {
.modalBody > * > * {
--public-content--padding: 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ declare const styles: {
readonly "overlay": string;
readonly "overlayBackground": string;
readonly "modal": string;
readonly "modalBody": string;
readonly "header": string;
readonly "closeButton": string;
readonly "actionBar": string;
Expand Down
5 changes: 4 additions & 1 deletion packages/components/src/Modal/Modal.rebuilt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
} from "./Modal.types";
import { useModalStyles } from "./useModalStyles";
import { MODAL_HEADER_ID } from "./constants";
import styles from "./Modal.rebuilt.module.css";
import { Heading } from "../Heading";
import { ButtonDismiss } from "../ButtonDismiss";
import { Button } from "../Button";
Expand Down Expand Up @@ -164,7 +165,9 @@ export function ModalContent({ children }: ModalContainerProps) {
if (startedInsideRef) startedInsideRef.current = true;
}}
>
{children}
<div className={styles.modalBody} tabIndex={-1}>
{children}
</div>
</motion.div>
</FloatingFocusManager>
</ModalOverlay>
Expand Down
6 changes: 6 additions & 0 deletions packages/site/src/content/Modal/Modal.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ Modals are overlays that allow users to view, edit, or show informations that
doesn't require a page to be built. It also prevent users from interacting with
the rest of the application until a specific action is taken.

## Scrolling

When modal content exceeds the available viewport height, the composed
`Modal.Provider` implementation automatically handles scrolling within the modal
itself, whereas the prop based `Modal` will result in scrolling the entire page.

## Related components

Use [SideDrawer](/components/SideDrawer) if you need to overlay the page's
Expand Down
119 changes: 119 additions & 0 deletions packages/site/src/pages/visualTests/VisualTestModalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const VisualTestModalPage = () => {
const [formModalOpen, setFormModalOpen] = useState(false);
const [tabModalOpen, setTabModalOpen] = useState(false);
const [narrowContentModalOpen, setNarrowContentModalOpen] = useState(false);
const [overflowModalOpen, setOverflowModalOpen] = useState(false);

return (
<Box padding="large">
Expand Down Expand Up @@ -337,6 +338,124 @@ export const VisualTestModalPage = () => {
</Modal.Content>
</Modal.Provider>
</section>

{/* Modal with overflowing content */}
<section>
<Text size="large">Modal with Overflowing Content</Text>
<Button
label="Open Modal with Overflowing Content"
onClick={() => setOverflowModalOpen(true)}
/>

<Modal.Provider
open={overflowModalOpen}
onRequestClose={() => setOverflowModalOpen(false)}
>
<Modal.Content>
<Modal.Header title="Modal with Overflowing Content" />
<Content>
<Text>
This modal contains a lot of content to test that the
max-height constraint works correctly and the modal
content scrolls instead of overflowing the viewport.
</Text>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
</Text>
<Text>
Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</Text>
<Text>
Sed ut perspiciatis unde omnis iste natus error sit
voluptatem accusantium doloremque laudantium, totam rem
aperiam, eaque ipsa quae ab illo inventore veritatis et
quasi architecto beatae vitae dicta sunt explicabo.
</Text>
<Text>
Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores
eos qui ratione voluptatem sequi nesciunt.
</Text>
<Text>
Neque porro quisquam est, qui dolorem ipsum quia dolor sit
amet, consectetur, adipisci velit, sed quia non numquam
eius modi tempora incidunt ut labore et dolore magnam
aliquam quaerat voluptatem.
</Text>
<Text>
Ut enim ad minima veniam, quis nostrum exercitationem
ullam corporis suscipit laboriosam, nisi ut aliquid ex ea
commodi consequatur? Quis autem vel eum iure reprehenderit
qui in ea voluptate velit esse quam nihil molestiae
consequatur.
</Text>
<Text>
At vero eos et accusamus et iusto odio dignissimos ducimus
qui blanditiis praesentium voluptatum deleniti atque
corrupti quos dolores et quas molestias excepturi sint
occaecati cupiditate non provident.
</Text>
<Text>
Similique sunt in culpa qui officia deserunt mollitia
animi, id est laborum et dolorum fuga. Et harum quidem
rerum facilis est et expedita distinctio.
</Text>
<Text>
Nam libero tempore, cum soluta nobis est eligendi optio
cumque nihil impedit quo minus id quod maxime placeat
facere possimus, omnis voluptas assumenda est, omnis dolor
repellendus.
</Text>
<Text>
Temporibus autem quibusdam et aut officiis debitis aut
rerum necessitatibus saepe eveniet ut et voluptates
repudiandae sint et molestiae non recusandae.
</Text>
<Text>
Itaque earum rerum hic tenetur a sapiente delectus, ut aut
reiciendis voluptatibus maiores alias consequatur aut
perferendis doloribus asperiores repellat.
</Text>
<Text>
This is additional content to ensure the modal definitely
overflows. The modal should have a max-height set and show
a scrollbar when content exceeds that height.
</Text>
<Text>
More content here to push the boundaries. The scrollbar
should appear when the content height exceeds the
available viewport height minus the edge padding.
</Text>
<Text>
Even more content to make absolutely sure we test the
overflow behavior. This should be enough to trigger
scrolling in most viewport sizes.
</Text>
<Text>
Final paragraph to ensure we have sufficient content to
test the max-height constraint and scrolling behavior of
the modal component.
</Text>
</Content>
<Modal.Actions
primary={{
label: "Save",
onClick: () => setOverflowModalOpen(false),
}}
secondary={{
label: "Cancel",
onClick: () => setOverflowModalOpen(false),
}}
/>
</Modal.Content>
</Modal.Provider>
</section>
</Stack>
</Stack>
</Stack>
Expand Down
14 changes: 14 additions & 0 deletions packages/site/tests/visual/modal.visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,18 @@ test.describe("Modal Visual Tests", () => {
});
});
});

test.describe("overflowing content modal", () => {
test("should test modal with overflowing content", async ({ page }) => {
const overflowModalButton = page.getByRole("button", {
name: "Open Modal with Overflowing Content",
exact: true,
});
await overflowModalButton.click();
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("19-overflow-modal-open.png", {
fullPage: true,
});
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading