Toolbar and icon redesign#349
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
WIP, not ready for review yet. |
|
Ready for review Comparison (with audio)
|
|
Oh and all the icons look beautiful by the way! |
Plan for the link tool:The thesis of svedit is visual in place editing. |
…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.
|
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;
I tweaked the css try fallback options for the anchor positioning, toolbar is now always in view. @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 |
|
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. |
|
autofocus issue is fixed too now |
|
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: Update after digging in:
|
make save sticky in toolbar.
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. |
|
Regarding the NodeNavigator: |
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.
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?
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.
scrol-to-text-issue.mov |
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. |
video is not loading, but I'll try to replicate |
|
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 |
|
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. |
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 |
Will push the fix for the scroll issue in the next ~30min |
|
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 |
|
just learned that iOS never ever supported the pseudo element ::selection ... 😵💫 |
| const selected_element = focus_node.parentElement; | ||
| setTimeout(() => { | ||
| try { | ||
| if (anchor_node.isConnected && focus_node.isConnected) { |
There was a problem hiding this comment.
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.
| // 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. |
There was a problem hiding this comment.
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. 🫣
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
So when the caret is in view, no scroll when changing marks, e.g making text bold
ah yeah, sorry forgot about that one.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
nice I'll check it out tomorrow
…iew in the browser." This reverts commit 6bd4469.
|
Merged work until "more elegant node selection markers" Separate PR's for individual fixes (like #350) for easier review/experimentation. |



Addresses issues discussed here:
#322 (comment)
Full list of changes:
Toolbar architecture (Toolbar.svelte)
Mobile keyboard
Link editing
NodeNavigator polish (Michael's component, demo-only)
Integration