diff --git a/.changeset/lucky-bats-jam.md b/.changeset/lucky-bats-jam.md
new file mode 100644
index 0000000000..e7aa3f96f5
--- /dev/null
+++ b/.changeset/lucky-bats-jam.md
@@ -0,0 +1,5 @@
+---
+"@melt-ui/svelte": minor
+---
+
+Popover: add optional `overlay` element builder for simplified modal behavior (part of #1018)
diff --git a/src/docs/content/builders/popover.md b/src/docs/content/builders/popover.md
index c41079c17f..3ca8cc667c 100644
--- a/src/docs/content/builders/popover.md
+++ b/src/docs/content/builders/popover.md
@@ -28,7 +28,9 @@ above to create your popover.
To specify that the popover should be open by default, set the `defaultOpen` prop to `true`.
```ts {2}
-const { trigger, content, open, arrow, close } = createPopover({
+const {
+ /** ... */
+} = createPopover({
defaultOpen: true
})
```
@@ -67,6 +69,36 @@ const popover = createPopover({
})
```
+### Modal Behavior
+
+To give the popover modal behavior, where body scrolling is disabled and an overlay is rendered
+behind the popover to prevent interaction with the rest of the page, use the `preventScroll` prop
+and `overlay` builder element.
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+```
+
+The [Modal Popover](#modal-popover) example below demonstrates this behavior in action.
+
## Example Components
### Nested Popovers
@@ -75,6 +107,12 @@ const popover = createPopover({
+### Modal Popover
+
+
+
+
+
## API Reference
diff --git a/src/docs/data/builders/popover.ts b/src/docs/data/builders/popover.ts
index e8f0ff4380..9d978a7424 100644
--- a/src/docs/data/builders/popover.ts
+++ b/src/docs/data/builders/popover.ts
@@ -41,6 +41,10 @@ const builder = builderSchema(BUILDER_NAME, {
name: 'content',
description: 'The builder store used to create the popover content.',
},
+ {
+ name: 'overlay',
+ description: 'The builder store used to create the popover overlay.',
+ },
{
name: 'close',
description: 'The builder store used to create the popover close button.',
@@ -78,6 +82,10 @@ const trigger = elementSchema('trigger', {
const content = elementSchema('content', {
description: 'The popover content.',
dataAttributes: [
+ {
+ name: 'data-state',
+ value: ATTRS.OPEN_CLOSED,
+ },
{
name: 'data-melt-popover-content',
value: ATTRS.MELT('content'),
@@ -85,6 +93,21 @@ const content = elementSchema('content', {
],
});
+const overlay = elementSchema('overlay', {
+ description:
+ 'The optional popover overlay element, which can be used to give the popover modal-like behavior where the user cannot interact with the rest of the page while the popover is open.',
+ dataAttributes: [
+ {
+ name: 'data-state',
+ value: ATTRS.OPEN_CLOSED,
+ },
+ {
+ name: 'data-melt-popover-overlay',
+ value: ATTRS.MELT('overlay'),
+ },
+ ],
+});
+
const arrow = elementSchema('arrow', {
title: 'arrow',
description: 'The optional arrow element.',
@@ -137,7 +160,7 @@ const keyboard: KeyboardSchema = [
},
];
-const schemas = [builder, trigger, content, close, arrow];
+const schemas = [builder, trigger, content, overlay, close, arrow];
const features = [
'Full keyboard navigation',
diff --git a/src/docs/previews/popover/modal/tailwind/index.svelte b/src/docs/previews/popover/modal/tailwind/index.svelte
new file mode 100644
index 0000000000..a2c1bd8dfb
--- /dev/null
+++ b/src/docs/previews/popover/modal/tailwind/index.svelte
@@ -0,0 +1,95 @@
+
+
+
+
+{#if $open}
+
+