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,92 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import { isValidElement } from "react";
3
-
4
- import { cn } from "@/lib/utils";
5
-
6
- interface StepProps {
7
- title: string;
8
- children?: ReactNode;
9
- icon?: ReactNode;
10
- stepNumber?: number;
11
- titleSize?: "p" | "h2" | "h3" | "h4";
12
- id?: string;
13
- }
14
-
15
- export const Step = ({
16
- title,
17
- children,
18
- icon,
19
- stepNumber,
20
- titleSize = "p",
21
- id,
22
- }: StepProps) => {
23
- const TitleTag = titleSize === "p" ? "div" : titleSize;
24
- const anchorId = id ?? title.toLowerCase().replaceAll(/\s+/g, "-");
25
-
26
- return (
27
- <div className="relative pb-8 pl-8 sm:pl-10 last:pb-0" id={anchorId}>
28
- <div
29
- aria-hidden
30
- className="absolute left-0 flex size-7 items-center justify-center rounded-full border border-border bg-muted font-mono text-xs font-medium"
31
- >
32
- {icon ?? stepNumber ?? null}
33
- </div>
34
- <TitleTag
35
- className={cn(
36
- "font-semibold leading-7",
37
- titleSize === "h2" && "text-xl",
38
- titleSize === "h3" && "text-lg",
39
- titleSize === "h4" && "text-base",
40
- titleSize === "p" && "text-base"
41
- )}
42
- >
43
- {title}
44
- </TitleTag>
45
- {children ? (
46
- <div className="mt-2 text-sm text-muted-foreground">{children}</div>
47
- ) : null}
48
- </div>
49
- );
50
- };
51
-
52
- interface StepsProps {
53
- children: ReactNode;
54
- titleSize?: "p" | "h2" | "h3" | "h4";
55
- }
56
-
57
- export const Steps = ({ children, titleSize }: StepsProps) => {
58
- const items = Array.isArray(children) ? children : [children];
59
-
60
- const hasStepChildren = items.some(
61
- (child) => isValidElement(child) && child.type === Step
62
- );
63
-
64
- if (!hasStepChildren) {
65
- return (
66
- <div className="steps mb-12 [counter-reset:step] md:ml-4 md:border-l md:pl-8 [&>h3]:step">
67
- {children}
68
- </div>
69
- );
70
- }
71
-
72
- let counter = 0;
73
- const numberedChildren = items.map((child) => {
74
- if (isValidElement<StepProps>(child) && child.type === Step) {
75
- counter += 1;
76
- const stepNumber = child.props.stepNumber ?? counter;
77
- return (
78
- <Step
79
- key={child.props.id ?? child.props.title}
80
- {...child.props}
81
- stepNumber={stepNumber}
82
- titleSize={child.props.titleSize ?? titleSize}
83
- />
84
- );
85
- }
86
- return child;
87
- });
88
-
89
- return (
90
- <div className="my-6 border-l border-border pl-2">{numberedChildren}</div>
91
- );
92
- };
@@ -1,193 +0,0 @@
1
- "use client";
2
-
3
- import { isValidElement, useCallback, useId, useMemo, useState } from "react";
4
- import type { KeyboardEvent, MouseEvent, ReactElement, ReactNode } from "react";
5
-
6
- import { cn } from "@/lib/utils";
7
-
8
- interface TabProps {
9
- title?: string;
10
- label?: string;
11
- icon?: ReactNode;
12
- id?: string;
13
- children: ReactNode;
14
- }
15
-
16
- interface ResolvedTabItem {
17
- element: ReactElement<TabProps>;
18
- key: string;
19
- label: string;
20
- }
21
-
22
- interface TabsProps {
23
- children: ReactNode;
24
- defaultTabIndex?: number;
25
- borderBottom?: boolean;
26
- }
27
-
28
- export const Tab = ({ children }: TabProps) => (
29
- <div className="p-4">{children}</div>
30
- );
31
-
32
- const clampTabIndex = (index: number, total: number) => {
33
- if (total <= 0) {
34
- return 0;
35
- }
36
-
37
- return Math.min(Math.max(index, 0), total - 1);
38
- };
39
-
40
- const sanitizeDomId = (value: string) =>
41
- value.replaceAll(/[^a-zA-Z0-9_-]/g, "-");
42
-
43
- const toNodeArray = (children: ReactNode): ReactNode[] =>
44
- Array.isArray(children) ? children.flatMap(toNodeArray) : [children];
45
-
46
- const resolveTabItems = (children: ReactNode): ResolvedTabItem[] =>
47
- toNodeArray(children)
48
- .filter((child): child is ReactElement<TabProps> =>
49
- isValidElement<TabProps>(child)
50
- )
51
- .map((element, index) => {
52
- const label =
53
- element.props.title ?? element.props.label ?? `Tab ${index + 1}`;
54
- const key = sanitizeDomId(
55
- String(element.props.id ?? element.key ?? `tab-${index + 1}`)
56
- );
57
-
58
- return {
59
- element,
60
- key,
61
- label,
62
- };
63
- });
64
-
65
- export const Tabs = ({
66
- children,
67
- defaultTabIndex = 0,
68
- borderBottom,
69
- }: TabsProps) => {
70
- const items = useMemo(() => resolveTabItems(children), [children]);
71
- const [active, setActive] = useState<number | null>(null);
72
- const activeIndex = clampTabIndex(active ?? defaultTabIndex, items.length);
73
- const activeItem = items[activeIndex];
74
- const tabsId = useId();
75
-
76
- const getTabId = useCallback(
77
- (index: number) => `${tabsId}-${items[index]?.key ?? index}-tab`,
78
- [items, tabsId]
79
- );
80
- const getPanelId = useCallback(
81
- (index: number) => `${tabsId}-${items[index]?.key ?? index}-panel`,
82
- [items, tabsId]
83
- );
84
- const focusTab = useCallback(
85
- (index: number) => {
86
- document.querySelector<HTMLElement>(`[id="${getTabId(index)}"]`)?.focus();
87
- },
88
- [getTabId]
89
- );
90
-
91
- const handleTabClick = useCallback((event: MouseEvent<HTMLButtonElement>) => {
92
- const index = Number(event.currentTarget.dataset.index ?? "0");
93
- setActive(index);
94
- }, []);
95
-
96
- const handleTabKeyDown = useCallback(
97
- (event: KeyboardEvent<HTMLButtonElement>) => {
98
- if (!items.length) {
99
- return;
100
- }
101
-
102
- const index = Number(event.currentTarget.dataset.index ?? activeIndex);
103
- const lastIndex = items.length - 1;
104
- let nextIndex: number | null = null;
105
-
106
- switch (event.key) {
107
- case "ArrowDown":
108
- case "ArrowRight": {
109
- nextIndex = index === lastIndex ? 0 : index + 1;
110
- break;
111
- }
112
- case "ArrowLeft":
113
- case "ArrowUp": {
114
- nextIndex = index === 0 ? lastIndex : index - 1;
115
- break;
116
- }
117
- case "End": {
118
- nextIndex = lastIndex;
119
- break;
120
- }
121
- case "Home": {
122
- nextIndex = 0;
123
- break;
124
- }
125
- default: {
126
- return;
127
- }
128
- }
129
-
130
- event.preventDefault();
131
- setActive(nextIndex);
132
- focusTab(nextIndex);
133
- },
134
- [activeIndex, focusTab, items.length]
135
- );
136
-
137
- if (!activeItem) {
138
- return null;
139
- }
140
-
141
- return (
142
- <div
143
- className={cn(
144
- "overflow-hidden rounded-xl bg-code",
145
- borderBottom && "border-b-2"
146
- )}
147
- >
148
- <div
149
- aria-orientation="horizontal"
150
- className="flex gap-1 border-b border-border bg-muted/50 px-2 pt-2"
151
- role="tablist"
152
- >
153
- {items.map((item, index) => {
154
- const isSelected = index === activeIndex;
155
-
156
- return (
157
- <button
158
- aria-controls={getPanelId(index)}
159
- aria-selected={isSelected}
160
- className={cn(
161
- "inline-flex cursor-pointer items-center gap-1.5 rounded-t-md border-b-2 bg-transparent px-3 py-2 text-sm transition-colors",
162
- isSelected
163
- ? "border-primary text-foreground"
164
- : "border-transparent text-muted-foreground hover:text-foreground"
165
- )}
166
- data-index={index}
167
- id={getTabId(index)}
168
- key={item.key}
169
- onClick={handleTabClick}
170
- onKeyDown={handleTabKeyDown}
171
- role="tab"
172
- tabIndex={isSelected ? 0 : -1}
173
- type="button"
174
- >
175
- {item.element.props.icon ? (
176
- <span className="shrink-0">{item.element.props.icon}</span>
177
- ) : null}
178
- {item.label}
179
- </button>
180
- );
181
- })}
182
- </div>
183
- <div
184
- aria-labelledby={getTabId(activeIndex)}
185
- id={getPanelId(activeIndex)}
186
- role="tabpanel"
187
- tabIndex={0}
188
- >
189
- {activeItem.element}
190
- </div>
191
- </div>
192
- );
193
- };
@@ -1,43 +0,0 @@
1
- import Link from "next/link";
2
- import type { ReactNode } from "react";
3
-
4
- interface TileProps {
5
- href: string;
6
- title?: string;
7
- description?: string;
8
- children: ReactNode;
9
- }
10
-
11
- export const Tile = ({ href, title, description, children }: TileProps) => {
12
- const isExternal = href.startsWith("http");
13
-
14
- const inner = (
15
- <div className="group/tile overflow-hidden rounded-xl border border-border bg-card transition-colors hover:border-primary/30 hover:bg-accent/50">
16
- <div className="flex items-center justify-center bg-muted/50 p-6">
17
- {children}
18
- </div>
19
- {title || description ? (
20
- <div className="border-t border-border p-3">
21
- {title ? (
22
- <div className="text-sm font-medium text-foreground">{title}</div>
23
- ) : null}
24
- {description ? (
25
- <div className="mt-0.5 text-xs text-muted-foreground">
26
- {description}
27
- </div>
28
- ) : null}
29
- </div>
30
- ) : null}
31
- </div>
32
- );
33
-
34
- if (isExternal) {
35
- return (
36
- <a href={href} rel="noopener noreferrer" target="_blank">
37
- {inner}
38
- </a>
39
- );
40
- }
41
-
42
- return <Link href={href}>{inner}</Link>;
43
- };
@@ -1,71 +0,0 @@
1
- "use client";
2
-
3
- import { useCallback, useRef, useState } from "react";
4
- import type { ReactNode } from "react";
5
-
6
- interface TooltipProps {
7
- tip: string;
8
- headline?: string;
9
- cta?: string;
10
- href?: string;
11
- children: ReactNode;
12
- }
13
-
14
- export const Tooltip = ({
15
- tip,
16
- headline,
17
- cta,
18
- href,
19
- children,
20
- }: TooltipProps) => {
21
- const [open, setOpen] = useState(false);
22
- const timeoutRef = useRef<ReturnType<typeof setTimeout>>(null);
23
-
24
- const show = useCallback(() => {
25
- if (timeoutRef.current) {
26
- clearTimeout(timeoutRef.current);
27
- }
28
- setOpen(true);
29
- }, []);
30
-
31
- const hide = useCallback(() => {
32
- timeoutRef.current = setTimeout(() => setOpen(false), 150);
33
- }, []);
34
-
35
- return (
36
- <span className="relative inline-block">
37
- <button
38
- className="cursor-help border-b border-dashed border-muted-foreground bg-transparent p-0 text-inherit"
39
- onBlur={hide}
40
- onFocus={show}
41
- onMouseEnter={show}
42
- onMouseLeave={hide}
43
- type="button"
44
- >
45
- {children}
46
- </button>
47
- {open ? (
48
- <span
49
- className="absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-64 -translate-x-1/2 rounded-lg border border-border bg-popover px-3 py-2 text-sm text-popover-foreground shadow-md"
50
- onMouseEnter={show}
51
- onMouseLeave={hide}
52
- role="tooltip"
53
- >
54
- {headline ? (
55
- <span className="mb-1 block font-semibold">{headline}</span>
56
- ) : null}
57
- <span className="block">{tip}</span>
58
- {cta && href ? (
59
- <a
60
- className="mt-1 block text-primary hover:underline"
61
- href={href}
62
- rel="noopener noreferrer"
63
- >
64
- {cta}
65
- </a>
66
- ) : null}
67
- </span>
68
- ) : null}
69
- </span>
70
- );
71
- };
@@ -1,120 +0,0 @@
1
- "use client";
2
-
3
- import { useCallback, useState } from "react";
4
- import type { ReactNode } from "react";
5
-
6
- import { cn } from "@/lib/utils";
7
-
8
- interface TreeFileProps {
9
- name: string;
10
- }
11
-
12
- export const TreeFile = ({ name }: TreeFileProps) => (
13
- <div className="flex items-center gap-2 py-0.5 pl-5 text-sm">
14
- <svg
15
- aria-hidden
16
- className="size-4 shrink-0 text-muted-foreground"
17
- fill="none"
18
- stroke="currentColor"
19
- strokeWidth={2}
20
- viewBox="0 0 24 24"
21
- >
22
- <path
23
- d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"
24
- strokeLinecap="round"
25
- strokeLinejoin="round"
26
- />
27
- <path
28
- d="M14 2v4a2 2 0 0 0 2 2h4"
29
- strokeLinecap="round"
30
- strokeLinejoin="round"
31
- />
32
- </svg>
33
- <span className="text-foreground">{name}</span>
34
- </div>
35
- );
36
-
37
- interface TreeFolderProps {
38
- name: string;
39
- defaultOpen?: boolean;
40
- openable?: boolean;
41
- children?: ReactNode;
42
- }
43
-
44
- export const TreeFolder = ({
45
- name,
46
- defaultOpen = false,
47
- openable = true,
48
- children,
49
- }: TreeFolderProps) => {
50
- const [open, setOpen] = useState(defaultOpen);
51
-
52
- const toggle = useCallback(() => {
53
- if (openable) {
54
- setOpen((prev) => !prev);
55
- }
56
- }, [openable]);
57
-
58
- return (
59
- <div>
60
- <button
61
- className={cn(
62
- "flex w-full items-center gap-2 py-0.5 text-sm border-none bg-transparent text-left",
63
- openable && "cursor-pointer hover:bg-accent/50 rounded"
64
- )}
65
- disabled={!openable}
66
- onClick={toggle}
67
- type="button"
68
- >
69
- <svg
70
- aria-hidden
71
- className={cn(
72
- "size-3 shrink-0 text-muted-foreground transition-transform",
73
- open && "rotate-90"
74
- )}
75
- fill="currentColor"
76
- viewBox="0 0 24 24"
77
- >
78
- <path d="m9 18 6-6-6-6" />
79
- </svg>
80
- <svg
81
- aria-hidden
82
- className="size-4 shrink-0 text-muted-foreground"
83
- fill="none"
84
- stroke="currentColor"
85
- strokeWidth={2}
86
- viewBox="0 0 24 24"
87
- >
88
- {open ? (
89
- <path
90
- d="M5 19a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h4l2 2h4a2 2 0 0 1 2 2v1M5 19h14a2 2 0 0 0 2-2v-5a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2Z"
91
- strokeLinecap="round"
92
- strokeLinejoin="round"
93
- />
94
- ) : (
95
- <path
96
- d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
97
- strokeLinecap="round"
98
- strokeLinejoin="round"
99
- />
100
- )}
101
- </svg>
102
- <span className="font-medium text-foreground">{name}</span>
103
- </button>
104
- {open && children ? (
105
- <div className="ml-3 border-l border-border pl-2">{children}</div>
106
- ) : null}
107
- </div>
108
- );
109
- };
110
-
111
- const TreeRoot = ({ children }: { children: ReactNode }) => (
112
- <div className="my-4 rounded-xl border border-border bg-card p-4 font-mono text-sm">
113
- {children}
114
- </div>
115
- );
116
-
117
- export const Tree = Object.assign(TreeRoot, {
118
- File: TreeFile,
119
- Folder: TreeFolder,
120
- });
@@ -1,71 +0,0 @@
1
- interface TypeField {
2
- description?: string;
3
- type?: string;
4
- optional?: boolean;
5
- required?: boolean;
6
- default?: string;
7
- }
8
-
9
- export const TypeTable = ({ type }: { type: Record<string, TypeField> }) => {
10
- const entries = Object.entries(type ?? {}).map(([name, field]) => ({
11
- name,
12
- ...field,
13
- }));
14
- const hasDefault = entries.some((entry) => entry.default);
15
-
16
- return (
17
- <div className="no-scrollbar my-4 w-full overflow-y-auto rounded-xl border border-border">
18
- <table className="relative w-full overflow-hidden border-none text-sm">
19
- <thead>
20
- <tr>
21
- <th className="border-b border-border bg-background/70 px-3 py-2.5 text-left text-xs uppercase tracking-wider text-muted-foreground">
22
- Field
23
- </th>
24
- <th className="border-b border-border bg-background/70 px-3 py-2.5 text-left text-xs uppercase tracking-wider text-muted-foreground">
25
- Type
26
- </th>
27
- <th className="border-b border-border bg-background/70 px-3 py-2.5 text-left text-xs uppercase tracking-wider text-muted-foreground">
28
- Description
29
- </th>
30
- <th className="border-b border-border bg-background/70 px-3 py-2.5 text-left text-xs uppercase tracking-wider text-muted-foreground">
31
- Required
32
- </th>
33
- {hasDefault ? (
34
- <th className="border-b border-border bg-background/70 px-3 py-2.5 text-left text-xs uppercase tracking-wider text-muted-foreground">
35
- Default
36
- </th>
37
- ) : null}
38
- </tr>
39
- </thead>
40
- <tbody>
41
- {entries.map((entry) => {
42
- const required = entry.required ?? !entry.optional;
43
- return (
44
- <tr key={entry.name}>
45
- <td className="border-b border-border px-3 py-2.5 text-left align-top">
46
- <code className="rounded-md bg-muted px-1.5 py-0.5 font-mono text-xs">
47
- {entry.name}
48
- </code>
49
- </td>
50
- <td className="border-b border-border px-3 py-2.5 text-left align-top">
51
- {entry.type ?? "\u2014"}
52
- </td>
53
- <td className="border-b border-border px-3 py-2.5 text-left align-top">
54
- {entry.description ?? ""}
55
- </td>
56
- <td className="border-b border-border px-3 py-2.5 text-left align-top">
57
- {required ? "Yes" : "Optional"}
58
- </td>
59
- {hasDefault ? (
60
- <td className="border-b border-border px-3 py-2.5 text-left align-top">
61
- {entry.default ?? "\u2014"}
62
- </td>
63
- ) : null}
64
- </tr>
65
- );
66
- })}
67
- </tbody>
68
- </table>
69
- </div>
70
- );
71
- };
@@ -1,44 +0,0 @@
1
- import type { ReactNode } from "react";
2
-
3
- interface UpdateProps {
4
- label: string;
5
- description?: string;
6
- tags?: string[];
7
- children: ReactNode;
8
- }
9
-
10
- export const Update = ({ label, description, tags, children }: UpdateProps) => {
11
- const anchorId = label.toLowerCase().replaceAll(/\s+/g, "-");
12
-
13
- return (
14
- <div
15
- className="relative border-b border-border py-8 first:pt-0 last:border-b-0"
16
- id={anchorId}
17
- >
18
- <div className="mb-4 flex flex-wrap items-center gap-3">
19
- <a
20
- className="text-lg font-semibold text-foreground hover:underline"
21
- href={`#${anchorId}`}
22
- >
23
- {label}
24
- </a>
25
- {description ? (
26
- <span className="rounded-full bg-muted px-2.5 py-0.5 text-xs font-medium text-muted-foreground">
27
- {description}
28
- </span>
29
- ) : null}
30
- {tags?.map((tag) => (
31
- <span
32
- className="rounded-full bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary"
33
- key={tag}
34
- >
35
- {tag}
36
- </span>
37
- ))}
38
- </div>
39
- <div className="prose prose-sm text-muted-foreground [&>p:first-child]:mt-0 [&>p:last-child]:mb-0">
40
- {children}
41
- </div>
42
- </div>
43
- );
44
- };
@@ -1,45 +0,0 @@
1
- import { cn } from "@/lib/utils";
2
-
3
- type AspectRatio = "16:9" | "4:3" | "1:1" | "21:9";
4
-
5
- const aspectRatioMap: Record<AspectRatio, string> = {
6
- "16:9": "pt-[56.25%]",
7
- "1:1": "pt-[100%]",
8
- "21:9": "pt-[42.86%]",
9
- "4:3": "pt-[75%]",
10
- };
11
-
12
- interface VideoProps {
13
- src: string;
14
- title?: string;
15
- height?: number;
16
- aspectRatio?: AspectRatio;
17
- }
18
-
19
- export const Video = ({
20
- src,
21
- title = "Video",
22
- height,
23
- aspectRatio = "16:9",
24
- }: VideoProps) => {
25
- const useFixedHeight = typeof height === "number";
26
-
27
- return (
28
- <div
29
- className={cn(
30
- "relative overflow-hidden rounded-xl border border-border bg-black",
31
- !useFixedHeight && aspectRatioMap[aspectRatio]
32
- )}
33
- style={useFixedHeight ? { height: `${height}px` } : undefined}
34
- >
35
- <iframe
36
- allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
37
- allowFullScreen
38
- className="absolute inset-0 h-full w-full border-0"
39
- sandbox="allow-popups allow-presentation allow-same-origin allow-scripts"
40
- src={src}
41
- title={title}
42
- />
43
- </div>
44
- );
45
- };