@farming-labs/next 0.1.12 → 0.1.16

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.
@@ -0,0 +1,46 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { ReactNode } from "react";
3
+
4
+ //#region src/changelog-rail-search.d.ts
5
+ interface ChangelogDirectoryEntry {
6
+ slug: string;
7
+ title: string;
8
+ description?: string;
9
+ date: string;
10
+ url: string;
11
+ version?: string;
12
+ tags: string[];
13
+ authors: string[];
14
+ image?: string;
15
+ content?: ReactNode;
16
+ }
17
+ interface ChangelogDirectoryProps {
18
+ title: string;
19
+ description?: string;
20
+ entries: ChangelogDirectoryEntry[];
21
+ searchEnabled: boolean;
22
+ actions?: ReactNode;
23
+ }
24
+ interface ChangelogTOCItem {
25
+ href: string;
26
+ title: string;
27
+ meta?: string;
28
+ }
29
+ declare function ChangelogTOC({
30
+ title,
31
+ items,
32
+ variant
33
+ }: {
34
+ title: string;
35
+ items: ChangelogTOCItem[];
36
+ variant?: "releases" | "content";
37
+ }): react_jsx_runtime0.JSX.Element | null;
38
+ declare function ChangelogDirectory({
39
+ title,
40
+ description,
41
+ entries,
42
+ searchEnabled,
43
+ actions
44
+ }: ChangelogDirectoryProps): react_jsx_runtime0.JSX.Element;
45
+ //#endregion
46
+ export { ChangelogDirectory, ChangelogDirectoryEntry, ChangelogTOC };
@@ -0,0 +1,416 @@
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { useEffect, useMemo, useState } from "react";
6
+
7
+ //#region src/changelog-rail-search.tsx
8
+ const MAGIC_PROSE = "fd-changelog-prose prose dark:prose-invert max-w-none min-w-0 prose-headings:scroll-mt-8 prose-headings:font-semibold prose-a:no-underline prose-headings:tracking-tight prose-headings:text-balance prose-p:tracking-tight prose-p:text-balance";
9
+ function formatTagLabel(tag) {
10
+ return tag.split(/[-_\s]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
11
+ }
12
+ function SearchIcon() {
13
+ return /* @__PURE__ */ jsxs("svg", {
14
+ "aria-hidden": "true",
15
+ viewBox: "0 0 24 24",
16
+ className: "size-4",
17
+ fill: "none",
18
+ stroke: "currentColor",
19
+ strokeWidth: "1.8",
20
+ strokeLinecap: "round",
21
+ strokeLinejoin: "round",
22
+ children: [/* @__PURE__ */ jsx("circle", {
23
+ cx: "11",
24
+ cy: "11",
25
+ r: "7"
26
+ }), /* @__PURE__ */ jsx("path", { d: "m20 20-3.5-3.5" })]
27
+ });
28
+ }
29
+ function formatTimelineDate(value) {
30
+ const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
31
+ if (Number.isNaN(parsed.valueOf())) return value;
32
+ return new Intl.DateTimeFormat("en-US", {
33
+ year: "numeric",
34
+ month: "long",
35
+ day: "numeric",
36
+ timeZone: "UTC"
37
+ }).format(parsed).toUpperCase();
38
+ }
39
+ function buildSearchHaystack(entry) {
40
+ return [
41
+ entry.title,
42
+ entry.description,
43
+ entry.date,
44
+ entry.version,
45
+ entry.tags.join(" "),
46
+ entry.authors.join(" ")
47
+ ].filter(Boolean).join(" ").toLowerCase();
48
+ }
49
+ function EmptyResults({ query }) {
50
+ return /* @__PURE__ */ jsxs("div", {
51
+ className: "rounded-lg border border-fd-border/70 bg-fd-muted/30 px-6 py-12 sm:px-8",
52
+ style: {
53
+ width: "min(100%, 48rem)",
54
+ maxWidth: "48rem",
55
+ minHeight: "10rem",
56
+ display: "flex",
57
+ flexDirection: "column",
58
+ alignItems: "flex-start",
59
+ justifyContent: "center",
60
+ textAlign: "left",
61
+ alignSelf: "flex-start",
62
+ marginLeft: 0,
63
+ marginRight: "auto"
64
+ },
65
+ children: [
66
+ /* @__PURE__ */ jsx("p", {
67
+ className: "text-xs font-medium uppercase tracking-[0.12em] text-fd-muted-foreground",
68
+ children: "No matches"
69
+ }),
70
+ /* @__PURE__ */ jsxs("h2", {
71
+ className: "mt-3 max-w-2xl text-2xl font-semibold tracking-tight text-fd-foreground sm:text-3xl",
72
+ children: [
73
+ "Nothing matched “",
74
+ query,
75
+ "”"
76
+ ]
77
+ }),
78
+ /* @__PURE__ */ jsx("p", {
79
+ className: "mt-3 max-w-xl text-sm leading-relaxed text-fd-muted-foreground",
80
+ children: "Try a release title, version, tag, or author name."
81
+ })
82
+ ]
83
+ });
84
+ }
85
+ function decodeHashValue(value) {
86
+ try {
87
+ return decodeURIComponent(value);
88
+ } catch {
89
+ return value;
90
+ }
91
+ }
92
+ function getHashTargetElement(href) {
93
+ if (!href.startsWith("#")) return null;
94
+ const targetId = decodeHashValue(href.slice(1));
95
+ if (!targetId) return null;
96
+ const candidates = Array.from(document.querySelectorAll("[id]")).filter((candidate) => candidate.id === targetId);
97
+ const element = candidates.find((candidate) => {
98
+ const rect = candidate.getBoundingClientRect();
99
+ return rect.width > 0 || rect.height > 0;
100
+ }) ?? candidates[0];
101
+ if (!element) return null;
102
+ const rect = element.getBoundingClientRect();
103
+ if (rect.width > 0 || rect.height > 0) return element;
104
+ return element.closest("h1, h2, h3, h4, h5, h6, section, article") ?? element.parentElement;
105
+ }
106
+ function ChangelogTOC({ title, items, variant = "releases" }) {
107
+ const tocId = `fd-changelog-toc-${variant}-${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
108
+ const [activeHref, setActiveHref] = useState(items[0]?.href ?? "");
109
+ useEffect(() => {
110
+ if (items.length === 0) {
111
+ setActiveHref("");
112
+ return;
113
+ }
114
+ let frameId = 0;
115
+ const updateActiveHref = () => {
116
+ const threshold = Math.max(140, window.innerHeight * .18);
117
+ let nextActiveHref = items[0]?.href ?? "";
118
+ for (const item of items) {
119
+ const element = getHashTargetElement(item.href);
120
+ if (!element) continue;
121
+ const { top } = element.getBoundingClientRect();
122
+ if (top <= threshold) nextActiveHref = item.href;
123
+ else break;
124
+ }
125
+ if (window.location.hash) {
126
+ const hashHref = `#${decodeHashValue(window.location.hash.slice(1))}`;
127
+ if (items.some((item) => item.href === hashHref)) nextActiveHref = hashHref;
128
+ }
129
+ setActiveHref(nextActiveHref);
130
+ };
131
+ const scheduleUpdate = () => {
132
+ if (frameId !== 0) return;
133
+ frameId = window.requestAnimationFrame(() => {
134
+ frameId = 0;
135
+ updateActiveHref();
136
+ });
137
+ };
138
+ updateActiveHref();
139
+ window.setTimeout(updateActiveHref, 0);
140
+ window.setTimeout(updateActiveHref, 250);
141
+ window.addEventListener("scroll", scheduleUpdate, { passive: true });
142
+ window.addEventListener("resize", scheduleUpdate);
143
+ window.addEventListener("hashchange", scheduleUpdate);
144
+ return () => {
145
+ if (frameId !== 0) window.cancelAnimationFrame(frameId);
146
+ window.removeEventListener("scroll", scheduleUpdate);
147
+ window.removeEventListener("resize", scheduleUpdate);
148
+ window.removeEventListener("hashchange", scheduleUpdate);
149
+ };
150
+ }, [items]);
151
+ if (items.length === 0) return null;
152
+ return /* @__PURE__ */ jsx("aside", {
153
+ id: tocId,
154
+ className: "fd-changelog-toc",
155
+ "aria-label": title,
156
+ "data-fd-changelog-toc": "true",
157
+ "data-variant": variant,
158
+ children: /* @__PURE__ */ jsxs("div", {
159
+ className: "fd-changelog-toc-card",
160
+ children: [/* @__PURE__ */ jsx("p", {
161
+ className: "fd-changelog-toc-heading",
162
+ children: title
163
+ }), /* @__PURE__ */ jsx("nav", {
164
+ className: "fd-changelog-toc-list",
165
+ children: items.map((item) => {
166
+ const isActive = item.href === activeHref;
167
+ return /* @__PURE__ */ jsxs("a", {
168
+ href: item.href,
169
+ className: "fd-changelog-toc-link",
170
+ "data-fd-changelog-toc-link": "true",
171
+ "data-active": isActive ? "true" : "false",
172
+ "aria-current": isActive ? "location" : void 0,
173
+ onClick: () => setActiveHref(item.href),
174
+ children: [item.meta ? /* @__PURE__ */ jsx("span", {
175
+ className: "fd-changelog-toc-meta",
176
+ children: item.meta
177
+ }) : null, /* @__PURE__ */ jsx("span", {
178
+ className: "fd-changelog-toc-title",
179
+ children: item.title
180
+ })]
181
+ }, item.href);
182
+ })
183
+ })]
184
+ })
185
+ });
186
+ }
187
+ function ChangelogTimelineItem({ entry, isLast }) {
188
+ return /* @__PURE__ */ jsxs("div", {
189
+ id: entry.slug,
190
+ className: "fd-changelog-entry relative scroll-mt-24 not-prose isolate",
191
+ children: [
192
+ /* @__PURE__ */ jsxs("div", {
193
+ className: "fd-changelog-mobile-summary",
194
+ children: [entry.version ? /* @__PURE__ */ jsx("div", {
195
+ className: "fd-changelog-version-box",
196
+ children: entry.version
197
+ }) : /* @__PURE__ */ jsx("div", {}), /* @__PURE__ */ jsx("time", {
198
+ className: "fd-changelog-date",
199
+ style: { marginBottom: "10px" },
200
+ dateTime: entry.date,
201
+ children: formatTimelineDate(entry.date)
202
+ })]
203
+ }),
204
+ /* @__PURE__ */ jsxs("div", {
205
+ className: "fd-changelog-mobile-content",
206
+ style: isLast ? void 0 : { paddingBottom: "5rem" },
207
+ children: [/* @__PURE__ */ jsxs("div", {
208
+ className: "flex flex-col gap-2",
209
+ children: [
210
+ /* @__PURE__ */ jsx("h2", {
211
+ className: "m-0 text-balance text-lg font-semibold leading-snug tracking-tight text-fd-foreground md:text-xl",
212
+ children: /* @__PURE__ */ jsx(Link, {
213
+ href: entry.url,
214
+ className: "text-inherit no-underline hover:underline",
215
+ children: entry.title
216
+ })
217
+ }),
218
+ entry.tags.length > 0 ? /* @__PURE__ */ jsx("div", {
219
+ className: "flex flex-wrap gap-2",
220
+ children: entry.tags.map((tag) => /* @__PURE__ */ jsx("span", {
221
+ className: "fd-changelog-tag",
222
+ "data-testid": "changelog-tag",
223
+ children: formatTagLabel(tag)
224
+ }, `${entry.slug}-${tag}`))
225
+ }) : null,
226
+ entry.description ? /* @__PURE__ */ jsx("p", {
227
+ className: "m-0 max-w-2xl text-sm leading-relaxed text-fd-muted-foreground",
228
+ children: entry.description
229
+ }) : null
230
+ ]
231
+ }), entry.content || entry.image ? /* @__PURE__ */ jsxs("div", {
232
+ className: MAGIC_PROSE,
233
+ children: [entry.image ? /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("img", {
234
+ src: entry.image,
235
+ alt: `${entry.title} preview`,
236
+ loading: "lazy",
237
+ decoding: "async"
238
+ }) }) : null, entry.content]
239
+ }) : null]
240
+ }),
241
+ /* @__PURE__ */ jsxs("div", {
242
+ className: "fd-changelog-desktop-grid",
243
+ style: isLast ? void 0 : { paddingBottom: "5rem" },
244
+ children: [
245
+ /* @__PURE__ */ jsx("div", {
246
+ className: "flex items-start justify-end pt-0.5",
247
+ children: entry.version ? /* @__PURE__ */ jsx("div", {
248
+ className: "fd-changelog-version-box",
249
+ children: entry.version
250
+ }) : /* @__PURE__ */ jsx("div", {
251
+ className: "h-9",
252
+ "aria-hidden": "true"
253
+ })
254
+ }),
255
+ /* @__PURE__ */ jsxs("div", {
256
+ className: "fd-changelog-rail",
257
+ "data-testid": "changelog-rail",
258
+ children: [/* @__PURE__ */ jsx("div", {
259
+ className: "fd-changelog-timeline-dot mt-1",
260
+ "data-testid": "changelog-timeline-dot",
261
+ "aria-hidden": true
262
+ }), isLast ? /* @__PURE__ */ jsx("div", {
263
+ className: "fd-changelog-rail-end-mask",
264
+ "aria-hidden": true
265
+ }) : null]
266
+ }),
267
+ /* @__PURE__ */ jsxs("div", {
268
+ className: "min-w-0 space-y-5",
269
+ children: [/* @__PURE__ */ jsx("time", {
270
+ className: "fd-changelog-date block pt-0.5",
271
+ dateTime: entry.date,
272
+ children: formatTimelineDate(entry.date)
273
+ }), /* @__PURE__ */ jsxs("div", {
274
+ className: "space-y-6",
275
+ children: [/* @__PURE__ */ jsxs("div", {
276
+ className: "flex flex-col gap-2",
277
+ children: [
278
+ /* @__PURE__ */ jsx("h2", {
279
+ className: "m-0 text-balance text-lg font-semibold leading-snug tracking-tight text-fd-foreground md:text-xl",
280
+ children: /* @__PURE__ */ jsx(Link, {
281
+ href: entry.url,
282
+ className: "text-inherit no-underline hover:underline",
283
+ children: entry.title
284
+ })
285
+ }),
286
+ entry.tags.length > 0 ? /* @__PURE__ */ jsx("div", {
287
+ className: "flex flex-wrap gap-2",
288
+ children: entry.tags.map((tag) => /* @__PURE__ */ jsx("span", {
289
+ className: "fd-changelog-tag",
290
+ "data-testid": "changelog-tag",
291
+ children: formatTagLabel(tag)
292
+ }, `${entry.slug}-${tag}`))
293
+ }) : null,
294
+ entry.description ? /* @__PURE__ */ jsx("p", {
295
+ className: "m-0 max-w-2xl text-sm leading-relaxed text-fd-muted-foreground",
296
+ children: entry.description
297
+ }) : null
298
+ ]
299
+ }), entry.content || entry.image ? /* @__PURE__ */ jsxs("div", {
300
+ className: MAGIC_PROSE,
301
+ children: [entry.image ? /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("img", {
302
+ src: entry.image,
303
+ alt: `${entry.title} preview`,
304
+ loading: "lazy",
305
+ decoding: "async"
306
+ }) }) : null, entry.content]
307
+ }) : null]
308
+ })]
309
+ })
310
+ ]
311
+ })
312
+ ]
313
+ });
314
+ }
315
+ function ChangelogDirectory({ title, description, entries, searchEnabled, actions }) {
316
+ const [query, setQuery] = useState("");
317
+ const normalizedQuery = query.trim().toLowerCase();
318
+ const filteredEntries = useMemo(() => {
319
+ if (!normalizedQuery) return entries;
320
+ return entries.filter((entry) => buildSearchHaystack(entry).includes(normalizedQuery));
321
+ }, [entries, normalizedQuery]);
322
+ const releaseCount = entries.length;
323
+ const hasResults = filteredEntries.length > 0;
324
+ const tocItems = filteredEntries.map((entry) => ({
325
+ href: `#${entry.slug}`,
326
+ title: entry.title,
327
+ meta: entry.version ?? formatTimelineDate(entry.date)
328
+ }));
329
+ const searchControl = searchEnabled ? /* @__PURE__ */ jsx("div", {
330
+ className: "fd-changelog-search-row",
331
+ children: /* @__PURE__ */ jsxs("label", {
332
+ className: "fd-changelog-search",
333
+ "aria-label": "Search changelog entries",
334
+ children: [/* @__PURE__ */ jsx("span", {
335
+ className: "fd-changelog-search-icon",
336
+ "aria-hidden": "true",
337
+ children: /* @__PURE__ */ jsx(SearchIcon, {})
338
+ }), /* @__PURE__ */ jsx("input", {
339
+ type: "text",
340
+ inputMode: "search",
341
+ autoComplete: "off",
342
+ value: query,
343
+ onChange: (event) => setQuery(event.target.value),
344
+ placeholder: "Search changelog entries",
345
+ className: "fd-changelog-search-input"
346
+ })]
347
+ })
348
+ }) : null;
349
+ return /* @__PURE__ */ jsxs("div", {
350
+ className: "fd-changelog-frame not-prose relative w-full pb-16",
351
+ children: [
352
+ /* @__PURE__ */ jsx("div", {
353
+ className: "fd-changelog-header-strip border-b-0 border-fd-border/50",
354
+ children: /* @__PURE__ */ jsxs("div", {
355
+ className: "flex flex-wrap items-center justify-between gap-4",
356
+ style: {
357
+ paddingTop: "1.25rem",
358
+ paddingBottom: "1.25rem"
359
+ },
360
+ children: [/* @__PURE__ */ jsxs("div", {
361
+ className: "min-w-0",
362
+ children: [/* @__PURE__ */ jsx("h1", {
363
+ className: "text-2xl font-semibold tracking-tight text-fd-foreground md:text-3xl",
364
+ children: title
365
+ }), /* @__PURE__ */ jsxs("p", {
366
+ className: "mt-0.5 text-sm text-fd-muted-foreground",
367
+ children: [
368
+ releaseCount,
369
+ " ",
370
+ releaseCount === 1 ? "release" : "releases"
371
+ ]
372
+ })]
373
+ }), actions ? /* @__PURE__ */ jsx("div", {
374
+ className: "flex flex-wrap items-center gap-2",
375
+ children: actions
376
+ }) : null]
377
+ })
378
+ }),
379
+ description || searchControl ? /* @__PURE__ */ jsxs(Fragment, { children: [
380
+ description ? /* @__PURE__ */ jsx("p", {
381
+ className: "max-w-2xl text-base leading-relaxed text-fd-muted-foreground",
382
+ style: { marginTop: "1rem" },
383
+ children: description
384
+ }) : null,
385
+ searchControl ? /* @__PURE__ */ jsx("div", {
386
+ style: { marginTop: description ? "1rem" : "1.25rem" },
387
+ children: searchControl
388
+ }) : null,
389
+ /* @__PURE__ */ jsx("hr", {
390
+ className: "border-0 border-t border-fd-border/40",
391
+ style: { marginTop: "1rem" }
392
+ })
393
+ ] }) : null,
394
+ /* @__PURE__ */ jsxs("div", {
395
+ className: hasResults ? "fd-changelog-shell fd-changelog-shell-shifted" : "fd-changelog-shell",
396
+ style: { paddingTop: "4rem" },
397
+ children: [/* @__PURE__ */ jsx("div", {
398
+ className: "fd-changelog-main fd-changelog-directory-feed relative",
399
+ children: hasResults ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
400
+ className: "fd-changelog-directory-line",
401
+ "aria-hidden": true
402
+ }), filteredEntries.map((entry, index) => /* @__PURE__ */ jsx(ChangelogTimelineItem, {
403
+ entry,
404
+ isLast: index === filteredEntries.length - 1
405
+ }, entry.slug))] }) : /* @__PURE__ */ jsx(EmptyResults, { query })
406
+ }), hasResults ? /* @__PURE__ */ jsx(ChangelogTOC, {
407
+ title: "Releases",
408
+ items: tocItems
409
+ }) : null]
410
+ })
411
+ ]
412
+ });
413
+ }
414
+
415
+ //#endregion
416
+ export { ChangelogDirectory, ChangelogTOC };
@@ -0,0 +1,36 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { DocsConfig } from "@farming-labs/theme";
3
+ import { ChangelogFrontmatter } from "@farming-labs/docs";
4
+ import { ComponentType } from "react";
5
+ import { Metadata } from "next";
6
+
7
+ //#region src/changelog.d.ts
8
+ interface GeneratedChangelogEntry {
9
+ slug: string;
10
+ date: string;
11
+ url: string;
12
+ sourcePath: string;
13
+ Component: ComponentType;
14
+ metadata?: ChangelogFrontmatter;
15
+ }
16
+ declare function createNextChangelogIndexPage(config: DocsConfig, entries: GeneratedChangelogEntry[]): () => react_jsx_runtime0.JSX.Element;
17
+ declare function createNextChangelogEntryPage(config: DocsConfig, entries: GeneratedChangelogEntry[]): (props: {
18
+ params?: Promise<{
19
+ slug?: string;
20
+ }> | {
21
+ slug?: string;
22
+ };
23
+ }) => Promise<react_jsx_runtime0.JSX.Element>;
24
+ declare function createNextChangelogStaticParams(entries: GeneratedChangelogEntry[]): () => {
25
+ slug: string;
26
+ }[];
27
+ declare function createNextChangelogIndexMetadata(config: DocsConfig): Metadata;
28
+ declare function createNextChangelogEntryMetadata(config: DocsConfig, entries: GeneratedChangelogEntry[]): (props: {
29
+ params?: Promise<{
30
+ slug?: string;
31
+ }> | {
32
+ slug?: string;
33
+ };
34
+ }) => Promise<Metadata>;
35
+ //#endregion
36
+ export { GeneratedChangelogEntry, createNextChangelogEntryMetadata, createNextChangelogEntryPage, createNextChangelogIndexMetadata, createNextChangelogIndexPage, createNextChangelogStaticParams };