@riebeckite/plugin-garden-explorer 0.0.8 → 0.0.9
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/dist/components/explorer-panels.d.ts +22 -0
- package/dist/components/garden-explorer.js +116 -113
- package/dist/index.js +116 -113
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GardenExplorerNote } from "../src/garden-explorer.js";
|
|
2
|
+
export declare function FilterList(props: {
|
|
3
|
+
title: string;
|
|
4
|
+
items: {
|
|
5
|
+
key: string;
|
|
6
|
+
label: string;
|
|
7
|
+
count: number;
|
|
8
|
+
}[];
|
|
9
|
+
selectedKey: string | null;
|
|
10
|
+
onSelect: (key: string) => void;
|
|
11
|
+
}): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
12
|
+
export declare function NoteList(props: {
|
|
13
|
+
notes: GardenExplorerNote[];
|
|
14
|
+
selectedSlug: string;
|
|
15
|
+
onSelect: (slug: string) => void;
|
|
16
|
+
}): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
17
|
+
export declare function NoteDetails(props: {
|
|
18
|
+
note: GardenExplorerNote;
|
|
19
|
+
noteBySlug: Map<string, GardenExplorerNote>;
|
|
20
|
+
relatedNotes: GardenExplorerNote[];
|
|
21
|
+
onSelect: (slug: string) => void;
|
|
22
|
+
}): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
@@ -70,8 +70,92 @@ function scoreFuzzyMatch(value, query) {
|
|
|
70
70
|
return Math.max(0, coverage * (1 - continuityPenalty));
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
// components/
|
|
73
|
+
// components/explorer-panels.tsx
|
|
74
74
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
75
|
+
function FilterList(props) {
|
|
76
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section", children: [
|
|
77
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
78
|
+
/* @__PURE__ */ jsx("div", { class: "garden-explorer__chips", children: props.items.slice(0, 28).map((item) => /* @__PURE__ */ jsxs(
|
|
79
|
+
"button",
|
|
80
|
+
{
|
|
81
|
+
type: "button",
|
|
82
|
+
class: "garden-explorer__chip",
|
|
83
|
+
"aria-pressed": props.selectedKey === item.key,
|
|
84
|
+
onClick: () => props.onSelect(item.key),
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
87
|
+
/* @__PURE__ */ jsx("span", { children: item.count })
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
item.key
|
|
91
|
+
)) })
|
|
92
|
+
] });
|
|
93
|
+
}
|
|
94
|
+
function NoteList(props) {
|
|
95
|
+
return /* @__PURE__ */ jsx("ul", { class: "garden-explorer__note-list", children: props.notes.map((note) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
type: "button",
|
|
99
|
+
"aria-pressed": props.selectedSlug === note.slug,
|
|
100
|
+
onClick: () => props.onSelect(note.slug),
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ jsx("span", { children: note.title }),
|
|
103
|
+
/* @__PURE__ */ jsx("small", { children: note.folder })
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
) }, note.slug)) });
|
|
107
|
+
}
|
|
108
|
+
function NoteDetails(props) {
|
|
109
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__details", children: [
|
|
110
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Selected Note" }),
|
|
111
|
+
/* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsx("a", { href: props.note.permalink, children: props.note.title }) }),
|
|
112
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__path", children: props.note.slug }),
|
|
113
|
+
props.note.excerpt && /* @__PURE__ */ jsx("p", { children: props.note.excerpt }),
|
|
114
|
+
/* @__PURE__ */ jsx("div", { class: "garden-explorer__tag-row", children: props.note.tags.map((tag) => /* @__PURE__ */ jsxs("span", { children: [
|
|
115
|
+
"#",
|
|
116
|
+
tag
|
|
117
|
+
] }, tag)) }),
|
|
118
|
+
/* @__PURE__ */ jsx(
|
|
119
|
+
LinkedNoteSection,
|
|
120
|
+
{
|
|
121
|
+
title: "Outgoing Links",
|
|
122
|
+
slugs: props.note.outgoing,
|
|
123
|
+
noteBySlug: props.noteBySlug,
|
|
124
|
+
onSelect: props.onSelect
|
|
125
|
+
}
|
|
126
|
+
),
|
|
127
|
+
/* @__PURE__ */ jsx(
|
|
128
|
+
LinkedNoteSection,
|
|
129
|
+
{
|
|
130
|
+
title: "Backlinks",
|
|
131
|
+
slugs: props.note.backlinks,
|
|
132
|
+
noteBySlug: props.noteBySlug,
|
|
133
|
+
onSelect: props.onSelect
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
137
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Related Notes" }),
|
|
138
|
+
/* @__PURE__ */ jsx(
|
|
139
|
+
NoteList,
|
|
140
|
+
{
|
|
141
|
+
notes: props.relatedNotes,
|
|
142
|
+
selectedSlug: props.note.slug,
|
|
143
|
+
onSelect: props.onSelect
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
] })
|
|
147
|
+
] });
|
|
148
|
+
}
|
|
149
|
+
function LinkedNoteSection(props) {
|
|
150
|
+
const notes = props.slugs.map((slug) => props.noteBySlug.get(slug)).filter((note) => note !== void 0);
|
|
151
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
152
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
153
|
+
notes.length > 0 ? /* @__PURE__ */ jsx(NoteList, { notes, selectedSlug: "", onSelect: props.onSelect }) : /* @__PURE__ */ jsx("p", { class: "garden-explorer__empty", children: "No notes." })
|
|
154
|
+
] });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// components/garden-explorer.tsx
|
|
158
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
|
|
75
159
|
var GRAPH_WIDTH = 900;
|
|
76
160
|
var GRAPH_HEIGHT = 620;
|
|
77
161
|
var MIN_SCALE = 0.6;
|
|
@@ -149,10 +233,10 @@ function GardenExplorer(props) {
|
|
|
149
233
|
scale: clamp(current.scale + delta, MIN_SCALE, MAX_SCALE)
|
|
150
234
|
}));
|
|
151
235
|
};
|
|
152
|
-
return /* @__PURE__ */
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
-
["graph", "explorer", "details"].map((panel) => /* @__PURE__ */
|
|
236
|
+
return /* @__PURE__ */ jsxs2("div", { class: "garden-explorer rr-garden-explorer", "data-garden-explorer": true, children: [
|
|
237
|
+
/* @__PURE__ */ jsxs2("fieldset", { class: "garden-explorer__mobile-tabs", children: [
|
|
238
|
+
/* @__PURE__ */ jsx2("legend", { class: "sr-only", children: "Explorer panels" }),
|
|
239
|
+
["graph", "explorer", "details"].map((panel) => /* @__PURE__ */ jsx2(
|
|
156
240
|
"button",
|
|
157
241
|
{
|
|
158
242
|
type: "button",
|
|
@@ -163,12 +247,12 @@ function GardenExplorer(props) {
|
|
|
163
247
|
}
|
|
164
248
|
))
|
|
165
249
|
] }),
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
250
|
+
/* @__PURE__ */ jsxs2("aside", { class: panelClass("explorer", mobilePanel), children: [
|
|
251
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__section", children: [
|
|
252
|
+
/* @__PURE__ */ jsx2("p", { class: "garden-explorer__eyebrow", children: "Explorer" }),
|
|
253
|
+
/* @__PURE__ */ jsxs2("label", { class: "garden-explorer__search", children: [
|
|
254
|
+
/* @__PURE__ */ jsx2("span", { class: "sr-only", children: "Search notes" }),
|
|
255
|
+
/* @__PURE__ */ jsx2(
|
|
172
256
|
"input",
|
|
173
257
|
{
|
|
174
258
|
type: "search",
|
|
@@ -178,7 +262,7 @@ function GardenExplorer(props) {
|
|
|
178
262
|
}
|
|
179
263
|
)
|
|
180
264
|
] }),
|
|
181
|
-
/* @__PURE__ */
|
|
265
|
+
/* @__PURE__ */ jsx2(
|
|
182
266
|
"button",
|
|
183
267
|
{
|
|
184
268
|
type: "button",
|
|
@@ -188,7 +272,7 @@ function GardenExplorer(props) {
|
|
|
188
272
|
}
|
|
189
273
|
)
|
|
190
274
|
] }),
|
|
191
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ jsx2(
|
|
192
276
|
FilterList,
|
|
193
277
|
{
|
|
194
278
|
title: "Tags",
|
|
@@ -201,7 +285,7 @@ function GardenExplorer(props) {
|
|
|
201
285
|
onSelect: (key) => setSelectedTag(key === selectedTag ? null : key)
|
|
202
286
|
}
|
|
203
287
|
),
|
|
204
|
-
/* @__PURE__ */
|
|
288
|
+
/* @__PURE__ */ jsx2(
|
|
205
289
|
FilterList,
|
|
206
290
|
{
|
|
207
291
|
title: "Folders",
|
|
@@ -214,9 +298,9 @@ function GardenExplorer(props) {
|
|
|
214
298
|
onSelect: (key) => setSelectedFolder(key === selectedFolder ? null : key)
|
|
215
299
|
}
|
|
216
300
|
),
|
|
217
|
-
/* @__PURE__ */
|
|
218
|
-
/* @__PURE__ */
|
|
219
|
-
/* @__PURE__ */
|
|
301
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__section", children: [
|
|
302
|
+
/* @__PURE__ */ jsx2("p", { class: "garden-explorer__eyebrow", children: "Notes" }),
|
|
303
|
+
/* @__PURE__ */ jsx2(
|
|
220
304
|
NoteList,
|
|
221
305
|
{
|
|
222
306
|
notes: filteredNotes,
|
|
@@ -226,14 +310,14 @@ function GardenExplorer(props) {
|
|
|
226
310
|
)
|
|
227
311
|
] })
|
|
228
312
|
] }),
|
|
229
|
-
/* @__PURE__ */
|
|
230
|
-
/* @__PURE__ */
|
|
231
|
-
/* @__PURE__ */
|
|
313
|
+
/* @__PURE__ */ jsxs2("section", { class: panelClass("graph", mobilePanel), "aria-label": "Note graph", children: [
|
|
314
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__graph-toolbar", children: [
|
|
315
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
232
316
|
filteredNotes.length,
|
|
233
317
|
" notes"
|
|
234
318
|
] }),
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
320
|
+
/* @__PURE__ */ jsx2(
|
|
237
321
|
"button",
|
|
238
322
|
{
|
|
239
323
|
type: "button",
|
|
@@ -242,7 +326,7 @@ function GardenExplorer(props) {
|
|
|
242
326
|
children: "−"
|
|
243
327
|
}
|
|
244
328
|
),
|
|
245
|
-
/* @__PURE__ */
|
|
329
|
+
/* @__PURE__ */ jsx2(
|
|
246
330
|
"button",
|
|
247
331
|
{
|
|
248
332
|
type: "button",
|
|
@@ -251,7 +335,7 @@ function GardenExplorer(props) {
|
|
|
251
335
|
children: "+"
|
|
252
336
|
}
|
|
253
337
|
),
|
|
254
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ jsx2(
|
|
255
339
|
"button",
|
|
256
340
|
{
|
|
257
341
|
type: "button",
|
|
@@ -261,7 +345,7 @@ function GardenExplorer(props) {
|
|
|
261
345
|
)
|
|
262
346
|
] })
|
|
263
347
|
] }),
|
|
264
|
-
/* @__PURE__ */
|
|
348
|
+
/* @__PURE__ */ jsx2(
|
|
265
349
|
"svg",
|
|
266
350
|
{
|
|
267
351
|
class: "garden-graph",
|
|
@@ -280,12 +364,12 @@ function GardenExplorer(props) {
|
|
|
280
364
|
y: current.y + event.movementY / current.scale
|
|
281
365
|
}));
|
|
282
366
|
},
|
|
283
|
-
children: /* @__PURE__ */
|
|
367
|
+
children: /* @__PURE__ */ jsxs2("g", { transform: `translate(${view.x} ${view.y}) scale(${view.scale})`, children: [
|
|
284
368
|
visibleEdges.map((edge) => {
|
|
285
369
|
const source = graphNodes.get(edge.source);
|
|
286
370
|
const target = graphNodes.get(edge.target);
|
|
287
371
|
if (!source || !target) return null;
|
|
288
|
-
return /* @__PURE__ */
|
|
372
|
+
return /* @__PURE__ */ jsx2(
|
|
289
373
|
"line",
|
|
290
374
|
{
|
|
291
375
|
class: "garden-graph__edge",
|
|
@@ -301,7 +385,7 @@ function GardenExplorer(props) {
|
|
|
301
385
|
const node = graphNodes.get(note.slug);
|
|
302
386
|
if (!node) return null;
|
|
303
387
|
const selected = note.slug === selectedSlug;
|
|
304
|
-
return /* @__PURE__ */
|
|
388
|
+
return /* @__PURE__ */ jsx2("g", { class: "garden-graph__node", children: /* @__PURE__ */ jsxs2(
|
|
305
389
|
"a",
|
|
306
390
|
{
|
|
307
391
|
href: `/explore?note=${encodeURIComponent(note.slug)}`,
|
|
@@ -311,7 +395,7 @@ function GardenExplorer(props) {
|
|
|
311
395
|
selectNote(note.slug);
|
|
312
396
|
},
|
|
313
397
|
children: [
|
|
314
|
-
/* @__PURE__ */
|
|
398
|
+
/* @__PURE__ */ jsx2(
|
|
315
399
|
"circle",
|
|
316
400
|
{
|
|
317
401
|
cx: node.x,
|
|
@@ -320,7 +404,7 @@ function GardenExplorer(props) {
|
|
|
320
404
|
"data-selected": selected ? "true" : "false"
|
|
321
405
|
}
|
|
322
406
|
),
|
|
323
|
-
/* @__PURE__ */
|
|
407
|
+
/* @__PURE__ */ jsx2("text", { x: node.x + 18, y: node.y + 5, children: note.title })
|
|
324
408
|
]
|
|
325
409
|
}
|
|
326
410
|
) }, note.slug);
|
|
@@ -329,7 +413,7 @@ function GardenExplorer(props) {
|
|
|
329
413
|
}
|
|
330
414
|
)
|
|
331
415
|
] }),
|
|
332
|
-
/* @__PURE__ */
|
|
416
|
+
/* @__PURE__ */ jsx2("aside", { class: panelClass("details", mobilePanel), children: selectedNote ? /* @__PURE__ */ jsx2(
|
|
333
417
|
NoteDetails,
|
|
334
418
|
{
|
|
335
419
|
note: selectedNote,
|
|
@@ -337,88 +421,7 @@ function GardenExplorer(props) {
|
|
|
337
421
|
relatedNotes,
|
|
338
422
|
onSelect: selectNote
|
|
339
423
|
}
|
|
340
|
-
) : /* @__PURE__ */
|
|
341
|
-
] });
|
|
342
|
-
}
|
|
343
|
-
function FilterList(props) {
|
|
344
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section", children: [
|
|
345
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
346
|
-
/* @__PURE__ */ jsx("div", { class: "garden-explorer__chips", children: props.items.slice(0, 28).map((item) => /* @__PURE__ */ jsxs(
|
|
347
|
-
"button",
|
|
348
|
-
{
|
|
349
|
-
type: "button",
|
|
350
|
-
class: "garden-explorer__chip",
|
|
351
|
-
"aria-pressed": props.selectedKey === item.key,
|
|
352
|
-
onClick: () => props.onSelect(item.key),
|
|
353
|
-
children: [
|
|
354
|
-
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
355
|
-
/* @__PURE__ */ jsx("span", { children: item.count })
|
|
356
|
-
]
|
|
357
|
-
},
|
|
358
|
-
item.key
|
|
359
|
-
)) })
|
|
360
|
-
] });
|
|
361
|
-
}
|
|
362
|
-
function NoteList(props) {
|
|
363
|
-
return /* @__PURE__ */ jsx("ul", { class: "garden-explorer__note-list", children: props.notes.map((note) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
364
|
-
"button",
|
|
365
|
-
{
|
|
366
|
-
type: "button",
|
|
367
|
-
"aria-pressed": props.selectedSlug === note.slug,
|
|
368
|
-
onClick: () => props.onSelect(note.slug),
|
|
369
|
-
children: [
|
|
370
|
-
/* @__PURE__ */ jsx("span", { children: note.title }),
|
|
371
|
-
/* @__PURE__ */ jsx("small", { children: note.folder })
|
|
372
|
-
]
|
|
373
|
-
}
|
|
374
|
-
) }, note.slug)) });
|
|
375
|
-
}
|
|
376
|
-
function NoteDetails(props) {
|
|
377
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__details", children: [
|
|
378
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Selected Note" }),
|
|
379
|
-
/* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsx("a", { href: props.note.permalink, children: props.note.title }) }),
|
|
380
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__path", children: props.note.slug }),
|
|
381
|
-
props.note.excerpt && /* @__PURE__ */ jsx("p", { children: props.note.excerpt }),
|
|
382
|
-
/* @__PURE__ */ jsx("div", { class: "garden-explorer__tag-row", children: props.note.tags.map((tag) => /* @__PURE__ */ jsxs("span", { children: [
|
|
383
|
-
"#",
|
|
384
|
-
tag
|
|
385
|
-
] }, tag)) }),
|
|
386
|
-
/* @__PURE__ */ jsx(
|
|
387
|
-
LinkedNoteSection,
|
|
388
|
-
{
|
|
389
|
-
title: "Outgoing Links",
|
|
390
|
-
slugs: props.note.outgoing,
|
|
391
|
-
noteBySlug: props.noteBySlug,
|
|
392
|
-
onSelect: props.onSelect
|
|
393
|
-
}
|
|
394
|
-
),
|
|
395
|
-
/* @__PURE__ */ jsx(
|
|
396
|
-
LinkedNoteSection,
|
|
397
|
-
{
|
|
398
|
-
title: "Backlinks",
|
|
399
|
-
slugs: props.note.backlinks,
|
|
400
|
-
noteBySlug: props.noteBySlug,
|
|
401
|
-
onSelect: props.onSelect
|
|
402
|
-
}
|
|
403
|
-
),
|
|
404
|
-
/* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
405
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Related Notes" }),
|
|
406
|
-
/* @__PURE__ */ jsx(
|
|
407
|
-
NoteList,
|
|
408
|
-
{
|
|
409
|
-
notes: props.relatedNotes,
|
|
410
|
-
selectedSlug: props.note.slug,
|
|
411
|
-
onSelect: props.onSelect
|
|
412
|
-
}
|
|
413
|
-
)
|
|
414
|
-
] })
|
|
415
|
-
] });
|
|
416
|
-
}
|
|
417
|
-
function LinkedNoteSection(props) {
|
|
418
|
-
const notes = props.slugs.map((slug) => props.noteBySlug.get(slug)).filter((note) => note !== void 0);
|
|
419
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
420
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
421
|
-
notes.length > 0 ? /* @__PURE__ */ jsx(NoteList, { notes, selectedSlug: "", onSelect: props.onSelect }) : /* @__PURE__ */ jsx("p", { class: "garden-explorer__empty", children: "No notes." })
|
|
424
|
+
) : /* @__PURE__ */ jsx2("p", { class: "garden-explorer__empty", children: "Select a note to inspect links." }) })
|
|
422
425
|
] });
|
|
423
426
|
}
|
|
424
427
|
function layoutNodes(notes, selectedSlug) {
|
package/dist/index.js
CHANGED
|
@@ -73,8 +73,92 @@ function scoreFuzzyMatch(value, query) {
|
|
|
73
73
|
return Math.max(0, coverage * (1 - continuityPenalty));
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// components/
|
|
76
|
+
// components/explorer-panels.tsx
|
|
77
77
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
78
|
+
function FilterList(props) {
|
|
79
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section", children: [
|
|
80
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
81
|
+
/* @__PURE__ */ jsx("div", { class: "garden-explorer__chips", children: props.items.slice(0, 28).map((item) => /* @__PURE__ */ jsxs(
|
|
82
|
+
"button",
|
|
83
|
+
{
|
|
84
|
+
type: "button",
|
|
85
|
+
class: "garden-explorer__chip",
|
|
86
|
+
"aria-pressed": props.selectedKey === item.key,
|
|
87
|
+
onClick: () => props.onSelect(item.key),
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
90
|
+
/* @__PURE__ */ jsx("span", { children: item.count })
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
item.key
|
|
94
|
+
)) })
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
function NoteList(props) {
|
|
98
|
+
return /* @__PURE__ */ jsx("ul", { class: "garden-explorer__note-list", children: props.notes.map((note) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
99
|
+
"button",
|
|
100
|
+
{
|
|
101
|
+
type: "button",
|
|
102
|
+
"aria-pressed": props.selectedSlug === note.slug,
|
|
103
|
+
onClick: () => props.onSelect(note.slug),
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ jsx("span", { children: note.title }),
|
|
106
|
+
/* @__PURE__ */ jsx("small", { children: note.folder })
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
) }, note.slug)) });
|
|
110
|
+
}
|
|
111
|
+
function NoteDetails(props) {
|
|
112
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__details", children: [
|
|
113
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Selected Note" }),
|
|
114
|
+
/* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsx("a", { href: props.note.permalink, children: props.note.title }) }),
|
|
115
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__path", children: props.note.slug }),
|
|
116
|
+
props.note.excerpt && /* @__PURE__ */ jsx("p", { children: props.note.excerpt }),
|
|
117
|
+
/* @__PURE__ */ jsx("div", { class: "garden-explorer__tag-row", children: props.note.tags.map((tag) => /* @__PURE__ */ jsxs("span", { children: [
|
|
118
|
+
"#",
|
|
119
|
+
tag
|
|
120
|
+
] }, tag)) }),
|
|
121
|
+
/* @__PURE__ */ jsx(
|
|
122
|
+
LinkedNoteSection,
|
|
123
|
+
{
|
|
124
|
+
title: "Outgoing Links",
|
|
125
|
+
slugs: props.note.outgoing,
|
|
126
|
+
noteBySlug: props.noteBySlug,
|
|
127
|
+
onSelect: props.onSelect
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
LinkedNoteSection,
|
|
132
|
+
{
|
|
133
|
+
title: "Backlinks",
|
|
134
|
+
slugs: props.note.backlinks,
|
|
135
|
+
noteBySlug: props.noteBySlug,
|
|
136
|
+
onSelect: props.onSelect
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
/* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
140
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Related Notes" }),
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
NoteList,
|
|
143
|
+
{
|
|
144
|
+
notes: props.relatedNotes,
|
|
145
|
+
selectedSlug: props.note.slug,
|
|
146
|
+
onSelect: props.onSelect
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
] })
|
|
150
|
+
] });
|
|
151
|
+
}
|
|
152
|
+
function LinkedNoteSection(props) {
|
|
153
|
+
const notes = props.slugs.map((slug) => props.noteBySlug.get(slug)).filter((note) => note !== void 0);
|
|
154
|
+
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
155
|
+
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
156
|
+
notes.length > 0 ? /* @__PURE__ */ jsx(NoteList, { notes, selectedSlug: "", onSelect: props.onSelect }) : /* @__PURE__ */ jsx("p", { class: "garden-explorer__empty", children: "No notes." })
|
|
157
|
+
] });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// components/garden-explorer.tsx
|
|
161
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
|
|
78
162
|
var GRAPH_WIDTH = 900;
|
|
79
163
|
var GRAPH_HEIGHT = 620;
|
|
80
164
|
var MIN_SCALE = 0.6;
|
|
@@ -152,10 +236,10 @@ function GardenExplorer(props) {
|
|
|
152
236
|
scale: clamp(current.scale + delta, MIN_SCALE, MAX_SCALE)
|
|
153
237
|
}));
|
|
154
238
|
};
|
|
155
|
-
return /* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
["graph", "explorer", "details"].map((panel) => /* @__PURE__ */
|
|
239
|
+
return /* @__PURE__ */ jsxs2("div", { class: "garden-explorer rr-garden-explorer", "data-garden-explorer": true, children: [
|
|
240
|
+
/* @__PURE__ */ jsxs2("fieldset", { class: "garden-explorer__mobile-tabs", children: [
|
|
241
|
+
/* @__PURE__ */ jsx2("legend", { class: "sr-only", children: "Explorer panels" }),
|
|
242
|
+
["graph", "explorer", "details"].map((panel) => /* @__PURE__ */ jsx2(
|
|
159
243
|
"button",
|
|
160
244
|
{
|
|
161
245
|
type: "button",
|
|
@@ -166,12 +250,12 @@ function GardenExplorer(props) {
|
|
|
166
250
|
}
|
|
167
251
|
))
|
|
168
252
|
] }),
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ jsxs2("aside", { class: panelClass("explorer", mobilePanel), children: [
|
|
254
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__section", children: [
|
|
255
|
+
/* @__PURE__ */ jsx2("p", { class: "garden-explorer__eyebrow", children: "Explorer" }),
|
|
256
|
+
/* @__PURE__ */ jsxs2("label", { class: "garden-explorer__search", children: [
|
|
257
|
+
/* @__PURE__ */ jsx2("span", { class: "sr-only", children: "Search notes" }),
|
|
258
|
+
/* @__PURE__ */ jsx2(
|
|
175
259
|
"input",
|
|
176
260
|
{
|
|
177
261
|
type: "search",
|
|
@@ -181,7 +265,7 @@ function GardenExplorer(props) {
|
|
|
181
265
|
}
|
|
182
266
|
)
|
|
183
267
|
] }),
|
|
184
|
-
/* @__PURE__ */
|
|
268
|
+
/* @__PURE__ */ jsx2(
|
|
185
269
|
"button",
|
|
186
270
|
{
|
|
187
271
|
type: "button",
|
|
@@ -191,7 +275,7 @@ function GardenExplorer(props) {
|
|
|
191
275
|
}
|
|
192
276
|
)
|
|
193
277
|
] }),
|
|
194
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ jsx2(
|
|
195
279
|
FilterList,
|
|
196
280
|
{
|
|
197
281
|
title: "Tags",
|
|
@@ -204,7 +288,7 @@ function GardenExplorer(props) {
|
|
|
204
288
|
onSelect: (key) => setSelectedTag(key === selectedTag ? null : key)
|
|
205
289
|
}
|
|
206
290
|
),
|
|
207
|
-
/* @__PURE__ */
|
|
291
|
+
/* @__PURE__ */ jsx2(
|
|
208
292
|
FilterList,
|
|
209
293
|
{
|
|
210
294
|
title: "Folders",
|
|
@@ -217,9 +301,9 @@ function GardenExplorer(props) {
|
|
|
217
301
|
onSelect: (key) => setSelectedFolder(key === selectedFolder ? null : key)
|
|
218
302
|
}
|
|
219
303
|
),
|
|
220
|
-
/* @__PURE__ */
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
/* @__PURE__ */
|
|
304
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__section", children: [
|
|
305
|
+
/* @__PURE__ */ jsx2("p", { class: "garden-explorer__eyebrow", children: "Notes" }),
|
|
306
|
+
/* @__PURE__ */ jsx2(
|
|
223
307
|
NoteList,
|
|
224
308
|
{
|
|
225
309
|
notes: filteredNotes,
|
|
@@ -229,14 +313,14 @@ function GardenExplorer(props) {
|
|
|
229
313
|
)
|
|
230
314
|
] })
|
|
231
315
|
] }),
|
|
232
|
-
/* @__PURE__ */
|
|
233
|
-
/* @__PURE__ */
|
|
234
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ jsxs2("section", { class: panelClass("graph", mobilePanel), "aria-label": "Note graph", children: [
|
|
317
|
+
/* @__PURE__ */ jsxs2("div", { class: "garden-explorer__graph-toolbar", children: [
|
|
318
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
235
319
|
filteredNotes.length,
|
|
236
320
|
" notes"
|
|
237
321
|
] }),
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
323
|
+
/* @__PURE__ */ jsx2(
|
|
240
324
|
"button",
|
|
241
325
|
{
|
|
242
326
|
type: "button",
|
|
@@ -245,7 +329,7 @@ function GardenExplorer(props) {
|
|
|
245
329
|
children: "−"
|
|
246
330
|
}
|
|
247
331
|
),
|
|
248
|
-
/* @__PURE__ */
|
|
332
|
+
/* @__PURE__ */ jsx2(
|
|
249
333
|
"button",
|
|
250
334
|
{
|
|
251
335
|
type: "button",
|
|
@@ -254,7 +338,7 @@ function GardenExplorer(props) {
|
|
|
254
338
|
children: "+"
|
|
255
339
|
}
|
|
256
340
|
),
|
|
257
|
-
/* @__PURE__ */
|
|
341
|
+
/* @__PURE__ */ jsx2(
|
|
258
342
|
"button",
|
|
259
343
|
{
|
|
260
344
|
type: "button",
|
|
@@ -264,7 +348,7 @@ function GardenExplorer(props) {
|
|
|
264
348
|
)
|
|
265
349
|
] })
|
|
266
350
|
] }),
|
|
267
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ jsx2(
|
|
268
352
|
"svg",
|
|
269
353
|
{
|
|
270
354
|
class: "garden-graph",
|
|
@@ -283,12 +367,12 @@ function GardenExplorer(props) {
|
|
|
283
367
|
y: current.y + event.movementY / current.scale
|
|
284
368
|
}));
|
|
285
369
|
},
|
|
286
|
-
children: /* @__PURE__ */
|
|
370
|
+
children: /* @__PURE__ */ jsxs2("g", { transform: `translate(${view.x} ${view.y}) scale(${view.scale})`, children: [
|
|
287
371
|
visibleEdges.map((edge) => {
|
|
288
372
|
const source = graphNodes.get(edge.source);
|
|
289
373
|
const target = graphNodes.get(edge.target);
|
|
290
374
|
if (!source || !target) return null;
|
|
291
|
-
return /* @__PURE__ */
|
|
375
|
+
return /* @__PURE__ */ jsx2(
|
|
292
376
|
"line",
|
|
293
377
|
{
|
|
294
378
|
class: "garden-graph__edge",
|
|
@@ -304,7 +388,7 @@ function GardenExplorer(props) {
|
|
|
304
388
|
const node = graphNodes.get(note.slug);
|
|
305
389
|
if (!node) return null;
|
|
306
390
|
const selected = note.slug === selectedSlug;
|
|
307
|
-
return /* @__PURE__ */
|
|
391
|
+
return /* @__PURE__ */ jsx2("g", { class: "garden-graph__node", children: /* @__PURE__ */ jsxs2(
|
|
308
392
|
"a",
|
|
309
393
|
{
|
|
310
394
|
href: `/explore?note=${encodeURIComponent(note.slug)}`,
|
|
@@ -314,7 +398,7 @@ function GardenExplorer(props) {
|
|
|
314
398
|
selectNote(note.slug);
|
|
315
399
|
},
|
|
316
400
|
children: [
|
|
317
|
-
/* @__PURE__ */
|
|
401
|
+
/* @__PURE__ */ jsx2(
|
|
318
402
|
"circle",
|
|
319
403
|
{
|
|
320
404
|
cx: node.x,
|
|
@@ -323,7 +407,7 @@ function GardenExplorer(props) {
|
|
|
323
407
|
"data-selected": selected ? "true" : "false"
|
|
324
408
|
}
|
|
325
409
|
),
|
|
326
|
-
/* @__PURE__ */
|
|
410
|
+
/* @__PURE__ */ jsx2("text", { x: node.x + 18, y: node.y + 5, children: note.title })
|
|
327
411
|
]
|
|
328
412
|
}
|
|
329
413
|
) }, note.slug);
|
|
@@ -332,7 +416,7 @@ function GardenExplorer(props) {
|
|
|
332
416
|
}
|
|
333
417
|
)
|
|
334
418
|
] }),
|
|
335
|
-
/* @__PURE__ */
|
|
419
|
+
/* @__PURE__ */ jsx2("aside", { class: panelClass("details", mobilePanel), children: selectedNote ? /* @__PURE__ */ jsx2(
|
|
336
420
|
NoteDetails,
|
|
337
421
|
{
|
|
338
422
|
note: selectedNote,
|
|
@@ -340,88 +424,7 @@ function GardenExplorer(props) {
|
|
|
340
424
|
relatedNotes,
|
|
341
425
|
onSelect: selectNote
|
|
342
426
|
}
|
|
343
|
-
) : /* @__PURE__ */
|
|
344
|
-
] });
|
|
345
|
-
}
|
|
346
|
-
function FilterList(props) {
|
|
347
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section", children: [
|
|
348
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
349
|
-
/* @__PURE__ */ jsx("div", { class: "garden-explorer__chips", children: props.items.slice(0, 28).map((item) => /* @__PURE__ */ jsxs(
|
|
350
|
-
"button",
|
|
351
|
-
{
|
|
352
|
-
type: "button",
|
|
353
|
-
class: "garden-explorer__chip",
|
|
354
|
-
"aria-pressed": props.selectedKey === item.key,
|
|
355
|
-
onClick: () => props.onSelect(item.key),
|
|
356
|
-
children: [
|
|
357
|
-
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
358
|
-
/* @__PURE__ */ jsx("span", { children: item.count })
|
|
359
|
-
]
|
|
360
|
-
},
|
|
361
|
-
item.key
|
|
362
|
-
)) })
|
|
363
|
-
] });
|
|
364
|
-
}
|
|
365
|
-
function NoteList(props) {
|
|
366
|
-
return /* @__PURE__ */ jsx("ul", { class: "garden-explorer__note-list", children: props.notes.map((note) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
367
|
-
"button",
|
|
368
|
-
{
|
|
369
|
-
type: "button",
|
|
370
|
-
"aria-pressed": props.selectedSlug === note.slug,
|
|
371
|
-
onClick: () => props.onSelect(note.slug),
|
|
372
|
-
children: [
|
|
373
|
-
/* @__PURE__ */ jsx("span", { children: note.title }),
|
|
374
|
-
/* @__PURE__ */ jsx("small", { children: note.folder })
|
|
375
|
-
]
|
|
376
|
-
}
|
|
377
|
-
) }, note.slug)) });
|
|
378
|
-
}
|
|
379
|
-
function NoteDetails(props) {
|
|
380
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__details", children: [
|
|
381
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Selected Note" }),
|
|
382
|
-
/* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsx("a", { href: props.note.permalink, children: props.note.title }) }),
|
|
383
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__path", children: props.note.slug }),
|
|
384
|
-
props.note.excerpt && /* @__PURE__ */ jsx("p", { children: props.note.excerpt }),
|
|
385
|
-
/* @__PURE__ */ jsx("div", { class: "garden-explorer__tag-row", children: props.note.tags.map((tag) => /* @__PURE__ */ jsxs("span", { children: [
|
|
386
|
-
"#",
|
|
387
|
-
tag
|
|
388
|
-
] }, tag)) }),
|
|
389
|
-
/* @__PURE__ */ jsx(
|
|
390
|
-
LinkedNoteSection,
|
|
391
|
-
{
|
|
392
|
-
title: "Outgoing Links",
|
|
393
|
-
slugs: props.note.outgoing,
|
|
394
|
-
noteBySlug: props.noteBySlug,
|
|
395
|
-
onSelect: props.onSelect
|
|
396
|
-
}
|
|
397
|
-
),
|
|
398
|
-
/* @__PURE__ */ jsx(
|
|
399
|
-
LinkedNoteSection,
|
|
400
|
-
{
|
|
401
|
-
title: "Backlinks",
|
|
402
|
-
slugs: props.note.backlinks,
|
|
403
|
-
noteBySlug: props.noteBySlug,
|
|
404
|
-
onSelect: props.onSelect
|
|
405
|
-
}
|
|
406
|
-
),
|
|
407
|
-
/* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
408
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: "Related Notes" }),
|
|
409
|
-
/* @__PURE__ */ jsx(
|
|
410
|
-
NoteList,
|
|
411
|
-
{
|
|
412
|
-
notes: props.relatedNotes,
|
|
413
|
-
selectedSlug: props.note.slug,
|
|
414
|
-
onSelect: props.onSelect
|
|
415
|
-
}
|
|
416
|
-
)
|
|
417
|
-
] })
|
|
418
|
-
] });
|
|
419
|
-
}
|
|
420
|
-
function LinkedNoteSection(props) {
|
|
421
|
-
const notes = props.slugs.map((slug) => props.noteBySlug.get(slug)).filter((note) => note !== void 0);
|
|
422
|
-
return /* @__PURE__ */ jsxs("div", { class: "garden-explorer__section garden-explorer__section--flush", children: [
|
|
423
|
-
/* @__PURE__ */ jsx("p", { class: "garden-explorer__eyebrow", children: props.title }),
|
|
424
|
-
notes.length > 0 ? /* @__PURE__ */ jsx(NoteList, { notes, selectedSlug: "", onSelect: props.onSelect }) : /* @__PURE__ */ jsx("p", { class: "garden-explorer__empty", children: "No notes." })
|
|
427
|
+
) : /* @__PURE__ */ jsx2("p", { class: "garden-explorer__empty", children: "Select a note to inspect links." }) })
|
|
425
428
|
] });
|
|
426
429
|
}
|
|
427
430
|
function layoutNodes(notes, selectedSlug) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/plugin-garden-explorer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"hono": "^4.12.25",
|
|
25
|
-
"@riebeckite/core": "0.0.
|
|
25
|
+
"@riebeckite/core": "0.0.9"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|