jamdesk 1.1.167 → 1.1.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,10 @@ const SYNCED_FILES = [
36
36
  // three must move together with the canonical.
37
37
  ['build-service/themes/index.ts', 'cli/vendored/themes/index.ts'],
38
38
  ['build-service/components/navigation/Header.tsx', 'cli/vendored/components/navigation/Header.tsx'],
39
+ [
40
+ "build-service/components/navigation/Sidebar.tsx",
41
+ "cli/vendored/components/navigation/Sidebar.tsx",
42
+ ],
39
43
  ];
40
44
  describe('CLI vendored files sync', () => {
41
45
  it.each(SYNCED_FILES)('should have matching content: %s', async (buildServicePath, vendoredPath) => {
@@ -1 +1 @@
1
- {"version":3,"file":"vendored-sync.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/vendored-sync.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vendored-sync.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/vendored-sync.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.167",
3
+ "version": "1.1.168",
4
4
  "description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
5
5
  "keywords": [
6
6
  "jamdesk",
@@ -122,36 +122,90 @@ function findFirstPageInGroups(groups: ResolvedGroup[]): string | null {
122
122
  return null;
123
123
  }
124
124
 
125
- /** Find all groups whose `expanded: true` schema flag should open them by default */
126
- function findInitiallyExpandedGroups(groups: ResolvedGroup[]): Set<string> {
127
- const result = new Set<string>();
128
- for (const group of groups) {
129
- if (group.expanded && group.name) result.add(group.name);
130
- if (group.nested) {
131
- findInitiallyExpandedGroups(group.nested).forEach(name => result.add(name));
132
- }
133
- }
134
- return result;
125
+ // A group's position within the resolved navigation tree, expressed as the
126
+ // chain of sibling indices from the root (e.g. `[1, 0]` = second top-level
127
+ // group's first nested group). This is the stable identity for accordion
128
+ // state — see `groupStateKey` for why we key on position rather than name.
129
+ type GroupIndexPath = readonly number[];
130
+
131
+ // The navigation context a group is rendered in. Locale + active tab/anchor
132
+ // scope the accordion state so a manual expansion on one tab (or in one
133
+ // language) never leaks into the same tree position on another — labels and
134
+ // index paths repeat across tabs/locales, but the scope does not.
135
+ function navigationScope(nav: {
136
+ currentLanguage?: string;
137
+ activeTab?: string;
138
+ activeAnchor?: string;
139
+ }): string {
140
+ return [
141
+ nav.currentLanguage ?? 'default',
142
+ nav.activeTab ?? nav.activeAnchor ?? 'root',
143
+ ].join(':');
135
144
  }
136
145
 
137
- /** Find all groups in the path from root to the page containing currentPath */
138
- function findGroupsContainingPath(groups: ResolvedGroup[], currentPath: string, parentNames: string[] = []): Set<string> {
139
- const result = new Set<string>();
140
- for (const group of groups) {
141
- const groupPath = group.name ? [...parentNames, group.name] : parentNames;
146
+ function groupStateKey(scope: string, indexPath: GroupIndexPath): string {
147
+ return `${scope}:${indexPath.join('.')}`;
148
+ }
142
149
 
143
- if (group.pages.some(page => page.path === currentPath)) {
144
- groupPath.forEach(name => result.add(name));
145
- }
150
+ function groupPanelId(scope: string, indexPath: GroupIndexPath): string {
151
+ const safeScope = scope.replace(/[^a-zA-Z0-9_-]/g, '-');
152
+ return `nav-group-${safeScope}-${indexPath.join('-')}`;
153
+ }
146
154
 
147
- if (group.nested) {
148
- const nestedResults = findGroupsContainingPath(group.nested, currentPath, groupPath);
149
- nestedResults.forEach(name => result.add(name));
155
+ /**
156
+ * Collect the scoped state keys of every NAMED ancestor of each group matching
157
+ * `predicate` (including the matching group itself when named), so a
158
+ * qualifying descendant opens the whole chain that leads to it. Walks
159
+ * `group.nested` by sibling index — the same named-group index used while
160
+ * rendering ordered `group.items` — so discovery and rendered keys agree.
161
+ */
162
+ function collectAncestorKeys(
163
+ groups: ResolvedGroup[],
164
+ scope: string,
165
+ predicate: (group: ResolvedGroup) => boolean,
166
+ parentPath: GroupIndexPath = [],
167
+ ancestorKeys: readonly string[] = [],
168
+ ): Set<string> {
169
+ const result = new Set<string>();
170
+ groups.forEach((group, index) => {
171
+ const indexPath = [...parentPath, index];
172
+ const key = groupStateKey(scope, indexPath);
173
+ const nextAncestors = group.name ? [...ancestorKeys, key] : ancestorKeys;
174
+ if (predicate(group)) {
175
+ nextAncestors.forEach((ancestorKey) => result.add(ancestorKey));
150
176
  }
151
- }
177
+ collectAncestorKeys(
178
+ group.nested ?? [], scope, predicate, indexPath, nextAncestors,
179
+ ).forEach((nestedKey) => result.add(nestedKey));
180
+ });
152
181
  return result;
153
182
  }
154
183
 
184
+ /**
185
+ * Named groups that should start open because a descendant carries the
186
+ * `expanded: true` schema flag.
187
+ */
188
+ function findInitiallyExpandedGroups(
189
+ groups: ResolvedGroup[],
190
+ scope: string,
191
+ ): Set<string> {
192
+ return collectAncestorKeys(groups, scope, (group) => Boolean(group.expanded && group.name));
193
+ }
194
+
195
+ /**
196
+ * Named groups on the path from the root to the page at `currentPath`, so the
197
+ * active page's ancestors open by default.
198
+ */
199
+ function findGroupsContainingPath(
200
+ groups: ResolvedGroup[],
201
+ currentPath: string,
202
+ scope: string,
203
+ ): Set<string> {
204
+ return collectAncestorKeys(groups, scope, (group) =>
205
+ group.pages.some((page) => page.path === currentPath),
206
+ );
207
+ }
208
+
155
209
  export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPositionProp, isOpen = false, onClose }: SidebarProps) {
156
210
  const pathname = usePathname() ?? '';
157
211
  const router = useRouter();
@@ -170,6 +224,7 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
170
224
  // the active page's parent group collapsed on first paint.
171
225
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(() => {
172
226
  const initialNav = resolveNavigation(config, pathname || '/');
227
+ const initialScope = navigationScope(initialNav);
173
228
  const rootPath = linkPrefix || '/';
174
229
  // `pathname || rootPath` handles both the null-pathname mask (`?? ''`
175
230
  // above) and the bare-root case in one expression — when pathname is the
@@ -181,8 +236,8 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
181
236
  if (firstPage) seedPath = `${linkPrefix}/${firstPage}`;
182
237
  }
183
238
  const initialPath = seedPath.replace(/^\/(?:docs\/)?/, '');
184
- const seeded = findGroupsContainingPath(initialNav.groups, initialPath);
185
- findInitiallyExpandedGroups(initialNav.groups).forEach((g) => seeded.add(g));
239
+ const seeded = findGroupsContainingPath(initialNav.groups, initialPath, initialScope);
240
+ findInitiallyExpandedGroups(initialNav.groups, initialScope).forEach((g) => seeded.add(g));
186
241
  return seeded;
187
242
  });
188
243
  const [logoError, setLogoError] = useState(false);
@@ -246,6 +301,12 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
246
301
  return resolveNavigation(config, effectivePathname || pathname || '/');
247
302
  }, [config, effectivePathname, pathname]);
248
303
 
304
+ // Locale + active tab/anchor scope for accordion state keys. Derived from the
305
+ // resolved navigation (never from a visible group label) so manually-toggled
306
+ // groups don't leak their open state across tabs or languages that reuse the
307
+ // same labels and tree positions.
308
+ const scope = navigationScope(resolvedNav);
309
+
249
310
  // Normalize bare root path to first page path for active state highlighting.
250
311
  // When an upstream proxy (e.g., Cloudflare Worker) follows the server redirect
251
312
  // from /docs → /docs/introduction internally, the browser URL stays at /docs.
@@ -263,16 +324,16 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
263
324
  // Memoize the groups that should be expanded for the current page
264
325
  const groupsForCurrentPage = useMemo(() => {
265
326
  const currentPath = activePathname?.replace(/^\/(?:docs\/)?/, '') || '';
266
- return findGroupsContainingPath(resolvedNav.groups, currentPath);
267
- }, [resolvedNav.groups, activePathname]);
327
+ return findGroupsContainingPath(resolvedNav.groups, currentPath, scope);
328
+ }, [resolvedNav.groups, activePathname, scope]);
268
329
 
269
330
  // Re-evaluated whenever the resolved nav changes (e.g. switching tabs in
270
331
  // multi-tab docs), so newly-flagged `expanded: true` groups open on cross-tab
271
332
  // navigation. Without this re-eval, the schema flag would only be honored at
272
333
  // first mount.
273
334
  const initiallyExpandedGroups = useMemo(
274
- () => findInitiallyExpandedGroups(resolvedNav.groups),
275
- [resolvedNav.groups],
335
+ () => findInitiallyExpandedGroups(resolvedNav.groups, scope),
336
+ [resolvedNav.groups, scope],
276
337
  );
277
338
 
278
339
  // Merge the current page's ancestor groups + `expanded: true` flagged groups
@@ -375,14 +436,14 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
375
436
  // Toggle group expansion; if expanding, navigate to first page.
376
437
  // The router.push must run AFTER the setState commits — calling it inside the
377
438
  // updater triggers "Cannot update a component (Router) while rendering Sidebar".
378
- const handleGroupClick = useCallback((group: ResolvedGroup) => {
379
- const willExpand = !expandedGroups.has(group.name);
439
+ const handleGroupClick = useCallback((group: ResolvedGroup, key: string) => {
440
+ const willExpand = !expandedGroups.has(key);
380
441
  setExpandedGroups(prev => {
381
442
  const newSet = new Set(prev);
382
- if (prev.has(group.name)) {
383
- newSet.delete(group.name);
443
+ if (prev.has(key)) {
444
+ newSet.delete(key);
384
445
  } else {
385
- newSet.add(group.name);
446
+ newSet.add(key);
386
447
  }
387
448
  return newSet;
388
449
  });
@@ -394,136 +455,149 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
394
455
  }
395
456
  }, [linkPrefix, expandedGroups, handleButtonNav]);
396
457
 
397
- // Render a navigation group (supports nesting)
398
- function renderGroup(group: ResolvedGroup, level: number = 0) {
399
- const isExpanded = expandedGroups.has(group.name);
400
-
401
- // Skip rendering if group has no name and no content
402
- if (!group.name && group.pages.length === 0 && !group.nested?.length && !group.items?.length) {
403
- return null;
404
- }
405
-
406
- // Don't fan out RSC prefetches for collapsed L0 sections on large docs
407
- // sites. L1+ Links are only in the DOM when their named ancestors are
408
- // expanded (see the rendering guard below), so `level !== 0` is safe
409
- // shorthand there.
410
- const shouldPrefetch = level !== 0 || isExpanded || !group.name;
411
-
412
- return (
413
- <div key={group.name || `group-${level}`} className={level === 0 ? 'ml-6' : level === 1 ? '' : 'ml-3'}>
414
- {group.name && (
415
- level === 0 ? (
416
- <button
417
- onClick={() => handleGroupClick(group)}
418
- className="flex items-center justify-between w-full text-left mb-2 cursor-pointer"
419
- >
420
- <span className="text-sm font-semibold text-[var(--color-text-tertiary)] flex items-center gap-2">
421
- {group.icon && (
422
- <i className={`${getIconClass(group.icon)} text-[14px]`} aria-hidden="true" />
423
- )}
424
- {group.name}
425
- {group.tag && (
426
- <span className="px-1.5 py-0.5 text-[9px] font-semibold rounded bg-[var(--color-accent)]/15 text-[var(--color-accent)] normal-case tracking-normal">
427
- {group.tag}
428
- </span>
429
- )}
430
- </span>
431
- </button>
432
- ) : (
433
- <button
434
- onClick={() => handleGroupClick(group)}
435
- className={`nav-group-l1 flex items-center gap-1.5 ${layout === 'header-logo' ? 'pr-3' : 'px-3'} py-1.5 rounded-lg text-sm transition-colors w-full text-left text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] cursor-pointer`}
436
- >
437
- <span className="truncate">{group.name}</span>
438
- <i
439
- className={`fa-solid fa-chevron-right text-[8px] text-[var(--color-text-muted)] transition-transform ${isExpanded ? 'rotate-90' : ''}`}
440
- aria-hidden="true"
441
- />
442
- {group.tag && (
443
- <span className="px-1.5 py-0.5 text-[10px] font-semibold rounded bg-[var(--color-accent)]/15 text-[var(--color-accent)]">
444
- {group.tag}
445
- </span>
446
- )}
447
- </button>
448
- )
449
- )}
458
+ // Render the pages and nested groups inside a group. Split out from
459
+ // renderGroup so a named group can gate its contents behind an expanded panel
460
+ // (mounting them only while open) while an unnamed group renders them inline.
461
+ function renderGroupContents(group: ResolvedGroup, level: number, indexPath: GroupIndexPath) {
462
+ const isExpanded = expandedGroups.has(groupStateKey(scope, indexPath));
463
+ // Closed named groups never reach here (their contents are unmounted), so a
464
+ // rendered named group is always expanded; unnamed groups always prefetch.
465
+ const shouldPrefetch = !group.name || isExpanded;
450
466
 
451
- {(level === 0 || isExpanded || !group.name) && (
452
- <>
453
- {group.items ? (
454
- // Use ordered items array when available (preserves page/group ordering)
455
- <div className={level === 1 ? 'ml-3' : ''}>
456
- {(() => {
457
- // Group consecutive pages into single ul elements for continuous border
458
- const elements: React.ReactNode[] = [];
459
- let currentPages: typeof group.items = [];
460
-
461
- const flushPages = () => {
462
- if (currentPages.length > 0) {
463
- elements.push(
464
- <ul key={`pages-${elements.length}`}>
465
- {currentPages.map((p) => p.type === 'page' && (
466
- <NavPage
467
- key={p.page.path}
468
- page={p.page}
469
- pathname={activePathname}
470
- layout={layout}
471
- onNavigate={handleNavigate}
472
- linkPrefix={linkPrefix}
473
- showSpinner={spinnerPathname === `${linkPrefix}/${p.page.path}`}
474
- prefetch={shouldPrefetch}
475
- />
476
- ))}
477
- </ul>
478
- );
479
- currentPages = [];
480
- }
481
- };
482
-
483
- group.items.forEach((item, idx) => {
484
- if (item.type === 'page') {
485
- currentPages.push(item);
486
- } else {
487
- flushPages();
488
- elements.push(
489
- <div key={item.group.name || `nested-${idx}`} className={level === 0 ? '' : level === 1 ? '' : 'mt-4'}>
490
- {renderGroup(item.group, level + 1)}
491
- </div>
492
- );
493
- }
494
- });
495
- flushPages();
496
-
497
- return elements;
498
- })()}
499
- </div>
500
- ) : (
501
- // Fallback to legacy pages + nested (for backwards compatibility)
502
- <>
503
- {group.pages.length > 0 && (
504
- <ul className={level === 1 ? 'ml-3' : ''}>
505
- {group.pages.map((page) => (
467
+ if (group.items) {
468
+ // Use ordered items array when available (preserves page/group ordering)
469
+ return (
470
+ <div className={level === 1 ? 'ml-3' : ''}>
471
+ {(() => {
472
+ // Group consecutive pages into single ul elements for continuous border
473
+ const elements: React.ReactNode[] = [];
474
+ let currentPages: typeof group.items = [];
475
+
476
+ const flushPages = () => {
477
+ if (currentPages.length > 0) {
478
+ elements.push(
479
+ <ul key={`pages-${elements.length}`}>
480
+ {currentPages.map((p) => p.type === 'page' && (
506
481
  <NavPage
507
- key={page.path}
508
- page={page}
482
+ key={p.page.path}
483
+ page={p.page}
509
484
  pathname={activePathname}
510
485
  layout={layout}
511
486
  onNavigate={handleNavigate}
512
487
  linkPrefix={linkPrefix}
513
- showSpinner={spinnerPathname === `${linkPrefix}/${page.path}`}
488
+ showSpinner={spinnerPathname === `${linkPrefix}/${p.page.path}`}
514
489
  prefetch={shouldPrefetch}
515
490
  />
516
491
  ))}
517
492
  </ul>
518
- )}
519
- {group.nested && group.nested.length > 0 && (
520
- <div className={level === 0 ? '' : level === 1 ? 'ml-3' : 'mt-4'}>
521
- {group.nested.map((nested) => renderGroup(nested, level + 1))}
522
- </div>
523
- )}
524
- </>
493
+ );
494
+ currentPages = [];
495
+ }
496
+ };
497
+
498
+ // Track the nested-group sibling index separately from the items
499
+ // index: the i-th nested group is the i-th group-typed item, which
500
+ // is the same index navigation-resolver assigns in `group.nested`.
501
+ // This keeps state keys aligned with the discovery helpers.
502
+ let nestedGroupIndex = 0;
503
+ group.items.forEach((item) => {
504
+ if (item.type === 'page') {
505
+ currentPages.push(item);
506
+ return;
507
+ }
508
+ flushPages();
509
+ const childIndex = nestedGroupIndex++;
510
+ elements.push(
511
+ <div key={groupStateKey(scope, [...indexPath, childIndex])} className={level <= 1 ? '' : 'mt-4'}>
512
+ {renderGroup(item.group, level + 1, [...indexPath, childIndex])}
513
+ </div>
514
+ );
515
+ });
516
+ flushPages();
517
+
518
+ return elements;
519
+ })()}
520
+ </div>
521
+ );
522
+ }
523
+
524
+ // Fallback to legacy pages + nested (for backwards compatibility)
525
+ return (
526
+ <>
527
+ {group.pages.length > 0 && (
528
+ <ul className={level === 1 ? 'ml-3' : ''}>
529
+ {group.pages.map((page) => (
530
+ <NavPage
531
+ key={page.path}
532
+ page={page}
533
+ pathname={activePathname}
534
+ layout={layout}
535
+ onNavigate={handleNavigate}
536
+ linkPrefix={linkPrefix}
537
+ showSpinner={spinnerPathname === `${linkPrefix}/${page.path}`}
538
+ prefetch={shouldPrefetch}
539
+ />
540
+ ))}
541
+ </ul>
542
+ )}
543
+ {group.nested && group.nested.length > 0 && (
544
+ <div className={level === 0 ? '' : level === 1 ? 'ml-3' : 'mt-4'}>
545
+ {group.nested.map((nested, childIndex) => renderGroup(nested, level + 1, [...indexPath, childIndex]))}
546
+ </div>
547
+ )}
548
+ </>
549
+ );
550
+ }
551
+
552
+ // Render a navigation group (supports nesting). Every named group — top-level
553
+ // or nested — is an accordion: a button carrying aria-expanded/aria-controls
554
+ // toggles an addressable panel whose descendants mount only while expanded.
555
+ function renderGroup(group: ResolvedGroup, level: number = 0, indexPath: GroupIndexPath = []) {
556
+ // Skip rendering if group has no name and no content
557
+ if (!group.name && group.pages.length === 0 && !group.nested?.length && !group.items?.length) {
558
+ return null;
559
+ }
560
+
561
+ const key = groupStateKey(scope, indexPath);
562
+ const panelId = groupPanelId(scope, indexPath);
563
+ const isExpanded = expandedGroups.has(key);
564
+ const isTopLevel = level === 0;
565
+ const outerClassName = isTopLevel ? 'ml-6' : level === 1 ? '' : 'ml-3';
566
+ const buttonClassName = isTopLevel
567
+ ? 'flex items-center gap-2 w-full min-h-8 py-1.5 mb-2 text-left text-sm font-semibold text-[var(--color-text-tertiary)] cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-accent)] focus-visible:ring-offset-2'
568
+ : `nav-group-l1 flex items-center gap-1.5 ${layout === 'header-logo' ? 'pr-3' : 'px-3'} py-1.5 rounded-lg text-sm transition-colors w-full text-left text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-accent)] focus-visible:ring-offset-2`;
569
+
570
+ return (
571
+ <div key={key} className={outerClassName}>
572
+ {group.name && (
573
+ <button
574
+ type="button"
575
+ aria-expanded={isExpanded}
576
+ aria-controls={panelId}
577
+ onClick={() => handleGroupClick(group, key)}
578
+ className={buttonClassName}
579
+ >
580
+ {group.icon && (
581
+ <i className={`${getIconClass(group.icon)} text-[14px]`} aria-hidden="true" />
582
+ )}
583
+ <span className="flex-1 min-w-0 truncate">{group.name}</span>
584
+ {group.tag && (
585
+ <span className={`${isTopLevel ? 'text-[9px]' : 'text-[10px]'} px-1.5 py-0.5 font-semibold rounded bg-[var(--color-accent)]/15 text-[var(--color-accent)]`}>
586
+ {group.tag}
587
+ </span>
525
588
  )}
526
- </>
589
+ <i
590
+ className={`fa-solid fa-chevron-right text-[8px] text-[var(--color-text-muted)] transition-transform ${isExpanded ? 'rotate-90' : ''}`}
591
+ aria-hidden="true"
592
+ />
593
+ </button>
594
+ )}
595
+ {group.name ? (
596
+ <div id={panelId} hidden={!isExpanded}>
597
+ {isExpanded && renderGroupContents(group, level, indexPath)}
598
+ </div>
599
+ ) : (
600
+ renderGroupContents(group, level, indexPath)
527
601
  )}
528
602
  </div>
529
603
  );
@@ -818,7 +892,7 @@ export function Sidebar({ config, layout = 'header-logo', tabsPosition: tabsPosi
818
892
 
819
893
  {/* Navigation Groups */}
820
894
  <div className="sidebar-nav-groups">
821
- {resolvedNav.groups.map((group) => renderGroup(group))}
895
+ {resolvedNav.groups.map((group, index) => renderGroup(group, 0, [index]))}
822
896
  </div>
823
897
  </nav>
824
898