duckfn-docs-kit 0.3.0 → 0.4.1
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/AGENTS.md +326 -234
- package/README.md +10 -6
- package/dist/IconButton.d.ts +22 -0
- package/dist/codemirror.d.ts +29 -0
- package/dist/download.d.ts +51 -0
- package/dist/index.d.ts +28 -7
- package/dist/index.js +2 -2
- package/dist/mermaid/DfkMermaid.d.ts +25 -0
- package/dist/mermaid/config.d.ts +48 -0
- package/dist/mermaid/remark.d.ts +40 -0
- package/dist/mermaid/remark.js +32 -0
- package/dist/mermaid/render.d.ts +92 -0
- package/dist/mermaid/styles.d.ts +6 -0
- package/dist/panzoom-view.d.ts +17 -0
- package/dist/{register-CALCwFBv.js → register-wdwf0LC4.js} +1365 -738
- package/dist/remark.d.ts +1 -1
- package/dist/source-dialog.d.ts +35 -0
- package/dist/sql/PreviewTabs.d.ts +39 -23
- package/dist/sql/SvgViewer.d.ts +53 -0
- package/dist/sql/client.js +1 -1
- package/dist/sql/harness.js +1 -1
- package/dist/sql/remark.d.ts +6 -1
- package/dist/sql/renderers.d.ts +9 -0
- package/package.json +6 -2
- package/src/IconButton.ts +50 -0
- package/src/codemirror.ts +97 -0
- package/src/download.ts +169 -0
- package/src/index.ts +31 -7
- package/src/mermaid/DfkMermaid.css +326 -0
- package/src/mermaid/DfkMermaid.ts +411 -0
- package/src/mermaid/config.ts +74 -0
- package/src/mermaid/remark.ts +98 -0
- package/src/mermaid/render.ts +172 -0
- package/src/mermaid/styles.ts +24 -0
- package/src/panzoom-view.ts +235 -0
- package/src/register.ts +3 -0
- package/src/remark.ts +1 -1
- package/src/source-dialog.ts +126 -0
- package/src/sql/DfkSql.css +13 -10
- package/src/sql/DfkSql.ts +60 -51
- package/src/sql/PreviewTabs.ts +98 -52
- package/src/sql/SvgViewer.ts +155 -0
- package/src/sql/remark.ts +6 -1
- package/src/sql/renderers.ts +433 -159
- package/src/sql/sql.css +189 -19
- package/dist/sql/editor.d.ts +0 -16
- package/src/sql/editor.ts +0 -75
package/src/sql/sql.css
CHANGED
|
@@ -191,12 +191,13 @@ dfk-sql:not(:defined) {
|
|
|
191
191
|
|
|
192
192
|
/* --- Result tabs --------------------------------------------------------- */
|
|
193
193
|
|
|
194
|
-
/* The strip is a row holding the scrolling tab list and
|
|
195
|
-
|
|
194
|
+
/* The strip is a row holding the scrolling tab list and, at its right end, the
|
|
195
|
+
chrome that acts on the result as a whole: `[the active tab's own controls]
|
|
196
|
+
[download] [fullscreen]`. The corner never scrolls with the list and never
|
|
197
|
+
shrinks, so those buttons stay put however many tabs there are. */
|
|
196
198
|
.dfk-sql-tabs {
|
|
197
199
|
display: flex;
|
|
198
200
|
align-items: center;
|
|
199
|
-
padding-right: 0.3rem;
|
|
200
201
|
border-bottom: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
201
202
|
background: var(--ifm-color-emphasis-100, #f5f5f5);
|
|
202
203
|
}
|
|
@@ -210,6 +211,63 @@ dfk-sql:not(:defined) {
|
|
|
210
211
|
overflow-x: auto;
|
|
211
212
|
}
|
|
212
213
|
|
|
214
|
+
.dfk-sql-tab-corner {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-shrink: 0;
|
|
217
|
+
align-items: center;
|
|
218
|
+
gap: 0.15rem;
|
|
219
|
+
padding-right: 0.3rem;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* One tab's own controls — a table's search and view switches, a figure's zoom
|
|
223
|
+
and edit buttons. Written by the renderers (and by an embedded
|
|
224
|
+
`<dfk-mermaid>`); only the active tab's container is shown. */
|
|
225
|
+
.dfk-sql-tab-actions {
|
|
226
|
+
display: flex;
|
|
227
|
+
align-items: center;
|
|
228
|
+
gap: 0.15rem;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.dfk-sql-tab-actions[hidden] {
|
|
232
|
+
display: none;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* The search box opens in place rather than as a popover over the canvas: the
|
|
236
|
+
table is as wide as the page, and a popover would cover the cells the reader
|
|
237
|
+
is searching. */
|
|
238
|
+
.dfk-sql-search-input {
|
|
239
|
+
width: 9rem;
|
|
240
|
+
padding: 0.1rem 0.4rem;
|
|
241
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
242
|
+
border-radius: var(--ifm-global-radius, 0.25rem);
|
|
243
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
244
|
+
color: var(--ifm-font-color-base, #181818);
|
|
245
|
+
font-family: inherit;
|
|
246
|
+
font-size: 0.75rem;
|
|
247
|
+
line-height: 1.5;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.dfk-sql-search-input:focus-visible {
|
|
251
|
+
outline: 2px solid var(--ifm-color-primary, #14459b);
|
|
252
|
+
outline-offset: -1px;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.dfk-sql-search-input[hidden] {
|
|
256
|
+
display: none;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.dfk-sql-search-count {
|
|
260
|
+
min-width: 2.2rem;
|
|
261
|
+
color: var(--ifm-color-emphasis-700, #666);
|
|
262
|
+
font-size: 0.7rem;
|
|
263
|
+
font-variant-numeric: tabular-nums;
|
|
264
|
+
text-align: center;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.dfk-sql-search-count[hidden] {
|
|
268
|
+
display: none;
|
|
269
|
+
}
|
|
270
|
+
|
|
213
271
|
.dfk-sql-tab {
|
|
214
272
|
padding: 0.15rem 0.65rem;
|
|
215
273
|
border: 1px solid transparent;
|
|
@@ -237,11 +295,13 @@ dfk-sql:not(:defined) {
|
|
|
237
295
|
|
|
238
296
|
/* --- Icon buttons and their tooltips ------------------------------------- */
|
|
239
297
|
|
|
240
|
-
/* The
|
|
241
|
-
`
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
298
|
+
/* The class names are written by the shared `IconButton` widget
|
|
299
|
+
(`src/IconButton.ts`). The same rules (and the `[data-tip]` tooltip below) are
|
|
300
|
+
declared in `DfkSql.css` and `DfkMermaid.css`, because the buttons are split
|
|
301
|
+
across shadow boundaries: the code-block actions live in `<dfk-sql>`'s tree,
|
|
302
|
+
a diagram's cluster in `<dfk-mermaid>`'s, and the fullscreen toggle in this
|
|
303
|
+
light-DOM tab strip. Keep the copies in sync. */
|
|
304
|
+
.dfk-icon-button {
|
|
245
305
|
position: relative;
|
|
246
306
|
display: inline-flex;
|
|
247
307
|
align-items: center;
|
|
@@ -257,27 +317,27 @@ dfk-sql:not(:defined) {
|
|
|
257
317
|
transition: background 0.12s ease, color 0.12s ease;
|
|
258
318
|
}
|
|
259
319
|
|
|
260
|
-
.dfk-
|
|
261
|
-
.dfk-
|
|
320
|
+
.dfk-icon-button:hover:not(:disabled),
|
|
321
|
+
.dfk-icon-button:focus-visible {
|
|
262
322
|
background: var(--ifm-color-emphasis-200, #e6e6e6);
|
|
263
323
|
color: var(--ifm-color-primary, #14459b);
|
|
264
324
|
}
|
|
265
325
|
|
|
266
|
-
.dfk-
|
|
326
|
+
.dfk-icon-button:disabled {
|
|
267
327
|
opacity: 0.45;
|
|
268
328
|
cursor: progress;
|
|
269
329
|
}
|
|
270
330
|
|
|
271
|
-
.dfk-
|
|
331
|
+
.dfk-icon-button[hidden] {
|
|
272
332
|
display: none;
|
|
273
333
|
}
|
|
274
334
|
|
|
275
335
|
/* A sticky state, e.g. the wrap toggle while wrapping is on. */
|
|
276
|
-
.dfk-
|
|
336
|
+
.dfk-icon-on {
|
|
277
337
|
color: var(--ifm-color-primary, #14459b);
|
|
278
338
|
}
|
|
279
339
|
|
|
280
|
-
.dfk-
|
|
340
|
+
.dfk-icon {
|
|
281
341
|
font-size: 1rem;
|
|
282
342
|
}
|
|
283
343
|
|
|
@@ -315,11 +375,16 @@ dfk-sql:not(:defined) {
|
|
|
315
375
|
bottom of the table from continuing into the page scroll (the page lurches
|
|
316
376
|
upward and the example leaves the screen). It is not inherited, so it is
|
|
317
377
|
declared on every scrolling box, including VTable's inner scroll containers
|
|
318
|
-
under `.dfk-sql-table`.
|
|
319
|
-
|
|
378
|
+
under `.dfk-sql-table`.
|
|
379
|
+
The panel is contained **only while the result is expanded**: `contain` applies
|
|
380
|
+
to any box with a non-visible `overflow`, and a panel is a scroll container
|
|
381
|
+
whether or not it has anything to scroll — so, inline, it would swallow the
|
|
382
|
+
wheel that should have gone to the page (a figure is a picture there, not a
|
|
383
|
+
viewport: see `DfkMermaid.css`). Expanded, the panel really does scroll, and
|
|
384
|
+
without this the wheel would move the page *behind* the overlay instead. */
|
|
320
385
|
.dfk-sql-table,
|
|
321
386
|
.dfk-sql-table *,
|
|
322
|
-
.dfk-sql-
|
|
387
|
+
.dfk-sql-result-expanded .dfk-sql-panel {
|
|
323
388
|
overscroll-behavior: contain;
|
|
324
389
|
}
|
|
325
390
|
|
|
@@ -345,18 +410,37 @@ dfk-sql:not(:defined) {
|
|
|
345
410
|
background: #fff;
|
|
346
411
|
}
|
|
347
412
|
|
|
413
|
+
/* The `svg` result is a pan/zoom viewport (the shared `PanZoomView`), with the
|
|
414
|
+
SVG in its content box. It draws no frame: the result panel is the frame, and
|
|
415
|
+
stacking a second one behind the tab strip is what made a two-box look. The
|
|
416
|
+
`overflow: hidden` clips a zoomed figure instead of letting it spill over the
|
|
417
|
+
page, and is also what panzoom expects of a pan element's parent. */
|
|
348
418
|
.dfk-sql-svg {
|
|
349
419
|
width: var(--dfk-sql-preview-width, 100%);
|
|
350
420
|
height: var(--dfk-sql-preview-height, auto);
|
|
351
421
|
padding: 0.5rem;
|
|
352
|
-
overflow:
|
|
422
|
+
overflow: hidden;
|
|
353
423
|
}
|
|
354
424
|
|
|
355
|
-
.dfk-sql-svg > svg {
|
|
425
|
+
.dfk-sql-svg-content > svg {
|
|
426
|
+
display: block;
|
|
427
|
+
margin: 0 auto;
|
|
356
428
|
max-width: 100%;
|
|
357
429
|
height: auto;
|
|
358
430
|
}
|
|
359
431
|
|
|
432
|
+
/* The cursor says what a drag will actually do, so it follows the zoom state
|
|
433
|
+
rather than being set once (`PanZoomView` writes the two state classes).
|
|
434
|
+
`cursor` is inherited, so it reaches the figure and every label in it. The
|
|
435
|
+
same two rules live in `DfkMermaid.css`. */
|
|
436
|
+
.dfk-sql-svg.dfk-panzoom-zoomed {
|
|
437
|
+
cursor: grab;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.dfk-sql-svg.dfk-panzoom-zoomed.dfk-panzoom-grabbing {
|
|
441
|
+
cursor: grabbing;
|
|
442
|
+
}
|
|
443
|
+
|
|
360
444
|
/* --- Fullscreen ---------------------------------------------------------- */
|
|
361
445
|
|
|
362
446
|
/* Also carries `.dfk-sql-result`, so `overflow` and the radius are re-declared
|
|
@@ -394,4 +478,90 @@ dfk-sql:not(:defined) {
|
|
|
394
478
|
panel is one full-height scroll area rather than a strip. */
|
|
395
479
|
.dfk-sql-result-expanded .dfk-sql-svg {
|
|
396
480
|
height: 100%;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/* --- Source dialog ------------------------------------------------------- */
|
|
484
|
+
|
|
485
|
+
/* The `svg` viewer's source editor (`SourceDialog`). The dialog itself is
|
|
486
|
+
modal — it renders in the top layer, so its position needs no help — but the
|
|
487
|
+
class names are written by the shared widget, which `<dfk-mermaid>` uses
|
|
488
|
+
inside its shadow root; these rules are that sheet's `.dfk-source-dialog*`
|
|
489
|
+
block, in the light DOM, and the two are kept in sync by hand. */
|
|
490
|
+
.dfk-source-dialog {
|
|
491
|
+
width: min(56rem, 92vw);
|
|
492
|
+
max-width: none;
|
|
493
|
+
padding: 0;
|
|
494
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
495
|
+
border-radius: var(--ifm-global-radius, 0.4rem);
|
|
496
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
497
|
+
color: var(--ifm-font-color-base, #181818);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.dfk-source-dialog::backdrop {
|
|
501
|
+
background: rgb(0 0 0 / 45%);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.dfk-source-dialog-body {
|
|
505
|
+
display: flex;
|
|
506
|
+
flex-direction: column;
|
|
507
|
+
gap: 0.5rem;
|
|
508
|
+
padding: 0.75rem;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.dfk-source-dialog-title {
|
|
512
|
+
margin: 0;
|
|
513
|
+
font-size: 0.95rem;
|
|
514
|
+
font-weight: 600;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.dfk-source-dialog-editor {
|
|
518
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
519
|
+
border-radius: var(--ifm-global-radius, 0.4rem);
|
|
520
|
+
overflow: hidden;
|
|
521
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
522
|
+
font-size: var(--ifm-code-font-size, 95%);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.dfk-source-dialog-editor .cm-editor {
|
|
526
|
+
outline: none;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.dfk-source-dialog-editor .cm-scroller {
|
|
530
|
+
max-height: 55vh;
|
|
531
|
+
font-family: var(--ifm-font-family-monospace, ui-monospace, SFMono-Regular,
|
|
532
|
+
Menlo, monospace);
|
|
533
|
+
line-height: 1.6;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.dfk-source-dialog-footer {
|
|
537
|
+
display: flex;
|
|
538
|
+
justify-content: flex-end;
|
|
539
|
+
gap: 0.5rem;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.dfk-source-dialog-button {
|
|
543
|
+
padding: 0.3rem 0.9rem;
|
|
544
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
545
|
+
border-radius: var(--ifm-global-radius, 0.25rem);
|
|
546
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
547
|
+
color: var(--ifm-font-color-base, #181818);
|
|
548
|
+
font-family: inherit;
|
|
549
|
+
font-size: 0.85rem;
|
|
550
|
+
cursor: pointer;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.dfk-source-dialog-button:hover {
|
|
554
|
+
border-color: var(--ifm-color-primary, #14459b);
|
|
555
|
+
color: var(--ifm-color-primary, #14459b);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.dfk-source-dialog-apply {
|
|
559
|
+
border-color: var(--ifm-color-primary, #14459b);
|
|
560
|
+
background: var(--ifm-color-primary, #14459b);
|
|
561
|
+
color: var(--ifm-button-color, #fff);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.dfk-source-dialog-apply:hover {
|
|
565
|
+
color: var(--ifm-button-color, #fff);
|
|
566
|
+
filter: brightness(1.1);
|
|
397
567
|
}
|
package/dist/sql/editor.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The CodeMirror 6 editor that *is* the code view of a runnable SQL block.
|
|
3
|
-
*
|
|
4
|
-
* Every CodeMirror module arrives through dynamic `import()` inside
|
|
5
|
-
* {@link mountSqlEditor}: a page full of SQL examples pays nothing for the
|
|
6
|
-
* editor on its critical path, and Docusaurus' Node prerender never evaluates
|
|
7
|
-
* any of it.
|
|
8
|
-
*/
|
|
9
|
-
export interface SqlEditor {
|
|
10
|
-
getValue(): string;
|
|
11
|
-
setValue(value: string): void;
|
|
12
|
-
/** Soft-wraps long lines, or stops wrapping them (the block's wrap toggle). */
|
|
13
|
-
setWrap(wrapped: boolean): void;
|
|
14
|
-
destroy(): void;
|
|
15
|
-
}
|
|
16
|
-
export declare function mountSqlEditor(container: HTMLElement, value: string, onChange: (value: string) => void): Promise<SqlEditor>;
|
package/src/sql/editor.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The CodeMirror 6 editor that *is* the code view of a runnable SQL block.
|
|
3
|
-
*
|
|
4
|
-
* Every CodeMirror module arrives through dynamic `import()` inside
|
|
5
|
-
* {@link mountSqlEditor}: a page full of SQL examples pays nothing for the
|
|
6
|
-
* editor on its critical path, and Docusaurus' Node prerender never evaluates
|
|
7
|
-
* any of it.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export interface SqlEditor {
|
|
11
|
-
getValue(): string;
|
|
12
|
-
setValue(value: string): void;
|
|
13
|
-
/** Soft-wraps long lines, or stops wrapping them (the block's wrap toggle). */
|
|
14
|
-
setWrap(wrapped: boolean): void;
|
|
15
|
-
destroy(): void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export async function mountSqlEditor(
|
|
19
|
-
container: HTMLElement,
|
|
20
|
-
value: string,
|
|
21
|
-
onChange: (value: string) => void,
|
|
22
|
-
): Promise<SqlEditor> {
|
|
23
|
-
const [
|
|
24
|
-
{basicSetup},
|
|
25
|
-
{sql},
|
|
26
|
-
{EditorView, keymap},
|
|
27
|
-
{defaultKeymap, historyKeymap},
|
|
28
|
-
{Compartment},
|
|
29
|
-
] = await Promise.all([
|
|
30
|
-
import('codemirror'),
|
|
31
|
-
import('@codemirror/lang-sql'),
|
|
32
|
-
import('@codemirror/view'),
|
|
33
|
-
import('@codemirror/commands'),
|
|
34
|
-
import('@codemirror/state'),
|
|
35
|
-
]);
|
|
36
|
-
|
|
37
|
-
// Wrapping is toggled from the outside, and reconfiguring it must not disturb
|
|
38
|
-
// the document or the undo history — that is exactly what a compartment is
|
|
39
|
-
// for, so the extension is swapped in place rather than rebuilt.
|
|
40
|
-
const wrap = new Compartment();
|
|
41
|
-
|
|
42
|
-
const view = new EditorView({
|
|
43
|
-
doc: value,
|
|
44
|
-
extensions: [
|
|
45
|
-
basicSetup,
|
|
46
|
-
sql(),
|
|
47
|
-
keymap.of([...defaultKeymap, ...historyKeymap]),
|
|
48
|
-
wrap.of([]),
|
|
49
|
-
EditorView.updateListener.of((update) => {
|
|
50
|
-
if (update.docChanged) {
|
|
51
|
-
onChange(update.state.doc.toString());
|
|
52
|
-
}
|
|
53
|
-
}),
|
|
54
|
-
],
|
|
55
|
-
parent: container,
|
|
56
|
-
// `root` is left to CodeMirror's own `getRoot(container)`. The container sits
|
|
57
|
-
// in `<dfk-sql>`'s shadow root, so style-mod mounts the base theme into that
|
|
58
|
-
// same shadow root — exactly where the `.cm-*` rules are needed. Pinning it
|
|
59
|
-
// to `document` would put them outside the editor's tree instead, where a
|
|
60
|
-
// shadow boundary stops them.
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
getValue: () => view.state.doc.toString(),
|
|
65
|
-
setValue: (next: string) =>
|
|
66
|
-
view.dispatch({
|
|
67
|
-
changes: {from: 0, to: view.state.doc.length, insert: next},
|
|
68
|
-
}),
|
|
69
|
-
setWrap: (wrapped: boolean) =>
|
|
70
|
-
view.dispatch({
|
|
71
|
-
effects: wrap.reconfigure(wrapped ? EditorView.lineWrapping : []),
|
|
72
|
-
}),
|
|
73
|
-
destroy: () => view.destroy(),
|
|
74
|
-
};
|
|
75
|
-
}
|