forked from CopilotKit/CopilotKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsidebar-framework-selector.tsx
More file actions
60 lines (56 loc) · 2.3 KB
/
Copy pathsidebar-framework-selector.tsx
File metadata and controls
60 lines (56 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// SidebarFrameworkSelector — server component that resolves the list of
// framework options from the registry and renders the client-side
// <FrameworkSelector /> with the `sidebar` variant.
//
// Mounted at the TOP of every docs sidebar (both `/docs/...` and
// `/<framework>/...`) so the "agentic backend" pivot is always visible
// — matching the docs.copilotkit.ai reference, where the selector is
// the sidebar's header element.
import React from "react";
import { FrameworkSelector } from "./framework-selector";
import { getCategoryLabel, getDocsMode, getIntegrations } from "@/lib/registry";
import { FRAMEWORK_CATEGORY_ORDER } from "@/lib/docs-render";
export function SidebarFrameworkSelector() {
// Sort by explicit sort_order, falling back to alphabetical slug for
// stability when multiple integrations share the default. Array#sort
// is not guaranteed stable across engines for ties, so we make the
// tiebreak explicit — otherwise "soon" integrations shuffle between
// renders on builds using different V8 revisions.
const options = getIntegrations()
.slice()
// Drop frameworks marked `docs_mode: hidden` in their manifest —
// they have no docs page in shell-docs, so listing them in the
// switcher would let users land on a 404. The framework still
// exists in the registry (its demo, manifest, and shell-dojo
// surface continue to work); it's just absent from the docs site.
.filter((i) => getDocsMode(i.slug) !== "hidden")
.sort((a, b) => {
const ao = a.sort_order ?? 999;
const bo = b.sort_order ?? 999;
if (ao !== bo) return ao - bo;
return a.slug.localeCompare(b.slug);
})
.map((i) => ({
slug: i.slug,
name: i.name,
category: i.category ?? "other",
logo: i.logo ?? null,
deployed: i.deployed,
}));
const categoryOrder = FRAMEWORK_CATEGORY_ORDER.map((id) => ({
id,
name: getCategoryLabel(id),
}));
return (
// The sidebar column itself is already fixed within the docs layout, so
// this selector can stay in normal flow. Keeping it non-sticky avoids a
// raised layer overlapping the first selected sidebar item at scroll-top.
<div>
<FrameworkSelector
options={options}
categoryOrder={categoryOrder}
variant="sidebar"
/>
</div>
);
}