build(frontend): knip also checks what ships; strict indexing in every project
`npm run knip` now runs a second, --production pass, which asks whether the code that ships uses an export, not just whether anything does. Of the 47 exports only tests reached: - 34 are exported for their test and say so with @internal, naming the test. - 11 were module-private names with a stray `export`. Two of them were not used at all and are deleted. - The unused alreadyReported re-export is gone. Test kits, the e2e suite and the two build-tooling modules are excluded from the production project, each named in knip.jsonc. noUncheckedIndexedAccess is now on for the node and e2e tsconfigs too (0 errors), matching the app project. tsconfig.node.json listed a tailwind.config.js that has not existed since Tailwind 4. That entry is now playwright.config.ts, which the typed lint finds through this project.
This commit is contained in:
@@ -43,6 +43,7 @@ export function applySyncFilter(rows: ManagedChannel[], value: unknown): Managed
|
||||
/** The Tags column filter predicate (item B): the "No tag" sentinel keeps channels the user hasn't
|
||||
* personally tagged (empty `tag_ids`); it's exclusive with real tag picks (the chip row enforces that),
|
||||
* so when present it wins. Otherwise a channel passes if it carries ANY selected tag id. */
|
||||
/** @internal exported for channelColumns.dom.test.tsx */
|
||||
export function tagsColumnTest(c: ManagedChannel, values: string[]): boolean {
|
||||
if (values.includes(NO_TAG_SENTINEL)) return c.tag_ids.length === 0;
|
||||
return values.some((v) => c.tag_ids.includes(Number(v)));
|
||||
|
||||
@@ -184,6 +184,7 @@ export function DetailKeywords({
|
||||
// The crew shows its first CREW_SHOWN names and a "Show N more" that opens the rest: the column beside the
|
||||
// text is the hero's tallest part, and twelve names ran it ~170px past the text (E31, the owner's call).
|
||||
// A list only a little longer than that shows whole: a toggle that hides one or two names saves no room.
|
||||
/** @internal exported for PlexInfo.dom.test.tsx */
|
||||
export const CREW_SHOWN = 6;
|
||||
const CREW_FOLD_OVER = CREW_SHOWN + 2;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { fieldClass } from "./fieldStyles";
|
||||
// and playlists. On the shell it reuses `Modal` in its `top` placement — same layer stack, Escape,
|
||||
// focus restore and Back-to-close as every other dialog.
|
||||
|
||||
export interface CommandItem {
|
||||
interface CommandItem {
|
||||
/** Unique across the whole palette; also the React key. */
|
||||
id: string;
|
||||
label: string;
|
||||
|
||||
@@ -13,6 +13,7 @@ import { SURFACE } from "./surfaces";
|
||||
// Built on the same AnchoredPopover platform as ActionMenu/Combobox (arrows/typeahead/Escape/anchor-flip);
|
||||
// reusable anywhere a small, known set of options currently renders as a chip group. See FilterSelect.dom.test.
|
||||
|
||||
/** @internal exported for FilterSelect.dom.test.tsx */
|
||||
export interface FilterSelectOption {
|
||||
value: string;
|
||||
label: string;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { SURFACE } from "./surfaces";
|
||||
// paragraph's, for prose that arrives after its page). The
|
||||
// shapes are shown through `LoadingState shape=…`, which owns the 300 ms reveal and the status role.
|
||||
|
||||
export function Skeleton({ className, inline = false }: { className?: string; inline?: boolean }) {
|
||||
function Skeleton({ className, inline = false }: { className?: string; inline?: boolean }) {
|
||||
// Inline: a span, for a bone inside phrasing content (a chip is a button, which may not hold a div).
|
||||
const Tag = inline ? "span" : "div";
|
||||
return (
|
||||
|
||||
@@ -12,8 +12,9 @@ import { startTransition, useEffect, useState } from "react";
|
||||
//
|
||||
// Not virtualization: every row still ends up in the DOM, so browser find, keyboard nav past the screen,
|
||||
// and the Back focus/scroll restore (which wait for the list to grow) keep working as they did.
|
||||
/** @internal exported for DataTable.progressive.dom.test.tsx */
|
||||
export const FIRST_ROWS = 30;
|
||||
export const STEP_ROWS = 40;
|
||||
const STEP_ROWS = 40;
|
||||
|
||||
// `view` names what the rows show (page, size, sort, filters). A new view starts over from the first
|
||||
// rows, so the urgent render after a click or a key stays small. New data for the same view (a refetch)
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
// - ceiling MAX_LOOKAHEAD_ROWS: a tall window renders many rows, and an uncapped lookahead would
|
||||
// eagerly prefetch several pages on every mount / filter change — wasted work on the app's
|
||||
// heaviest query (the feed). The cap bounds that while still buffering a couple of screens ahead.
|
||||
/** @internal exported for readAhead.test.ts */
|
||||
export const PREFETCH_ROWS = 4;
|
||||
/** @internal exported for readAhead.test.ts */
|
||||
export const PREFETCH_VIEWPORTS = 2;
|
||||
/** @internal exported for readAhead.test.ts */
|
||||
export const MAX_LOOKAHEAD_ROWS = 40;
|
||||
|
||||
/** How many rows ahead of the last rendered row to keep buffered, for a viewport rendering
|
||||
* `renderedRows` rows. Clamped to [PREFETCH_ROWS, MAX_LOOKAHEAD_ROWS]. */
|
||||
/** @internal exported for readAhead.test.ts */
|
||||
export function readAheadLookahead(renderedRows: number): number {
|
||||
return Math.min(MAX_LOOKAHEAD_ROWS, Math.max(PREFETCH_ROWS, renderedRows * PREFETCH_VIEWPORTS));
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@ import { CONTENT_ID } from "./landmarks";
|
||||
// back (`room - saving > FOLD_AT`): a page barely taller than the window would otherwise fold, lose its
|
||||
// scroll, land at the top, unfold, and so on, with every wheel tick;
|
||||
// - unfold only at the very top, not at the fold point: between the two the header keeps whatever it was.
|
||||
/** @internal exported for scrollFold.test.ts */
|
||||
export const FOLD_AT = 32;
|
||||
|
||||
export interface ScrollPosition {
|
||||
interface ScrollPosition {
|
||||
// The scroller's scrollTop.
|
||||
top: number;
|
||||
// How far it can scroll at all: scrollHeight − clientHeight.
|
||||
@@ -20,6 +21,7 @@ export interface ScrollPosition {
|
||||
}
|
||||
|
||||
// `saving` = the height the header gives back when it folds (measured while it is unfolded).
|
||||
/** @internal exported for scrollFold.test.ts */
|
||||
export function nextFolded(
|
||||
folded: boolean,
|
||||
{ top, room }: ScrollPosition,
|
||||
|
||||
@@ -28,5 +28,3 @@ export const SURFACE = {
|
||||
/** A full-width sticky band (the design lab's header): square. */
|
||||
band: "glass",
|
||||
} as const;
|
||||
|
||||
export type SurfaceRole = keyof typeof SURFACE;
|
||||
|
||||
Reference in New Issue
Block a user