blodemd 0.0.15 → 0.2.0

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.
Files changed (286) hide show
  1. package/README.md +26 -1
  2. package/dist/cli.mjs +217 -217
  3. package/dist/cli.mjs.map +1 -1
  4. package/package.json +3 -36
  5. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  6. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  7. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  8. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  9. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  10. package/dev-server/app/error.tsx +0 -24
  11. package/dev-server/app/favicon.ico +0 -0
  12. package/dev-server/app/globals.css +0 -4
  13. package/dev-server/app/layout.tsx +0 -38
  14. package/dev-server/app/not-found.tsx +0 -18
  15. package/dev-server/app/search/route.ts +0 -17
  16. package/dev-server/components/dev-reload-script.tsx +0 -86
  17. package/dev-server/components/providers.tsx +0 -15
  18. package/dev-server/lib/dev-state.ts +0 -8
  19. package/dev-server/lib/local-content-source.ts +0 -103
  20. package/dev-server/lib/local-runtime.tsx +0 -555
  21. package/dev-server/next-env.d.ts +0 -5
  22. package/dev-server/next.config.js +0 -54
  23. package/dev-server/package.json +0 -61
  24. package/dev-server/postcss.config.mjs +0 -7
  25. package/dev-server/public/glide-variable.woff2 +0 -0
  26. package/dev-server/tsconfig.json +0 -50
  27. package/docs/app/globals.css +0 -471
  28. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  29. package/docs/components/api/api-playground.tsx +0 -467
  30. package/docs/components/api/api-reference.tsx +0 -157
  31. package/docs/components/content/collection-index.tsx +0 -114
  32. package/docs/components/docs/contextual-menu.tsx +0 -495
  33. package/docs/components/docs/copy-page-menu.tsx +0 -364
  34. package/docs/components/docs/doc-header.tsx +0 -223
  35. package/docs/components/docs/doc-shell.tsx +0 -355
  36. package/docs/components/docs/doc-sidebar.tsx +0 -256
  37. package/docs/components/docs/doc-toc.tsx +0 -46
  38. package/docs/components/docs/mobile-nav.tsx +0 -195
  39. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  40. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  41. package/docs/components/git/repo-picker.tsx +0 -529
  42. package/docs/components/icons/doc-icon.tsx +0 -96
  43. package/docs/components/mdx/accordion.tsx +0 -83
  44. package/docs/components/mdx/agent-instructions.tsx +0 -17
  45. package/docs/components/mdx/badge.tsx +0 -79
  46. package/docs/components/mdx/callout.tsx +0 -88
  47. package/docs/components/mdx/card.tsx +0 -110
  48. package/docs/components/mdx/code-block.tsx +0 -80
  49. package/docs/components/mdx/code-group.tsx +0 -203
  50. package/docs/components/mdx/color.tsx +0 -87
  51. package/docs/components/mdx/columns.tsx +0 -25
  52. package/docs/components/mdx/expandable.tsx +0 -45
  53. package/docs/components/mdx/field-layout.tsx +0 -77
  54. package/docs/components/mdx/frame.tsx +0 -23
  55. package/docs/components/mdx/get-text-content.ts +0 -18
  56. package/docs/components/mdx/icon.tsx +0 -12
  57. package/docs/components/mdx/iframe.tsx +0 -62
  58. package/docs/components/mdx/index.tsx +0 -121
  59. package/docs/components/mdx/installer.tsx +0 -20
  60. package/docs/components/mdx/panel.tsx +0 -11
  61. package/docs/components/mdx/param-field.tsx +0 -56
  62. package/docs/components/mdx/preview.tsx +0 -36
  63. package/docs/components/mdx/prompt.tsx +0 -63
  64. package/docs/components/mdx/request-example.tsx +0 -27
  65. package/docs/components/mdx/response-field.tsx +0 -42
  66. package/docs/components/mdx/steps.tsx +0 -92
  67. package/docs/components/mdx/tabs.tsx +0 -193
  68. package/docs/components/mdx/tile.tsx +0 -43
  69. package/docs/components/mdx/tooltip.tsx +0 -71
  70. package/docs/components/mdx/tree.tsx +0 -120
  71. package/docs/components/mdx/type-table.tsx +0 -71
  72. package/docs/components/mdx/update.tsx +0 -44
  73. package/docs/components/mdx/video.tsx +0 -45
  74. package/docs/components/mdx/view.tsx +0 -66
  75. package/docs/components/posthog-provider.tsx +0 -42
  76. package/docs/components/providers.tsx +0 -15
  77. package/docs/components/tenant-analytics.tsx +0 -49
  78. package/docs/components/third-parties.tsx +0 -32
  79. package/docs/components/ui/badge.tsx +0 -61
  80. package/docs/components/ui/breadcrumb.tsx +0 -112
  81. package/docs/components/ui/button-group.tsx +0 -83
  82. package/docs/components/ui/button.tsx +0 -65
  83. package/docs/components/ui/card.tsx +0 -92
  84. package/docs/components/ui/command.tsx +0 -167
  85. package/docs/components/ui/copy-button.tsx +0 -129
  86. package/docs/components/ui/dialog.tsx +0 -146
  87. package/docs/components/ui/field.tsx +0 -237
  88. package/docs/components/ui/input.tsx +0 -23
  89. package/docs/components/ui/kbd.tsx +0 -98
  90. package/docs/components/ui/label.tsx +0 -22
  91. package/docs/components/ui/morph-icon.tsx +0 -79
  92. package/docs/components/ui/popover.tsx +0 -267
  93. package/docs/components/ui/search-dialog.tsx +0 -431
  94. package/docs/components/ui/search.tsx +0 -101
  95. package/docs/components/ui/separator.tsx +0 -26
  96. package/docs/components/ui/sheet.tsx +0 -133
  97. package/docs/components/ui/sidebar.tsx +0 -758
  98. package/docs/components/ui/skeleton.tsx +0 -11
  99. package/docs/components/ui/switch.tsx +0 -32
  100. package/docs/components/ui/tabs.tsx +0 -138
  101. package/docs/components/ui/theme-toggle.tsx +0 -62
  102. package/docs/components/ui/tooltip.tsx +0 -53
  103. package/docs/components/web-mcp.tsx +0 -115
  104. package/docs/lib/agent-skills.ts +0 -48
  105. package/docs/lib/api-client.ts +0 -72
  106. package/docs/lib/config.ts +0 -6
  107. package/docs/lib/content-root.ts +0 -33
  108. package/docs/lib/content-source.ts +0 -70
  109. package/docs/lib/contextual-options.ts +0 -222
  110. package/docs/lib/dashboard-session.ts +0 -167
  111. package/docs/lib/db.ts +0 -13
  112. package/docs/lib/docs-collection.ts +0 -7
  113. package/docs/lib/docs-runtime.tsx +0 -745
  114. package/docs/lib/edge-config.ts +0 -95
  115. package/docs/lib/env.ts +0 -23
  116. package/docs/lib/etag.ts +0 -22
  117. package/docs/lib/github-install.ts +0 -33
  118. package/docs/lib/llms-full.ts +0 -82
  119. package/docs/lib/marketing-markdown.ts +0 -79
  120. package/docs/lib/marketing-site.ts +0 -31
  121. package/docs/lib/mdx.ts +0 -98
  122. package/docs/lib/navigation.ts +0 -288
  123. package/docs/lib/openapi-proxy.ts +0 -88
  124. package/docs/lib/openapi.ts +0 -158
  125. package/docs/lib/platform-config.ts +0 -6
  126. package/docs/lib/project-authz.ts +0 -46
  127. package/docs/lib/routes.ts +0 -103
  128. package/docs/lib/server-cache.ts +0 -83
  129. package/docs/lib/shiki.ts +0 -44
  130. package/docs/lib/supabase.ts +0 -37
  131. package/docs/lib/tenancy.ts +0 -364
  132. package/docs/lib/tenant-headers.ts +0 -43
  133. package/docs/lib/tenant-static.ts +0 -705
  134. package/docs/lib/tenant-utility-context.ts +0 -62
  135. package/docs/lib/tenants.ts +0 -72
  136. package/docs/lib/theme.ts +0 -29
  137. package/docs/lib/time-ago.ts +0 -24
  138. package/docs/lib/toc.ts +0 -2
  139. package/docs/lib/use-mobile.ts +0 -19
  140. package/docs/lib/use-tab-observer.ts +0 -71
  141. package/docs/lib/utils.ts +0 -5
  142. package/packages/@repo/common/dist/index.d.ts +0 -16
  143. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  144. package/packages/@repo/common/dist/index.js +0 -84
  145. package/packages/@repo/common/package.json +0 -34
  146. package/packages/@repo/common/src/index.ts +0 -101
  147. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  148. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  149. package/packages/@repo/contracts/dist/analytics.js +0 -18
  150. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  151. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  152. package/packages/@repo/contracts/dist/dates.js +0 -2
  153. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  154. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  155. package/packages/@repo/contracts/dist/deployment.js +0 -46
  156. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  157. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  158. package/packages/@repo/contracts/dist/domain.js +0 -36
  159. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  160. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  161. package/packages/@repo/contracts/dist/git.js +0 -24
  162. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  163. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  164. package/packages/@repo/contracts/dist/ids.js +0 -11
  165. package/packages/@repo/contracts/dist/index.d.ts +0 -11
  166. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  167. package/packages/@repo/contracts/dist/index.js +0 -12
  168. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  169. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  170. package/packages/@repo/contracts/dist/pagination.js +0 -15
  171. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  172. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  173. package/packages/@repo/contracts/dist/project.js +0 -25
  174. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  175. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  176. package/packages/@repo/contracts/dist/tenant.js +0 -58
  177. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  178. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  179. package/packages/@repo/contracts/dist/user.js +0 -9
  180. package/packages/@repo/contracts/package.json +0 -37
  181. package/packages/@repo/contracts/src/analytics.ts +0 -33
  182. package/packages/@repo/contracts/src/dates.ts +0 -4
  183. package/packages/@repo/contracts/src/deployment.ts +0 -73
  184. package/packages/@repo/contracts/src/domain.ts +0 -51
  185. package/packages/@repo/contracts/src/git.ts +0 -31
  186. package/packages/@repo/contracts/src/ids.ts +0 -23
  187. package/packages/@repo/contracts/src/index.ts +0 -12
  188. package/packages/@repo/contracts/src/pagination.ts +0 -21
  189. package/packages/@repo/contracts/src/project.ts +0 -32
  190. package/packages/@repo/contracts/src/tenant.ts +0 -94
  191. package/packages/@repo/contracts/src/user.ts +0 -12
  192. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  193. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  194. package/packages/@repo/models/dist/docs-config.js +0 -531
  195. package/packages/@repo/models/dist/index.d.ts +0 -3
  196. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/index.js +0 -3
  198. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  199. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/tenant.js +0 -1
  201. package/packages/@repo/models/package.json +0 -37
  202. package/packages/@repo/models/src/docs-config.ts +0 -629
  203. package/packages/@repo/models/src/index.ts +0 -3
  204. package/packages/@repo/models/src/tenant.ts +0 -44
  205. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  206. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  207. package/packages/@repo/prebuild/dist/index.js +0 -2
  208. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  209. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  211. package/packages/@repo/prebuild/package.json +0 -39
  212. package/packages/@repo/prebuild/src/index.ts +0 -2
  213. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  214. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  215. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  216. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  217. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  218. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  220. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  221. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/constants.js +0 -14
  223. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  224. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/content-index.js +0 -291
  226. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  227. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-source.js +0 -1
  229. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  230. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  232. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  233. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/index.js +0 -13
  235. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  236. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  238. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  239. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  241. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  242. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  244. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  245. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  247. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  248. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/search-index.js +0 -23
  250. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  251. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/serialization.js +0 -108
  253. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  254. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  256. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  257. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/types.js +0 -1
  259. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  260. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  262. package/packages/@repo/previewing/package.json +0 -41
  263. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  264. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  265. package/packages/@repo/previewing/src/constants.ts +0 -16
  266. package/packages/@repo/previewing/src/content-index.ts +0 -384
  267. package/packages/@repo/previewing/src/content-source.ts +0 -12
  268. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  269. package/packages/@repo/previewing/src/index.ts +0 -71
  270. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  271. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  272. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  273. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  274. package/packages/@repo/previewing/src/search-index.ts +0 -38
  275. package/packages/@repo/previewing/src/serialization.ts +0 -191
  276. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  277. package/packages/@repo/previewing/src/types.ts +0 -105
  278. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  279. package/packages/@repo/validation/dist/index.d.ts +0 -12
  280. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  281. package/packages/@repo/validation/dist/index.js +0 -30
  282. package/packages/@repo/validation/package.json +0 -38
  283. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  284. package/packages/@repo/validation/src/index.ts +0 -59
  285. package/scripts/prepare-package.mjs +0 -53
  286. package/scripts/repo-packages.mjs +0 -8
