blodemd 0.1.0 → 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 (289) hide show
  1. package/dist/cli.mjs +50 -174
  2. package/dist/cli.mjs.map +1 -1
  3. package/package.json +3 -36
  4. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  5. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  6. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  7. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  8. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  9. package/dev-server/app/error.tsx +0 -24
  10. package/dev-server/app/favicon.ico +0 -0
  11. package/dev-server/app/globals.css +0 -4
  12. package/dev-server/app/layout.tsx +0 -38
  13. package/dev-server/app/not-found.tsx +0 -18
  14. package/dev-server/app/search/route.ts +0 -17
  15. package/dev-server/components/dev-reload-script.tsx +0 -86
  16. package/dev-server/components/providers.tsx +0 -15
  17. package/dev-server/lib/dev-state.ts +0 -8
  18. package/dev-server/lib/local-content-source.ts +0 -103
  19. package/dev-server/lib/local-runtime.tsx +0 -555
  20. package/dev-server/next-env.d.ts +0 -5
  21. package/dev-server/next.config.js +0 -54
  22. package/dev-server/package.json +0 -61
  23. package/dev-server/postcss.config.mjs +0 -7
  24. package/dev-server/public/glide-variable.woff2 +0 -0
  25. package/dev-server/tsconfig.json +0 -50
  26. package/docs/app/globals.css +0 -471
  27. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  28. package/docs/components/api/api-playground.tsx +0 -467
  29. package/docs/components/api/api-reference.tsx +0 -157
  30. package/docs/components/content/collection-index.tsx +0 -114
  31. package/docs/components/docs/contextual-menu.tsx +0 -495
  32. package/docs/components/docs/copy-page-menu.tsx +0 -364
  33. package/docs/components/docs/doc-header.tsx +0 -223
  34. package/docs/components/docs/doc-shell.tsx +0 -355
  35. package/docs/components/docs/doc-sidebar.tsx +0 -256
  36. package/docs/components/docs/doc-toc.tsx +0 -46
  37. package/docs/components/docs/mobile-nav.tsx +0 -195
  38. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  39. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  40. package/docs/components/git/repo-picker.tsx +0 -529
  41. package/docs/components/icons/doc-icon.tsx +0 -96
  42. package/docs/components/mdx/accordion.tsx +0 -83
  43. package/docs/components/mdx/agent-instructions.tsx +0 -17
  44. package/docs/components/mdx/badge.tsx +0 -79
  45. package/docs/components/mdx/callout.tsx +0 -88
  46. package/docs/components/mdx/card.tsx +0 -110
  47. package/docs/components/mdx/code-block.tsx +0 -80
  48. package/docs/components/mdx/code-group.tsx +0 -203
  49. package/docs/components/mdx/color.tsx +0 -87
  50. package/docs/components/mdx/columns.tsx +0 -25
  51. package/docs/components/mdx/expandable.tsx +0 -45
  52. package/docs/components/mdx/field-layout.tsx +0 -77
  53. package/docs/components/mdx/frame.tsx +0 -23
  54. package/docs/components/mdx/get-text-content.ts +0 -18
  55. package/docs/components/mdx/icon.tsx +0 -12
  56. package/docs/components/mdx/iframe.tsx +0 -62
  57. package/docs/components/mdx/index.tsx +0 -121
  58. package/docs/components/mdx/installer.tsx +0 -20
  59. package/docs/components/mdx/panel.tsx +0 -11
  60. package/docs/components/mdx/param-field.tsx +0 -56
  61. package/docs/components/mdx/preview.tsx +0 -36
  62. package/docs/components/mdx/prompt.tsx +0 -63
  63. package/docs/components/mdx/request-example.tsx +0 -27
  64. package/docs/components/mdx/response-field.tsx +0 -42
  65. package/docs/components/mdx/steps.tsx +0 -92
  66. package/docs/components/mdx/tabs.tsx +0 -193
  67. package/docs/components/mdx/tile.tsx +0 -43
  68. package/docs/components/mdx/tooltip.tsx +0 -71
  69. package/docs/components/mdx/tree.tsx +0 -120
  70. package/docs/components/mdx/type-table.tsx +0 -71
  71. package/docs/components/mdx/update.tsx +0 -44
  72. package/docs/components/mdx/video.tsx +0 -45
  73. package/docs/components/mdx/view.tsx +0 -66
  74. package/docs/components/posthog-provider.tsx +0 -42
  75. package/docs/components/providers.tsx +0 -15
  76. package/docs/components/tenant-analytics.tsx +0 -49
  77. package/docs/components/third-parties.tsx +0 -32
  78. package/docs/components/ui/badge.tsx +0 -61
  79. package/docs/components/ui/breadcrumb.tsx +0 -112
  80. package/docs/components/ui/button-group.tsx +0 -83
  81. package/docs/components/ui/button.tsx +0 -65
  82. package/docs/components/ui/card.tsx +0 -92
  83. package/docs/components/ui/command.tsx +0 -167
  84. package/docs/components/ui/copy-button.tsx +0 -129
  85. package/docs/components/ui/dialog.tsx +0 -146
  86. package/docs/components/ui/field.tsx +0 -237
  87. package/docs/components/ui/input.tsx +0 -23
  88. package/docs/components/ui/kbd.tsx +0 -98
  89. package/docs/components/ui/label.tsx +0 -22
  90. package/docs/components/ui/morph-icon.tsx +0 -79
  91. package/docs/components/ui/popover.tsx +0 -267
  92. package/docs/components/ui/search-dialog.tsx +0 -431
  93. package/docs/components/ui/search.tsx +0 -101
  94. package/docs/components/ui/separator.tsx +0 -26
  95. package/docs/components/ui/sheet.tsx +0 -133
  96. package/docs/components/ui/sidebar.tsx +0 -758
  97. package/docs/components/ui/skeleton.tsx +0 -11
  98. package/docs/components/ui/switch.tsx +0 -32
  99. package/docs/components/ui/tabs.tsx +0 -138
  100. package/docs/components/ui/theme-toggle.tsx +0 -62
  101. package/docs/components/ui/tooltip.tsx +0 -53
  102. package/docs/components/web-mcp.tsx +0 -115
  103. package/docs/lib/agent-skills.ts +0 -48
  104. package/docs/lib/api-client.ts +0 -72
  105. package/docs/lib/config.ts +0 -6
  106. package/docs/lib/content-root.ts +0 -33
  107. package/docs/lib/content-source.ts +0 -70
  108. package/docs/lib/contextual-options.ts +0 -222
  109. package/docs/lib/dashboard-session.ts +0 -167
  110. package/docs/lib/db.ts +0 -13
  111. package/docs/lib/docs-collection.ts +0 -7
  112. package/docs/lib/docs-runtime.tsx +0 -745
  113. package/docs/lib/edge-config.ts +0 -95
  114. package/docs/lib/env.ts +0 -23
  115. package/docs/lib/etag.ts +0 -22
  116. package/docs/lib/github-install.ts +0 -33
  117. package/docs/lib/llms-full.ts +0 -82
  118. package/docs/lib/marketing-markdown.ts +0 -79
  119. package/docs/lib/marketing-site.ts +0 -31
  120. package/docs/lib/mdx.ts +0 -98
  121. package/docs/lib/navigation.ts +0 -288
  122. package/docs/lib/openapi-proxy.ts +0 -88
  123. package/docs/lib/openapi.ts +0 -158
  124. package/docs/lib/platform-config.ts +0 -6
  125. package/docs/lib/project-authz.ts +0 -46
  126. package/docs/lib/routes.ts +0 -103
  127. package/docs/lib/server-cache.ts +0 -83
  128. package/docs/lib/shiki.ts +0 -44
  129. package/docs/lib/supabase.ts +0 -37
  130. package/docs/lib/tenancy.ts +0 -364
  131. package/docs/lib/tenant-headers.ts +0 -43
  132. package/docs/lib/tenant-static.ts +0 -705
  133. package/docs/lib/tenant-utility-context.ts +0 -62
  134. package/docs/lib/tenants.ts +0 -72
  135. package/docs/lib/theme.ts +0 -29
  136. package/docs/lib/time-ago.ts +0 -24
  137. package/docs/lib/toc.ts +0 -2
  138. package/docs/lib/use-mobile.ts +0 -19
  139. package/docs/lib/use-tab-observer.ts +0 -71
  140. package/docs/lib/utils.ts +0 -5
  141. package/packages/@repo/common/dist/index.d.ts +0 -16
  142. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  143. package/packages/@repo/common/dist/index.js +0 -84
  144. package/packages/@repo/common/package.json +0 -34
  145. package/packages/@repo/common/src/index.ts +0 -101
  146. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  147. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  148. package/packages/@repo/contracts/dist/analytics.js +0 -18
  149. package/packages/@repo/contracts/dist/api-key.d.ts +0 -27
  150. package/packages/@repo/contracts/dist/api-key.d.ts.map +0 -1
  151. package/packages/@repo/contracts/dist/api-key.js +0 -20
  152. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  153. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  154. package/packages/@repo/contracts/dist/dates.js +0 -2
  155. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  156. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  157. package/packages/@repo/contracts/dist/deployment.js +0 -46
  158. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  159. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  160. package/packages/@repo/contracts/dist/domain.js +0 -36
  161. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  162. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  163. package/packages/@repo/contracts/dist/git.js +0 -24
  164. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  165. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  166. package/packages/@repo/contracts/dist/ids.js +0 -11
  167. package/packages/@repo/contracts/dist/index.d.ts +0 -12
  168. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  169. package/packages/@repo/contracts/dist/index.js +0 -13
  170. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  171. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  172. package/packages/@repo/contracts/dist/pagination.js +0 -15
  173. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  174. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  175. package/packages/@repo/contracts/dist/project.js +0 -25
  176. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  177. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  178. package/packages/@repo/contracts/dist/tenant.js +0 -58
  179. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  180. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  181. package/packages/@repo/contracts/dist/user.js +0 -9
  182. package/packages/@repo/contracts/package.json +0 -37
  183. package/packages/@repo/contracts/src/analytics.ts +0 -33
  184. package/packages/@repo/contracts/src/api-key.ts +0 -27
  185. package/packages/@repo/contracts/src/dates.ts +0 -4
  186. package/packages/@repo/contracts/src/deployment.ts +0 -73
  187. package/packages/@repo/contracts/src/domain.ts +0 -51
  188. package/packages/@repo/contracts/src/git.ts +0 -31
  189. package/packages/@repo/contracts/src/ids.ts +0 -23
  190. package/packages/@repo/contracts/src/index.ts +0 -13
  191. package/packages/@repo/contracts/src/pagination.ts +0 -21
  192. package/packages/@repo/contracts/src/project.ts +0 -32
  193. package/packages/@repo/contracts/src/tenant.ts +0 -94
  194. package/packages/@repo/contracts/src/user.ts +0 -12
  195. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  196. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/docs-config.js +0 -531
  198. package/packages/@repo/models/dist/index.d.ts +0 -3
  199. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/index.js +0 -3
  201. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  202. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  203. package/packages/@repo/models/dist/tenant.js +0 -1
  204. package/packages/@repo/models/package.json +0 -37
  205. package/packages/@repo/models/src/docs-config.ts +0 -629
  206. package/packages/@repo/models/src/index.ts +0 -3
  207. package/packages/@repo/models/src/tenant.ts +0 -44
  208. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  209. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/index.js +0 -2
  211. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  212. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  213. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  214. package/packages/@repo/prebuild/package.json +0 -39
  215. package/packages/@repo/prebuild/src/index.ts +0 -2
  216. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  217. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  218. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  220. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  221. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  223. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  224. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/constants.js +0 -14
  226. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  227. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-index.js +0 -291
  229. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  230. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/content-source.js +0 -1
  232. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  233. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  235. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  236. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/index.js +0 -13
  238. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  239. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  241. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  242. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  244. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  245. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  247. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  248. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  250. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  251. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/search-index.js +0 -23
  253. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  254. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/serialization.js +0 -108
  256. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  257. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  259. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  260. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/types.js +0 -1
  262. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  263. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  264. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  265. package/packages/@repo/previewing/package.json +0 -41
  266. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  267. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  268. package/packages/@repo/previewing/src/constants.ts +0 -16
  269. package/packages/@repo/previewing/src/content-index.ts +0 -384
  270. package/packages/@repo/previewing/src/content-source.ts +0 -12
  271. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  272. package/packages/@repo/previewing/src/index.ts +0 -71
  273. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  274. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  275. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  276. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  277. package/packages/@repo/previewing/src/search-index.ts +0 -38
  278. package/packages/@repo/previewing/src/serialization.ts +0 -191
  279. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  280. package/packages/@repo/previewing/src/types.ts +0 -105
  281. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  282. package/packages/@repo/validation/dist/index.d.ts +0 -12
  283. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  284. package/packages/@repo/validation/dist/index.js +0 -30
  285. package/packages/@repo/validation/package.json +0 -38
  286. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  287. package/packages/@repo/validation/src/index.ts +0 -59
  288. package/scripts/prepare-package.mjs +0 -53
  289. 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
- };