Repository navigation
feat(collection): a binder of your own, and the set picker's Binders tab (#1074) - #1126
Conversation
…tab (#1074) `?custom=<id>` opens one of your binders: its rules narrow the pool, its own numbers head the panel ("Complete binder"), and the toolbar names it beside its cover's medal. The set picker gains a Binders tab, My collection first and then your shelf in order, each row with its cover, its name and how complete it is; opening one clears the page's filters, and a set picked inside it keeps the binder, read as "Amber · Set 12". A binder that isn't on your shelf says so with a way back, and a failed read says so with a Try again. A friend's binder shows none of yours. No binder's name reaches an attribute or PostHog: every row and trigger is named by one screen-reader-only line and carries `ph-no-capture`. It all stays behind `VITE_SHOW_BINDERS`. With the flag off the bundler folds every binder module away, which `binderCodeGuard` holds the build to, so the lazy chunks ship under their own size budget (owner, 2026-11-03). The toolbar's button grows for a binder's name, taking the room from the search field and keeping its right edge at the panel's, since 71px cut every name short (owner, 2026-11-03). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🎨 Design-surface change detected This PR touches files mirrored by the Inkweave design system project. What changed:
To refresh: open the design system Claude project and prompt:
This is a reminder, not a blocker. Configured in |
size-limit report 📦
|
CI's knip checks exports since #1119, and five binder names were exported only for their own module: the e2e helper's REST path, the shelf's forget, and three story fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
There was a problem hiding this comment.
1 issue found across 59 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/web/src/features/collection/SetPicker.tsx">
<violation number="1" location="apps/web/src/features/collection/SetPicker.tsx:399">
P3: If the list chunk is still loading on first open, `useFocusOpenChoiceOnMount` sees only the active tab; this row never receives focus when it resolves. Focus the selected binder when the lazy list mounts.</violation>
</file>
Tip: instead of fixing issues one by one fix them all with cubic
View guided diff | Re-trigger cubic
- A binder chunk that resolves empty, as a stale one does in production, is a failed load with its Try again, never a module the page calls into. - A one-set binder whose rules hold no card counts that set, empty, so its numbers stop shimmering. - Vercel's tools drop `custom` from the address, as PostHog masks it. - A failed shelf read is read again the next time collection mode wants it. - A binder's rules drop the dual-ink switch where the page drops it, so its analytics kinds and its line name only what the binder applies. - A binder row the guard leaves out reaches Sentry. - A count changed inside a binder keeps its cards, so no rule reruns. - The picker's slot fills its group, so a short binder name keeps Collection and the gear at the panel's right edge. - Comments drop the issue tags that only recorded where code came from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
|
Review pass on 944178e: of the 18 threads, 13 are fixed, each behaviour change with a test that fails without it (the binders.spec Prettier thread in part: its double blank line). These stay as they are, with the reasons on their threads:
Generated by Claude Code |
…s-inside E2E_TESTS.md's total: master's 401 tests in 36 files plus this branch's 8 tests in binders.spec.ts, 409 in 37 (playwright --list agrees). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
…s-inside E2E_TESTS.md's total: master's 411 tests in 37 files plus this branch's 8 tests in binders.spec.ts, 419 in 38 (playwright --list agrees). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
…cts (#1074) On WebKit's production build the binder showed a moment before the toolbar named it, so the helper's check of which button was there picked "Binder set", which then went, and the click waited out the test (Full E2E, 3 Nov, "My collection closes the binder", flaky). Each caller now names its button, and the click waits for that one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
…s-inside #1120 landed first, so the User-facing JS budget goes to 463 kB, the owner's pick for whichever of #1120 and #1126 merged second (2026-11-03). Master measures 460.18 kB; with the binders it measures 462,802 B in a build with the Bundle Size job's env. E2E_TESTS.md's total: master's 419 tests in 37 files plus this branch's 8 tests in binders.spec.ts, 427 in 38 (playwright --list agrees). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DjrxDXnQkU2y3Yc3iHWuWs
|
Full E2E's WebKit job is red on one test this PR doesn't touch: The run before (bc09808) also showed Generated by Claude Code |
There was a problem hiding this comment.
Gates Passed
6 Quality Gates Passed
See analysis details in CodeScene
Absence of Expected Change Pattern
- inkweave/apps/web/src/features/collection/binderCards.ts is usually changed with: inkweave/apps/web/src/features/collection/collectionStats.test.ts
- inkweave/apps/web/src/features/collection/CollectionSetPanel.stories.tsx is usually changed with: inkweave/apps/web/src/features/collection/collectionStats.test.ts
- inkweave/apps/web/src/shared/lib/analytics.ts is usually changed with: inkweave/apps/web/src/shared/lib/tests/analytics.test.ts
- inkweave/apps/web/src/pages/browseView.ts is usually changed with: inkweave/apps/web/src/pages/tests/browseView.test.ts
- inkweave/apps/web/src/features/collection/collectionStats.ts is usually changed with: inkweave/apps/web/src/features/collection/collectionStats.test.ts
Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
Brings in #1126 (binders). The docked toolbar keeps this branch's shape, where Collection and its actions stay in the same elements in both modes, and takes #1126's binder-sized picker group and slot (pickerSpanStyle, pickerSlotStyle). E2E_TESTS.md's total is the sum of both sides: 432 tests across 39 spec files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J57kHm4KbVuqMeE1Gsqocv
Part of #1074 (PR 2 of 3: Steps 9 to 22 of the issue). Everything here sits behind
VITE_SHOW_BINDERS, which stays off in Production until #1075's Step 23.What it does
?binder=<scope>&custom=<id>narrows the pool to the binder's rules, heads the panel with its own numbers ("Complete binder"), and names it in the toolbar beside its cover's medal. A set picked inside it keeps the binder, read as "Amber · Set 12".ph-no-capture.Off means not loaded
Every module under
features/collection/binders/is reached only through a dynamic import the bundler folds onSHOW_BINDERS, andbinderCodeGuard(build-guards.ts) fails a flag-off build in which a page can load any of it. Checked with a flag-off production build: the binder chunks are emitted but nothing loads them.Size budgets (owner's pick on the card, 2026-11-03)
collectionStats, which was its own chunk on master and now joins Browse's.Design check
Screenshots at 1920, 390 and 393, on the real page over the test stubs with the deployed card art: Binders Design Check (a private page on the owner's Claude account).
Tests
BinderTab,SetPicker(tabs, opening tab, arrows round three tabs, toolbar label and medal, no name in attributes),CollectionSetPanel(Complete binder),CollectionBinderSection(empty states name the binder),useBrowseCollection(params, friend guard, unknown and failed binder, import over the whole pool,pickerNamesBinder),BrowseToolbar(the group grows only for a binder). Each new assertion was checked to fail with its source line broken.binders.spec.ts, 8 tests on every project, over a stubbedcollection_binders(e2e/helpers/binders.ts). Green on chromium and mobile-chrome, as iscollection-mode.spec.ts.BinderMedal,BinderTab,UnknownBinder, the picker's binder states and the panel's.check:storiesnow also scans a feature's other folders, such ascollection/binders.check:design,check:stories, knip, the web, inkweave-ui and script suites, CodeScene (strict, passed).After merge
The owner sets Preview
VITE_SHOW_BINDERS=true, so staging and PR previews show binders. Production stays off.Generated by Claude Code
Summary by cubic
Adds binders of your own:
?custom=<id>opens a binder, narrowing the pool to its rules and naming it in the toolbar beside its cover's medal, and the set picker gains a Binders tab. Everything sits behindVITE_SHOW_BINDERS, which stays off in Production.New Features
ph-no-capture; Vercel's tools dropcustomtoo.Rollout
binderCodeGuardfails a flag-off build that could load any.VITE_SHOW_BINDERS=truein Preview; Production stays off until the follow-up.Written for commit a1649a7. Summary will update on new commits.