duckfn-docs-kit 0.1.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/AGENTS.md +689 -0
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/dom.d.ts +69 -0
- package/dist/home/DfkFeatures.d.ts +20 -0
- package/dist/home/DfkHero.d.ts +25 -0
- package/dist/home/DfkNextSteps.d.ts +16 -0
- package/dist/home/styles.d.ts +8 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +2 -0
- package/dist/register-DKLiYs-F.js +2324 -0
- package/dist/register.d.ts +10 -0
- package/dist/remark.d.ts +21 -0
- package/dist/remark.js +15 -0
- package/dist/runtimeConfig-Bokbb8VH.js +106 -0
- package/dist/sql/DfkSql.d.ts +7 -0
- package/dist/sql/PreviewTabs.d.ts +37 -0
- package/dist/sql/client.d.ts +1 -0
- package/dist/sql/client.js +4 -0
- package/dist/sql/editor.d.ts +16 -0
- package/dist/sql/extensions.d.ts +108 -0
- package/dist/sql/extensions.js +198 -0
- package/dist/sql/remark.d.ts +88 -0
- package/dist/sql/remark.js +69 -0
- package/dist/sql/renderers.d.ts +44 -0
- package/dist/sql/runtime.d.ts +105 -0
- package/dist/sql/runtimeConfig.d.ts +80 -0
- package/dist/sql/styles.d.ts +6 -0
- package/dist/toc-toggle/TocToggle.d.ts +46 -0
- package/dist/toc-toggle/TocToggle.js +69 -0
- package/dist/toc-toggle/client.d.ts +1 -0
- package/dist/toc-toggle/client.js +9 -0
- package/dist/toc-toggle/plugin.d.ts +36 -0
- package/dist/toc-toggle/plugin.js +13 -0
- package/dist/types.d.ts +42 -0
- package/package.json +73 -0
- package/src/dom.ts +109 -0
- package/src/home/DfkFeatures.ts +78 -0
- package/src/home/DfkHero.ts +128 -0
- package/src/home/DfkNextSteps.ts +73 -0
- package/src/home/home.css +520 -0
- package/src/home/styles.ts +28 -0
- package/src/index.ts +59 -0
- package/src/kit.css +19 -0
- package/src/register.ts +39 -0
- package/src/remark.ts +60 -0
- package/src/sql/DfkSql.css +226 -0
- package/src/sql/DfkSql.ts +620 -0
- package/src/sql/PreviewTabs.ts +169 -0
- package/src/sql/client.ts +16 -0
- package/src/sql/editor.ts +75 -0
- package/src/sql/extensions.ts +470 -0
- package/src/sql/remark.ts +213 -0
- package/src/sql/renderers.ts +916 -0
- package/src/sql/runtime.ts +348 -0
- package/src/sql/runtimeConfig.ts +249 -0
- package/src/sql/sql.css +397 -0
- package/src/sql/styles.ts +24 -0
- package/src/theme/tokens.css +75 -0
- package/src/toc-toggle/TocToggle.css +69 -0
- package/src/toc-toggle/TocToggle.ts +172 -0
- package/src/toc-toggle/client.ts +20 -0
- package/src/toc-toggle/plugin.ts +54 -0
- package/src/types.ts +47 -0
- package/src/vite-env.d.ts +8 -0
package/src/sql/sql.css
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/* Light-DOM styles for `<dfk-sql>`: the result container. It lives in the
|
|
2
|
+
element's light DOM (not the shadow root) because VTable injects a
|
|
3
|
+
*document-level* stylesheet that a shadow boundary could not host — the same
|
|
4
|
+
light-DOM exception as the TOC toggle (see AGENTS.md rule 9). It is created
|
|
5
|
+
only when a query runs, so the light DOM still starts empty (rule 11). Every
|
|
6
|
+
class carries the `dfk-sql-` prefix so nothing can collide with the host site.
|
|
7
|
+
*
|
|
8
|
+
* The code area — the editor and the buttons floating over it — is in the shadow
|
|
9
|
+
* root instead, and is styled by `DfkSql.css`.
|
|
10
|
+
*
|
|
11
|
+
* Imported through `kit.css`; the consuming site gets it with the one-line
|
|
12
|
+
* `@import 'duckfn-docs-kit/src/kit.css'` it already has. */
|
|
13
|
+
|
|
14
|
+
/* The remark plugin prerenders two children: the loading ghost, and the original
|
|
15
|
+
code node (the class dates from when it was slotted as a read-only preview).
|
|
16
|
+
The code view is the CodeMirror editor now, so that copy must never show —
|
|
17
|
+
hiding it here rather than deleting it in JS also removes the flash between
|
|
18
|
+
parsing the prerendered HTML and the element upgrading.
|
|
19
|
+
The ghost is the one child that *does* show, and only while the element is
|
|
20
|
+
un-upgraded: once it upgrades it is unslotted like the rest and renders
|
|
21
|
+
nowhere, so no JS ever has to remove it. */
|
|
22
|
+
dfk-sql > :not([slot]):not(.dfk-sql-editor-skeleton) {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* --- Loading placeholders ------------------------------------------------- */
|
|
27
|
+
|
|
28
|
+
/* Two heavy libraries arrive through lazy `import()`s — CodeMirror for the
|
|
29
|
+
editor, VTable for a table result — and on a slow link both windows are long
|
|
30
|
+
enough to see. Each therefore gets a placeholder: one bar per line of SQL where
|
|
31
|
+
the editor goes, two rows where the table goes. Both are as tall as what
|
|
32
|
+
replaces them, so neither swap moves the page.
|
|
33
|
+
|
|
34
|
+
The editor ghost is drawn twice: here, for the window *before* the kit's JS has
|
|
35
|
+
defined `<dfk-sql>` at all (the bars are prerendered by `sql/remark.ts`), and
|
|
36
|
+
by `#setEditorPending` inside the shadow tree once it has. This file carries the
|
|
37
|
+
first copy and `DfkSql.css` the second — a shadow tree sees neither the
|
|
38
|
+
document's rules nor its `@keyframes` — so keep the bar and the timing of the
|
|
39
|
+
two in sync.
|
|
40
|
+
|
|
41
|
+
The line count is the SQL's *source* line count, which is a deliberate
|
|
42
|
+
approximation: a line long enough to wrap makes the editor taller than its
|
|
43
|
+
ghost, and knowing the wrapped height would mean laying the text out first —
|
|
44
|
+
measuring the site's fonts and column width — for a placeholder. */
|
|
45
|
+
@keyframes dfk-sql-shimmer {
|
|
46
|
+
from {
|
|
47
|
+
background-position: 0% 0;
|
|
48
|
+
}
|
|
49
|
+
to {
|
|
50
|
+
background-position: 100% 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Before the element upgrades it has no shadow tree, and its prerendered text is
|
|
55
|
+
hidden by the rule above, so without this the block would be an invisible hole
|
|
56
|
+
that pops in and pushes the rest of the page down. `:not(:defined)` paints the
|
|
57
|
+
box the editor will live in; the bars inside come from the plugin. It also
|
|
58
|
+
keeps standing in when no JS ever runs, which is the honest thing to show for a
|
|
59
|
+
block that needs it. */
|
|
60
|
+
dfk-sql:not(:defined) {
|
|
61
|
+
display: block;
|
|
62
|
+
margin: 1rem 0;
|
|
63
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
64
|
+
border-radius: var(--ifm-global-radius, 0.4rem);
|
|
65
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
66
|
+
/* The editor's own code font size, so a bar is as tall as a line of code. */
|
|
67
|
+
font-size: var(--ifm-code-font-size, 95%);
|
|
68
|
+
/* Floor of one line for a hand-written block, which carries no prerendered
|
|
69
|
+
ghost to be sized by. `border-box` (the sites' reset) counts the border. */
|
|
70
|
+
min-height: calc(1.6em + 10px);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* The bars themselves: `sql/remark.ts` emits this markup for the pre-upgrade
|
|
74
|
+
window, `#setEditorPending` builds the same nodes inside the shadow tree, and
|
|
75
|
+
`DfkSql.css` carries that second copy of these two rules. */
|
|
76
|
+
.dfk-sql-editor-skeleton {
|
|
77
|
+
/* CodeMirror's own content inset — `.cm-content` carries `padding: 4px 0` and
|
|
78
|
+
this box has none — on the container, so it is paid once, not per line. */
|
|
79
|
+
padding: 4px 0.75rem;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.dfk-sql-editor-skeleton-line {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
/* One code line box, exactly: `.cm-scroller`'s `line-height: 1.6`. The half
|
|
86
|
+
leading that centres a line's text is the flex centring here — margins would
|
|
87
|
+
collapse between neighbouring lines and stack the bars closer than the code
|
|
88
|
+
they stand in for. */
|
|
89
|
+
height: 1.6em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.dfk-sql-editor-skeleton-line::before {
|
|
93
|
+
content: '';
|
|
94
|
+
flex: 1;
|
|
95
|
+
height: 0.75em;
|
|
96
|
+
border-radius: 0.25em;
|
|
97
|
+
background-color: var(--ifm-color-emphasis-200, #e6e6e6);
|
|
98
|
+
/* Base colour plus a lighter band travelling through it; `background-size:
|
|
99
|
+
200%` is what gives `background-position` room to move (at 100% it cannot). */
|
|
100
|
+
background-image: linear-gradient(
|
|
101
|
+
90deg,
|
|
102
|
+
transparent 0%,
|
|
103
|
+
var(--ifm-color-emphasis-100, #f5f5f5) 50%,
|
|
104
|
+
transparent 100%
|
|
105
|
+
);
|
|
106
|
+
background-size: 200% 100%;
|
|
107
|
+
animation: dfk-sql-shimmer 1.6s linear infinite;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* `.dfk-sql-table` holds these while VTable's bundle is in flight; `mountTable`
|
|
111
|
+
drops them as soon as the canvas is in place — or hands the box to the error
|
|
112
|
+
view if the import failed. The box already has its final height (the renderer
|
|
113
|
+
derives `--dfk-sql-table-height` from the row count), so the rows only have to
|
|
114
|
+
read as "a table is coming"; the row rhythm comes from the renderer's
|
|
115
|
+
`ROW_HEIGHT`. Every row is built the same way, so the columns line up. */
|
|
116
|
+
.dfk-sql-table-skeleton {
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
/* Clipped to the box: a one-row result is shorter than two skeleton rows. */
|
|
120
|
+
height: 100%;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.dfk-sql-table-skeleton-row {
|
|
125
|
+
display: flex;
|
|
126
|
+
align-items: center;
|
|
127
|
+
gap: 1.5rem;
|
|
128
|
+
height: var(--dfk-sql-skeleton-row-height, 30px);
|
|
129
|
+
padding: 0 0.75rem;
|
|
130
|
+
border-bottom: 1px solid var(--ifm-color-emphasis-100, #f5f5f5);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.dfk-sql-table-skeleton-cell {
|
|
134
|
+
flex: 1;
|
|
135
|
+
height: 0.7em;
|
|
136
|
+
border-radius: 0.25em;
|
|
137
|
+
background-color: var(--ifm-color-emphasis-200, #e6e6e6);
|
|
138
|
+
background-image: linear-gradient(
|
|
139
|
+
90deg,
|
|
140
|
+
transparent 0%,
|
|
141
|
+
var(--ifm-color-emphasis-100, #f5f5f5) 50%,
|
|
142
|
+
transparent 100%
|
|
143
|
+
);
|
|
144
|
+
background-size: 200% 100%;
|
|
145
|
+
animation: dfk-sql-shimmer 1.6s linear infinite;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* A bar that sweeps forever is decoration; readers who asked for less motion get
|
|
149
|
+
the static grey. Mirrored in `DfkSql.css`. */
|
|
150
|
+
@media (prefers-reduced-motion: reduce) {
|
|
151
|
+
.dfk-sql-editor-skeleton-line,
|
|
152
|
+
.dfk-sql-table-skeleton-cell {
|
|
153
|
+
animation: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.dfk-sql-result {
|
|
158
|
+
border: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
159
|
+
border-top: none;
|
|
160
|
+
border-radius: 0 0 var(--ifm-global-radius, 0.4rem)
|
|
161
|
+
var(--ifm-global-radius, 0.4rem);
|
|
162
|
+
overflow: hidden;
|
|
163
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.dfk-sql-result:empty {
|
|
167
|
+
display: none;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.dfk-sql-text {
|
|
171
|
+
margin: 0;
|
|
172
|
+
padding: 0.5rem 0.75rem;
|
|
173
|
+
font-family: var(--ifm-font-family-monospace, ui-monospace, SFMono-Regular,
|
|
174
|
+
Menlo, monospace);
|
|
175
|
+
font-size: var(--ifm-code-font-size, 95%);
|
|
176
|
+
white-space: pre-wrap;
|
|
177
|
+
word-break: break-word;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.dfk-sql-error {
|
|
181
|
+
margin: 0;
|
|
182
|
+
padding: 0.5rem 0.75rem;
|
|
183
|
+
font-family: var(--ifm-font-family-monospace, ui-monospace, SFMono-Regular,
|
|
184
|
+
Menlo, monospace);
|
|
185
|
+
font-size: var(--ifm-code-font-size, 95%);
|
|
186
|
+
white-space: pre-wrap;
|
|
187
|
+
word-break: break-word;
|
|
188
|
+
color: var(--ifm-color-danger-contrast, #fff);
|
|
189
|
+
background: var(--ifm-color-danger, #d32f2f);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* --- Result tabs --------------------------------------------------------- */
|
|
193
|
+
|
|
194
|
+
/* The strip is a row holding the scrolling tab list and the corner button
|
|
195
|
+
(the fullscreen toggle, owned by `<dfk-sql>`). */
|
|
196
|
+
.dfk-sql-tabs {
|
|
197
|
+
display: flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
padding-right: 0.3rem;
|
|
200
|
+
border-bottom: 1px solid var(--ifm-global-border-color, #e0e0e0);
|
|
201
|
+
background: var(--ifm-color-emphasis-100, #f5f5f5);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.dfk-sql-tab-list {
|
|
205
|
+
display: flex;
|
|
206
|
+
flex: 1;
|
|
207
|
+
gap: 0.25rem;
|
|
208
|
+
min-width: 0;
|
|
209
|
+
padding: 0.3rem 0.5rem 0;
|
|
210
|
+
overflow-x: auto;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.dfk-sql-tab {
|
|
214
|
+
padding: 0.15rem 0.65rem;
|
|
215
|
+
border: 1px solid transparent;
|
|
216
|
+
border-bottom: none;
|
|
217
|
+
border-radius: var(--ifm-global-radius, 0.4rem)
|
|
218
|
+
var(--ifm-global-radius, 0.4rem) 0 0;
|
|
219
|
+
background: transparent;
|
|
220
|
+
color: var(--ifm-color-emphasis-700, #666);
|
|
221
|
+
font-family: inherit;
|
|
222
|
+
font-size: 0.8rem;
|
|
223
|
+
line-height: 1.5;
|
|
224
|
+
white-space: nowrap;
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.dfk-sql-tab:hover {
|
|
229
|
+
color: var(--ifm-color-primary, #14459b);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.dfk-sql-tab-active {
|
|
233
|
+
border-color: var(--ifm-global-border-color, #e0e0e0);
|
|
234
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
235
|
+
color: var(--ifm-font-color-base, #181818);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* --- Icon buttons and their tooltips ------------------------------------- */
|
|
239
|
+
|
|
240
|
+
/* The same rules (and the `[data-tip]` tooltip below) are declared in
|
|
241
|
+
`DfkSql.css`, because the buttons are split across the shadow boundary: the
|
|
242
|
+
code-block actions live in the shadow tree, the fullscreen toggle lives in
|
|
243
|
+
this light-DOM tab strip. Keep the two copies in sync. */
|
|
244
|
+
.dfk-sql-icon-button {
|
|
245
|
+
position: relative;
|
|
246
|
+
display: inline-flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
justify-content: center;
|
|
249
|
+
width: 1.6rem;
|
|
250
|
+
height: 1.6rem;
|
|
251
|
+
padding: 0;
|
|
252
|
+
border: none;
|
|
253
|
+
border-radius: var(--ifm-global-radius, 0.25rem);
|
|
254
|
+
background: transparent;
|
|
255
|
+
color: var(--ifm-color-emphasis-700, #666);
|
|
256
|
+
cursor: pointer;
|
|
257
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.dfk-sql-icon-button:hover:not(:disabled),
|
|
261
|
+
.dfk-sql-icon-button:focus-visible {
|
|
262
|
+
background: var(--ifm-color-emphasis-200, #e6e6e6);
|
|
263
|
+
color: var(--ifm-color-primary, #14459b);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.dfk-sql-icon-button:disabled {
|
|
267
|
+
opacity: 0.45;
|
|
268
|
+
cursor: progress;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.dfk-sql-icon-button[hidden] {
|
|
272
|
+
display: none;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* A sticky state, e.g. the wrap toggle while wrapping is on. */
|
|
276
|
+
.dfk-sql-icon-on {
|
|
277
|
+
color: var(--ifm-color-primary, #14459b);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.dfk-sql-icon {
|
|
281
|
+
font-size: 1rem;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
[data-tip]::after {
|
|
285
|
+
content: attr(data-tip);
|
|
286
|
+
position: absolute;
|
|
287
|
+
top: calc(100% + 0.3rem);
|
|
288
|
+
right: 0;
|
|
289
|
+
z-index: 2;
|
|
290
|
+
padding: 0.15rem 0.4rem;
|
|
291
|
+
border-radius: var(--ifm-global-radius, 0.25rem);
|
|
292
|
+
background: var(--ifm-color-emphasis-800, #333);
|
|
293
|
+
color: var(--ifm-color-emphasis-0, #fff);
|
|
294
|
+
font-size: 0.7rem;
|
|
295
|
+
line-height: 1.4;
|
|
296
|
+
white-space: nowrap;
|
|
297
|
+
opacity: 0;
|
|
298
|
+
pointer-events: none;
|
|
299
|
+
transition: opacity 0.12s ease;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
[data-tip]:hover::after,
|
|
303
|
+
[data-tip]:focus-visible::after {
|
|
304
|
+
opacity: 1;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* --- Panels -------------------------------------------------------------- */
|
|
308
|
+
|
|
309
|
+
.dfk-sql-panels {
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: column;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* `overscroll-behavior: contain` is what stops a wheel that has reached the
|
|
315
|
+
bottom of the table from continuing into the page scroll (the page lurches
|
|
316
|
+
upward and the example leaves the screen). It is not inherited, so it is
|
|
317
|
+
declared on every scrolling box, including VTable's inner scroll containers
|
|
318
|
+
under `.dfk-sql-table`. */
|
|
319
|
+
.dfk-sql-panel,
|
|
320
|
+
.dfk-sql-table,
|
|
321
|
+
.dfk-sql-table *,
|
|
322
|
+
.dfk-sql-svg {
|
|
323
|
+
overscroll-behavior: contain;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.dfk-sql-panel {
|
|
327
|
+
min-height: 0;
|
|
328
|
+
overflow: auto;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* --- Rendered results ---------------------------------------------------- */
|
|
332
|
+
|
|
333
|
+
.dfk-sql-table {
|
|
334
|
+
width: 100%;
|
|
335
|
+
/* VTable measures its container, so the box needs a real height; a taller
|
|
336
|
+
result grows with the rows up to a ceiling. */
|
|
337
|
+
height: var(--dfk-sql-table-height, 240px);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.dfk-sql-frame {
|
|
341
|
+
display: block;
|
|
342
|
+
width: var(--dfk-sql-preview-width, 100%);
|
|
343
|
+
height: var(--dfk-sql-preview-height, 360px);
|
|
344
|
+
border: none;
|
|
345
|
+
background: #fff;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.dfk-sql-svg {
|
|
349
|
+
width: var(--dfk-sql-preview-width, 100%);
|
|
350
|
+
height: var(--dfk-sql-preview-height, auto);
|
|
351
|
+
padding: 0.5rem;
|
|
352
|
+
overflow: auto;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.dfk-sql-svg > svg {
|
|
356
|
+
max-width: 100%;
|
|
357
|
+
height: auto;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/* --- Fullscreen ---------------------------------------------------------- */
|
|
361
|
+
|
|
362
|
+
/* Also carries `.dfk-sql-result`, so `overflow` and the radius are re-declared
|
|
363
|
+
here rather than fought with `!important`.
|
|
364
|
+
The background must be the *surface* colour, not `--ifm-background-color`:
|
|
365
|
+
a site may legitimately define the latter as `transparent` (this one does),
|
|
366
|
+
which would leave the overlay see-through with the page showing underneath. */
|
|
367
|
+
.dfk-sql-result-expanded {
|
|
368
|
+
position: fixed;
|
|
369
|
+
inset: 0;
|
|
370
|
+
z-index: 2147483000;
|
|
371
|
+
display: flex;
|
|
372
|
+
flex-direction: column;
|
|
373
|
+
overflow: hidden;
|
|
374
|
+
border: none;
|
|
375
|
+
border-radius: 0;
|
|
376
|
+
background: var(--ifm-background-surface-color, #fff);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.dfk-sql-result-expanded .dfk-sql-panels,
|
|
380
|
+
.dfk-sql-result-expanded .dfk-sql-panel {
|
|
381
|
+
flex: 1;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.dfk-sql-result-expanded .dfk-sql-table {
|
|
385
|
+
/* The extra height is the point of the fullscreen view. */
|
|
386
|
+
height: 100%;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.dfk-sql-result-expanded .dfk-sql-frame {
|
|
390
|
+
height: 100%;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/* An inline `<svg>` gets the same treatment as the frame and the table so the
|
|
394
|
+
panel is one full-height scroll area rather than a strip. */
|
|
395
|
+
.dfk-sql-result-expanded .dfk-sql-svg {
|
|
396
|
+
height: 100%;
|
|
397
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// The `<dfk-sql>` code box's shadow-root CSS as an inline string (Vite `?inline`
|
|
2
|
+
// import), mirroring `home/styles.ts`. It covers the CodeMirror editor and the
|
|
3
|
+
// action cluster, both of which live in this tree. Only the *result* container
|
|
4
|
+
// stays in the light DOM, styled by `sql.css` through `kit.css` instead: VTable
|
|
5
|
+
// injects a document-level stylesheet, which a shadow boundary could not host.
|
|
6
|
+
//
|
|
7
|
+
// The type declaration lives in `vite-env.d.ts`; `tsc` never resolves the
|
|
8
|
+
// `?inline` suffix, so the module graph stays buildable without Vite running.
|
|
9
|
+
import sqlCss from './DfkSql.css?inline';
|
|
10
|
+
|
|
11
|
+
let sheet: CSSStyleSheet | null = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The one parsed stylesheet shared by every `<dfk-sql>` shadow root.
|
|
15
|
+
* Created lazily: `CSSStyleSheet` does not exist during Docusaurus' Node
|
|
16
|
+
* prerender, and only the browser ever calls this.
|
|
17
|
+
*/
|
|
18
|
+
export function sqlStyles(): CSSStyleSheet {
|
|
19
|
+
if (!sheet) {
|
|
20
|
+
sheet = new CSSStyleSheet();
|
|
21
|
+
sheet.replaceSync(sqlCss);
|
|
22
|
+
}
|
|
23
|
+
return sheet;
|
|
24
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brand colour tokens for duckfn-family docs sites.
|
|
3
|
+
*
|
|
4
|
+
* The palette comes from the project logo (drawn with a deep blue body,
|
|
5
|
+
* #14459b, and a golden beak, #fcb103). The `--duckfn-*` variables are what the
|
|
6
|
+
* shared components (home.css) pick their tints, glows and borders from, so the
|
|
7
|
+
* brand colour stays defined in exactly one place. They are written out
|
|
8
|
+
* explicitly instead of derived with `color-mix()` to avoid relying on a newer
|
|
9
|
+
* CSS feature for something this central.
|
|
10
|
+
*
|
|
11
|
+
* Contrast, checked against the palettes below:
|
|
12
|
+
* #14459b on white 8.9:1 -> light-mode primary for text and links
|
|
13
|
+
* white on #14459b 8.9:1 -> buttons and badges
|
|
14
|
+
* #4d8fe8 on #1b1b1d 5.2:1 -> dark-mode primary for text and links
|
|
15
|
+
* #fcb103 on #14459b 4.8:1 -> yellow is only legible on brand blue
|
|
16
|
+
* #fcb103 on white 1.8:1 -> NOT a text colour; see the note below.
|
|
17
|
+
*
|
|
18
|
+
* The `--ifm-*` Infima wiring (the seven-step primary ramp) deliberately does
|
|
19
|
+
* NOT live here: each site owns that mapping for its own brand.
|
|
20
|
+
*/
|
|
21
|
+
:root {
|
|
22
|
+
--duckfn-blue: #14459b;
|
|
23
|
+
/* Ends of the gradient the homepage headline is painted with. */
|
|
24
|
+
--duckfn-blue-deep: #0e306c;
|
|
25
|
+
--duckfn-blue-bright: #1a5aca;
|
|
26
|
+
/* Tinted surfaces: card icon chips, the code showcase band, hover shadows. */
|
|
27
|
+
--duckfn-blue-soft: #e8eefb;
|
|
28
|
+
--duckfn-tint: #f6f8fc;
|
|
29
|
+
/* Kept faint on purpose: the home page stretches these over a very large
|
|
30
|
+
radius, and a stronger tint shows the gradient's steps as visible bands. */
|
|
31
|
+
--duckfn-glow: rgba(20, 69, 155, 0.12);
|
|
32
|
+
--duckfn-glow-warm: rgba(252, 177, 3, 0.16);
|
|
33
|
+
--duckfn-card-bg: #ffffff;
|
|
34
|
+
--duckfn-card-border: #e3e8f2;
|
|
35
|
+
--duckfn-shadow: 0 8px 24px rgba(20, 69, 155, 0.12);
|
|
36
|
+
--duckfn-yellow: #fcb103;
|
|
37
|
+
/* Home page buttons, kept apart from the primary because the dark mode value
|
|
38
|
+
of `--ifm-color-primary` is too light to carry white text. Measured against
|
|
39
|
+
their own label: white on #14459b is 8.9:1, white on the hover #0e306c is
|
|
40
|
+
12.7:1. The outline border is decorative — the label above it carries the
|
|
41
|
+
contrast — so it is allowed to stay faint. */
|
|
42
|
+
--duckfn-btn-bg: #14459b;
|
|
43
|
+
--duckfn-btn-bg-hover: #0e306c;
|
|
44
|
+
--duckfn-btn-fg: #ffffff;
|
|
45
|
+
--duckfn-outline-border: #bccbe8;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* For readability concerns, you should choose a lighter palette in dark mode.
|
|
49
|
+
The primary has to move well away from #14459b here: the deep blue only
|
|
50
|
+
reaches about 2.4:1 against #1b1b1d, which is unreadable for text. */
|
|
51
|
+
[data-theme='dark'] {
|
|
52
|
+
--duckfn-blue: #4d8fe8;
|
|
53
|
+
--duckfn-blue-deep: #4d8fe8;
|
|
54
|
+
--duckfn-blue-bright: #9ecbff;
|
|
55
|
+
--duckfn-blue-soft: #17253d;
|
|
56
|
+
--duckfn-tint: #1f2733;
|
|
57
|
+
--duckfn-glow: rgba(77, 143, 232, 0.16);
|
|
58
|
+
--duckfn-glow-warm: rgba(252, 177, 3, 0.12);
|
|
59
|
+
--duckfn-card-bg: #242526;
|
|
60
|
+
--duckfn-card-border: #33405c;
|
|
61
|
+
--duckfn-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
62
|
+
--duckfn-yellow: #fcb103;
|
|
63
|
+
/* The dark primary is a light blue, so white on it would only reach 3.3:1.
|
|
64
|
+
The button therefore gets its own deeper blue: white on #2f6fd0 is 4.9:1,
|
|
65
|
+
and the one-notch-lighter hover stays at 4.4:1. */
|
|
66
|
+
--duckfn-btn-bg: #2f6fd0;
|
|
67
|
+
--duckfn-btn-bg-hover: #3576dd;
|
|
68
|
+
--duckfn-btn-fg: #ffffff;
|
|
69
|
+
--duckfn-outline-border: #33405c;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* The yellow is an accent, never a text colour: #fcb103 on white is 1.8:1.
|
|
73
|
+
Safe uses (all already at or above 4.5:1): as a chip behind the deep blue,
|
|
74
|
+
as the icon chip background in dark mode, as a decorative underline or
|
|
75
|
+
border, and for small shapes that are not the only carrier of meaning. */
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table-of-contents toggle styles.
|
|
3
|
+
*
|
|
4
|
+
* Docusaurus has no `hideable` option for the right-hand TOC, so the control
|
|
5
|
+
* and the layout switch are provided by the kit's `toc-toggle` module: the
|
|
6
|
+
* button is injected above the TOC, and the `toc-collapsed` class on `<body>`
|
|
7
|
+
* drives the rules below.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
.toc-toggle {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
width: 2rem;
|
|
15
|
+
height: 2rem;
|
|
16
|
+
/* Right edge of the TOC column, next to the list it controls. */
|
|
17
|
+
margin-left: auto;
|
|
18
|
+
margin-bottom: 0.5rem;
|
|
19
|
+
border-radius: 50%;
|
|
20
|
+
background-color: var(--ifm-color-emphasis-200);
|
|
21
|
+
color: var(--ifm-color-emphasis-800);
|
|
22
|
+
transition: background-color var(--ifm-transition-fast)
|
|
23
|
+
var(--ifm-transition-timing-default);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.toc-toggle:hover {
|
|
27
|
+
background-color: var(--ifm-color-emphasis-300);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.toc-toggle::after {
|
|
31
|
+
content: '';
|
|
32
|
+
width: 1rem;
|
|
33
|
+
height: 1rem;
|
|
34
|
+
background-color: currentColor;
|
|
35
|
+
/* chevron-right: "push the TOC away"; it is flipped when collapsed. */
|
|
36
|
+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E")
|
|
37
|
+
center / contain no-repeat;
|
|
38
|
+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E")
|
|
39
|
+
center / contain no-repeat;
|
|
40
|
+
transition: transform var(--ifm-transition-fast)
|
|
41
|
+
var(--ifm-transition-timing-default);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
body.toc-collapsed .toc-toggle::after {
|
|
45
|
+
transform: rotate(180deg);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Collapsed: the column shrinks to a strip that keeps the button reachable, the
|
|
49
|
+
list is hidden, and the article takes the freed width. Infima sizes columns
|
|
50
|
+
through --ifm-col-width, so overriding that one property covers the width.
|
|
51
|
+
|
|
52
|
+
These rules go into the theme's own cascade layer on purpose: `future.v4`
|
|
53
|
+
makes Docusaurus emit layered CSS, and for `!important` declarations layer
|
|
54
|
+
order wins over specificity — an unlayered `!important` loses to a layered
|
|
55
|
+
one, so the `max-width` below would silently do nothing outside this layer. */
|
|
56
|
+
@layer docusaurus.theme-classic {
|
|
57
|
+
body.toc-collapsed .toc-column {
|
|
58
|
+
--ifm-col-width: 2.5rem;
|
|
59
|
+
padding: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
body.toc-collapsed .toc-column .theme-doc-toc-desktop {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
body.toc-collapsed [class*='docItemCol'] {
|
|
67
|
+
max-width: 100% !important;
|
|
68
|
+
}
|
|
69
|
+
}
|