@yaakdoc/react 0.0.0-stage → 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.
- package/LICENSE +21 -0
- package/README.md +232 -2
- package/dist/client.d.ts +9 -0
- package/dist/client.js +26 -0
- package/dist/color-mode-B-vJCVkP.js +77 -0
- package/dist/index-CoQ7pnuB.d.ts +471 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +551 -0
- package/dist/island-BWyuL4_6.d.ts +29 -0
- package/dist/islands.d.ts +170 -0
- package/dist/islands.js +152 -0
- package/dist/llm-Ddn5hWnS.js +205 -0
- package/dist/run-in-yaak-CMMcDS7S.js +164 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.js +139 -0
- package/dist/site-DyK7ZcqQ.js +371 -0
- package/dist/theme.d.ts +45 -0
- package/dist/theme.js +7 -0
- package/dist/types-BY2lOvlK.d.ts +101 -0
- package/package.json +85 -3
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { n as RunInYaakLink } from "./run-in-yaak-CMMcDS7S.js";
|
|
2
|
+
import { absoluteUrl, authLabel, methodLabel } from "@yaakdoc/core";
|
|
3
|
+
import { createContext, use } from "react";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/context.tsx
|
|
6
|
+
const YaakdocContext = createContext(null);
|
|
7
|
+
function YaakdocProvider({ document, site, page, children }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(YaakdocContext, {
|
|
9
|
+
value: {
|
|
10
|
+
document,
|
|
11
|
+
site,
|
|
12
|
+
page
|
|
13
|
+
},
|
|
14
|
+
children
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function useYaakdocContext() {
|
|
18
|
+
const value = use(YaakdocContext);
|
|
19
|
+
if (!value) throw new Error("yaakdoc hooks must be used inside <YaakdocProvider>. Note: islands are hydrated in isolation and cannot use these hooks; pass data via props instead.");
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
/** The prepared documentation (requests, folders, tree, environment...). */
|
|
23
|
+
const useDocument = () => useYaakdocContext().document;
|
|
24
|
+
/** Site configuration and branding. */
|
|
25
|
+
const useSite = () => useYaakdocContext().site;
|
|
26
|
+
/** The page currently being rendered. */
|
|
27
|
+
const usePage = () => useYaakdocContext().page;
|
|
28
|
+
/** Theme-specific options from `themeOptions` in the config. */
|
|
29
|
+
const useThemeOptions = () => useYaakdocContext().site.themeOptions;
|
|
30
|
+
function useRequest(id) {
|
|
31
|
+
const request = useDocument().requests[id];
|
|
32
|
+
if (!request) throw new Error(`Unknown request id "${id}"`);
|
|
33
|
+
return request;
|
|
34
|
+
}
|
|
35
|
+
function useFolder(id) {
|
|
36
|
+
const folder = useDocument().folders[id];
|
|
37
|
+
if (!folder) throw new Error(`Unknown folder id "${id}"`);
|
|
38
|
+
return folder;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/site-url.ts
|
|
42
|
+
/**
|
|
43
|
+
* Absolute URL of a site path (one starting with `/`, including the base) when the public site
|
|
44
|
+
* URL is configured; `null` otherwise (or for URLs that aren't site paths).
|
|
45
|
+
*/
|
|
46
|
+
function toAbsoluteUrl(site, path) {
|
|
47
|
+
return site.url && path.startsWith("/") ? absoluteUrl(site.url, site.base, path) : null;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/hooks.ts
|
|
51
|
+
/**
|
|
52
|
+
* Data for "Copy page/section" actions, or `null` when they are disabled (or there is no Markdown
|
|
53
|
+
* twin). `absoluteUrl` is `null` when the public site URL isn't configured.
|
|
54
|
+
*/
|
|
55
|
+
function usePageActions(markdownUrl) {
|
|
56
|
+
const site = useSite();
|
|
57
|
+
if (!markdownUrl || !site.llms.enabled || !site.llms.copyButton) return null;
|
|
58
|
+
return {
|
|
59
|
+
markdownUrl,
|
|
60
|
+
absoluteUrl: toAbsoluteUrl(site, markdownUrl),
|
|
61
|
+
openIn: site.llms.openIn
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Name and export URL for the "Run in Yaak" button, or `null` when it is disabled. */
|
|
65
|
+
function useRunInYaak() {
|
|
66
|
+
const site = useSite();
|
|
67
|
+
if (!site.runInYaak) return null;
|
|
68
|
+
const { name, dataUrl } = site.runInYaak;
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
dataUrl: toAbsoluteUrl(site, dataUrl) ?? dataUrl
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/overrides.tsx
|
|
76
|
+
const ComponentsContext = createContext({});
|
|
77
|
+
/**
|
|
78
|
+
* Provides component overrides. Every base component created with {@link overridable} renders the
|
|
79
|
+
* override registered under its name instead, so themes can swap any piece (MDX-style) – including
|
|
80
|
+
* pieces rendered internally by other base components.
|
|
81
|
+
*/
|
|
82
|
+
function ComponentsProvider({ components, children }) {
|
|
83
|
+
const parent = use(ComponentsContext);
|
|
84
|
+
return /* @__PURE__ */ jsx(ComponentsContext, {
|
|
85
|
+
value: {
|
|
86
|
+
...parent,
|
|
87
|
+
...components
|
|
88
|
+
},
|
|
89
|
+
children
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const useComponents = () => use(ComponentsContext);
|
|
93
|
+
/**
|
|
94
|
+
* Wraps a default component so it can be replaced through {@link ComponentsProvider}.
|
|
95
|
+
* The override receives the same props plus `Default`, the original implementation, so it can
|
|
96
|
+
* decorate rather than replace.
|
|
97
|
+
*/
|
|
98
|
+
function overridable(name, Default) {
|
|
99
|
+
function Overridable(props) {
|
|
100
|
+
const Override = use(ComponentsContext)[name];
|
|
101
|
+
if (Override && Override !== Wrapped) return /* @__PURE__ */ jsx(Override, {
|
|
102
|
+
...props,
|
|
103
|
+
Default
|
|
104
|
+
});
|
|
105
|
+
return /* @__PURE__ */ jsx(Default, { ...props });
|
|
106
|
+
}
|
|
107
|
+
const Wrapped = Object.assign(Overridable, {
|
|
108
|
+
displayName: name,
|
|
109
|
+
Default
|
|
110
|
+
});
|
|
111
|
+
return Wrapped;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/primitives/basic.tsx
|
|
115
|
+
/** Renders trusted, pre-sanitized HTML (descriptions are sanitized at build time). */
|
|
116
|
+
const Html = overridable("Html", function Html({ html, as: As = "div", ...props }) {
|
|
117
|
+
return /* @__PURE__ */ jsx(As, {
|
|
118
|
+
"data-yd": "html",
|
|
119
|
+
...props,
|
|
120
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
/** Rendered Markdown (a description). */
|
|
124
|
+
const Markdown = overridable("Markdown", function Markdown({ html, className }) {
|
|
125
|
+
if (!html) return null;
|
|
126
|
+
return /* @__PURE__ */ jsx(Html, {
|
|
127
|
+
html,
|
|
128
|
+
className,
|
|
129
|
+
"data-yd": "markdown"
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
/** HTTP method (or gRPC / WS) badge. Style via `[data-method="get"]` etc. */
|
|
133
|
+
const MethodBadge = overridable("MethodBadge", function MethodBadge({ request, className }) {
|
|
134
|
+
const label = methodLabel(request);
|
|
135
|
+
return /* @__PURE__ */ jsx("span", {
|
|
136
|
+
"data-yd": "method",
|
|
137
|
+
"data-method": label.toLowerCase(),
|
|
138
|
+
"data-kind": request.kind,
|
|
139
|
+
className,
|
|
140
|
+
children: label
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
/**
|
|
144
|
+
* Request URL with `{{variables}}` and `:path` parameters wrapped in spans
|
|
145
|
+
* (`[data-yd="url-variable"]`, `[data-yd="url-param"]`) for styling.
|
|
146
|
+
*/
|
|
147
|
+
const RequestUrl = overridable("RequestUrl", function RequestUrl({ url, className }) {
|
|
148
|
+
const parts = url.split(/(\{\{[^}]+\}\}|:[A-Za-z_][\w-]*(?=\/|$|\?|\.|#))/g).filter(Boolean);
|
|
149
|
+
return /* @__PURE__ */ jsx("code", {
|
|
150
|
+
"data-yd": "url",
|
|
151
|
+
className,
|
|
152
|
+
children: parts.map((part, index) => part.startsWith("{{") ? /* @__PURE__ */ jsx("span", {
|
|
153
|
+
"data-yd": "url-variable",
|
|
154
|
+
children: part
|
|
155
|
+
}, index) : part.startsWith(":") && index > 0 ? /* @__PURE__ */ jsx("span", {
|
|
156
|
+
"data-yd": "url-param",
|
|
157
|
+
children: part
|
|
158
|
+
}, index) : part)
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
/** Generic two-column table for headers and parameters. */
|
|
162
|
+
const KeyValueTable = overridable("KeyValueTable", function KeyValueTable({ items, caption, columns = ["Name", "Value"], className, showInherited = true }) {
|
|
163
|
+
if (items.length === 0) return null;
|
|
164
|
+
return /* @__PURE__ */ jsxs("table", {
|
|
165
|
+
"data-yd": "kv-table",
|
|
166
|
+
className,
|
|
167
|
+
children: [
|
|
168
|
+
caption ? /* @__PURE__ */ jsx("caption", { children: caption }) : null,
|
|
169
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [/* @__PURE__ */ jsx("th", {
|
|
170
|
+
scope: "col",
|
|
171
|
+
children: columns[0]
|
|
172
|
+
}), /* @__PURE__ */ jsx("th", {
|
|
173
|
+
scope: "col",
|
|
174
|
+
children: columns[1]
|
|
175
|
+
})] }) }),
|
|
176
|
+
/* @__PURE__ */ jsx("tbody", { children: items.map((item, index) => /* @__PURE__ */ jsxs("tr", {
|
|
177
|
+
"data-enabled": item.enabled,
|
|
178
|
+
children: [/* @__PURE__ */ jsxs("td", { children: [
|
|
179
|
+
/* @__PURE__ */ jsx("code", {
|
|
180
|
+
"data-yd": "kv-name",
|
|
181
|
+
children: item.name
|
|
182
|
+
}),
|
|
183
|
+
!item.enabled ? /* @__PURE__ */ jsx("span", {
|
|
184
|
+
"data-yd": "optional",
|
|
185
|
+
children: "optional"
|
|
186
|
+
}) : null,
|
|
187
|
+
showInherited && "inheritedFrom" in item && item.inheritedFrom ? /* @__PURE__ */ jsx("span", {
|
|
188
|
+
"data-yd": "inherited",
|
|
189
|
+
title: `Inherited from ${item.inheritedFrom.model} "${item.inheritedFrom.name}"`,
|
|
190
|
+
children: item.inheritedFrom.model
|
|
191
|
+
}) : null
|
|
192
|
+
] }), /* @__PURE__ */ jsx("td", { children: item.value ? /* @__PURE__ */ jsx("code", {
|
|
193
|
+
"data-yd": "kv-value",
|
|
194
|
+
children: item.value
|
|
195
|
+
}) : null })]
|
|
196
|
+
}, index)) })
|
|
197
|
+
]
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
/** Describes the effective authentication of a request/folder. */
|
|
201
|
+
const AuthInfo = overridable("AuthInfo", function AuthInfo({ auth, className }) {
|
|
202
|
+
if (!auth) return /* @__PURE__ */ jsx("p", {
|
|
203
|
+
"data-yd": "auth",
|
|
204
|
+
"data-auth": "none",
|
|
205
|
+
className,
|
|
206
|
+
children: "No authentication required."
|
|
207
|
+
});
|
|
208
|
+
const fields = auth.fields;
|
|
209
|
+
return /* @__PURE__ */ jsxs("p", {
|
|
210
|
+
"data-yd": "auth",
|
|
211
|
+
"data-auth": auth.type,
|
|
212
|
+
className,
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ jsx("strong", { children: authLabel(auth.type) }),
|
|
215
|
+
auth.type === "apikey" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
216
|
+
" ",
|
|
217
|
+
"— send ",
|
|
218
|
+
/* @__PURE__ */ jsx("code", { children: String(fields.key || "X-API-Key") }),
|
|
219
|
+
" in the",
|
|
220
|
+
" ",
|
|
221
|
+
fields.location === "query" ? "query string" : "headers",
|
|
222
|
+
"."
|
|
223
|
+
] }) : auth.type === "bearer" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
224
|
+
" ",
|
|
225
|
+
"— send ",
|
|
226
|
+
/* @__PURE__ */ jsxs("code", { children: [
|
|
227
|
+
"Authorization: ",
|
|
228
|
+
String(fields.prefix || "Bearer"),
|
|
229
|
+
" <token>"
|
|
230
|
+
] }),
|
|
231
|
+
"."
|
|
232
|
+
] }) : auth.type === "basic" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
233
|
+
" ",
|
|
234
|
+
"— send ",
|
|
235
|
+
/* @__PURE__ */ jsx("code", { children: "Authorization: Basic <base64(username:password)>" }),
|
|
236
|
+
"."
|
|
237
|
+
] }) : null,
|
|
238
|
+
auth.inheritedFrom ? /* @__PURE__ */ jsxs("span", {
|
|
239
|
+
"data-yd": "inherited",
|
|
240
|
+
children: [
|
|
241
|
+
" ",
|
|
242
|
+
"Inherited from ",
|
|
243
|
+
auth.inheritedFrom.model,
|
|
244
|
+
" \"",
|
|
245
|
+
auth.inheritedFrom.name,
|
|
246
|
+
"\"."
|
|
247
|
+
]
|
|
248
|
+
}) : null
|
|
249
|
+
]
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/primitives/site.tsx
|
|
254
|
+
/** Site logo (light/dark variants) linking to the docs home, falling back to the title. */
|
|
255
|
+
const Logo = overridable("Logo", function Logo({ className, showTitle = true }) {
|
|
256
|
+
const site = useSite();
|
|
257
|
+
const logo = site.logo;
|
|
258
|
+
const href = logo?.href ?? site.base;
|
|
259
|
+
const size = {
|
|
260
|
+
width: logo?.width,
|
|
261
|
+
height: logo?.height
|
|
262
|
+
};
|
|
263
|
+
return /* @__PURE__ */ jsxs("a", {
|
|
264
|
+
href,
|
|
265
|
+
"data-yd": "logo",
|
|
266
|
+
className,
|
|
267
|
+
children: [
|
|
268
|
+
logo?.light ? /* @__PURE__ */ jsx("img", {
|
|
269
|
+
src: logo.light,
|
|
270
|
+
alt: logo.alt,
|
|
271
|
+
"data-yd-logo": logo.dark ? "light" : "both",
|
|
272
|
+
...size
|
|
273
|
+
}) : null,
|
|
274
|
+
logo?.dark ? /* @__PURE__ */ jsx("img", {
|
|
275
|
+
src: logo.dark,
|
|
276
|
+
alt: logo.alt,
|
|
277
|
+
"data-yd-logo": logo.light ? "dark" : "both",
|
|
278
|
+
...size
|
|
279
|
+
}) : null,
|
|
280
|
+
showTitle ? /* @__PURE__ */ jsx("span", {
|
|
281
|
+
"data-yd": "site-title",
|
|
282
|
+
children: site.title
|
|
283
|
+
}) : null
|
|
284
|
+
]
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
/** Header links from `branding.links`. */
|
|
288
|
+
const SiteLinks = overridable("SiteLinks", function SiteLinks({ className }) {
|
|
289
|
+
const site = useSite();
|
|
290
|
+
if (site.links.length === 0) return null;
|
|
291
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
292
|
+
"data-yd": "site-links",
|
|
293
|
+
className,
|
|
294
|
+
children: site.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
|
|
295
|
+
href: link.href,
|
|
296
|
+
"data-icon": link.icon,
|
|
297
|
+
.../^https?:/.test(link.href) ? {
|
|
298
|
+
target: "_blank",
|
|
299
|
+
rel: "noopener"
|
|
300
|
+
} : {},
|
|
301
|
+
children: link.label
|
|
302
|
+
}) }, link.href))
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
/** Footer text from `branding.footer` plus an llms.txt link. */
|
|
306
|
+
const Footer = overridable("Footer", function Footer({ className }) {
|
|
307
|
+
const site = useSite();
|
|
308
|
+
return /* @__PURE__ */ jsxs("footer", {
|
|
309
|
+
"data-yd": "footer",
|
|
310
|
+
className,
|
|
311
|
+
children: [site.footerHtml ? /* @__PURE__ */ jsx(Html, {
|
|
312
|
+
html: site.footerHtml,
|
|
313
|
+
"data-yd": "footer-text"
|
|
314
|
+
}) : null, site.llms.txtUrl ? /* @__PURE__ */ jsx("a", {
|
|
315
|
+
href: site.llms.txtUrl,
|
|
316
|
+
"data-yd": "llms-link",
|
|
317
|
+
children: "llms.txt"
|
|
318
|
+
}) : null]
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
const declarations = (vars) => Object.entries(vars).filter(([, value]) => value).map(([key, value]) => `${key}:${value.replace(/[;{}<]/g, "")}`).join(";");
|
|
322
|
+
/**
|
|
323
|
+
* Branding as CSS custom properties on :root:
|
|
324
|
+
* `--yd-color-primary`, `--yd-color-accent`, `--yd-color-background`, `--yd-color-foreground`,
|
|
325
|
+
* `--yd-font-sans`, `--yd-font-mono` (with per-mode overrides under `[data-theme]`).
|
|
326
|
+
*/
|
|
327
|
+
function brandingCss(site) {
|
|
328
|
+
const { colors, fonts } = site;
|
|
329
|
+
const base = declarations({
|
|
330
|
+
"--yd-color-primary": colors.primary,
|
|
331
|
+
"--yd-color-accent": colors.accent,
|
|
332
|
+
"--yd-font-sans": fonts.sans,
|
|
333
|
+
"--yd-font-mono": fonts.mono
|
|
334
|
+
});
|
|
335
|
+
const mode = (c) => declarations({
|
|
336
|
+
"--yd-color-primary": c?.primary,
|
|
337
|
+
"--yd-color-accent": c?.accent,
|
|
338
|
+
"--yd-color-background": c?.background,
|
|
339
|
+
"--yd-color-foreground": c?.foreground
|
|
340
|
+
});
|
|
341
|
+
const light = mode(colors.light);
|
|
342
|
+
const dark = mode(colors.dark);
|
|
343
|
+
return [
|
|
344
|
+
base && `:root{${base}}`,
|
|
345
|
+
light && `:root[data-theme="light"]{${light}}`,
|
|
346
|
+
dark && `:root[data-theme="dark"]{${dark}}@media (prefers-color-scheme:dark){:root:not([data-theme]){${dark}}}`
|
|
347
|
+
].filter(Boolean).join("");
|
|
348
|
+
}
|
|
349
|
+
function BrandingStyles() {
|
|
350
|
+
const css = brandingCss(useSite());
|
|
351
|
+
return css ? /* @__PURE__ */ jsx("style", {
|
|
352
|
+
"data-yd": "branding",
|
|
353
|
+
dangerouslySetInnerHTML: { __html: css }
|
|
354
|
+
}) : null;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* "Run in Yaak" link for the site's shareable export (renders nothing unless `runInYaak` is enabled
|
|
358
|
+
* in the config).
|
|
359
|
+
*/
|
|
360
|
+
const RunInYaak = overridable("RunInYaak", function RunInYaak({ badge, className }) {
|
|
361
|
+
const runInYaak = useRunInYaak();
|
|
362
|
+
if (!runInYaak) return null;
|
|
363
|
+
return /* @__PURE__ */ jsx(RunInYaakLink, {
|
|
364
|
+
name: runInYaak.name,
|
|
365
|
+
dataUrl: runInYaak.dataUrl,
|
|
366
|
+
...badge ? { badge } : {},
|
|
367
|
+
...className ? { className } : {}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
//#endregion
|
|
371
|
+
export { useRequest as C, usePage as S, useThemeOptions as T, useRunInYaak as _, SiteLinks as a, useDocument as b, Html as c, MethodBadge as d, RequestUrl as f, usePageActions as g, useComponents as h, RunInYaak as i, KeyValueTable as l, overridable as m, Footer as n, brandingCss as o, ComponentsProvider as p, Logo as r, AuthInfo as s, BrandingStyles as t, Markdown as u, toAbsoluteUrl as v, useSite as w, useFolder as x, YaakdocProvider as y };
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { _ as ThemeRuntime, g as ThemeComponents, o as LayoutProps } from "./types-BY2lOvlK.js";
|
|
2
|
+
//#region src/theme.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Node-side theme manifest. This module must stay free of React/runtime imports: it is loaded by the
|
|
5
|
+
* yaakdoc engine in Node to discover the theme's files and Vite plugins.
|
|
6
|
+
*/
|
|
7
|
+
/** Anything with a `parse` method (e.g. a Zod schema) can validate theme options. */
|
|
8
|
+
export type OptionsValidator = {
|
|
9
|
+
parse(input: unknown): unknown;
|
|
10
|
+
};
|
|
11
|
+
export type ThemeDefinition = {
|
|
12
|
+
/** Theme name, e.g. "kiseki". */
|
|
13
|
+
name: string;
|
|
14
|
+
/**
|
|
15
|
+
* Server entry module (relative to the manifest file, or absolute). Its default export is a
|
|
16
|
+
* `ThemeRuntime`: `{ Layout, components?, Head? }`. Processed by Vite, so TSX source is fine.
|
|
17
|
+
*/
|
|
18
|
+
entry: string;
|
|
19
|
+
/**
|
|
20
|
+
* Client entry module that hydrates islands, e.g.
|
|
21
|
+
* `hydrateIslands([...builtinIslands, MyIsland])`. Defaults to hydrating the built-in islands.
|
|
22
|
+
*/
|
|
23
|
+
client?: string;
|
|
24
|
+
/** CSS entry files (relative to the manifest), loaded in order. */
|
|
25
|
+
styles?: string[];
|
|
26
|
+
/** Vite plugins the theme needs (e.g. Tailwind). */
|
|
27
|
+
vitePlugins?: () => any[] | Promise<any[]>;
|
|
28
|
+
/** Shiki themes for syntax highlighting (default: github-light / github-dark). */
|
|
29
|
+
highlight?: {
|
|
30
|
+
light: string;
|
|
31
|
+
dark: string;
|
|
32
|
+
};
|
|
33
|
+
/** Validates/defaults `themeOptions` from the config. */
|
|
34
|
+
options?: OptionsValidator;
|
|
35
|
+
/** What `yaakdoc eject` copies (globs relative to the manifest directory). */
|
|
36
|
+
eject?: {
|
|
37
|
+
files?: string[];
|
|
38
|
+
/** Packages the ejected theme imports; printed after ejecting. */
|
|
39
|
+
dependencies?: string[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/** Defines a yaakdoc theme. */
|
|
43
|
+
export declare function defineTheme(definition: ThemeDefinition): ThemeDefinition;
|
|
44
|
+
//#endregion
|
|
45
|
+
export type { LayoutProps, ThemeComponents, ThemeRuntime };
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { EnvironmentRef, PreparedDocument } from "@yaakdoc/core";
|
|
2
|
+
import { ComponentType, ReactNode } from "react";
|
|
3
|
+
import { Branding, HeadTag, ResolvedConfig } from "@yaakdoc/config";
|
|
4
|
+
//#region src/types.d.ts
|
|
5
|
+
type ColorMode = "light" | "dark";
|
|
6
|
+
type ColorModePreference = Branding["defaultColorMode"];
|
|
7
|
+
type SiteColors = NonNullable<Branding["colors"]>;
|
|
8
|
+
type ModeColors = NonNullable<SiteColors["light"]>;
|
|
9
|
+
type SiteFonts = NonNullable<Branding["fonts"]>;
|
|
10
|
+
type LlmProvider = ResolvedConfig["llms"]["openIn"][number];
|
|
11
|
+
/** An environment readers can switch to. */
|
|
12
|
+
type EnvironmentOption = EnvironmentRef;
|
|
13
|
+
/** Logo with local paths resolved to public URLs. */
|
|
14
|
+
type SiteLogo = {
|
|
15
|
+
light?: string;
|
|
16
|
+
dark?: string;
|
|
17
|
+
alt: string;
|
|
18
|
+
href: string;
|
|
19
|
+
width?: number;
|
|
20
|
+
height?: number;
|
|
21
|
+
};
|
|
22
|
+
/** Site-wide, serializable data derived from the yaakdoc config and the export. */
|
|
23
|
+
type SiteData = {
|
|
24
|
+
title: string;
|
|
25
|
+
description: string;
|
|
26
|
+
/** Absolute public URL of the deployed site, if configured. */
|
|
27
|
+
url: string | null;
|
|
28
|
+
/** Base path, always with leading and trailing slash. */
|
|
29
|
+
base: string;
|
|
30
|
+
pages: ResolvedConfig["pages"];
|
|
31
|
+
logo: SiteLogo | null;
|
|
32
|
+
favicon: string | null;
|
|
33
|
+
colors: SiteColors;
|
|
34
|
+
fonts: SiteFonts;
|
|
35
|
+
links: Branding["links"];
|
|
36
|
+
/** Footer rendered from Markdown. */
|
|
37
|
+
footerHtml: string | null;
|
|
38
|
+
defaultColorMode: ColorModePreference;
|
|
39
|
+
colorModeToggle: boolean;
|
|
40
|
+
llms: ResolvedConfig["llms"] & {
|
|
41
|
+
/** URL of llms.txt, when enabled. */
|
|
42
|
+
txtUrl: string | null;
|
|
43
|
+
fullTxtUrl: string | null;
|
|
44
|
+
};
|
|
45
|
+
showVariables: boolean;
|
|
46
|
+
/** "Run in Yaak" button, when enabled. */
|
|
47
|
+
runInYaak: {
|
|
48
|
+
name: string;
|
|
49
|
+
/** URL of the importable export (may be relative to the site when `url` is unknown). */
|
|
50
|
+
dataUrl: string;
|
|
51
|
+
} | null;
|
|
52
|
+
head: HeadTag[];
|
|
53
|
+
themeOptions: Record<string, unknown>;
|
|
54
|
+
/** e.g. "yaakdoc 1.0.0" */
|
|
55
|
+
generator: string;
|
|
56
|
+
};
|
|
57
|
+
type PageKind = "index" | "folder" | "request" | "not-found";
|
|
58
|
+
type PageData = {
|
|
59
|
+
kind: PageKind;
|
|
60
|
+
/** Folder or request id for `folder` / `request` pages. */
|
|
61
|
+
id: string | null;
|
|
62
|
+
/** Route path, e.g. `/` or `/docs/products/get-a-product/`. */
|
|
63
|
+
path: string;
|
|
64
|
+
/** Document title (without the site title suffix). */
|
|
65
|
+
title: string;
|
|
66
|
+
description: string;
|
|
67
|
+
/** Markdown twin of this page, if any. */
|
|
68
|
+
markdownUrl: string | null;
|
|
69
|
+
};
|
|
70
|
+
type Assets = {
|
|
71
|
+
styles: string[];
|
|
72
|
+
scripts: string[];
|
|
73
|
+
/** Inline styles (dev mode). `id` is used for HMR (`data-vite-dev-id`). */
|
|
74
|
+
inlineStyles: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
css: string;
|
|
77
|
+
}>;
|
|
78
|
+
modulePreloads: string[];
|
|
79
|
+
};
|
|
80
|
+
type LayoutProps = {
|
|
81
|
+
page: PageData;
|
|
82
|
+
};
|
|
83
|
+
type ThemeComponents = Partial<Record<string, ComponentType<any>>>;
|
|
84
|
+
/** Runtime part of a theme (rendered by the SSR entry). */
|
|
85
|
+
type ThemeRuntime = {
|
|
86
|
+
Layout: ComponentType<LayoutProps>;
|
|
87
|
+
/** Overrides for base components (by component name, e.g. `MethodBadge`). */
|
|
88
|
+
components?: ThemeComponents;
|
|
89
|
+
/** Extra elements rendered in <head>. */
|
|
90
|
+
Head?: ComponentType<{
|
|
91
|
+
page: PageData;
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
type RenderContext = {
|
|
95
|
+
document: PreparedDocument;
|
|
96
|
+
site: SiteData;
|
|
97
|
+
page: PageData;
|
|
98
|
+
children?: ReactNode;
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { ThemeRuntime as _, HeadTag as a, ModeColors as c, RenderContext as d, SiteColors as f, ThemeComponents as g, SiteLogo as h, EnvironmentOption as i, PageData as l, SiteFonts as m, ColorMode as n, LayoutProps as o, SiteData as p, ColorModePreference as r, LlmProvider as s, Assets as t, PageKind as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,88 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yaakdoc/react",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Unstyled, composable React components and the island runtime for yaakdoc themes.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"@yaakdoc/source": "./src/index.ts",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./islands": {
|
|
15
|
+
"@yaakdoc/source": "./src/islands/index.ts",
|
|
16
|
+
"types": "./dist/islands.d.ts",
|
|
17
|
+
"default": "./dist/islands.js"
|
|
18
|
+
},
|
|
19
|
+
"./client": {
|
|
20
|
+
"@yaakdoc/source": "./src/client.ts",
|
|
21
|
+
"types": "./dist/client.d.ts",
|
|
22
|
+
"default": "./dist/client.js"
|
|
23
|
+
},
|
|
24
|
+
"./server": {
|
|
25
|
+
"@yaakdoc/source": "./src/server.tsx",
|
|
26
|
+
"types": "./dist/server.d.ts",
|
|
27
|
+
"default": "./dist/server.js"
|
|
28
|
+
},
|
|
29
|
+
"./theme": {
|
|
30
|
+
"@yaakdoc/source": "./src/theme.ts",
|
|
31
|
+
"types": "./dist/theme.d.ts",
|
|
32
|
+
"default": "./dist/theme.js"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"sideEffects": false,
|
|
37
|
+
"keywords": [
|
|
38
|
+
"yaak",
|
|
39
|
+
"yaakdoc",
|
|
40
|
+
"react",
|
|
41
|
+
"components",
|
|
42
|
+
"headless",
|
|
43
|
+
"theme"
|
|
44
|
+
],
|
|
45
|
+
"author": "József Sallai @jozsefsallai",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"files": [
|
|
48
|
+
"/dist",
|
|
49
|
+
"/README.md",
|
|
50
|
+
"/LICENSE"
|
|
51
|
+
],
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/jozsefsallai/yaakdoc.git",
|
|
55
|
+
"directory": "packages/react"
|
|
56
|
+
},
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/jozsefsallai/yaakdoc/issues"
|
|
59
|
+
},
|
|
60
|
+
"homepage": "https://github.com/jozsefsallai/yaakdoc#readme",
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.19"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"react": "^19.0.0",
|
|
66
|
+
"react-dom": "^19.0.0"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@repo/tsconfig": "0.0.0",
|
|
70
|
+
"@types/react": "^19.3.0",
|
|
71
|
+
"@types/react-dom": "^19.3.0",
|
|
72
|
+
"react": "^19.3.1",
|
|
73
|
+
"react-dom": "^19.3.1"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@yaakdoc/config": "^0.2.0",
|
|
77
|
+
"@yaakdoc/core": "^0.2.0"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsdown",
|
|
81
|
+
"dev": "tsdown --watch --no-clean",
|
|
82
|
+
"test": "vitest run",
|
|
83
|
+
"check-types": "tsc",
|
|
84
|
+
"lint": "biome lint .",
|
|
85
|
+
"lint:fix": "biome lint . --write",
|
|
86
|
+
"format": "biome format . --write"
|
|
87
|
+
}
|
|
6
88
|
}
|