From 752deb779e9dd743e6da01b37234c3a2d59cd51a Mon Sep 17 00:00:00 2001 From: jackwener Date: Mon, 13 Jul 2026 21:40:47 +0800 Subject: [PATCH] chore(ui): remove orphaned primitives/scroll-area.tsx (Round A follow-up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zero consumers and never exported from the index — kept alive only by a contract assertion that read the file and a knip ignore. The invariant that assertion carried (no Base UI scrollbar reintroduction) is upgraded to a repo-wide source ban across both workspaces, so coverage got stronger, not weaker. --- .../overlay-scrollbars-contract.test.ts | 32 ++++++++++++++--- knip.json | 3 +- .../frontend-simplification-map-2026-07-13.md | 5 +++ packages/ui/src/primitives/scroll-area.tsx | 34 ------------------- 4 files changed, 33 insertions(+), 41 deletions(-) delete mode 100644 packages/ui/src/primitives/scroll-area.tsx diff --git a/apps/desktop/src/main/__tests__/overlay-scrollbars-contract.test.ts b/apps/desktop/src/main/__tests__/overlay-scrollbars-contract.test.ts index b4d3ba3668..038013dbeb 100644 --- a/apps/desktop/src/main/__tests__/overlay-scrollbars-contract.test.ts +++ b/apps/desktop/src/main/__tests__/overlay-scrollbars-contract.test.ts @@ -1,5 +1,5 @@ import { strict as assert } from 'node:assert'; -import { readFile } from 'node:fs/promises'; +import { readFile, readdir } from 'node:fs/promises'; import { describe, it } from 'node:test'; import { resolve } from 'node:path'; import { readRendererContractCss } from './contract-css-helpers.js'; @@ -12,6 +12,18 @@ function repoFile(path: string): Promise { return readFile(resolve(REPO_ROOT, path), 'utf8'); } +async function readWorkspaceSources(dir: string): Promise> { + const root = resolve(REPO_ROOT, dir); + const entries = await readdir(root, { recursive: true, withFileTypes: true }); + const sources: Array<[string, string]> = []; + for (const entry of entries) { + if (!entry.isFile() || !/\.tsx?$/.test(entry.name)) continue; + const abs = resolve(entry.parentPath, entry.name); + sources.push([abs.slice(root.length + 1), await readFile(abs, 'utf8')]); + } + return sources; +} + describe('OverlayScrollbars integration contract', () => { it('keeps KingSora OverlayScrollbars as a shared UI dependency', async () => { const uiPackage = JSON.parse(await repoFile('packages/ui/package.json')) as { @@ -44,11 +56,21 @@ describe('OverlayScrollbars integration contract', () => { assert.match(src, /elements:\s*\{[\s\S]*viewport,[\s\S]*content,[\s\S]*\}/, 'OverlayScrollbars must mount with explicit viewport/content elements'); }); - it('backs shared primitive ScrollArea with OverlayScrollbars instead of Base UI scrollbars', async () => { - const primitiveScrollArea = await repoFile('packages/ui/src/primitives/scroll-area.tsx'); + it('keeps Base UI ScrollArea banned across both workspaces', async () => { + // Simplification Round A follow-up: the orphaned primitives/scroll-area.tsx + // wrapper (zero consumers, never exported from the ui index) is deleted; + // the invariant it carried — nothing reintroduces Base UI scrollbars — + // now holds repo-wide instead of for one file. + const uiSources = await readWorkspaceSources('packages/ui/src'); + const desktopSources = await readWorkspaceSources('apps/desktop/src'); - assert.match(primitiveScrollArea, /OverlayScrollArea/, 'shared primitive ScrollArea must render the shared OverlayScrollArea primitive'); - assert.doesNotMatch(primitiveScrollArea, /@base-ui\/react\/scroll-area/, 'shared primitive ScrollArea must not reintroduce Base UI ScrollArea'); + for (const [file, src] of [...uiSources, ...desktopSources]) { + assert.doesNotMatch( + src, + /@base-ui\/react\/scroll-area/, + `${file} must not reintroduce Base UI ScrollArea — all scroll surfaces go through OverlayScrollArea`, + ); + } }); it('loads vendor CSS and defines the Maka theme tokens', async () => { diff --git a/knip.json b/knip.json index 0c415137ef..de5ef069f8 100644 --- a/knip.json +++ b/knip.json @@ -47,8 +47,7 @@ "src/**/*.{ts,tsx}", "stories/**/*.{ts,tsx}" ], - "ignoreDependencies": ["@storybook/react-vite"], - "ignore": ["src/primitives/scroll-area.tsx"] + "ignoreDependencies": ["@storybook/react-vite"] } } } diff --git a/notes/frontend-simplification-map-2026-07-13.md b/notes/frontend-simplification-map-2026-07-13.md index 7bfc224792..7824808a10 100644 --- a/notes/frontend-simplification-map-2026-07-13.md +++ b/notes/frontend-simplification-map-2026-07-13.md @@ -89,6 +89,11 @@ dist/**/*.test.js). Real finds verified by hand before acting. of the @maka/ui helper. Deliberately NOT converted: use-workspace-instructions- controller (lifecycle-counter variant, not boilerplate) and app-shell.tsx rendererMountedRef (Round B owns that file). +- [x] **A follow-up — orphan scroll-area.tsx removed.** primitives/scroll-area.tsx + (34 lines, zero consumers, never exported from the ui index) deleted together with + its knip ignore; the overlay-scrollbars contract's per-file assertion upgraded to a + repo-wide ban on @base-ui react scroll-area imports (stronger invariant, no + coverage lost). - [ ] **D-2 — mounted-guard long tail**: ~30 remaining `*MountedRef` sites across renderer settings pages and packages/ui panels (see `grep -ri "mountedref = useRef"`). Mechanical agent sweep: swap to useMountedRef, keep per-site companion-ref cleanup diff --git a/packages/ui/src/primitives/scroll-area.tsx b/packages/ui/src/primitives/scroll-area.tsx deleted file mode 100644 index 0cf0169e9d..0000000000 --- a/packages/ui/src/primitives/scroll-area.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { OverlayScrollArea } from "../overlay-scroll-area.js"; -import { cn } from "../utils.js"; -import type React from "react"; - -export function ScrollArea({ - className, - children, - scrollFade = false, - scrollbarGutter = false, - fill = false, - clampContentMinWidth = true, - ...props -}: React.HTMLAttributes & { - scrollFade?: boolean; - scrollbarGutter?: boolean; - fill?: boolean; - clampContentMinWidth?: boolean; -}): React.ReactElement { - return ( - - {children} - - ); -}