diff --git a/backend/Cargo.lock b/backend/Cargo.lock
index 332ac16..77e9e38 100644
--- a/backend/Cargo.lock
+++ b/backend/Cargo.lock
@@ -1517,7 +1517,7 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "mangalord"
-version = "0.88.0"
+version = "0.89.0"
dependencies = [
"anyhow",
"argon2",
diff --git a/backend/Cargo.toml b/backend/Cargo.toml
index 88ade25..765d388 100644
--- a/backend/Cargo.toml
+++ b/backend/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mangalord"
-version = "0.88.0"
+version = "0.89.0"
edition = "2021"
default-run = "mangalord"
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/package.json b/frontend/package.json
index 18e80b3..50639c3 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "mangalord-frontend",
- "version": "0.88.0",
+ "version": "0.89.0",
"private": true,
"type": "module",
"scripts": {
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'} -