Problem
src/components/docs/docs-index-grid.tsx and src/components/docs/docs-index-list.tsx (the two /docs index view modes added in #205) both independently implement the exact same grouping logic:
// docs-index-grid.tsx
{DOCS_GROUPS.map((group) => {
const entries = docsPages.filter((entry) => entry.group === group);
if (entries.length === 0) return null;
return ( /* ...grid render... */ );
})}
// docs-index-list.tsx
{DOCS_GROUPS.map((group) => {
const entries = docsPages.filter((entry) => entry.group === group);
if (entries.length === 0) return null;
return ( /* ...list render... */ );
})}
The DOCS_GROUPS.map(...).filter(entry => entry.group === group) grouping/skip-empty logic is character-for-character identical in both files, only the JSX each renders per group differs. If a third view mode is ever added (or the grouping rule changes, e.g. to also skip a group behind a feature flag), it has to be updated in two places that can silently drift.
Fix
Extract a small shared helper, e.g. groupDocsByTopic(docsPages: DocsNavEntry[]): { group: DocsGroup; entries: DocsNavEntry[] }[] in src/lib/docs-nav.ts, that both components call and then just map over to render their own JSX per entry.
Acceptance criteria
Problem
src/components/docs/docs-index-grid.tsxandsrc/components/docs/docs-index-list.tsx(the two/docsindex view modes added in #205) both independently implement the exact same grouping logic:The
DOCS_GROUPS.map(...).filter(entry => entry.group === group)grouping/skip-empty logic is character-for-character identical in both files, only the JSX each renders per group differs. If a third view mode is ever added (or the grouping rule changes, e.g. to also skip a group behind a feature flag), it has to be updated in two places that can silently drift.Fix
Extract a small shared helper, e.g.
groupDocsByTopic(docsPages: DocsNavEntry[]): { group: DocsGroup; entries: DocsNavEntry[] }[]insrc/lib/docs-nav.ts, that both components call and then just map over to render their own JSX per entry.Acceptance criteria
DocsIndexGridandDocsIndexListrender identically to beforesrc/components/docs/docs-index.test.tsxstill passes