Skip to content

Commit 72818c0

Browse files
committed
docs(portal): add examples
1 parent 4982e26 commit 72818c0

File tree

8 files changed

+153
-0
lines changed

8 files changed

+153
-0
lines changed

docs/src/pages/components/ComposedModal.svx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ Create a modal with a header, body, and footer. Each section can be customized i
1818

1919
<FileSource src="/framed/Modal/ComposedModal" />
2020

21+
## With Portal
22+
23+
Wrap `ComposedModal` in a `Portal` to ensure it renders above all z-index stacking contexts and parent overflow constraints, preventing visual clipping and layering issues.
24+
25+
<FileSource src="/framed/Portal/ComposedModalPortal" />
26+
2127
## Prevent default close behavior
2228

2329
The modal dispatches a cancelable `close` event, allowing you to prevent the modal from closing using `e.preventDefault()`. The event includes a `trigger` property indicating what triggered the close attempt: `"escape-key"`, `"outside-click"`, or `"close-button"`.

docs/src/pages/components/Modal.svx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Create a basic modal dialog with primary and secondary actions. This variant is
1616

1717
<FileSource src="/framed/Modal/Modal" />
1818

19+
## With Portal
20+
21+
Wrap `Modal` in a `Portal` to escape parent containers with `overflow: hidden` or z-index stacking contexts. This ensures the modal appears above all content and isn't clipped by parent boundaries.
22+
23+
<FileSource src="/framed/Portal/ModalPortal" />
24+
1925
## Custom focus
2026

2127
Control which element receives focus when the modal opens. Use `selectorPrimaryFocus` to specify the target element using CSS selectors.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script>
2+
import { Portal } from "carbon-components-svelte";
3+
import Preview from "../../components/Preview.svelte";
4+
</script>
5+
6+
The `Portal` component renders its content directly into `document.body`, allowing you to escape parent overflow constraints and z-index stacking contexts.
7+
8+
## Default Portal
9+
10+
Render content in a portal. This is useful for modals, tooltips, and menus that need to escape parent containers.
11+
12+
<FileSource src="/framed/Portal/BasicPortal" />
13+
14+
## Multiple Portals
15+
16+
Each portal instance is independent and creates its own element in `document.body`. Each portal is automatically cleaned up when it is removed.
17+
18+
<FileSource src="/framed/Portal/MultiplePortals" />
19+
20+
## Custom Tag
21+
22+
Use the `tag` prop to specify a custom HTML element. By default, Portal uses a `div` element.
23+
24+
<FileSource src="/framed/Portal/CustomTagPortal" />
25+
26+
## Modal with Portal
27+
28+
Wrap `Modal` in a `Portal` to escape parent containers with `overflow: hidden` or z-index stacking contexts. This ensures the modal appears above all content and isn't clipped by parent boundaries.
29+
30+
<FileSource src="/framed/Portal/ModalPortal" />
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
import { Portal } from "carbon-components-svelte";
3+
</script>
4+
5+
<div>
6+
<div>This is rendered inside the div</div>
7+
<br />
8+
<Portal>This is rendered outside of the div</Portal>
9+
</div>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<script>
2+
import {
3+
Button,
4+
ComposedModal,
5+
ModalBody,
6+
ModalFooter,
7+
ModalHeader,
8+
Portal,
9+
Stack,
10+
} from "carbon-components-svelte";
11+
12+
let open = false;
13+
</script>
14+
15+
<Stack gap={5} style="overflow: hidden; position: relative; height: 200px;">
16+
<p>
17+
This container hides overflowing content. Without a portal, the modal would
18+
be clipped.
19+
</p>
20+
<div>
21+
<Button on:click={() => (open = true)}>Open modal</Button>
22+
</div>
23+
<Portal>
24+
<ComposedModal bind:open>
25+
<ModalHeader title="Composed Modal in Portal" />
26+
<ModalBody>
27+
<p>
28+
This composed modal is rendered in a portal, ensuring it appears above
29+
all z-index stacking contexts and parent overflow constraints.
30+
</p>
31+
</ModalBody>
32+
<ModalFooter
33+
primaryButtonText="Confirm"
34+
secondaryButtonText="Cancel"
35+
on:click:button--secondary={() => (open = false)}
36+
/>
37+
</ComposedModal>
38+
</Portal>
39+
</Stack>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
import { Portal } from "carbon-components-svelte";
3+
</script>
4+
5+
<Portal tag="section">
6+
This portal uses a section tag.
7+
</Portal>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script>
2+
import { Button, Modal, Portal, Stack } from "carbon-components-svelte";
3+
4+
let open = false;
5+
</script>
6+
7+
<Stack gap={5} style="overflow: hidden; position: relative; height: 200px;">
8+
<p>
9+
This container hides overflowing content. Without a portal, the modal would
10+
be clipped.
11+
</p>
12+
<div>
13+
<Button on:click={() => (open = true)}>Open modal</Button>
14+
</div>
15+
<Portal>
16+
<Modal
17+
bind:open
18+
modalHeading="Modal in Portal"
19+
primaryButtonText="Confirm"
20+
secondaryButtonText="Cancel"
21+
on:click:button--secondary={() => (open = false)}
22+
>
23+
<p>
24+
This modal is rendered in a portal, escaping the parent container's
25+
overflow constraints and ensuring it appears above all other content.
26+
</p>
27+
</Modal>
28+
</Portal>
29+
</Stack>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script>
2+
import { Button, ButtonSet, Portal } from "carbon-components-svelte";
3+
4+
let showPortal1 = false;
5+
let showPortal2 = false;
6+
</script>
7+
8+
<ButtonSet>
9+
<Button on:click={() => (showPortal1 = !showPortal1)}>
10+
{showPortal1 ? "Unmount portal 1" : "Mount portal 1"}
11+
</Button>
12+
<Button on:click={() => (showPortal2 = !showPortal2)}>
13+
{showPortal2 ? "Unmount portal 2" : "Mount portal 2"}
14+
</Button>
15+
</ButtonSet>
16+
17+
{#if showPortal1}
18+
<Portal>
19+
Portal content 1
20+
</Portal>
21+
{/if}
22+
23+
{#if showPortal2}
24+
<Portal>
25+
Portal content 2
26+
</Portal>
27+
{/if}

0 commit comments

Comments
 (0)