@@ -1,758 +0,0 @@
1
- "use client";
2
- // oxlint-disable eslint-plugin-unicorn/no-document-cookie -- sidebar state persisted via cookie (by design)
3
- // oxlint-disable eslint/no-shadow -- registry code; upstream uses `open` in nested scopes
4
- // oxlint-disable eslint/no-param-reassign -- registry code normalises tooltip prop
5
- // oxlint-disable eslint-plugin-react/button-has-type -- trigger intentionally uses default button behavior
6
- // oxlint-disable eslint-plugin-react-perf/jsx-no-new-function-as-prop -- registry-defined trigger composition
7
-
8
- import { mergeProps } from "@base-ui/react/merge-props";
9
- import { useRender } from "@base-ui/react/use-render";
10
- import { PanelLeftIcon } from "blode-icons-react";
11
- import { cva } from "class-variance-authority";
12
- import type { VariantProps } from "class-variance-authority";
13
- import type * as React from "react";
14
- import {
15
- createContext,
16
- useCallback,
17
- useContext,
18
- useEffect,
19
- useMemo,
20
- useState,
21
- } from "react";
22
-
23
- import { Button } from "@/components/ui/button";
24
- import { Input } from "@/components/ui/input";
25
- import { Separator } from "@/components/ui/separator";
26
- import {
27
- Sheet,
28
- SheetContent,
29
- SheetDescription,
30
- SheetHeader,
31
- SheetTitle,
32
- } from "@/components/ui/sheet";
33
- import { Skeleton } from "@/components/ui/skeleton";
34
- import {
35
- Tooltip,
36
- TooltipContent,
37
- TooltipProvider,
38
- TooltipTrigger,
39
- } from "@/components/ui/tooltip";
40
- import { useIsMobile } from "@/lib/use-mobile";
41
- import { cn } from "@/lib/utils";
42
-
43
- const SIDEBAR_COOKIE_NAME = "sidebar_state";
44
- const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
45
- const SIDEBAR_WIDTH = "16rem";
46
- const SIDEBAR_WIDTH_MOBILE = "18rem";
47
- const SIDEBAR_WIDTH_ICON = "3rem";
48
- const SIDEBAR_KEYBOARD_SHORTCUT = "b";
49
-
50
- interface SidebarContextProps {
51
- isMobile: boolean;
52
- open: boolean;
53
- openMobile: boolean;
54
- setOpen: (open: boolean) => void;
55
- setOpenMobile: (open: boolean) => void;
56
- state: "expanded" | "collapsed";
57
- toggleSidebar: () => void;
58
- }
59
-
60
- const SidebarContext = createContext<SidebarContextProps | null>(null);
61
-
62
- const useSidebar = () => {
63
- const context = useContext(SidebarContext);
64
- if (!context) {
65
- throw new Error("useSidebar must be used within a SidebarProvider.");
66
- }
67
-
68
- return context;
69
- };
70
-
71
- const SidebarProvider = ({
72
- defaultOpen = true,
73
- open: openProp,
74
- onOpenChange: setOpenProp,
75
- className,
76
- style,
77
- children,
78
- ...props
79
- }: React.ComponentProps<"div"> & {
80
- defaultOpen?: boolean;
81
- open?: boolean;
82
- onOpenChange?: (open: boolean) => void;
83
- }) => {
84
- const isMobile = useIsMobile();
85
- const [openMobile, setOpenMobile] = useState(false);
86
-
87
- // This is the internal state of the sidebar.
88
- // We use openProp and setOpenProp for control from outside the component.
89
- const [_open, _setOpen] = useState(defaultOpen);
90
- const open = openProp ?? _open;
91
- const setOpen = useCallback(
92
- (value: boolean | ((value: boolean) => boolean)) => {
93
- const openState = typeof value === "function" ? value(open) : value;
94
- if (setOpenProp) {
95
- setOpenProp(openState);
96
- } else {
97
- _setOpen(openState);
98
- }
99
-
100
- // This sets the cookie to keep the sidebar state.
101
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
102
- },
103
- [setOpenProp, open]
104
- );
105
-
106
- // Helper to toggle the sidebar.
107
- const toggleSidebar = useCallback(
108
- () =>
109
- isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open),
110
- [isMobile, setOpen]
111
- );
112
-
113
- // Adds a keyboard shortcut to toggle the sidebar.
114
- useEffect(() => {
115
- const handleKeyDown = (event: KeyboardEvent) => {
116
- if (
117
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
118
- (event.metaKey || event.ctrlKey)
119
- ) {
120
- event.preventDefault();
121
- toggleSidebar();
122
- }
123
- };
124
-
125
- window.addEventListener("keydown", handleKeyDown);
126
- return () => window.removeEventListener("keydown", handleKeyDown);
127
- }, [toggleSidebar]);
128
-
129
- // We add a state so that we can do data-state="expanded" or "collapsed".
130
- // This makes it easier to style the sidebar with Tailwind classes.
131
- const state = open ? "expanded" : "collapsed";
132
-
133
- const contextValue = useMemo<SidebarContextProps>(
134
- () => ({
135
- isMobile,
136
- open,
137
- openMobile,
138
- setOpen,
139
- setOpenMobile,
140
- state,
141
- toggleSidebar,
142
- }),
143
- [state, open, setOpen, isMobile, openMobile, toggleSidebar]
144
- );
145
-
146
- return (
147
- <SidebarContext.Provider value={contextValue}>
148
- <TooltipProvider delayDuration={0}>
149
- <div
150
- className={cn(
151
- "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar",
152
- className
153
- )}
154
- data-slot="sidebar-wrapper"
155
- style={
156
- {
157
- "--sidebar-width": SIDEBAR_WIDTH,
158
- "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
159
- ...style,
160
- } as React.CSSProperties
161
- }
162
- {...props}
163
- >
164
- {children}
165
- </div>
166
- </TooltipProvider>
167
- </SidebarContext.Provider>
168
- );
169
- };
170
-
171
- const Sidebar = ({
172
- side = "left",
173
- variant = "sidebar",
174
- collapsible = "offcanvas",
175
- className,
176
- children,
177
- ...props
178
- }: React.ComponentProps<"div"> & {
179
- side?: "left" | "right";
180
- variant?: "sidebar" | "floating" | "inset";
181
- collapsible?: "offcanvas" | "icon" | "none";
182
- }) => {
183
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
184
-
185
- if (collapsible === "none") {
186
- return (
187
- <div
188
- className={cn(
189
- "flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground",
190
- className
191
- )}
192
- data-slot="sidebar"
193
- {...props}
194
- >
195
- {children}
196
- </div>
197
- );
198
- }
199
-
200
- if (isMobile) {
201
- return (
202
- <Sheet onOpenChange={setOpenMobile} open={openMobile} {...props}>
203
- <SheetContent
204
- className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
205
- data-mobile="true"
206
- data-sidebar="sidebar"
207
- data-slot="sidebar"
208
- side={side}
209
- style={
210
- {
211
- "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
212
- } as React.CSSProperties
213
- }
214
- >
215
- <SheetHeader className="sr-only">
216
- <SheetTitle>Sidebar</SheetTitle>
217
- <SheetDescription>Displays the mobile sidebar.</SheetDescription>
218
- </SheetHeader>
219
- <div className="flex h-full w-full flex-col">{children}</div>
220
- </SheetContent>
221
- </Sheet>
222
- );
223
- }
224
-
225
- return (
226
- <div
227
- className="group peer hidden text-sidebar-foreground md:block"
228
- data-collapsible={state === "collapsed" ? collapsible : ""}
229
- data-side={side}
230
- data-slot="sidebar"
231
- data-state={state}
232
- data-variant={variant}
233
- >
234
- {/* This is what handles the sidebar gap on desktop */}
235
- <div
236
- className={cn(
237
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
238
- "group-data-[collapsible=offcanvas]:w-0",
239
- "group-data-[side=right]:rotate-180",
240
- variant === "floating" || variant === "inset"
241
- ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
242
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
243
- )}
244
- data-slot="sidebar-gap"
245
- />
246
- <div
247
- className={cn(
248
- "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
249
- side === "left"
250
- ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
251
- : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
252
- // Adjust the padding for floating and inset variants.
253
- variant === "floating" || variant === "inset"
254
- ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
255
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
256
- className
257
- )}
258
- data-slot="sidebar-container"
259
- {...props}
260
- >
261
- <div
262
- className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm"
263
- data-sidebar="sidebar"
264
- data-slot="sidebar-inner"
265
- >
266
- {children}
267
- </div>
268
- </div>
269
- </div>
270
- );
271
- };
272
-
273
- const SidebarTrigger = ({
274
- className,
275
- onClick,
276
- ...props
277
- }: React.ComponentProps<typeof Button>) => {
278
- const { toggleSidebar } = useSidebar();
279
-
280
- return (
281
- <Button
282
- className={cn("size-7", className)}
283
- data-sidebar="trigger"
284
- data-slot="sidebar-trigger"
285
- onClick={(event) => {
286
- onClick?.(event);
287
- toggleSidebar();
288
- }}
289
- size="icon"
290
- variant="ghost"
291
- {...props}
292
- >
293
- <PanelLeftIcon />
294
- <span className="sr-only">Toggle Sidebar</span>
295
- </Button>
296
- );
297
- };
298
-
299
- const SidebarRail = ({
300
- className,
301
- ...props
302
- }: React.ComponentProps<"button">) => {
303
- const { toggleSidebar } = useSidebar();
304
-
305
- return (
306
- <button
307
- aria-label="Toggle Sidebar"
308
- className={cn(
309
- "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
310
- "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
311
- "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
312
- "group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full",
313
- "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
314
- "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
315
- className
316
- )}
317
- data-sidebar="rail"
318
- data-slot="sidebar-rail"
319
- onClick={toggleSidebar}
320
- tabIndex={-1}
321
- title="Toggle Sidebar"
322
- {...props}
323
- />
324
- );
325
- };
326
-
327
- const SidebarInset = ({
328
- className,
329
- ...props
330
- }: React.ComponentProps<"main">) => (
331
- <main
332
- className={cn(
333
- "relative flex w-full flex-1 flex-col bg-background",
334
- "md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm",
335
- className
336
- )}
337
- data-slot="sidebar-inset"
338
- {...props}
339
- />
340
- );
341
-
342
- const SidebarInput = ({
343
- className,
344
- ...props
345
- }: React.ComponentProps<typeof Input>) => (
346
- <Input
347
- className={cn("h-8 w-full bg-background shadow-none", className)}
348
- data-sidebar="input"
349
- data-slot="sidebar-input"
350
- {...props}
351
- />
352
- );
353
-
354
- const SidebarHeader = ({
355
- className,
356
- ...props
357
- }: React.ComponentProps<"div">) => (
358
- <div
359
- className={cn("flex flex-col gap-2 p-2", className)}
360
- data-sidebar="header"
361
- data-slot="sidebar-header"
362
- {...props}
363
- />
364
- );
365
-
366
- const SidebarFooter = ({
367
- className,
368
- ...props
369
- }: React.ComponentProps<"div">) => (
370
- <div
371
- className={cn("flex flex-col gap-2 p-2", className)}
372
- data-sidebar="footer"
373
- data-slot="sidebar-footer"
374
- {...props}
375
- />
376
- );
377
-
378
- const SidebarSeparator = ({
379
- className,
380
- ...props
381
- }: React.ComponentProps<typeof Separator>) => (
382
- <Separator
383
- className={cn("mx-2 w-auto bg-sidebar-border", className)}
384
- data-sidebar="separator"
385
- data-slot="sidebar-separator"
386
- {...props}
387
- />
388
- );
389
-
390
- const SidebarContent = ({
391
- className,
392
- ...props
393
- }: React.ComponentProps<"div">) => (
394
- <div
395
- className={cn(
396
- "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
397
- className
398
- )}
399
- data-sidebar="content"
400
- data-slot="sidebar-content"
401
- {...props}
402
- />
403
- );
404
-
405
- const SidebarGroup = ({ className, ...props }: React.ComponentProps<"div">) => (
406
- <div
407
- className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
408
- data-sidebar="group"
409
- data-slot="sidebar-group"
410
- {...props}
411
- />
412
- );
413
-
414
- const SidebarGroupLabel = ({
415
- className,
416
- asChild = false,
417
- children,
418
- ...props
419
- }: React.ComponentProps<"div"> & { asChild?: boolean }) =>
420
- useRender({
421
- defaultTagName: "div",
422
- props: mergeProps<"div">(
423
- {
424
- className: cn(
425
- "flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
426
- "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
427
- className
428
- ),
429
- },
430
- asChild ? props : { ...props, children }
431
- ),
432
- render: asChild ? (children as React.ReactElement) : undefined,
433
- state: {
434
- sidebar: "group-label",
435
- slot: "sidebar-group-label",
436
- },
437
- });
438
-
439
- const SidebarGroupAction = ({
440
- className,
441
- asChild = false,
442
- children,
443
- ...props
444
- }: React.ComponentProps<"button"> & { asChild?: boolean }) =>
445
- useRender({
446
- defaultTagName: "button",
447
- props: mergeProps<"button">(
448
- {
449
- className: cn(
450
- "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
451
- // Increases the hit area of the button on mobile.
452
- "after:absolute after:-inset-2 md:after:hidden",
453
- "group-data-[collapsible=icon]:hidden",
454
- className
455
- ),
456
- },
457
- asChild ? props : { ...props, children }
458
- ),
459
- render: asChild ? (children as React.ReactElement) : undefined,
460
- state: {
461
- sidebar: "group-action",
462
- slot: "sidebar-group-action",
463
- },
464
- });
465
-
466
- const SidebarGroupContent = ({
467
- className,
468
- ...props
469
- }: React.ComponentProps<"div">) => (
470
- <div
471
- className={cn("w-full text-sm", className)}
472
- data-sidebar="group-content"
473
- data-slot="sidebar-group-content"
474
- {...props}
475
- />
476
- );
477
-
478
- const SidebarMenu = ({ className, ...props }: React.ComponentProps<"ul">) => (
479
- <ul
480
- className={cn("flex w-full min-w-0 flex-col gap-1", className)}
481
- data-sidebar="menu"
482
- data-slot="sidebar-menu"
483
- {...props}
484
- />
485
- );
486
-
487
- const SidebarMenuItem = ({
488
- className,
489
- ...props
490
- }: React.ComponentProps<"li">) => (
491
- <li
492
- className={cn("group/menu-item relative", className)}
493
- data-sidebar="menu-item"
494
- data-slot="sidebar-menu-item"
495
- {...props}
496
- />
497
- );
498
-
499
- const sidebarMenuButtonVariants = cva(
500
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active]:bg-sidebar-accent data-[active]:font-medium data-[active]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
501
- {
502
- defaultVariants: {
503
- size: "default",
504
- variant: "default",
505
- },
506
- variants: {
507
- size: {
508
- default: "h-8 text-sm",
509
- lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
510
- sm: "h-7 text-xs",
511
- },
512
- variant: {
513
- default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
514
- outline:
515
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
516
- },
517
- },
518
- }
519
- );
520
-
521
- const SidebarMenuButton = ({
522
- asChild = false,
523
- isActive = false,
524
- variant = "default",
525
- size = "default",
526
- tooltip,
527
- className,
528
- children,
529
- ...props
530
- }: React.ComponentProps<"button"> & {
531
- asChild?: boolean;
532
- isActive?: boolean;
533
- tooltip?: string | React.ComponentProps<typeof TooltipContent>;
534
- } & VariantProps<typeof sidebarMenuButtonVariants>) => {
535
- const { isMobile, state } = useSidebar();
536
-
537
- const button = useRender({
538
- defaultTagName: "button",
539
- props: mergeProps<"button">(
540
- {
541
- className: cn(sidebarMenuButtonVariants({ size, variant }), className),
542
- },
543
- asChild ? props : { ...props, children }
544
- ),
545
- render: asChild ? (children as React.ReactElement) : undefined,
546
- state: {
547
- active: isActive,
548
- sidebar: "menu-button",
549
- size,
550
- slot: "sidebar-menu-button",
551
- },
552
- });
553
-
554
- if (!tooltip) {
555
- return button;
556
- }
557
-
558
- if (typeof tooltip === "string") {
559
- tooltip = {
560
- children: tooltip,
561
- };
562
- }
563
-
564
- return (
565
- <Tooltip>
566
- <TooltipTrigger asChild>{button}</TooltipTrigger>
567
- <TooltipContent
568
- align="center"
569
- hidden={state !== "collapsed" || isMobile}
570
- side="right"
571
- {...tooltip}
572
- />
573
- </Tooltip>
574
- );
575
- };
576
-
577
- const SidebarMenuAction = ({
578
- className,
579
- asChild = false,
580
- showOnHover = false,
581
- children,
582
- ...props
583
- }: React.ComponentProps<"button"> & {
584
- asChild?: boolean;
585
- showOnHover?: boolean;
586
- }) =>
587
- useRender({
588
- defaultTagName: "button",
589
- props: mergeProps<"button">(
590
- {
591
- className: cn(
592
- "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
593
- // Increases the hit area of the button on mobile.
594
- "after:absolute after:-inset-2 md:after:hidden",
595
- "peer-data-[size=sm]/menu-button:top-1",
596
- "peer-data-[size=default]/menu-button:top-1.5",
597
- "peer-data-[size=lg]/menu-button:top-2.5",
598
- "group-data-[collapsible=icon]:hidden",
599
- showOnHover &&
600
- "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active]/menu-button:text-sidebar-accent-foreground md:opacity-0",
601
- className
602
- ),
603
- },
604
- asChild ? props : { ...props, children }
605
- ),
606
- render: asChild ? (children as React.ReactElement) : undefined,
607
- state: {
608
- sidebar: "menu-action",
609
- slot: "sidebar-menu-action",
610
- },
611
- });
612
-
613
- const SidebarMenuBadge = ({
614
- className,
615
- ...props
616
- }: React.ComponentProps<"div">) => (
617
- <div
618
- className={cn(
619
- "pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums",
620
- "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active]/menu-button:text-sidebar-accent-foreground",
621
- "peer-data-[size=sm]/menu-button:top-1",
622
- "peer-data-[size=default]/menu-button:top-1.5",
623
- "peer-data-[size=lg]/menu-button:top-2.5",
624
- "group-data-[collapsible=icon]:hidden",
625
- className
626
- )}
627
- data-sidebar="menu-badge"
628
- data-slot="sidebar-menu-badge"
629
- {...props}
630
- />
631
- );
632
-
633
- const SidebarMenuSkeleton = ({
634
- className,
635
- showIcon = false,
636
- ...props
637
- }: React.ComponentProps<"div"> & {
638
- showIcon?: boolean;
639
- }) => {
640
- // Random width between 50 to 90%.
641
- const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);
642
-
643
- return (
644
- <div
645
- className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
646
- data-sidebar="menu-skeleton"
647
- data-slot="sidebar-menu-skeleton"
648
- {...props}
649
- >
650
- {showIcon && (
651
- <Skeleton
652
- className="size-4 rounded-md"
653
- data-sidebar="menu-skeleton-icon"
654
- />
655
- )}
656
- <Skeleton
657
- className="h-4 max-w-(--skeleton-width) flex-1"
658
- data-sidebar="menu-skeleton-text"
659
- style={
660
- {
661
- "--skeleton-width": width,
662
- } as React.CSSProperties
663
- }
664
- />
665
- </div>
666
- );
667
- };
668
-
669
- const SidebarMenuSub = ({
670
- className,
671
- ...props
672
- }: React.ComponentProps<"ul">) => (
673
- <ul
674
- className={cn(
675
- "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-sidebar-border border-l px-2.5 py-0.5",
676
- "group-data-[collapsible=icon]:hidden",
677
- className
678
- )}
679
- data-sidebar="menu-sub"
680
- data-slot="sidebar-menu-sub"
681
- {...props}
682
- />
683
- );
684
-
685
- const SidebarMenuSubItem = ({
686
- className,
687
- ...props
688
- }: React.ComponentProps<"li">) => (
689
- <li
690
- className={cn("group/menu-sub-item relative", className)}
691
- data-sidebar="menu-sub-item"
692
- data-slot="sidebar-menu-sub-item"
693
- {...props}
694
- />
695
- );
696
-
697
- const SidebarMenuSubButton = ({
698
- asChild = false,
699
- size = "md",
700
- isActive = false,
701
- className,
702
- children,
703
- ...props
704
- }: React.ComponentProps<"a"> & {
705
- asChild?: boolean;
706
- size?: "sm" | "md";
707
- isActive?: boolean;
708
- }) =>
709
- useRender({
710
- defaultTagName: "a",
711
- props: mergeProps<"a">(
712
- {
713
- className: cn(
714
- "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
715
- "data-[active]:bg-sidebar-accent data-[active]:text-sidebar-accent-foreground",
716
- size === "sm" && "text-xs",
717
- size === "md" && "text-sm",
718
- "group-data-[collapsible=icon]:hidden",
719
- className
720
- ),
721
- },
722
- asChild ? props : { ...props, children }
723
- ),
724
- render: asChild ? (children as React.ReactElement) : undefined,
725
- state: {
726
- active: isActive,
727
- sidebar: "menu-sub-button",
728
- size,
729
- slot: "sidebar-menu-sub-button",
730
- },
731
- });
732
-
733
- export {
734
- Sidebar,
735
- SidebarContent,
736
- SidebarFooter,
737
- SidebarGroup,
738
- SidebarGroupAction,
739
- SidebarGroupContent,
740
- SidebarGroupLabel,
741
- SidebarHeader,
742
- SidebarInput,
743
- SidebarInset,
744
- SidebarMenu,
745
- SidebarMenuAction,
746
- SidebarMenuBadge,
747
- SidebarMenuButton,
748
- SidebarMenuItem,
749
- SidebarMenuSkeleton,
750
- SidebarMenuSub,
751
- SidebarMenuSubButton,
752
- SidebarMenuSubItem,
753
- SidebarProvider,
754
- SidebarRail,
755
- SidebarSeparator,
756
- SidebarTrigger,
757
- useSidebar,
758
- };