Skip to content

Commit 54e7402

Browse files
committed
fix(docs): restore Paper interaction styling and verify responsive controls
1 parent 07ce188 commit 54e7402

10 files changed

Lines changed: 80 additions & 20 deletions

‎apps/docs/components/docs/navigation-drawer.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function DocsNavigationDrawer({ children }: DocsNavigationDrawerProps) {
5454
}}
5555
className={cn(
5656
docsScrollAreaClass,
57-
'mt-5 min-h-0 flex-1 overflow-y-auto overscroll-contain pb-6'
57+
'-mx-1 mt-5 min-h-0 flex-1 overflow-y-auto overscroll-contain px-1 pb-6'
5858
)}
5959
>
6060
<SidebarNavigation

‎apps/docs/components/docs/navigation.tsx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface NavigationItemProps extends Omit<SidebarNavigationProps, 'nodes'> {
1717
}
1818

1919
const rowClass =
20-
'group flex min-h-[30px] w-full items-center gap-1.5 rounded-lg px-2 py-[5px] text-docs-nav text-[var(--docs-text)] transition-colors focus-visible:outline-2 focus-visible:outline-[var(--docs-muted)] focus-visible:-outline-offset-2'
20+
'group flex min-h-[30px] w-full items-center gap-1.5 rounded-lg px-2 py-[5px] text-docs-nav text-[var(--docs-text)] transition-colors focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2'
2121

