diff --git a/frontend/e2e/page-context-menu.spec.ts b/frontend/e2e/page-context-menu.spec.ts
index d7ea12c..f42255c 100644
--- a/frontend/e2e/page-context-menu.spec.ts
+++ b/frontend/e2e/page-context-menu.spec.ts
@@ -373,5 +373,12 @@ test.describe('page action sheet (mobile long-press)', () => {
await expect(page.getByTestId('page-action-add-tag')).toBeVisible();
await expect(page.getByTestId('page-action-save-image')).toBeVisible();
await expect(page.getByTestId('page-action-copy-link')).toBeVisible();
+
+ // The editor itself opens as a bottom Sheet on mobile (not a centered
+ // Modal), so the action-sheet → editor flow stays one consistent
+ // idiom. Sheet renders a `${testid}-scrim`; Modal a `${testid}-backdrop`.
+ await page.getByTestId('page-action-add-tag').click();
+ await expect(page.getByTestId('add-tags-modal-scrim')).toBeVisible();
+ await expect(page.getByTestId('add-tags-modal-backdrop')).toHaveCount(0);
});
});
diff --git a/frontend/src/lib/components/AdaptiveDialog.svelte b/frontend/src/lib/components/AdaptiveDialog.svelte
new file mode 100644
index 0000000..9f27e45
--- /dev/null
+++ b/frontend/src/lib/components/AdaptiveDialog.svelte
@@ -0,0 +1,53 @@
+
+
+{#if isMobile}
+
hello
` +})); + +describe('AdaptiveDialog', () => { + it('renders a centered Modal on desktop (the scrim is the Modal backdrop)', async () => { + stubMatchMedia(false); + render(AdaptiveDialog, { + props: { open: true, title: 'Tag this page', onClose: () => {}, testid: 'dlg', children: body } + }); + // Modal exposes a `${testid}-backdrop`; Sheet exposes `${testid}-scrim`. + expect(await screen.findByTestId('dlg-backdrop')).toBeTruthy(); + expect(screen.queryByTestId('dlg-scrim')).toBeNull(); + expect(screen.getByRole('dialog', { name: 'Tag this page' })).toBeTruthy(); + expect(screen.getByTestId('dlg-body')).toBeTruthy(); + }); + + it('renders a bottom Sheet on mobile', async () => { + stubMatchMedia(true); + render(AdaptiveDialog, { + props: { open: true, title: 'Tag this page', onClose: () => {}, testid: 'dlg', children: body } + }); + // The effect flips to mobile after mount; poll for the Sheet scrim. + expect(await screen.findByTestId('dlg-scrim')).toBeTruthy(); + expect(screen.queryByTestId('dlg-backdrop')).toBeNull(); + expect(screen.getByRole('dialog', { name: 'Tag this page' })).toBeTruthy(); + }); + + it('renders nothing when closed', () => { + stubMatchMedia(false); + render(AdaptiveDialog, { + props: { open: false, title: 'Tag this page', onClose: () => {}, testid: 'dlg', children: body } + }); + expect(screen.queryByRole('dialog')).toBeNull(); + }); +}); diff --git a/frontend/src/lib/components/AddToCollectionModal.svelte b/frontend/src/lib/components/AddToCollectionModal.svelte index 37f9499..d1d8d04 100644 --- a/frontend/src/lib/components/AddToCollectionModal.svelte +++ b/frontend/src/lib/components/AddToCollectionModal.svelte @@ -1,5 +1,5 @@ -Loading your collections…
{:else if error} @@ -235,7 +235,7 @@ {creating ? 'Creating…' : 'Create + add'} -