Skip to content

Toolbar and icon redesign#349

Merged
michael merged 20 commits into
mainfrom
toolbar-and-icon-redesign
Jul 21, 2026
Merged

Toolbar and icon redesign#349
michael merged 20 commits into
mainfrom
toolbar-and-icon-redesign

Conversation

@johannesmutter

Copy link
Copy Markdown
Collaborator

Addresses issues discussed here:

#322 (comment)

Full list of changes:

Toolbar architecture (Toolbar.svelte)

  • Replaced per-button bubbles with two unified pill toolbars: a floating contextual toolbar (desktop) and a persistent bottom toolbar — built from shared snippets, zero duplicated markup
  • Floating toolbar positioned with pure CSS anchor positioning on the selection's element (position-anchor, flip via position-try-fallbacks, auto-hide via position-visibility), re-mounted per anchor to avoid stale-position bugs
  • Contextual compositions: text → text tools; node gap → insert only (nothing if not insertable); node → section/marker + NodeNavigator + delete; property → NodeNavigator + delete + image input
  • Disabled-instead-of-hidden within groups; undo/redo rendered from first paint (disabled until commands register) — no load reflow
  • Bottom bar: desktop shows only undo/redo/Save (fully static); mobile is one scrollable bar including Save
  • Scrolling moved into an unpadded, pill-clipped inner scroller — sticky tools pin at exact scrollport edges, content can't leak into padding or rounded corners
  • Sticky << (select-parent) left and keyboard-dismiss right; dividers flush while pinned, 4px outer margin at rest
  • << ladder ascends text → node → parent, hidden at top level; delete moved behind undo/redo on mobile
  • No gaps between buttons (hitboxes tile); hover styles gated to @media (hover: hover) (no stuck hover on touch); no fade transitions (double-toolbar artifact); pulse animations removed
  • All colors from existing variables or relative oklch(from …) colors; active state uses --svedit-editing-fill

Mobile keyboard

  • Viewport meta: interactive-widget=resizes-content + maximum-scale=1 (input-zoom suppression), no viewport-fit=cover (tab-bar gap fix)
  • iOS keyboard inset via visualViewport with an exponential follower (smooth, no lag)
  • New keyboard-dismiss button (treated hide-keyboard.svg), touch-only, text selections only

