Skip to content

Pick a row or folder, then copy and paste it - #160

Merged
ryankiley merged 32 commits into
mainfrom
ryan/scoped-paste
Oct 19, 2026
Merged

ryankiley merged 32 commits into
mainfrom
ryan/scoped-paste

Conversation

@ryankiley

@ryankiley ryankiley commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

A press in the panel's side padding level with a row picks it, as a layer is picked in a design tool, and a press beside a folder's header picks the folder; the pick shows as a soft band behind it, edge to edge, reaching 3px past the row on both sides; nothing moves, and focus moves to the picked control or header without a ring. ⌘C and ⌘V (ctrl elsewhere) then act on the pick, or with nothing picked on the page, on the row holding focus: a row copies its value and pastes one back, and a folder copies its values object and pastes into its own keys, so two folders with the same keys trade values. Both run through the browser's own copy and paste events, so the system clipboard works in and out with no permission prompt. A paste lands only what fits each control and answers on the band, brightening when it lands and tinting red when nothing fits; a screen reader hears either. Escape or a press elsewhere drops the pick, a text field, a selection or a held key keeps the browser's keys, and it fits the 23 KiB gate.

Paste reads the clipboard inside the click and takes back a copy's values object, the changed-only map or a whole toJSON() state through fromJSON, one undo step, saved and announced like any load. A value lands only where it fits the control, so a stray key, a mistyped value or a reserved path is skipped, never coerced or written onto a prototype; nothing usable shows a red cross. The parse lives in a lazy chunk, the markup toolbar gets the same button, and the gate moves to 23 KiB for the icons.
⌘C and ⌘V act on the row or folder under the pointer, else the one holding focus. A row copies its value and pastes one back; a folder copies its values object and pastes into its own keys, reading a whole-panel copy at its own path, so two folders with the same keys trade values. Only the panel under the pointer acts, focus on the page or in a text field keeps the browser's keys, the copy and the read happen inside the keypress, and pastes pass the button's checks.
A press in the panel's side padding level with a row picks it with a ring, and beside a folder's header picks the folder; ⌘C and ⌘V act on the pick, or with none on the page on the focused row, in place of whatever the pointer rested on. Escape or a press elsewhere drops the pick, and the page holds one. The gate moves to 24 KiB for what core runs inside the press and the keypress.
@ryankiley ryankiley changed the title Copy and paste a folder or a row with the keyboard Pick a row or folder, then copy and paste it Oct 18, 2026
The pick's ring becomes a filled band behind the row, in the accent at low strength, running across the panel to its edges at any nesting depth and meeting its neighbours halfway across the gap; the panel clips it to its rounded edge while something is picked.
A disabled control takes nothing; a tuple must keep its length and a list of stops stay between 2 and 64; a colour must be one the browser can parse, not just one that starts like it; a key holding a literal dot pastes back from the panel's own copy; and a layout that changes nothing reports nothing pasted.
…right

A folder's paste tries each reading of the copy, as it stands and unflattened, at the folder's path and as its own, and takes the one that lands most, so a folder whose subfolder shares its name pastes its own copy back. A copy that finishes after destroy() shows no toast.
A picked row eases 3px of room open on both sides, so its band clears the row's surface by 6px above and below wherever it sits, under a folder's header or at the end of a run, and still stops 3px short of its neighbours.
The band behind a picked row drops from 16% to 9% of the accent, near the kit's own hover tint.
The panel page gets a Copy & paste example: two lights driven by two folders with the same keys, picked, copied and pasted onto each other. A new test copies every valued type's row onto its twin and a whole folder of them in one step, and pastes each onto every other type to check nothing crosses where it shouldn't.
The picked row is in view, so the toolbar's copy and paste icons flashing their check or cross say enough; the toolbar buttons themselves keep their toast.
Tweakit no longer shows toasts. The copy button confirms with its icon's check alone, the presets menu with its list and the values it loads, and a markup button with no handler does nothing visible; the toast's code and CSS go, 234 B off the core download.
# Conflicts:
#	site/pages/panel-api.mjs
With the toast gone, one visually hidden status region for the page says it in words instead: values copied, nothing changed, copy failed, a preset saved or loaded. Sighted users see nothing new.
The toolbar's paste button, its icons, the markup toolbar's paste and the whole-panel paste go; a picked row or folder's ⌘V keeps the same checks and answers on the band itself, brightening when a paste lands and tinting red when nothing fits. Picking fits main's 23 KiB gate without a raise.
@ryankiley
ryankiley changed the base branch from ryan/paste-button to main October 18, 2026 21:41
The picked row no longer eases its neighbours apart: its band reaches 3px past it, halfway across the gap, on both sides. The bodies that clip a folder or the panel set their clip edges 3px further out, offset by an equal negative margin, so a first or last row's band isn't cut; every row's position matches main in open, folder-collapsed and panel-collapsed states.
…it to the panel

A pick out of sight (filtered, hidden by its condition, folded away, on another tab) takes nothing; picking lets go of focus and any selection so the keys answer to the pick; rows are found by their own box, not a probe an overlay can block; a touch never picks; a press in a picked folder's indent picks the row; a removed panel frees the page's pick; and a paste is its own undo step. The band is lighter than a slider's fill and an inline panel clips it to its rounded corners.
Picking a row now focuses its control and picking a folder focuses its header, so its keys work and a screen reader names it. A mouse pick shows no focus ring, and a text row isn't focused, so ⌘V still pastes the row. Focus left on a row that went out of sight no longer takes ⌘C or ⌘V.
On a loaded runner a refusal can answer after the test's 200ms wait, and the test counted that silent band as a paste that landed. It now waits up to 2s and fails plainly if the band never answers.
A picked ⌘C or ⌘V now steps focus to one hidden field for the keypress, lets the browser copy or paste there, and steps back. That uses the system clipboard both ways with no permission to grant, where reading the clipboard directly was denied in some browsers and the paste did nothing. The band's flash moved into the lazy paste chunk to stay inside the size gate.
Each paste's flash cleared itself after 450ms on a timer the next paste didn't cancel, so a quick second paste on the same row lost its flash early. On a loaded runner that made the cross-type test see no answer. A new flash now cancels the old timer.
In some browsers the copy or paste a keypress runs arrives a few milliseconds after the keydown, passed on by the app's menu. Focus had already stepped back from the hidden field by then, so the paste landed on the slider and nothing caught it. Copy and paste are now caught page-wide, and focus steps back when one lands, or after a second with none.
A picked ⌘C no longer flashes the check on the toolbar's copy button, which copies the whole panel and so read as the wrong thing. A screen reader still hears what was copied.
@ryankiley
ryankiley merged commit 9103440 into main Oct 19, 2026
2 checks passed
@ryankiley
ryankiley deleted the ryan/scoped-paste branch October 19, 2026 01:15
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.

1 participant