Skip to content

Commit 2bae897

Browse files
committed
Set-level sidebar: docs-style groups with the current page expanded
Multi-page sets can now carry the whole set's sidebar. nav frontmatter (groups of labelled page links, identical on every page of the set) compiles into hidden set-nav markup whose sim: links resolve like any other; the shell lifts it into the left rail as muted group labels over page links, recognises the current page by title, and nests that page's section list beneath it — the docs sidebar's exact shape. Pages without nav keep the plain section list.
1 parent 7431b5f commit 2bae897

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

‎apps/sim/lib/workspace-files/artifact-stylesheet.ts‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,10 @@ figcaption { font-size: 0.875em; line-height: 1.4285714; color: var(--text-prima
506506
padding, rounded-lg, weight 400, hover/active surfaces, no underline. The
507507
group label mirrors the sidebar separators: 12px, normal weight, muted. */
508508
.rail[data-rail="nav"] { padding-top: 20px; min-width: 150px; }
509+
/* Set navigation: docs-style groups with the current page's sections nested. */
510+
.rail[data-rail="nav"] .rail-title:not(:first-child) { margin-top: 1.25rem; }
511+
.rail[data-rail="nav"] li.is-current > a { color: var(--text-primary); }
512+
.rail-sections { margin: 2px 0 4px 12px; }
509513
.rail[data-rail="toc"] { min-width: 150px; }
510514
.rail[data-rail="nav"] .rail-title { font-size: var(--text-caption); font-weight: 400; color: var(--text-muted); margin: 0 0 0.4rem; padding: 0 0.5rem; }
511515
.rail[data-rail="nav"] li { margin-bottom: 1px; }
@@ -665,7 +669,45 @@ export const SIM_ARTIFACT_SHELL = `<script>
665669
li.appendChild(a)
666670
leftList.appendChild(li)
667671
}
668-
left.append(leftTitle, leftList)
672+
// A multi-page set carries its whole sidebar (compiler-emitted set-nav):
673+
// groups of page links, the current page recognised by title and its
674+
// sections nested beneath it — the docs' sidebar shape. A lone page
675+
// keeps the plain section list.
676+
const setNav = page.querySelector('nav.set-nav')
677+
if (setNav) {
678+
let currentEntry = null
679+
for (const group of setNav.querySelectorAll('section')) {
680+
const label = group.querySelector('h6')
681+
if (label) {
682+
const t = document.createElement('div')
683+
t.className = 'rail-title'
684+
t.textContent = label.textContent
685+
left.appendChild(t)
686+
}
687+
const ol = document.createElement('ol')
688+
for (const src of group.querySelectorAll('a')) {
689+
const li = document.createElement('li')
690+
const a = src.cloneNode(true)
691+
if ((a.textContent || '').trim() === document.title.trim()) {
692+
li.classList.add('is-current')
693+
currentEntry = li
694+
}
695+
li.appendChild(a)
696+
ol.appendChild(li)
697+
}
698+
left.appendChild(ol)
699+
}
700+
if (currentEntry) {
701+
leftList.classList.add('rail-sections')
702+
currentEntry.appendChild(leftList)
703+
} else {
704+
leftTitle.textContent = 'On this page'
705+
left.append(leftTitle, leftList)
706+
}
707+
setNav.remove()
708+
} else {
709+
left.append(leftTitle, leftList)
710+
}
669711
670712
// Right rail — the clerk TOC.
671713
const right = document.createElement('nav')
@@ -812,7 +854,7 @@ export const SIM_ARTIFACT_SHELL = `<script>
812854
}
813855
if (actions.childElementCount > 0) mid.insertBefore(actions, mid.firstChild)
814856
815-
const navLinks = [...leftList.querySelectorAll('a')]
857+
const navLinks = [...left.querySelectorAll('a')]
816858
search.addEventListener('input', () => {
817859
const q = search.value.trim().toLowerCase()
818860
for (const a of navLinks) a.hidden = q !== '' && !(a.textContent || '').toLowerCase().includes(q)

‎apps/sim/lib/workspace-files/page-compile.test.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ describe('compileSimPage', () => {
152152
expect(html).not.toContain('Previous')
153153
})
154154

155+
it('emits the set navigation for nav frontmatter', () => {
156+
const html = compileSimPage(
157+
'---\ntitle: Overview\nnav:\n - label: Get Started\n pages:\n - "[Overview](sim:file/a)"\n - "[API Reference](sim:file/b)"\n---\nBody.',
158+
{ workspaceId: 'ws1' }
159+
)
160+
expect(html).toContain('<nav class="set-nav" hidden aria-label="Pages">')
161+
expect(html).toContain('<h6>Get Started</h6>')
162+
expect(html).toContain('<a href="/workspace/ws1/files/a" data-sim-link="">Overview</a>')
163+
})
164+
155165
it('renders sim:accordion like sim:faq with title keys', () => {
156166
const html = compileSimPage(
157167
'---\ntitle: T\n---\n```sim:accordion\n- title: Advanced options\n markdown: The details.\n```'

0 commit comments

Comments
 (0)