Link editing

  • Link mark URLs editable inline, same pattern as image URLs (writes to the mark's payload node)
  • Link creation without window.prompt: creates empty href, autofocuses the input (preventScroll, model-value param — fixes the link-click scroll), Escape cancels and removes
  • URL inputs: flat, font: inherit at 14px, content-sized width with shared --toolbar-item-max-width, no redundant "URL:" label or divider next to the link icon

NodeNavigator polish (Michael's component, demo-only)

  • Flattened (no nested border/background/shadow), no optgroup headings over single options, label truncated at the shared max-width, pulse removed with explanatory comment

Integration

  • Checkout updated to TypeScript main; entire redesign ported to TS and the new APIs; NodeNavigator adopted in place of the cycle buttons; Toolbar moved after Svedit in +page.svelte (anchors must precede the positioned element)

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
svedit Ready Ready Preview, Comment Jul 21, 2026 11:36pm

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

WIP, not ready for review yet.

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

Ready for review

Comparison (with audio)

Before After
RPReplay_Final1784381879.MP4
RPReplay_Final1784381993-2.mp4

@michael

michael commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Probably the best rich text editing experience I've seen on mobile so far! Amazing! 👏

  • keeping the tools visible above the VirtualKeyboard makes a huge difference!
    • flickering is a bit annoying but I hope one day placing above the keyboard with native means will fix that
  • I actually very much enjoy the Escape workflow. Yes it's maybe one extra click, but the Escape button being always visible on the left, makes it quite accessible. You don't need to think about document structure, you just put a selection anywhere deep in the document, press Escape once and you have the context.
  • Agreed, toolbar feels more calm when its a continuous shape, not multiple floating buttons.

Regarding "floating tools on Desktop":

  • It's fine to have that now in the Svedit demo as an alternative approach to explore
    • below points are no change requests, as this is more a personal opinion
  • Personally I'm not a big fan of the floating tools:
    • they appear in places of my workspace rather unexpectedly
    • sometimes right under my cursor I accidentally click a tool, but i just wanted to make a new selection
    • they are covering content where I'm working currently
  • Issues
    •  When you select multiple nodes (more than can be fit on one screen) you'll often see no tools (e.g. you have to scroll all the way up where the selection begins to make a section or add a marker (I think here the fixed toolbar works better)
    • Currently for very long paragraphs exceeding the screen height you see no tools either (because they are at the top of the node). For text selections this would be solved once we always have an positioning anchor for any selection, but the above issue with selecting multiple nodes still persists)
    • In Editable I already have some app-specific separate floating tools like link preview/Image resizer/cropper etc then those would battle with the "main tools". So I think I will stick with a fixed toolbar in Editable for that reason
    • again i'm sure the issues are solvable, and it's maybe worth to have svedit explore that path because there are also clear benefits (like less mouse travel) and some people may prefer this as it's more contextual, easier to discover things. Just for me personally the "clean canvas + fixed toolbar" approach is favorable.

Bugs found (while testing on Desktop)

  • Because you now auto-focus the URL field when the edit link tool is open, there's a focus-race-condition. Try create a new link (focus is set to the URL field) then click at some other text at the canvas the URL editor doesn't close, instead grabs the focus back. The reason is that when the svedit canvas transitions from unfocused to focused it needs a rerender (to clear the selection fragments that are only allowed in unfocused state, which grabs the focus, so as a known limitation you have to sometimes click twice, first to select the canvas and another time to move the selection where you actually wanted).
    • quick fix for the demo: don't autofocus the URL field
    • the real solution for apps is to replicate the flow I have in editable.website (no input fields in the toolbar (means no focus stealing/battling), show link preview when cursor is under the link, click on edit opens modal for url editing with an explicit confirm button - same for link creation: this is the same flow as google docs has for it)

As said the mobile experience is almost perfect I'd say. Just a few questions to you:

  1. it has a lovely icon, but maybe we should drop the "hide keyboard" tool, since there's a native button for that right underneath? Then we could make the save button sticky on the right instead (and save some space)? Probably even make Undo/Redo + Save sticky?

  2. Currently (only on mobile it seems) when I create a new button in story.buttons, the URL field gets auto focus. I find that surprising, would rather stay on the canvas and type the label, but also have tools to create and edit the link. E.g. here's how it looks for a nav item or button in Editable: image What do you think?

  3. You are not showing the node inspector on text selections now. I think this is good as it makes space for the text tools. Only minus is that you'd need to first "escape" in order to discover the text type (paragraph, heading). I mean maybe this is perfectly fine, and nudges you to discover and use the escape tool right from the start. Wdyt?

Related: Maybe this is hint that the node inspector should be less magical too, because currently, the node type/variant that is shown is computed like this:

  • find the closest node with variants (where you can switch something)
  • if no "switchable node" found, show the current node type+variant (but read-only just as an info)

If we wanted to have a 1:1 link from what is selected, and what is shown in the node inspector, we should always show the the current selected node, no auto-parent-discovery. This would mean:

  • click inside a list item
  • press ESC (selects the list_item and shows "List item" in the node inspector - nothing to switch/toggle)
  • press ESC again (selects the whole list and shows "List (square)" - now you can switch, and because of what is selected you know exactly what will be switched)

So that would be less magical, and technically correct, but comes at cost of extra Escape clicks and maybe there's a case to say that users should not be bothered with detail info like "List item" or "Image grid item" because to them only "List" or "Image grid" is relevant. Anyways the purist in me is bothered by the inconsistency that currently you select a list item, but the node inspector says "list" and when you switch the variant you will notice that the selection changes to the parent node (the one that has the variants). What do you think? Should it be more exact, or is that "magic lookup" I'm doing now helpful (without being too confusing)?


No code review done just yet. Focus on the specs/decisions first.

@michael

michael commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Oh and all the icons look beautiful by the way!

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

Plan for the link tool:

The thesis of svedit is visual in place editing.
A read-only preview with an Edit button is the CMS-form ceremony, I thought we want to replace with something better. In my opinion it makes sense in a classic CMS, e.g. in Wordpress, but not when everything is editable and already in an editing state. So a nested "edit" toggle in a popover feels alien to this principle. caret → Edit → type → confirm feel also as too many extra steps. URL editing doesn't need extra safety (through multi step flow), compared to editing text in the canvas. A single state popover feels cleaner and more native to svedit, also less code.

LINK TOOL — FULL PICTURE
═══════════════════════════════════════════════════════════════════════

Two surfaces, never visible at the same time
────────────────────────────────────────────

  RANGE SELECTED  (formatting mode)     CARET INSIDE LINK  (link mode)
  ─────────────────────────────────     ──────────────────────────────
  floating toolbar (desktop)            link popover, anchored below
  bottom bar (mobile)                   the link (desktop AND mobile)

  ┌───────────────────────────┐         … sample [selected] text …
  │ ‹ │ B  I  <>  ✎  🔗 │ …  │                       │caret
  └───────────────────────────┘         ┌────────────┴────────┬───┬───┐
   · link = toggle only                 │ https://svedit.dev ↵│ ↗ │ ⌫ │
   · NO URL input in toolbars anymore   └─────────────────────┴───┴───┘
   · inside a link: B/I disabled,         │                     │   │
     not hidden (stability)               │                     │   └ remove link
                                          │                     └ open in new tab
                                          └ URL input, directly editable
                                            ↵ = hint glyph only (not clickable),
                                            inside the field, right-aligned,
                                            input padding reserves its space

Flows
─────
  CREATE   select text → tap link toggle → link created (href: "")
           → popover appears at caret → type URL → ↵ commits + closes (morph from annotation toolbar)

  EDIT     click anywhere into link text (plain caret, no range needed)
           → popover appears → click input → type
             ↵ / blur = commit   (one `set` per edit, unchanged = no-op)
             Esc      = revert + close (a still-empty link is removed)

  REMOVE   ⌫ button only — clearing the field ≠ removing the link

  OPEN     ↗ button in popover
           ⌘/Ctrl-click the link while editing (title hint on the <a>)

…esign (toolbars, popovers), and global declarations like min-height silently fight their explicit sizes (min-height beats height). Style buttons where they live — the perftest page carries its own defaults.
@michael

michael commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Proposal sounds good. Let‘s try, and see how it feels!

one toolbar, separate from annotation toolbar.
one click to edit and autosave on blur;
highlight broken links;
@johannesmutter

Copy link
Copy Markdown
Collaborator Author

When you select multiple nodes (more than can be fit on one screen) you'll often see no tools (e.g. you have to scroll all the way up where the selection begins to make a section or add a marker (I think here the fixed toolbar works better)

I tweaked the css try fallback options for the anchor positioning, toolbar is now always in view.
Remaining challenge: if there's e.g. a sticky main menu at the top, the toolbar could overlap it ... but then one could change the offset or change the placement fallback to e.g. bottom, or to next to the other toolbar with undo, redo and save.

@position-try --stay-in-viewport {
  ...
  top: calc(var(--top-toolbar-safe-area, 0px) + var(--s-2));
}
Screenshot.2026-07-19.003482.Svedit.-.A.tiny.library.for.building.editable.websites.in.Svelte.mp4

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

Generally I feel floating toolbars work well for selection of smaller items (in relation to viewport) ... but for both smaller screens and larger items fixed toolbars work better. So that's why mobile has always a fixed toolbar. For the Svedit demo I think it's good that both concepts are shown to developers. So they can see what suites there content better.

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

autofocus issue is fixed too now

@johannesmutter

johannesmutter commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

this iOS form assist toolbar here is a huge waste of space. Even the up and down chevrons are not clickable. Only that checkmark to close the virtual keyboard. Would prefer to get rid of that toolbar and keep the more compact custom hide toolbar button. But no idea if that's possible. if not sure we should remove the custom hide toolbar button

Filed a feature request for Safari:
https://bugs.webkit.org/show_bug.cgi?id=319762


Update after digging in:

  • Confirmed: web content cannot remove or slim the form assistant bar. The only known removals are native WKWebView overrides (what Capacitor's hideFormAccessoryBar does via an inputAccessoryView swizzle) — nothing reachable from Safari or a PWA. Filed a WebKit feature request: [link].
  • So: removed our hide-keyboard tool (the native checkmark covers dismissal) and made Save sticky on the right instead. Left undo/redo unpinned for now — pinning them too costs roughly 40% of the scrollable width on small phones, and they sit one scroll-tick left of Save. Easy to revisit after testing.
  • Had an idea to make the chevrons useful for text property navigation: but unfortunately not feasible. They only navigate real text-entry controls (inputs, textareas, independently focusable contenteditable hosts). But because Svedit is deliberately a single contenteditable canvas, a second field never exists for them to target, and tabindex on text properties doesn't enroll plain elements as form fields. The only architecture that would feed them is contenteditable-per-property, which would break the single-canvas selection model.
image

make save sticky in toolbar.
@johannesmutter

Copy link
Copy Markdown
Collaborator Author

You are not showing the node inspector on text selections now. I think this is good as it makes space for the text tools. Only minus is that you'd need to first "escape" in order to discover the text type (paragraph, heading). I mean maybe this is perfectly fine, and nudges you to discover and use the escape tool right from the start. Wdyt?

I think not overloading the toolbar with options is the priority here, and showing the tools "nested" mapping to the nested hierarchy of > node array > node > property > fragment ... is the right move.

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

Regarding the NodeNavigator:
IMHO mixing type and layout is not the right approach.
In my app I'm actually making type selection obsolete. There's just text and media. And layout. And layout selection is not expressed through a dropdown. Semantics are handled through an explicit, but optional semantics layer. You can keep everything untyped or type things: nodes, words, … content that is typed is then computable, e.g. to render a textblock that is typed with a date in a calendar.
...
but that's already going too far off topic 😆
...
So for svedit I think it's fine how it's done currently. Flexible and not too prescriptive.

@michael

michael commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Generally I feel floating toolbars work well for selection of smaller items (in relation to viewport) ... but for both smaller screens and larger items fixed toolbars work better. So that's why mobile has always a fixed toolbar. For the Svedit demo I think it's good that both concepts are shown to developers. So they can see what suites there content better.

Yes it looks good this way. On mobile the fixed toolbar feels very contextual and "close" because there's not so much screen estate anyways.


autofocus issue is fixed too now

Looks good now! 👍


On the native iOS form assist toolbar: Yes I think it's correct there's no way to remove it. Legitimate to request a way to opt out of this. We'd gain so much space for editing. Will bring this up at the next W3C meeting (see w3c/editing#545)

How is the situation with Android (currently have no device) are they showing a similar toolbar, or is it more compact there?


Regarding the NodeNavigator:
IMHO mixing type and layout is not the right approach.
In my app I'm actually making type selection obsolete. There's just text and media. And layout. And layout selection is not expressed through a dropdown. Semantics are handled through an explicit, but optional semantics layer. You can keep everything untyped or type things: nodes, words, … content that is typed is then computable, e.g. to render a textblock that is typed with a date in a calendar.
...
but that's already going too far off topic 😆
...
So for svedit I think it's fine how it's done currently. Flexible and not too > prescriptive.

I'd be very curious how you do it, I don't yet understand the mechanism for the description only. Is there some place to try this out at some url? Or have a video?


The edge cases with tools becoming placed outside of the screen are solved now. Just few glitches I noticed, which probably are not related to this work, but just surfaced because of it.

  • In a long text property that exceeds the screen boundaries, an unexpected scroll-to-selection takes place when togging/untoggling marks (expected: selection is already in view - no jump)
scrol-to-text-issue.mov

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

How is the situation with Android (currently have no device) are they showing a similar toolbar, or is it more compact there?

Generally android natively handles form navigation and dismissal directly inside the primary soft keyboard layout, not a separate form control toolbar, but there are so many different keyboards, so not sure what the actual landscape looks like. On my Android tablet it's much more compact compared to iPad toolbar.

@johannesmutter

Copy link
Copy Markdown
Collaborator Author
  • In a long text property that exceeds the screen boundaries, an unexpected scroll-to-selection takes place when togging/untoggling marks (expected: selection is already in view - no jump)

video is not loading, but I'll try to replicate

@michael

michael commented Jul 19, 2026

Copy link
Copy Markdown
Owner

video is not loading, but I'll try to replicate

let me know if you still need the video or more precise steps to reproduce

Small possible nit: For node cursors, would it maybe make sense to also expose the "backspace" tool on desktop? We show it for node selections but not for collapsed node cursos atm (on desktop the backspace tool is exposed). I suppose it's just hard to make this look nice visually with the floating tools approach? Maybe the "backspace. delete backwards" tool could live in the main toolbar near the undo/redo?

image

@michael

michael commented Jul 19, 2026

Copy link
Copy Markdown
Owner

A bit of new glitch, caused by the now always visible toolbar is that when you first click a text and the keyboard comes out, that the caret is behind the toolbar.

ScreenRecording_07-19-2026.17-42-19_1_smaller.mov

@michael

michael commented Jul 21, 2026

Copy link
Copy Markdown
Owner

FYI: Planning to merge this later today, and prepare a Svedit 0.13.0 release. Would create a separate issue for the remaining issues, which we can address anytime later. Will start evening-ish.

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

For node cursors, would it maybe make sense to also expose the "backspace" tool on desktop? We show it for node selections but not for collapsed node cursos atm (on desktop the backspace tool is exposed).

I think the backspace tool should not appear on desktop. It's too easy then to misclick and accidentally (and maybe without noticing) delete the previous node. It's why on mobile I already put it on the far right in the toolbar. Also it creates decision fatigue, when there's both the + button and the delete button next to each other. For a regular click at most one new tool should appear where you click: a drag handle, an "add" button, ... drag click is a different story ... because that's a more controlled gesture, so the user is already more careful, but single click ... too dangerous to break stuff

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

FYI: Planning to merge this later today, and prepare a Svedit 0.13.0 release. Would create a separate issue for the remaining issues, which we can address anytime later. Will start evening-ish.

Will push the fix for the scroll issue in the next ~30min

@michael

michael commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Kk. Take your time, I'm still busy with VPS deployment stuff for Editable.

BTW: Can now deploy deploy to a naked DigitalOcean droplet for instance. Should also work for Nodion, Hetzner etc.

https://github.com/michael/editable/tree/generic-deploy#deploy-to-a-vps-experimental

@johannesmutter

Copy link
Copy Markdown
Collaborator Author

just learned that iOS never ever supported the pseudo element ::selection ... 😵‍💫
so nicer rendering of text + node selection highlights is not really possible atm.

https://caniuse.com/css-selection

Comment thread src/lib/Svedit.svelte Outdated
const selected_element = focus_node.parentElement;
setTimeout(() => {
try {
if (anchor_node.isConnected && focus_node.isConnected) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is too defensive. If we have an anchor_node reference we can assume it's in the visible DOM. Also had to battle this defensive coding style several times.

Comment thread src/lib/Svedit.svelte Outdated
// viewport on every re-render (e.g. annotation toggles). Capture the
// nodes now: the browser selection is live and may be cleared before
// this deferred callback runs, e.g. when app UI focuses an external
// input.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which issue is this solving?

It doesn't address the cursor gets rendered behind the toolbar on mobile (see #349 (comment)). I mean technically nothing is wrong, the cursor IS in the viewport, just happen to be covered by the toolbar now because we moved it above the soft keyboard.

I don't really have a good idea how to solve this reliably either. I mean we could somehow redefine "visible screen" and exclude the lower part (safe zone for toolbars). And then we somehow need to tell the scrollIntoView mechanism that a collapsed cursor should not just be visible but visible above the safe zone.

Tricky, also an option to just accept the behavior for now, until we get an idea. the whole mechanism we have in place that uses native scrollNodeIntoView is still full of edge cases we don't cover, and possibly we need to handle this manually to get reliable results (like our own scroll_into_view that respects parameters like safe zones). Maybe this topic needs a dedicated release. 🫣

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is addressing the issue you mentioned here:

In a long text property that exceeds the screen boundaries, an unexpected scroll-to-selection takes place when togging/untoggling marks (expected: selection is already in view - no jump)

So when the caret is in view, no scroll when changing marks, e.g making text bold


Yeah been trying all kinds of alternative approaches this evening.

at least one intersting approach for perfect toolbar stability when scrolling came out of this, explained by claude below:

Before (fixed + translate): position: fixed on iOS pins an element to the layout viewport — but the keyboard only shrinks and pans the visual viewport, the window you actually see. Whenever iOS panned the visual viewport (keyboard reveals, scrolling with the keyboard open, rubber-banding), the fixed toolbar's visual position drifted, because its anchor (the layout viewport) was moving relative to your eyes. The JS compensated by listening to visualViewport resize and scroll and re-translating via --keyboard-inset — but those events arrive after the frame in which the viewport already moved, and iOS reports jittery, sometimes stale values mid-pan. So the toolbar rendered at the old spot for a frame, then corrected: that's the flicker. The exponential follower smoothed the jitter but bought that with visible lag ("toolbar lags behind the finger"). Structurally it was a chase loop: main-thread JS trying to track compositor-driven viewport motion, per frame, forever — during every scroll.

Now (grid layer in the shell): the toolbar's position is a layout fact, not a chased value. It sits in the shell's grid, pinned by align-self: end plus margin-bottom: var(--keyboard-inset). Its inputs are the shell height (static while editing) and the keyboard inset — and crucially, scrolling changes neither. The document is locked, so the layout viewport never pans; all scrolling happens inside .app-scroller, which is an ordinary element scroll that can't move anything outside itself. During scrolling there is literally nothing to update — zero JS, zero events, the compositor moves only the inner content while the toolbar layer stays put. The only moments JS touches anything are the keyboard's open/close transitions: a handful of events across ~250ms, each a single CSS-variable write, no follower or smoothing needed because there's no continuous drift to smooth.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So when the caret is in view, no scroll when changing marks, e.g making text bold

ah yeah, sorry forgot about that one.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that assumes the svedit doc is fullscreen, would cause double scrollbars when svedit is just a container in another layout. e.g. a small comment box. But maybe fine

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. So the toolbar positioning is app-land (or Svedit-demo land) not library land. We should be careful not to mix them up. Atm, Svedit does that right thing in terms of scroll things into viewport. It doesn't, and shouldn't know about collisions with toolbars etc. A bit of a cat and mouse hunt here. The challenge is really to only provide means that an app can do "corrections", but not tangle up Svedit with app concerns.

That said, hacks to improve this are fine in routes/* but shouldn't be placed in lib/*.

Totally fine if we address this later, maybe this just needs an idea spark in a calm moment.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes svedit should always try to have the caret in the center of the layout viewport when the software keyboard is open. because we cannot make assumptions e.g. that there's a bottom or a top toolbar.

But also svedit could have an opinion how to create super stable toolbars that don't lag, jitter, etc.
The idea with the grid layer in the shell is quite a promising direction. I have never seen this stability on a web based bottom toolbar before, only in native apps.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's experiment with that. I'd suggest we get this PR merged until the "more elegant node selection markers" commit, and you work on the fixes/improvements in a new PR? We can try out different approaches and compare?

That ok for you?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never seen this stability on a web based bottom toolbar before, only in native apps.

TLDraw has a stable mobile toolbar, but I think they don't have a body-scrollable container involved. but they also somehow deal with the opening/closing of the virtual keyboard reliably.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice I'll check it out tomorrow

@michael
michael merged commit 004b316 into main Jul 21, 2026
1 of 2 checks passed
@michael

michael commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Merged work until "more elegant node selection markers"

Separate PR's for individual fixes (like #350) for easier review/experimentation.

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