refactor(ui): move Tabs and Table into the kit, and start policing it - #786
Open
markhayden wants to merge 1 commit into
Open
refactor(ui): move Tabs and Table into the kit, and start policing it#786markhayden wants to merge 1 commit into
markhayden wants to merge 1 commit into
Conversation
Two public kit component families had their real implementations in the root `src/components/ui/` tree while every peer lived in `packages/ui`, and the SDK published them with `export *` — which is how their structural sub-parts (TableCaption, TabsContent, …) ended up in the public surface undocumented. The other seven files there are thin re-export shims and are untouched. - Both implementations move to `packages/ui/src/primitives/`, switching from the app's `@/lib/utils` cn to the kit's own. - `export *` becomes an explicit list. Deliberately NOT narrowed: the public API freeze is byte-identical at 300 values / 404 types, so this makes the surface intentional without breaking a single consumer. The move exposed a coupled problem. `packages/ui` was the ONE browser surface the legacy-styles ratchet never scanned, so relocating these files would have silently erased 25 tracked units and orphaned an approved exception — the ledger would have reported a 25-unit improvement for work nobody did. `ui:legacy-styles:generate` refused to run, which is the check from #783 doing its job. So the scanner now covers `packages/ui/src`. Two refinements keep that baseline honest rather than noisy: - An arbitrary value that resolves a `--bakin-*` custom property is the token system being applied, not a magic number. Sometimes it is the ONLY correct spelling: `text-[length:var(--bakin-typography-size-meta)]` exists because the shorthand shares the `text-*` merge group with colour and gets silently dropped. Counting those as debt flagged the prescribed pattern — including the primitive added in #782 — as a violation. Literal values (`w-[240px]`) still count. This drops the kit's arbitrary-size from 244 to 55 and is a fleet-wide correction. - Generated artifacts are excluded. The token files define the palette in hex because that is their job; you fix the generator, not the output. That is 60 of the 64 raw-palette hits. Net: 106 -> 174 paths, 982 -> 1135 units. Every one of those +153 is pre-existing code becoming visible — zero lines of product code changed. The naive version of this would have recorded +402. Census drops 102 -> 100 because it never tracked `packages/ui` at all; Button, Card, and Badge are uncensused too, so Tabs and Table are simply joining their peers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Came out of the PR 4 host-chrome audit. The styling migration follows separately — this is the structural finding that audit surfaced.
The finding
Tabs*andTable*— two public kit component families — had their real implementations in rootsrc/components/ui/while every peer lived inpackages/ui. The SDK published them withexport *, which is how their structural sub-parts (TableCaption,TabsContent, …) ended up in the public surface undocumented. The other seven files there are thin re-export shims, untouched.packages/ui/src/primitives/, switching to the kit's owncn.export *becomes an explicit list — deliberately not narrowed. The public API freeze is byte-identical at 300 values / 404 types, so the surface becomes intentional without breaking a single consumer.The coupled problem it exposed
packages/uiwas the one browser surface the legacy-styles ratchet never scanned. Relocating these files would have silently erased 25 tracked units and orphaned an approved exception — the ledger would have reported a 25-unit improvement for work nobody did.ui:legacy-styles:generaterefused to run. That's #783's check doing exactly its job.So the scanner now covers
packages/ui/src. Two refinements keep the baseline honest rather than noisy:Token applications aren't magic numbers. An arbitrary value resolving a
--bakin-*property is the token system working — and sometimes the only correct spelling.text-[length:var(--bakin-typography-size-meta)]exists precisely because the shorthand shares thetext-*merge group with colour and gets silently dropped. Counting those as debt flagged the prescribed pattern — including the primitive added in #782 — as a violation, which teaches people to ignore the ratchet. Literal values (w-[240px]) still count. Kit arbitrary-size: 244 → 55, and it's a fleet-wide correction.Generated artifacts are excluded. The token files define the palette in hex because that is their job; you fix the generator, not the output. That's 60 of the 64 raw-palette hits.
What the numbers mean
Every one of those +153 is pre-existing code becoming visible — zero lines of product code changed. The naive version of this would have recorded +402, most of it false.
This also closes the gap I've flagged twice: the kit being unpoliced is what let the
WorkspacePagefont-size drop ship unnoticed.Census
102 → 100, because the census never tracked
packages/uiat all.Button,Card, andBadgeare uncensused too — Tabs and Table are joining their peers, not losing coverage.Verification
typecheck ✅ · lint ✅ (0 errors) ·
bun test tests/ui/ tests/components/ tests/architecture/ tests/scripts/→ 1326 pass, 0 failGates: public-api (byte-identical), census, kit-coverage, performance, legacy-styles, check-cycles — all green. Vendor chunks consolidated 36 → 35 because the SDK no longer reaches across into root
src/.🤖 Generated with Claude Code