2222
function containsPath(node: NavNode, pathname: string): boolean {
2323
return (
@@ -68,7 +68,8 @@ function NavigationItem({ node, pathname, onNavigate }: NavigationItemProps) {
6868
<div
6969
className={cn(
7070
'group/branch flex min-h-[30px] items-center rounded-lg transition-colors hover:bg-[var(--docs-hover)] active:bg-[var(--docs-pressed)]',
71-
isCurrent && 'bg-[var(--docs-selected)] hover:bg-[var(--docs-selected-hover)]'
71+
isCurrent &&
72+
'bg-[var(--docs-selected)] shadow-[var(--docs-current-edge)] hover:bg-[var(--docs-selected-hover)]'
7273
)}
7374
>
7475
<Link
@@ -89,7 +90,7 @@ function NavigationItem({ node, pathname, onNavigate }: NavigationItemProps) {
8990
aria-label={`${expanded ? 'Collapse' : 'Expand'} ${node.title}`}
9091
aria-expanded={expanded}
9192
onClick={toggle}
92-
className='focus-visible:-outline-offset-2 mr-0.5 flex size-7 shrink-0 items-center justify-center rounded-md opacity-0 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-[var(--docs-muted)] group-focus-within/branch:opacity-100 group-hover/branch:opacity-100 [@media(hover:none)]:opacity-100'
93+
className='mr-0.5 flex size-7 shrink-0 items-center justify-center rounded-md opacity-0 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] group-focus-within/branch:opacity-100 group-hover/branch:opacity-100 [@media(hover:none)]:opacity-100'
9394
>
9495
<ChevronDown
9596
className={cn('size-4 transition-transform', !expanded && '-rotate-90')}

‎apps/docs/components/docs/primitives.tsx‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ export const docsMenuClass =
1010
export const docsDialogClass =
1111
'docs-portal rounded-2xl border border-[var(--docs-border)] bg-[var(--docs-overlay)] text-[var(--docs-text)] shadow-[var(--docs-dialog-shadow)] backdrop-blur-[var(--docs-chrome-blur)]'
1212

13-
export const docsScrollAreaClass =
14-
'[scrollbar-width:thin] [scrollbar-color:var(--docs-muted)_transparent] [&::-webkit-scrollbar]:size-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-[var(--docs-muted)] [&::-webkit-scrollbar-track]:bg-transparent'
13+
export const docsScrollAreaClass = '[scrollbar-width:thin]'
1514

1615
export const docsInlineLinkClass =
17-
'rounded-sm font-semibold text-[var(--docs-link)] focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2'
16+
'rounded-sm text-[var(--docs-prose-link)] underline decoration-current underline-offset-4 focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2 dark:underline-offset-[3px]'
1817

1918
export const docsMenuItemClass =
2019
'flex min-h-[30px] cursor-pointer items-center gap-2 rounded-md px-2 outline-none data-[highlighted]:bg-[var(--docs-hover)] data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 dark:data-[disabled]:text-[var(--docs-disabled)] dark:data-[disabled]:opacity-100'

‎apps/docs/components/docs/search.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ export function DocsSearchTrigger({ compact = false }: DocsSearchTriggerProps) {
104104
aria-haspopup='dialog'
105105
onClick={(event) => show?.(event.currentTarget)}
106106
className={cn(
107-
'flex items-center gap-1.5 rounded-lg text-[var(--docs-muted)] text-docs-nav focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2',
107+
'flex items-center gap-1.5 rounded-lg text-[var(--docs-muted)] text-docs-nav transition-colors hover:bg-[var(--docs-hover)] focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2 active:bg-[var(--docs-pressed)] motion-reduce:transition-none',
108108
compact
109-
? 'before:-z-10 relative isolate size-11 justify-center before:absolute before:inset-1.5 before:rounded-lg before:transition-colors hover:before:bg-[var(--docs-hover)] active:before:bg-[var(--docs-pressed)] motion-reduce:before:transition-none'
110-
: 'h-[30px] w-full border border-[var(--docs-border)] bg-[var(--docs-reading)] px-[7px] transition-colors hover:bg-[var(--docs-hover)] active:bg-[var(--docs-pressed)] motion-reduce:transition-none'
109+
? 'size-11 justify-center'
110+
: 'h-[30px] w-full border border-[var(--docs-border)] bg-[var(--docs-reading)] px-[7px]'
111111
)}
112112
>
113113
<Search className='size-4 shrink-0' aria-hidden />

‎apps/docs/components/docs/shell.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function DocsShell({ children, navigationBySection }: DocsShellProps) {
9898
key={section}
9999
className={cn(
100100
docsScrollAreaClass,
101-
'sticky top-24 hidden max-h-[calc(100dvh-120px)] min-w-0 space-y-5 overflow-y-auto overscroll-contain pb-5 lg:block'
101+
'-mx-1 sticky top-24 hidden max-h-[calc(100dvh-120px)] min-w-0 space-y-5 overflow-y-auto overscroll-contain px-1 pb-5 lg:block'
102102
)}
103103
>
104104
<DocsSearchTrigger />

‎apps/docs/components/docs/table-of-contents.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function TableOfContents({ headings, active, compact = false }: TableOfCo
2929
'dark:-mx-2 block rounded-md pointer-coarse:py-3 text-docs-control leading-5 transition-colors focus-visible:outline-2 focus-visible:outline-[var(--docs-link)] focus-visible:outline-offset-2 dark:px-2 dark:hover:bg-[var(--docs-hover)]',
3030
depth > 2 && 'pl-3 dark:pl-5',
3131
active === id
32-
? 'font-medium text-[var(--docs-toc-current)]'
32+
? 'text-[var(--docs-toc-current)] dark:underline dark:underline-offset-[3px]'
3333
: 'text-[var(--docs-muted)] hover:text-[var(--docs-heading)] dark:hover:text-[var(--docs-muted)]'
3434
)}
3535
>

‎apps/docs/components/docs/tokens.css‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@
4545
--docs-hover: rgb(10 10 10 / 6%);
4646
--docs-selected: rgb(0 0 0 / 8%);
4747
--docs-selected-hover: var(--docs-selected);
48+
--docs-current-edge: none;
4849
--docs-pressed: rgb(0 0 0 / 12%);
4950
--docs-link: #0066cc;
51+
--docs-prose-link: var(--docs-link);
5052
--docs-toc-current: var(--docs-link);
5153
--docs-glass: rgb(255 255 255 / 80%);
5254
--docs-overlay: rgb(255 255 255 / 88%);
@@ -132,8 +134,10 @@
132134
--docs-hover: #2b2b2b;
133135
--docs-selected: #333;
134136
--docs-selected-hover: var(--docs-pressed);
137+
--docs-current-edge: inset 2px 0 0 var(--docs-boundary);
135138
--docs-pressed: #3a3a3a;
136139
--docs-link: #8abeff;
140+
--docs-prose-link: var(--docs-heading);
137141
--docs-toc-current: var(--docs-muted);
138142
--docs-glass: rgb(20 20 20 / 92%);
139143
--docs-overlay: rgb(36 36 36 / 92%);

‎apps/docs/scripts/benchmark-readiness.ts‎

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { createLogger } from '@sim/logger'
1515
import { getErrorMessage } from '@sim/utils/errors'
1616
import { sleep } from '@sim/utils/helpers'
1717
import { isRecordLike } from '@sim/utils/object'
18+
import { escapeRegExp } from '@sim/utils/string'
1819

1920
/** Bounded production measurements: no builds, writes to services, or corpus crawling. */
2021
const logger = createLogger('DocsReadinessBenchmark', { logLevel: 'INFO' })
@@ -1014,17 +1015,35 @@ async function tabControl(
10141015
control: { scenario: string; label: string; choice: RegExp }
10151016
) {
10161017
await measure(profile, route, repetition, control.scenario, async () => {
1017-
const list = run.page.getByRole('tablist', { name: control.label, exact: true })
1018-
const tab = list.getByRole('tab', { name: control.choice }).filter({ visible: true }).first()
1018+
const list = run.page.getByRole('tablist', {
1019+
name: control.label,
1020+
exact: true,
1021+
includeHidden: true,
1022+
})
1023+
const tab = list.getByRole('tab', { name: control.choice, includeHidden: true }).first()
10191024
if (!(await tab.count()))
10201025
return {
10211026
status: 'unavailable',
10221027
error: `No matching ${control.label} tab on this baseline.`,
10231028
}
1024-
const choices = await list.getByRole('tab').count()
1025-
await tab.scrollIntoViewIfNeeded()
1029+
const choices = await list.getByRole('tab', { includeHidden: true }).count()
1030+
const presentation = (await tab.isVisible()) ? 'tabs' : 'menu'
1031+
let trigger = tab
1032+
if (presentation === 'menu') {
1033+
const picker = run.page.getByRole('button', {
1034+
name: new RegExp(`^${escapeRegExp(control.label)}:`),
1035+
})
1036+
if (!(await picker.isVisible()))
1037+
return {
1038+
status: 'unavailable',
1039+
error: `No visible ${control.label} control on this baseline.`,
1040+
}
1041+
await picker.click()
1042+
trigger = run.page.getByRole('menuitemradio', { name: control.choice }).first()
1043+
}
1044+
await trigger.scrollIntoViewIfNeeded()
10261045
const start = performance.now()
1027-
await tab.click()
1046+
await trigger.click()
10281047
await expect(tab).toHaveAttribute('aria-selected', 'true')
10291048
const id = await tab.getAttribute('aria-controls')
10301049
if (!id) throw new Error('Tab has no linked content')
@@ -1036,6 +1055,7 @@ async function tabControl(
10361055
feedbackMs: choices > 1 ? performance.now() - start : undefined,
10371056
data: {
10381057
choices,
1058+
presentation,
10391059
selected: await tab.textContent(),
10401060
contentLength: (await panel.textContent())?.length,
10411061
applicableTransition: choices > 1,
@@ -1117,11 +1137,13 @@ async function apiControls(
11171137
if (!(await button.count()))
11181138
return { status: 'unavailable', error: 'No named request-copy button on this baseline.' }
11191139
const selected = run.page
1120-
.getByRole('tablist', { name: 'Request language', exact: true })
1121-
.getByRole('tab', { selected: true })
1140+
.getByRole('tablist', { name: 'Request language', exact: true, includeHidden: true })
1141+
.getByRole('tab', { selected: true, includeHidden: true })
11221142
const id = await selected.getAttribute('aria-controls')
11231143
if (!id) throw new Error('Selected request has no panel')
1124-
const expected = await run.page.locator(`[id="${id}"] code`).textContent()
1144+
const panel = run.page.locator(`[id="${id}"]`)
1145+
await panel.waitFor({ state: 'visible' })
1146+
const expected = await panel.locator('code').textContent()
11251147
await button.scrollIntoViewIfNeeded()
11261148
const start = performance.now()
11271149
await button.click()

‎apps/docs/scripts/test-navigation-e2e.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,13 @@ try {
16021602
})
16031603
} finally {
16041604
await browser?.close()
1605+
if (!results.length)
1606+
results.push({
1607+
name: 'Check selection',
1608+
status: 'failed',
1609+
durationMs: 0,
1610+
error: `No checks matched DOCS_NAVIGATION_FILTER=${process.env.DOCS_NAVIGATION_FILTER ?? ''}`,
1611+
})
16051612
await writeFile(
16061613
reportPath,
16071614
`${JSON.stringify({ origin: target.origin, engine, limitations: engine === 'webkit' ? ['Clipboard readback, reduced-transparency emulation and controlled network throttling remain Chromium-only; this is Playwright WebKit, not native Safari.'] : [], results }, null, 2)}\n`

‎apps/docs/scripts/test-search-postgres-e2e.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,33 @@ async function verifyDatabase() {
296296
assert.equal(results[0]?.id, probe)
297297
assert.equal(results[0]?.url, 'https://docs.sim.ai/introduction')
298298
})
299+
await check('Repeated lower-ranked chunks do not outrank a stronger page match', async () => {
300+
const otherPage = getPage('/getting-started')
301+
assert(otherPage)
302+
const rankingQuery = 'simrankingprobe'
303+
try {
304+
for (const candidate of [page, otherPage])
305+
await sql`
306+
INSERT INTO docs_embeddings (chunk_id, chunk_text, source_document, source_link, header_text, header_level, token_count, embedding, metadata)
307+
VALUES (${generateId()}, ${candidate === page ? `${rankingQuery} ${rankingQuery}` : rankingQuery}, ${candidate.sourcePath}, ${`https://docs.sim.ai${candidate.url}`}, ${candidate.title}, 1, 2, ${vector}::vector, ${sql.json({ contentHash: candidate.contentHash })})
308+
`
309+
const expected = ['https://docs.sim.ai/introduction', 'https://docs.sim.ai/getting-started']
310+
assert.deepEqual(
311+
(await searchDocs(rankingQuery)).map((result) => result.url),
312+
expected
313+
)
314+
await sql`
315+
INSERT INTO docs_embeddings (chunk_id, chunk_text, source_document, source_link, header_text, header_level, token_count, embedding, metadata)
316+
VALUES (${generateId()}, ${rankingQuery}, ${otherPage.sourcePath}, 'https://docs.sim.ai/getting-started', ${otherPage.title}, 1, 1, ${vector}::vector, ${sql.json({ contentHash: otherPage.contentHash })})
317+
`
318+
assert.deepEqual(
319+
(await searchDocs(rankingQuery)).map((result) => result.url),
320+
expected
321+
)
322+
} finally {
323+
await sql`DELETE FROM docs_embeddings WHERE chunk_text_tsv @@ plainto_tsquery('english', ${rankingQuery})`
324+
}
325+
})
299326
await check('Stale index hashes cannot supply search citations', async () => {
300327
await sql`UPDATE docs_embeddings SET metadata = '{"contentHash":"stale"}' WHERE chunk_id = ${probe}`
301328
assert.deepEqual(await searchDocs(query), [])

0 commit comments

Comments
 (0)