Repository navigation
feat(app): rebuild Knobs as a stack of features - #57921
Conversation
There was a problem hiding this comment.
The new layout works as described, with one problem. In happy-dom, Global renders as its own panel above the tabs, Experiments sorts last, the tab strip disappears when there is only one section, and the panel test and the packages/ui typecheck both pass. I couldn't render it in a real browser here, so before/after screenshots or a short clip of the debug-bar panel would help.
Public API: unchanged. The only addition is an internal knobs store id, opencode-motion-global.
Concerns:
- Duplicate toolbar (inline): the lower panel still shows a header toolbar with no title, and each header's Reset, Copy and Random now covers only half the knobs.
- Variants drop Speed and Slow motion: Global now lives in a store with
persist: "none", so a saved variant no longer records or restores them. Older saved variants still load, but their Global values are ignored. If that's intended, it's fine.
| ...keys, | ||
| }) | ||
|
|
||
| const stopPanel = controls.mount(lower, { |
There was a problem hiding this comment.
title: false only clears the title text. In knobs 0.3.0 the header (Undo/Redo/Reset/Copy/Random) still renders unless header: false is passed. In happy-dom, all five buttons stay visible here, so there's a second, untitled toolbar row between Global and the tabs. The two toolbars also split the panel-wide commands: the top Reset, Random and Copy now cover only Speed and Slow motion, and this one covers only the sections. Either hide this header and keep one set of panel-wide commands, or make sure both headers' Reset and Copy cover all knobs.
9809aa0 to
7b663e5
Compare
d61497f to
5cbd2e4
Compare
There was a problem hiding this comment.
The new commit fixes my earlier point (thread 1). There is now one store and one panel, with Global as a pinned group, so the second untitled header and the split Reset/Copy are gone. I checked it in happy-dom: motion-tuning-panel.test.ts passes (4 tests), and the packages/ui and packages/gui-extensions typechecks are clean. I couldn't check it in a real browser.
Public API: unchanged. motionTuning gains optional section, description and target, which are internal. knobs moves to the prerelease 0.4.0-next.12, as the description notes.
New concern: the hover outline flickers as the pointer moves within a single row (inline).
packages/ui/src/motion-tuning-panel.ts:266:pointeroverbubbles from every child element of a row, so moving the pointer across one row callsshowrepeatedly. Each call runsclear(), which fades out and removes the current frame, then adds a new one at opacity 0. In happy-dom, hovering a row and then one of its child elements left two frames: the first at opacity 0, the second a new element. The outline blinks while the pointer moves across a row. Keeping the frames when the[data-field]/[data-group]spot hasn't changed since the last call (and only clearing when it does) would avoid this.
5cbd2e4 to
bf8dbcd
Compare
There was a problem hiding this comment.
The newest push looks sound. My earlier point about the second, untitled header is fixed, since the panel is now a single store with Global pinned. The new per-tab presets (scopedPresets) and the mode switching that now follows its tab read correctly. I checked in happy-dom: motion-tuning-panel.test.ts passes (4 tests) and the packages/ui and packages/gui-extensions typechecks are clean. I couldn't check it in a real browser.
Public API: unchanged. The knobs dependency is now the prerelease 0.4.0-next.13.
bf8dbcd to
36375f5
Compare
There was a problem hiding this comment.
The latest changes look sound, with no new concerns. They add a card per experiment, ordered sidebar to composer, rename rows, pass card descriptions as groupDescriptions, and gate Rounded stop size with when. The earlier point about the second, untitled header stays addressed, since Global is pinned in the single panel. Knob ids and the opencode.motion.v2 storage key are unchanged, so values already saved on a device still load.
I checked it with tests and type checks: in packages/app, motion-tuning-panel.test.ts and panel-motion.test.ts pass (19 tests); in packages/ui, motion-tuning.test.ts passes (4 tests). Typechecks are clean in packages/ui, packages/app and packages/gui-extensions. I didn't render the panel in a browser; the description's before/after image covers it.
Public API: unchanged. description and target are new optional fields on the internal motionTuning options.
There was a problem hiding this comment.
The latest push looks sound, with no new concerns. The hover-outline flicker I pointed out earlier is fixed: the outline now comes from knobs' onActive and only redraws when the target changes. The doubled-header point stays addressed. Card descriptions now render under each card's title, and Experiments cards fold. In happy-dom, a folded card's summary updated live when its choice changed from outside the panel.
I checked it with tests and type checks: in packages/app, motion-tuning-panel.test.ts and panel-motion.test.ts pass (19 tests); in packages/ui, motion-tuning.test.ts passes (4 tests). Typechecks are clean in packages/ui, packages/app and packages/gui-extensions. I didn't render it in a browser; the description's before/after and hover images cover it.
Public API: unchanged. The knobs prerelease moves to 0.4.0-next.16 in both packages/ui and packages/app.
5d06896 to
2519d1b
Compare
There was a problem hiding this comment.
The new commits look fine, with no new concerns: they add a description to the Sidebar hover card and move knobs to 0.4.0-next.17 in packages/ui and packages/app. The earlier doubled-header point stays addressed.
I checked it with tests and type checks: in packages/app, motion-tuning-panel.test.ts and panel-motion.test.ts pass (19 tests); in packages/ui, motion-tuning.test.ts passes (4 tests). typecheck:tsc is clean in packages/ui, packages/app and packages/gui-extensions. I didn't render it in a browser; the description's images cover it.
Public API: unchanged.
2519d1b to
56b82da
Compare
There was a problem hiding this comment.
This push reworks the panel, and I found nothing that would block it. Speed and Slow motion become one global.speed choice, with motionGlobals.time() = 1/speed. The debug bar's SPEED and SLOW cells drive that choice, the panel gets area tabs with folded per-feature cards, and knobs moves to 0.4.0-next.20. The earlier doubled-header point stays addressed: there's one store and one header, with Global pinned. Nothing else in the repo still reads motionGlobals.slow. Saved speed/slow values are dropped, as your Risk section notes.
I checked it with tests and type checks: in packages/app, the panel and motion browser tests pass (30) and the components-lab tests pass (4); in packages/ui, motion-tuning.test.ts passes (4). typecheck:tsc is clean in packages/ui, packages/app and packages/gui-extensions. I didn't render it in a browser; the description's screenshot covers it.
Public API: unchanged. motionGlobals and the knob ids are internal developer tooling.
56b82da to
1036192
Compare
There was a problem hiding this comment.
The rebuild type-checks cleanly across the four changed packages, and the new motion-tuning-features tests pass, but one existing test now fails.
I ran the tests closest to the change: in packages/ui, motion-tuning-features.test.ts and motion-tuning.test.ts pass (6); in packages/app, the components-lab tests pass (4). typecheck:tsc is clean in packages/ui, packages/app, packages/gui-extensions and packages/session-ui. Nothing still imports motion-tuning-panel or the message menu. I didn't render the panel in a browser; the description's screenshots and video cover it.
The earlier doubled-header point no longer applies, since the knobs panel is gone.
Public API: unchanged. @opencode/ui's internal ./motion-tuning-panel export is replaced by ./motion-tuning-features, and nothing else in the repo used the old one.
Blocking: test-browser/panel-motion.test.ts now fails one test, "swaps the spring knobs for James's while it's on" (inline). It passes on pr/base.
|
|
||
| const group = "Sidebars" | ||
|
|
||
| const subsection = "Open & close" |
There was a problem hiding this comment.
Moving the Sidebars knobs into subsection: "Open & close" breaks test-browser/panel-motion.test.ts › "swaps the spring knobs for James's while it's on". The test still selects knob.group === "Sidebars" && !knob.subsection, so it now finds nothing and fails at line 457 ([] instead of ["Spring", "Motion", "Contents fade", "Edge fade"]). The file passes 16/16 on pr/base and 15/16 here. Filtering on knob.subsection === "Open & close" in the test should fix it.
1036192 to
f61d421
Compare
There was a problem hiding this comment.
The failing test from my last review is fixed: panel-motion.test.ts now selects the "Open & close" subsection and passes 16/16, the same as on pr/base. Nothing else changed since that review, where the packages/ui and components-lab tests passed and the typechecks were clean. The earlier knobs-header point no longer applies, since that panel was removed.
Public API: unchanged.
The Knobs panel is now a list of features under their areas. Opening one pushes its page: its presets, its controls on one grid, Replay where a trigger exists, Focus on the part of the app it changes, and Reset to Shipped. Wide enough, the list and the page sit side by side. Speed and slow motion stay in the debug bar. Also removes the Message menu experiment.
f61d421 to
4c075c8
Compare
There was a problem hiding this comment.
The latest push looks sound, with no new concerns. The Message menu removal is reverted cleanly. In the panel, Escape now goes back or closes, focus moves into and out of a page, the push mirrors in RTL, and the Enabled switch row is keyed so it controls the open feature's switch. A feature now reads as Custom when a non-spring control was tuned by hand.
I checked it with tests and type checks: in packages/ui, motion-tuning-features.test.ts and motion-tuning.test.ts pass (6); in packages/app, panel-motion.test.ts passes 16/16. typecheck:tsc is clean in packages/ui, packages/app, packages/gui-extensions and packages/session-ui. I couldn't run the new Playwright test in debug-bar.spec.ts, because no browser is installed here.
Public API: unchanged.
What it does
Rebuilds the Knobs panel as the Stack layout from D-27. The home screen is a list of features under small area headings. Each row has a one-line hint and a dot when the feature differs from Shipped. Tapping a feature opens its page:
When the panel is wide, the list and the page sit side by side. Drag the left edge to resize it.
Speed and slow motion are no longer in Knobs; they stay in the debug bar's SPEED and SLOW cells. The global preset strip and the cards are gone.
The Message menu experiment stays; #58867 removes it. Until then it shows as its own feature under Composer.
How it works
@opencode/ui/motion-tuning-features(replacesmotion-tuning-panel) groups registered knobs into features by area and subsection, and holds per-feature presets, changed and reset. It is covered bymotion-tuning-features.test.ts;debug-bar.spec.tschecks a page's Enabled switch stays bound to its own feature after switching.gui-extensions/src/debug/motion.tsxandmotion-rows.tsx. It reads and writes the samemotionTuningregistry and storage, so edits still apply live. It no longer uses the knobs library; the components lab still does.description(the hint) andtarget(a selector Focus outlines and scrolls to).What knobs would need to do this itself:
Risk
This is debug-only UI (dev and Beta). The registry API only gains fields.
Proof
Wide:
Push and back: https://problems.kitlangton.com/media/5JlWsFzas6dc65_fU-uSAw.mp4