Skip to content

redesign: add-bookmark flow as bottom sheet (mobile) / dialog (desktop)#46

Merged
pheuberger merged 3 commits into
mainfrom
claude/bookmark-add-dialog-redesign-n1db6s
Jul 11, 2026
Merged

redesign: add-bookmark flow as bottom sheet (mobile) / dialog (desktop)#46
pheuberger merged 3 commits into
mainfrom
claude/bookmark-add-dialog-redesign-n1db6s

Conversation

@pheuberger

Copy link
Copy Markdown
Owner

Redesigns the add-bookmark flow from first principles around its one
job: capture a link fast. New bookmarks no longer use the inline draft
card at the top of the list; they go through a new AddBookmarkDialog.

Why: the inline card scrolled with the list under the sticky header, so
on phones the tags row and Save/Cancel actions routinely ended up under
the soft keyboard, Enter-to-save was the only reliable affordance, and
multi-line notes were impossible (Enter saved, Shift+Enter doesn't
exist on touch). The URL - the only required field - was a 16px line at
the top of a form that gave title and description equal billing.

The new dialog:

  • Bottom sheet on mobile: pinned to the viewport bottom with a sticky
    footer, so the full-width Save button stays visible above the
    keyboard (verified at 390x450 keyboard-up viewport - the body
    scrolls, the footer doesn't). index.html now sets
    interactive-widget=resizes-content so Android Chrome resizes the
    layout viewport. Centered top-anchored dialog on sm+.
  • URL first: the only required field, hero position, one-tap Paste
    button inside the field, Save disabled until a URL is entered,
    inline errors for invalid/unreadable clipboard.
  • Content suggestions finally reach manual adds: committing a URL
    (paste or blur) auto-fills empty title/description and offers
    suggested tags as one-tap chips when the opt-in feature is enabled.
  • Notes are a real textarea: Enter inserts a newline, Cmd/Ctrl+Enter
    saves from anywhere; Enter in URL/title saves (enterKeyHint go/done).
  • Draft protection: tapping outside a non-empty draft no longer
    discards it; Cancel and Esc still do.
  • All touch targets >=44px; Radix Dialog provides focus trap, scroll
    lock and aria wiring; entrance animations respect
    prefers-reduced-motion.

BookmarkInlineCard is now edit-only (the URL was never editable there
anyway since URLs are immutable after create), dropping its isNew
branches, paste button and draft badge. Draft-card tests moved to
AddBookmarkDialog.test.jsx and extended (suggestions, disabled save,
newline-in-notes); inline card tests trimmed to edit behaviors.

Verified with Playwright at 390x844 (touch), 390x450 (keyboard up) and
1440x900: paste -> autofill -> tag -> read-later -> save -> toast ->
appears in list and in the Read Later filter; invalid URL and dirty-
draft dismissal probed. npm run test:coverage passes all thresholds
(52 files, 1282 tests).

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01NibfKDyuyzU7MPgyeNe7yD

Redesigns the add-bookmark flow from first principles around its one
job: capture a link fast. New bookmarks no longer use the inline draft
card at the top of the list; they go through a new AddBookmarkDialog.

Why: the inline card scrolled with the list under the sticky header, so
on phones the tags row and Save/Cancel actions routinely ended up under
the soft keyboard, Enter-to-save was the only reliable affordance, and
multi-line notes were impossible (Enter saved, Shift+Enter doesn't
exist on touch). The URL - the only required field - was a 16px line at
the top of a form that gave title and description equal billing.

The new dialog:

- Bottom sheet on mobile: pinned to the viewport bottom with a sticky
  footer, so the full-width Save button stays visible above the
  keyboard (verified at 390x450 keyboard-up viewport - the body
  scrolls, the footer doesn't). index.html now sets
  interactive-widget=resizes-content so Android Chrome resizes the
  layout viewport. Centered top-anchored dialog on sm+.
- URL first: the only required field, hero position, one-tap Paste
  button inside the field, Save disabled until a URL is entered,
  inline errors for invalid/unreadable clipboard.
- Content suggestions finally reach manual adds: committing a URL
  (paste or blur) auto-fills empty title/description and offers
  suggested tags as one-tap chips when the opt-in feature is enabled.
- Notes are a real textarea: Enter inserts a newline, Cmd/Ctrl+Enter
  saves from anywhere; Enter in URL/title saves (enterKeyHint go/done).
- Draft protection: tapping outside a non-empty draft no longer
  discards it; Cancel and Esc still do.
- All touch targets >=44px; Radix Dialog provides focus trap, scroll
  lock and aria wiring; entrance animations respect
  prefers-reduced-motion.

BookmarkInlineCard is now edit-only (the URL was never editable there
anyway since URLs are immutable after create), dropping its isNew
branches, paste button and draft badge. Draft-card tests moved to
AddBookmarkDialog.test.jsx and extended (suggestions, disabled save,
newline-in-notes); inline card tests trimmed to edit behaviors.

Verified with Playwright at 390x844 (touch), 390x450 (keyboard up) and
1440x900: paste -> autofill -> tag -> read-later -> save -> toast ->
appears in list and in the Read Later filter; invalid URL and dirty-
draft dismissal probed. npm run test:coverage passes all thresholds
(52 files, 1282 tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NibfKDyuyzU7MPgyeNe7yD
@netlify

netlify Bot commented Jul 11, 2026

Copy link
Copy Markdown

Deploy Preview for hypermarkk ready!

Name Link
🔨 Latest commit 6bd69ec
🔍 Latest deploy log https://app.netlify.com/projects/hypermarkk/deploys/6a521b00d770520008b50ac4
😎 Deploy Preview https://deploy-preview-46--hypermarkk.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

claude added 2 commits July 11, 2026 10:17
Opening the add-bookmark dialog on a real iPhone zoomed the page and
pushed the sheet off screen. iOS Safari auto-zooms whenever a focused
form control's font-size is under 16px, and the dialog autofocuses its
URL field, which (like every input in the app) rendered at 14px
(text-sm) — so the zoom fired on open, before any tap on the field.

Force all text inputs, selects and textareas to 16px below the sm
breakpoint (!important to beat Tailwind's .text-sm utility). This also
covers the search bar, tag inputs and the inline edit card, which would
trigger the same zoom on focus. Desktop keeps the compact 14px sizes.

Verified via Playwright: computed font-size is 16px for URL/title/
notes/tags/search at 390px and 14px at 1440px, with the sheet layout
unchanged. Full test suite passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NibfKDyuyzU7MPgyeNe7yD
On iPhone the sheet's save footer disappeared behind the keyboard. iOS
Safari ignores interactive-widget=resizes-content and overlays the
keyboard on the layout viewport, so a bottom-0 fixed sheet stays pinned
under it.

While the dialog is open, track window.visualViewport (resize + scroll)
and compute how much of the layout viewport the keyboard covers
(innerHeight - vv.height - vv.offsetTop, so it also handles Safari
scrolling the visual viewport). The inset is written to CSS variables
on the sheet element, consumed only by the <640px positioning rules:
bottom lifts by the keyboard height and max-height caps to the visible
area. With no keyboard the variables resolve to the original
bottom-pinned sheet; desktop positioning never reads them.

The element handle uses callback-ref state rather than a plain ref -
Radix assigns the forwarded ref after parent effects run, so a useRef
was still null on the effect's first pass.

Verified in Chromium with a scripted visualViewport fake: 336px
keyboard -> sheet bottom lifts 336px and the Save button sits above the
keyboard line; dismiss -> returns to bottom:0; desktop dialog position
unchanged. Full suite passes (52 files, 1284 tests) with new unit tests
covering the inset math and keyboard dismissal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NibfKDyuyzU7MPgyeNe7yD
@pheuberger pheuberger merged commit f0ae72a into main Jul 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants