Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
17b7333
feat(behaviors): slot model deriving kp/mt/lt/mo from Hold/Tap (#16 s…
numachang Jun 6, 2026
5f4f5a7
feat(behaviors): Normal/Hold-mode slot surface for the binding editor…
numachang Jun 6, 2026
22b776d
docs(design): converge slot model on Normal / Hold mode (#16)
numachang Jun 6, 2026
cd87751
fix(behaviors): keycap send-with badges + slot-surface polish; keep h…
numachang Jun 6, 2026
b5dad4c
fix(behaviors): address PR #29 review — drop EXPERIMENT comment, show…
numachang Jun 6, 2026
1f006ee
Merge pull request #29 from numachang/feature/key-picker-step2
numachang Jun 6, 2026
429b7af
feat(behaviors): Step 3a — keycap behavior tiles in the Normal grid (…
numachang Jun 7, 2026
2076357
fix(behaviors): address PR #30 review — Step 3a nits (#16)
numachang Jun 7, 2026
c858604
Merge pull request #30 from numachang/feature/key-picker-step3
numachang Jun 7, 2026
cbbd354
feat(behaviors): Step 3b — Sticky Key / Key Toggle latches, flavor ti…
numachang Jun 7, 2026
2e7b10b
fix(behaviors): memoize Basic-tile predicates to clear exhaustive-dep…
numachang Jun 7, 2026
6cba832
Merge pull request #32 from numachang/feature/key-picker-step3b
numachang Jun 7, 2026
ed24e8c
docs(design): sync §3c/§5 Step 3b to the as-built key-state latch
numachang Jun 7, 2026
c883767
feat(behaviors): Step 4 — persistent layer switches as a "Layer" tab …
numachang Jun 9, 2026
9c151c8
refactor(behaviors): unify Sticky/Toggle latch across key and layer f…
numachang Jun 9, 2026
16d312a
fix(behaviors): keep the Layer tab usable while a key latch is active…
numachang Jun 9, 2026
d9378b2
feat(keyboard): paramless behaviors read as key legends, not badges (…
numachang Jun 9, 2026
22f5747
fix(keyboard): size paramless legends by length (14/12/10px) (#16)
numachang Jun 9, 2026
da57efe
fix(keyboard): tighten the editor picker row now that "More behaviors…
numachang Jun 9, 2026
66885c3
refactor(behaviors): move flavor tiles into the Apps/Media/Special ta…
numachang Jun 9, 2026
e4f882e
feat(behaviors): Step 5 — drain the residual area into shaped homes (…
numachang Jun 10, 2026
e8b7d55
test(mock): split Corne demo fixture exercising the custom routes (#16)
numachang Jun 10, 2026
6186cf0
docs(design): record Step 5 (drain the residual) as built (#16)
numachang Jun 10, 2026
ffa65ae
fix(behaviors): address PR #33 review — preserve hold-tap identity, f…
numachang Jun 10, 2026
c7880f0
Merge pull request #33 from numachang/feature/key-picker-step4
numachang Jun 10, 2026
9179241
docs(design): record the accepted known edges from the PR #34 review …
numachang Jun 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
741 changes: 612 additions & 129 deletions docs/design/key-picker-rethink.md

Large diffs are not rendered by default.

24 changes: 11 additions & 13 deletions src/App.edit.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,28 +114,26 @@ describe("persistent clear tiles (key-picker rethink, step 1)", () => {
).toBeInTheDocument();
});

it("returns a None'd key to Key Press in one grid click", async () => {
it("clears a key to None and back to Key Press from the Normal grid", async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
await connectDemo(user);
await changeQtoNone(user);

// The None tile now reports itself as active.
expect(
await screen.findByRole("button", { name: "None", pressed: true })
).toBeInTheDocument();
// Q is now None: Hold mode is off and the Normal slot is empty. The Normal
// grid stays shown (it's always present — None is a value, the in-grid tile),
// so promoting back is one grid click.
await waitFor(() =>
expect(
screen.getByRole("checkbox", { name: "Hold mode" })
).not.toBeChecked()
);

// With Q set to None its keymap tile no longer reads "Q", so the only
// remaining "Q" button is the live keycode grid's tile. Clicking it must
// promote the binding straight back to Key Press (no tab round trip).
// Clicking a key in the always-shown Normal grid derives Key Press.
const gridQ = await screen.findAllByRole("button", { name: /\bQ\b/ });
await user.click(gridQ[gridQ.length - 1]);

await waitFor(() =>
expect(
screen
.getAllByRole("radio", { name: "Key Press" })
.some((r) => r.getAttribute("aria-checked") === "true")
).toBe(true)
expect(screen.getByText("Key Press")).toBeInTheDocument()
);
});
});
Loading
Loading