@orbytes/astrolab 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +37 -0
- package/README.md +410 -0
- package/bin/lab-cull.mjs +401 -0
- package/bin/pin-gallery.mjs +121 -0
- package/defaults.mjs +120 -0
- package/dist/core/astro-integration.js +130 -0
- package/dist/core/index.js +6 -0
- package/dist/core/lib-paths.js +29 -0
- package/dist/core/options.js +173 -0
- package/dist/core/utils/get-exports.js +52 -0
- package/dist/core/utils/invariant.js +12 -0
- package/dist/core/utils/kebab-case.js +15 -0
- package/dist/core/utils/path-builder.js +22 -0
- package/dist/core/utils/path.js +53 -0
- package/dist/core/virtual-module/get-story-modules.js +60 -0
- package/dist/core/virtual-module/story-modules.js +8 -0
- package/dist/core/virtual-module/virtual-module-ids.js +22 -0
- package/dist/core/virtual-module/virtual-routes.js +83 -0
- package/dist/core/virtual-module/vite-plugin.js +98 -0
- package/docs/PIN-CONTRACT.md +263 -0
- package/docs/PIN.md +429 -0
- package/index.d.ts +279 -0
- package/index.mjs +347 -0
- package/package.json +93 -0
- package/src/Empty.astro +4 -0
- package/src/Home.astro +298 -0
- package/src/LabHead.astro +1102 -0
- package/src/core/LICENSE-astrobook +166 -0
- package/src/core/astro-integration.ts +166 -0
- package/src/core/client.ts +89 -0
- package/src/core/index.ts +7 -0
- package/src/core/lib/components/empty.astro +1 -0
- package/src/core/lib/components/head.astro +1 -0
- package/src/core/lib/components/home.astro +8 -0
- package/src/core/lib/components/with-decorators.astro +22 -0
- package/src/core/lib/pages/app.astro +19 -0
- package/src/core/lib/pages/preview.astro +17 -0
- package/src/core/lib/pages/story.astro +16 -0
- package/src/core/lib-paths.ts +72 -0
- package/src/core/options.ts +262 -0
- package/src/core/utils/get-exports.ts +59 -0
- package/src/core/utils/invariant.ts +13 -0
- package/src/core/utils/kebab-case.ts +30 -0
- package/src/core/utils/path-builder.ts +45 -0
- package/src/core/utils/path.ts +80 -0
- package/src/core/virtual-module/get-story-modules.ts +110 -0
- package/src/core/virtual-module/story-modules.ts +9 -0
- package/src/core/virtual-module/virtual-module-ids.ts +17 -0
- package/src/core/virtual-module/virtual-routes.ts +130 -0
- package/src/core/virtual-module/vite-plugin.ts +125 -0
- package/src/pin/board.mjs +1521 -0
- package/src/pin/index.mjs +666 -0
- package/src/pin/shot.mjs +427 -0
- package/src/pin/source-stamp.mjs +159 -0
- package/src/pin/tickets.mjs +697 -0
- package/src/pin/toolbar.js +3181 -0
- package/src/shell/Browse.astro +371 -0
- package/src/shell/CardGrid.astro +297 -0
- package/src/shell/Viewport.astro +1330 -0
- package/src/shell/index.json.ts +12 -0
- package/src/shell/lab-index.ts +344 -0
- package/src/shell/lab-params.ts +245 -0
- package/src/shell/live-files.mjs +164 -0
- package/src/shell/marks.mjs +136 -0
- package/src/types/index.ts +6 -0
- package/src/types/types.ts +239 -0
- package/src/types/virtual.d.ts +29 -0
- package/src/ui/components/app.astro +13 -0
- package/src/ui/components/build-path.ts +13 -0
- package/src/ui/components/build-tree.ts +108 -0
- package/src/ui/components/collapse-duration.ts +28 -0
- package/src/ui/components/compress-terms.ts +10 -0
- package/src/ui/components/dashboard-layout.astro +39 -0
- package/src/ui/components/home.astro +65 -0
- package/src/ui/components/layout.astro +110 -0
- package/src/ui/components/preview-layout.astro +109 -0
- package/src/ui/components/sidebar-button-fullscreen.astro +38 -0
- package/src/ui/components/sidebar-button-search.astro +23 -0
- package/src/ui/components/sidebar-button-theme.astro +9 -0
- package/src/ui/components/sidebar-button.astro +24 -0
- package/src/ui/components/sidebar-resize-handle.astro +74 -0
- package/src/ui/components/sidebar-search-panel.astro +41 -0
- package/src/ui/components/sidebar-search-script.ts +103 -0
- package/src/ui/components/sidebar-title.astro +17 -0
- package/src/ui/components/sidebar-tree-node.astro +143 -0
- package/src/ui/components/sidebar-tree.astro +84 -0
- package/src/ui/components/sidebar.astro +29 -0
- package/src/ui/components/theme-message.ts +26 -0
- package/src/ui/components/theme-script.astro +71 -0
- package/src/ui/components/theme-toggle.astro +63 -0
- package/src/ui/components/theme.ts +32 -0
- package/src/ui/index.ts +4 -0
- package/src/ui/lab.css +549 -0
- package/virtual.d.ts +42 -0
package/src/ui/lab.css
ADDED
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/* =============================================================================================
|
|
2
|
+
lab.css — THE lab's chrome stylesheet. The only one.
|
|
3
|
+
|
|
4
|
+
THE RULING THIS FILE EXISTS FOR (2026-09-22):
|
|
5
|
+
|
|
6
|
+
The lab is not styled in the styles of the website being built. It has one standard style
|
|
7
|
+
across every site. A user who wants it styled differently edits this open source code —
|
|
8
|
+
but that is never the default.
|
|
9
|
+
|
|
10
|
+
So the line runs between CHROME and PREVIEW, and it runs exactly there:
|
|
11
|
+
|
|
12
|
+
CHROME the lab's own furniture — layout, sidebar, search, toolbar, the home page, the
|
|
13
|
+
folder pages, the viewport configurator. Styled HERE and nowhere else. It never
|
|
14
|
+
receives the consumer's `css` list and never receives the consumer's `head`.
|
|
15
|
+
PREVIEW the story itself (/lab/stories/<id>) and the story rendered inside the dashboard.
|
|
16
|
+
It receives the consumer's `css` list and `head` — that is how the site's tokens
|
|
17
|
+
and fonts arrive, and seeing a component as the real site renders it is the whole
|
|
18
|
+
point of the lab.
|
|
19
|
+
|
|
20
|
+
ISOLATION RUNS BOTH WAYS, and that is why this file looks the way it does:
|
|
21
|
+
|
|
22
|
+
1. EVERY TOKEN IS `--lab-*`. The consumer owns `--color-background`, `--font-body`,
|
|
23
|
+
`--radius-pill` and the rest; a lab that read those names would wear the client's brand,
|
|
24
|
+
which is the exact thing the ruling forbids. Nothing here reads a name the consumer could
|
|
25
|
+
also define, so the two palettes cannot collide even where both stylesheets are in one
|
|
26
|
+
document (the dashboard, which must carry both).
|
|
27
|
+
2. NOTHING HERE IS A BARE ELEMENT SELECTOR that could reach a story. Every rule is anchored
|
|
28
|
+
on a chrome class, a chrome id, or a chrome custom element. `html`/`body` carry the
|
|
29
|
+
`.lab-shell` class rather than being styled as elements, and the chrome's font, colour
|
|
30
|
+
and font-size are set on the chrome's own boxes — never inherited down from `body`, which
|
|
31
|
+
on a dashboard page is shared with the preview.
|
|
32
|
+
3. NO CASCADE LAYER. The previous build put the lab's token fallbacks in
|
|
33
|
+
`@layer orbytes-lab-fallback` so the consumer would win; that was the leak, expressed as
|
|
34
|
+
a policy. The lab wins now.
|
|
35
|
+
|
|
36
|
+
WHAT THIS FILE IS NOT. This is the FUNCTION pass, not the design pass: plain, legible,
|
|
37
|
+
working, dark mode intact. Semantic class names (`.lab-sidebar`, `.lab-tree-row`) rather than
|
|
38
|
+
a hand-rolled utility set, precisely so the next pass is a restyle and not a rewrite. It
|
|
39
|
+
replaces the UnoCSS atomic classes the upstream `@astrobook/ui` was built from — this package
|
|
40
|
+
ships source and has no build step, so Uno was never an option here.
|
|
41
|
+
|
|
42
|
+
Typography ships with the package: a system font stack, no webfont, no build step, no
|
|
43
|
+
consumer dependency.
|
|
44
|
+
============================================================================================= */
|
|
45
|
+
|
|
46
|
+
/* ---------------------------------------------------------------------------------------------
|
|
47
|
+
Tokens. Light is the default; `.dark` on <html> is set by the theme script before paint
|
|
48
|
+
(src/ui/components/theme-script.astro) and is the hook LabHead's own styles key off too.
|
|
49
|
+
--------------------------------------------------------------------------------------------- */
|
|
50
|
+
:root {
|
|
51
|
+
--lab-font-body:
|
|
52
|
+
system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
53
|
+
"Apple Color Emoji", "Segoe UI Emoji";
|
|
54
|
+
--lab-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
55
|
+
/* The chrome has one face today. The name exists so phase 2 can split display from body
|
|
56
|
+
without touching every rule that asks for it. */
|
|
57
|
+
--lab-font-heading: var(--lab-font-body);
|
|
58
|
+
|
|
59
|
+
--lab-color-bg: #ffffff;
|
|
60
|
+
--lab-color-bg-sunken: #f9fafb;
|
|
61
|
+
--lab-color-surface: #f4f4f5;
|
|
62
|
+
--lab-color-surface-raised: #ffffff;
|
|
63
|
+
--lab-color-border: #e4e4e7;
|
|
64
|
+
--lab-color-border-strong: #d4d4d8;
|
|
65
|
+
|
|
66
|
+
--lab-color-text: #3f3f46;
|
|
67
|
+
--lab-color-text-strong: #18181b;
|
|
68
|
+
--lab-color-text-muted: #71717a;
|
|
69
|
+
--lab-color-text-faint: #a1a1aa;
|
|
70
|
+
|
|
71
|
+
--lab-color-accent: #2563eb;
|
|
72
|
+
--lab-color-accent-text: #ffffff;
|
|
73
|
+
/* The accent that reads on the INVERTED active tree row, where the ground flips to the other
|
|
74
|
+
theme's. LabHead.astro's live pill is the only thing that needs it. */
|
|
75
|
+
--lab-color-accent-inverse: #60a5fa;
|
|
76
|
+
--lab-color-focus: #18181b;
|
|
77
|
+
|
|
78
|
+
/* The inverted active row in the tree. */
|
|
79
|
+
--lab-color-active-bg: #27272a;
|
|
80
|
+
--lab-color-active-text: #ffffff;
|
|
81
|
+
|
|
82
|
+
--lab-radius: 4px;
|
|
83
|
+
--lab-radius-pill: 100px;
|
|
84
|
+
--lab-radius-square: 0;
|
|
85
|
+
--lab-transition: 150ms ease;
|
|
86
|
+
|
|
87
|
+
--lab-sidebar-width: attr(data-sidebar-width px, 300px);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:root.dark {
|
|
91
|
+
--lab-color-bg: #18181b;
|
|
92
|
+
--lab-color-bg-sunken: #111113;
|
|
93
|
+
--lab-color-surface: #1f1f23;
|
|
94
|
+
--lab-color-surface-raised: #27272a;
|
|
95
|
+
--lab-color-border: #3f3f46;
|
|
96
|
+
--lab-color-border-strong: #52525b;
|
|
97
|
+
|
|
98
|
+
--lab-color-text: #d4d4d8;
|
|
99
|
+
--lab-color-text-strong: #fafafa;
|
|
100
|
+
--lab-color-text-muted: #a1a1aa;
|
|
101
|
+
--lab-color-text-faint: #71717a;
|
|
102
|
+
|
|
103
|
+
--lab-color-accent: #60a5fa;
|
|
104
|
+
--lab-color-accent-text: #09090b;
|
|
105
|
+
--lab-color-accent-inverse: #2563eb;
|
|
106
|
+
--lab-color-focus: #fafafa;
|
|
107
|
+
|
|
108
|
+
--lab-color-active-bg: #e4e4e7;
|
|
109
|
+
--lab-color-active-text: #18181b;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* ---------------------------------------------------------------------------------------------
|
|
113
|
+
The document frame. Structure only — no font, no colour, nothing that would inherit into a
|
|
114
|
+
story rendered in <main> on a dashboard page.
|
|
115
|
+
--------------------------------------------------------------------------------------------- */
|
|
116
|
+
html.lab-shell {
|
|
117
|
+
height: 100%;
|
|
118
|
+
max-height: 100vh;
|
|
119
|
+
overflow: hidden;
|
|
120
|
+
-webkit-text-size-adjust: 100%;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
body.lab-shell {
|
|
124
|
+
margin: 0;
|
|
125
|
+
padding: 0;
|
|
126
|
+
display: flex;
|
|
127
|
+
flex-direction: row;
|
|
128
|
+
align-items: stretch;
|
|
129
|
+
justify-content: flex-start;
|
|
130
|
+
min-height: 100%;
|
|
131
|
+
max-height: 100%;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.lab-main {
|
|
135
|
+
flex: 1;
|
|
136
|
+
min-width: 0;
|
|
137
|
+
overflow: auto;
|
|
138
|
+
box-sizing: border-box;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Box-sizing is scoped to the chrome for the same reason: on a dashboard page a `*` selector
|
|
142
|
+
would cross into the story. */
|
|
143
|
+
.lab-chrome,
|
|
144
|
+
.lab-chrome *,
|
|
145
|
+
.lab-chrome *::before,
|
|
146
|
+
.lab-chrome *::after {
|
|
147
|
+
box-sizing: border-box;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* The chrome's own typographic ground. Declared on the chrome boxes, not on `body`, because the
|
|
151
|
+
consumer's `body { font-family; font-size }` is in the same document on a dashboard page — a
|
|
152
|
+
class here beats an element selector there, and nothing inherits into the preview from us. */
|
|
153
|
+
.lab-chrome {
|
|
154
|
+
font-family: var(--lab-font-body);
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
line-height: 1.45;
|
|
157
|
+
color: var(--lab-color-text);
|
|
158
|
+
-webkit-font-smoothing: antialiased;
|
|
159
|
+
-moz-osx-font-smoothing: grayscale;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.lab-sr-only {
|
|
163
|
+
position: absolute;
|
|
164
|
+
width: 1px;
|
|
165
|
+
height: 1px;
|
|
166
|
+
padding: 0;
|
|
167
|
+
margin: -1px;
|
|
168
|
+
overflow: hidden;
|
|
169
|
+
clip-path: inset(50%);
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
border: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.lab-focus-ring:focus-visible {
|
|
175
|
+
outline: 2px solid var(--lab-color-focus);
|
|
176
|
+
outline-offset: -1px;
|
|
177
|
+
z-index: 20;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* ---------------------------------------------------------------------------------------------
|
|
181
|
+
Sidebar. `#astrobook-sidebar` is a DOM contract, not a style choice: LabHead.astro's collapse
|
|
182
|
+
script and pill decorator both query it by that id. Same for the resize-handle element.
|
|
183
|
+
--------------------------------------------------------------------------------------------- */
|
|
184
|
+
#astrobook-sidebar {
|
|
185
|
+
display: flex;
|
|
186
|
+
flex-direction: column;
|
|
187
|
+
flex-shrink: 0;
|
|
188
|
+
width: var(--lab-sidebar-width, 300px);
|
|
189
|
+
min-width: 100px;
|
|
190
|
+
max-width: calc(100vw - 100px);
|
|
191
|
+
border-right: 1px solid var(--lab-color-border);
|
|
192
|
+
background-color: var(--lab-color-bg-sunken);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
:root[data-sidebar-resizing] {
|
|
196
|
+
cursor: ew-resize;
|
|
197
|
+
user-select: none;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
astrobook-sidebar-resize-handle {
|
|
201
|
+
position: relative;
|
|
202
|
+
left: -2px;
|
|
203
|
+
display: block;
|
|
204
|
+
width: 4px;
|
|
205
|
+
flex: none;
|
|
206
|
+
cursor: ew-resize;
|
|
207
|
+
transition: background-color var(--lab-transition);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
astrobook-sidebar-resize-handle:hover {
|
|
211
|
+
background-color: var(--lab-color-border-strong);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.lab-sidebar__nav {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-direction: column;
|
|
217
|
+
min-height: 100%;
|
|
218
|
+
max-height: 100%;
|
|
219
|
+
overflow-y: hidden;
|
|
220
|
+
padding: 0;
|
|
221
|
+
margin: 0;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.lab-sidebar__header {
|
|
225
|
+
display: flex;
|
|
226
|
+
align-items: center;
|
|
227
|
+
gap: 0.125rem;
|
|
228
|
+
padding: 0.75rem 0.5rem;
|
|
229
|
+
border-bottom: 1px solid var(--lab-color-border);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.lab-sidebar__title {
|
|
233
|
+
min-width: 0;
|
|
234
|
+
flex: 0 1 auto;
|
|
235
|
+
overflow: hidden;
|
|
236
|
+
text-overflow: ellipsis;
|
|
237
|
+
white-space: nowrap;
|
|
238
|
+
padding: 0.35rem 0.5rem;
|
|
239
|
+
border-radius: var(--lab-radius);
|
|
240
|
+
font-weight: 600;
|
|
241
|
+
color: var(--lab-color-text-muted);
|
|
242
|
+
text-decoration: none;
|
|
243
|
+
transition: color var(--lab-transition);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.lab-sidebar__title:hover {
|
|
247
|
+
color: var(--lab-color-text-strong);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.lab-sidebar__spacer {
|
|
251
|
+
flex: 1 1 auto;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* The button class name is a DOM contract too: LabHead.astro creates the collapse, cull,
|
|
255
|
+
viewport, staging and code buttons and sets `className = "astrobook-sidebar-button"` on each,
|
|
256
|
+
so every injected control inherits this shape without knowing anything about the stylesheet. */
|
|
257
|
+
.astrobook-sidebar-button {
|
|
258
|
+
display: flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
justify-content: center;
|
|
261
|
+
flex: none;
|
|
262
|
+
width: 2rem;
|
|
263
|
+
height: 2rem;
|
|
264
|
+
padding: 0.375rem;
|
|
265
|
+
border: 0;
|
|
266
|
+
border-radius: var(--lab-radius);
|
|
267
|
+
background: transparent;
|
|
268
|
+
color: var(--lab-color-text-muted);
|
|
269
|
+
font: inherit;
|
|
270
|
+
font-size: 1rem;
|
|
271
|
+
text-decoration: none;
|
|
272
|
+
cursor: pointer;
|
|
273
|
+
transition:
|
|
274
|
+
color var(--lab-transition),
|
|
275
|
+
background-color var(--lab-transition);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.astrobook-sidebar-button:hover {
|
|
279
|
+
color: var(--lab-color-text-strong);
|
|
280
|
+
background-color: var(--lab-color-surface);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.astrobook-sidebar-button[data-active] {
|
|
284
|
+
color: var(--lab-color-text-strong);
|
|
285
|
+
background-color: var(--lab-color-surface);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.astrobook-sidebar-button svg {
|
|
289
|
+
display: block;
|
|
290
|
+
width: 1rem;
|
|
291
|
+
height: 1rem;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* ---------------------------------------------------------------------------------------------
|
|
295
|
+
Search. The ids are the contract (LabHead widens matches by appending terms to
|
|
296
|
+
`data-search-text`, and opens the panel on ⌘K by clicking the toggle).
|
|
297
|
+
--------------------------------------------------------------------------------------------- */
|
|
298
|
+
#astrobook-search-panel {
|
|
299
|
+
interpolate-size: allow-keywords;
|
|
300
|
+
height: 0;
|
|
301
|
+
overflow: clip;
|
|
302
|
+
border-bottom: 1px solid transparent;
|
|
303
|
+
transition: height var(--lab-transition);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
#astrobook-search-panel[data-open] {
|
|
307
|
+
height: max-content;
|
|
308
|
+
border-bottom-color: var(--lab-color-border);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.lab-search__row {
|
|
312
|
+
display: flex;
|
|
313
|
+
align-items: center;
|
|
314
|
+
padding: 0.5rem;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.lab-search__field {
|
|
318
|
+
position: relative;
|
|
319
|
+
display: flex;
|
|
320
|
+
flex: 1;
|
|
321
|
+
align-items: center;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.lab-search__icon {
|
|
325
|
+
position: absolute;
|
|
326
|
+
left: 0.5rem;
|
|
327
|
+
display: block;
|
|
328
|
+
width: 0.875rem;
|
|
329
|
+
height: 0.875rem;
|
|
330
|
+
pointer-events: none;
|
|
331
|
+
color: var(--lab-color-text-faint);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
#astrobook-search-input {
|
|
335
|
+
width: 100%;
|
|
336
|
+
padding: 0.3rem 0.5rem 0.3rem 1.75rem;
|
|
337
|
+
border: 1px solid var(--lab-color-border);
|
|
338
|
+
border-radius: var(--lab-radius);
|
|
339
|
+
background-color: var(--lab-color-surface-raised);
|
|
340
|
+
font-family: var(--lab-font-body);
|
|
341
|
+
font-size: 0.875rem;
|
|
342
|
+
color: var(--lab-color-text-strong);
|
|
343
|
+
outline: none;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
#astrobook-search-input::placeholder {
|
|
347
|
+
color: var(--lab-color-text-faint);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
#astrobook-search-input:focus {
|
|
351
|
+
border-color: var(--lab-color-border-strong);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* ---------------------------------------------------------------------------------------------
|
|
355
|
+
The tree. Every selector below is one LabHead.astro also queries — see its DOM contract block.
|
|
356
|
+
--------------------------------------------------------------------------------------------- */
|
|
357
|
+
astrobook-sidebar-tree {
|
|
358
|
+
display: flex;
|
|
359
|
+
flex-direction: column;
|
|
360
|
+
gap: 2px;
|
|
361
|
+
overflow-y: auto;
|
|
362
|
+
padding: 0.75rem 0.5rem 2rem;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
astrobook-sidebar-node {
|
|
366
|
+
display: contents;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.astrobook-sidebar-link {
|
|
370
|
+
display: flex;
|
|
371
|
+
align-items: center;
|
|
372
|
+
gap: 0.5rem;
|
|
373
|
+
list-style: none;
|
|
374
|
+
padding: 0.25rem 0.5rem;
|
|
375
|
+
border-radius: var(--lab-radius);
|
|
376
|
+
font-size: 0.875rem;
|
|
377
|
+
text-decoration: none;
|
|
378
|
+
cursor: pointer;
|
|
379
|
+
user-select: none;
|
|
380
|
+
transition:
|
|
381
|
+
color var(--lab-transition),
|
|
382
|
+
background-color var(--lab-transition);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.astrobook-sidebar-link::-webkit-details-marker {
|
|
386
|
+
display: none;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/* Folder and module rows. */
|
|
390
|
+
.lab-tree-row--group {
|
|
391
|
+
color: var(--lab-color-text-muted);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.lab-tree-row--group:hover {
|
|
395
|
+
color: var(--lab-color-text-strong);
|
|
396
|
+
background-color: var(--lab-color-surface);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/* Story rows. The two state classes are toggled by the inline script in sidebar-tree.astro and
|
|
400
|
+
are styled by LabHead.astro as well — do not rename either. */
|
|
401
|
+
.astrobook-sidebar-story-link-inactive {
|
|
402
|
+
color: var(--lab-color-text);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.astrobook-sidebar-story-link-inactive:hover {
|
|
406
|
+
color: var(--lab-color-text-strong);
|
|
407
|
+
background-color: var(--lab-color-surface);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.astrobook-sidebar-story-link-active,
|
|
411
|
+
.astrobook-sidebar-story-link-active:hover {
|
|
412
|
+
color: var(--lab-color-active-text);
|
|
413
|
+
background-color: var(--lab-color-active-bg);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.lab-tree-icon {
|
|
417
|
+
display: block;
|
|
418
|
+
flex: none;
|
|
419
|
+
width: 0.875rem;
|
|
420
|
+
height: 0.875rem;
|
|
421
|
+
color: var(--lab-color-text-faint);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.astrobook-sidebar-story-link-active .lab-tree-icon {
|
|
425
|
+
color: inherit;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.lab-tree-children {
|
|
429
|
+
display: flex;
|
|
430
|
+
flex-direction: column;
|
|
431
|
+
gap: 2px;
|
|
432
|
+
padding-left: 0.75rem;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* The collapse animation, lifted verbatim in behaviour from upstream's scoped block so the
|
|
436
|
+
chevron and the details height still move together. */
|
|
437
|
+
details[data-astrobook-collapsible] {
|
|
438
|
+
--lab-collapse-ease: cubic-bezier(0, 0, 0.2, 1);
|
|
439
|
+
interpolate-size: allow-keywords;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
details[data-astrobook-collapsible]::details-content {
|
|
443
|
+
height: 0;
|
|
444
|
+
overflow: clip;
|
|
445
|
+
transition:
|
|
446
|
+
height var(--collapse-duration, 150ms) var(--lab-collapse-ease),
|
|
447
|
+
content-visibility var(--collapse-duration, 150ms) var(--lab-collapse-ease) allow-discrete;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
details[data-astrobook-collapsible][open]::details-content {
|
|
451
|
+
height: auto;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
[data-astrobook-chevron] {
|
|
455
|
+
transform: rotate(-90deg);
|
|
456
|
+
transition: transform var(--collapse-duration, 150ms) var(--lab-collapse-ease);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
details[data-astrobook-collapsible][open] > summary > [data-astrobook-chevron] {
|
|
460
|
+
transform: rotate(0deg);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/* ---------------------------------------------------------------------------------------------
|
|
464
|
+
Theme toggle (vendored — see components/theme-script.astro for why the dependency went).
|
|
465
|
+
--------------------------------------------------------------------------------------------- */
|
|
466
|
+
.lab-theme-toggle {
|
|
467
|
+
display: flex;
|
|
468
|
+
align-items: center;
|
|
469
|
+
justify-content: center;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.lab-theme-toggle .lab-theme-icon--dark {
|
|
473
|
+
display: none;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
:root.dark .lab-theme-toggle .lab-theme-icon--light {
|
|
477
|
+
display: none;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
:root.dark .lab-theme-toggle .lab-theme-icon--dark {
|
|
481
|
+
display: block;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/* ---------------------------------------------------------------------------------------------
|
|
485
|
+
The built-in splash. Reachable only when a consumer leaves `home` at its default; this package
|
|
486
|
+
always passes its own (src/Home.astro), so this is the fallback path, kept working.
|
|
487
|
+
--------------------------------------------------------------------------------------------- */
|
|
488
|
+
.lab-splash {
|
|
489
|
+
display: flex;
|
|
490
|
+
flex-direction: column;
|
|
491
|
+
align-items: center;
|
|
492
|
+
justify-content: center;
|
|
493
|
+
height: 100%;
|
|
494
|
+
width: 100%;
|
|
495
|
+
padding: 1.5rem;
|
|
496
|
+
background-color: var(--lab-color-bg);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.lab-splash__title {
|
|
500
|
+
margin: 0;
|
|
501
|
+
font-size: 2rem;
|
|
502
|
+
font-weight: 700;
|
|
503
|
+
letter-spacing: -0.02em;
|
|
504
|
+
text-align: center;
|
|
505
|
+
color: var(--lab-color-text-strong);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.lab-splash__subtitle {
|
|
509
|
+
margin: 0.75rem 0 0;
|
|
510
|
+
font-size: 1rem;
|
|
511
|
+
text-align: center;
|
|
512
|
+
color: var(--lab-color-text-muted);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.lab-splash__badges {
|
|
516
|
+
display: flex;
|
|
517
|
+
flex-wrap: wrap;
|
|
518
|
+
align-items: center;
|
|
519
|
+
justify-content: center;
|
|
520
|
+
gap: 0.75rem;
|
|
521
|
+
margin-top: 1.5rem;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.lab-splash__badge {
|
|
525
|
+
display: inline-flex;
|
|
526
|
+
align-items: center;
|
|
527
|
+
gap: 0.5rem;
|
|
528
|
+
padding: 0.25rem 0.75rem;
|
|
529
|
+
border: 1px solid var(--lab-color-border);
|
|
530
|
+
border-radius: var(--lab-radius-pill);
|
|
531
|
+
font-family: var(--lab-font-mono);
|
|
532
|
+
font-size: 0.8125rem;
|
|
533
|
+
color: var(--lab-color-text-muted);
|
|
534
|
+
text-decoration: none;
|
|
535
|
+
transition:
|
|
536
|
+
color var(--lab-transition),
|
|
537
|
+
border-color var(--lab-transition);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.lab-splash__badge:hover {
|
|
541
|
+
color: var(--lab-color-text-strong);
|
|
542
|
+
border-color: var(--lab-color-border-strong);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.lab-splash__badge svg {
|
|
546
|
+
display: block;
|
|
547
|
+
width: 0.875rem;
|
|
548
|
+
height: 0.875rem;
|
|
549
|
+
}
|
package/virtual.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// The virtual modules the lab's own pages read. Defined by the integration (../index.mjs) so the
|
|
2
|
+
// resolved options, the consumer's head component and the consumer's CSS reach the package's
|
|
3
|
+
// .astro pages without any of them importing a path out of the consumer's tree.
|
|
4
|
+
declare module "virtual:orbytes-lab/config.mjs" {
|
|
5
|
+
export interface LabTier {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
responsive: boolean;
|
|
9
|
+
cullable: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface LabConfig {
|
|
12
|
+
directory: string;
|
|
13
|
+
subpath: string;
|
|
14
|
+
title: string;
|
|
15
|
+
css: string[];
|
|
16
|
+
stagingUrl: string | null;
|
|
17
|
+
previewUrlTemplate: string | null;
|
|
18
|
+
feedbucketKey: string | null;
|
|
19
|
+
tiers: LabTier[];
|
|
20
|
+
sectionsTier: string | null;
|
|
21
|
+
cullTier: string | null;
|
|
22
|
+
responsiveDir: string | null;
|
|
23
|
+
cullDir: string | null;
|
|
24
|
+
responsiveFile: string;
|
|
25
|
+
cullFile: string;
|
|
26
|
+
}
|
|
27
|
+
const config: LabConfig;
|
|
28
|
+
export default config;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare module "virtual:orbytes-lab/user-head.mjs" {
|
|
32
|
+
/**
|
|
33
|
+
* The consumer's own head component, or the package's Empty.astro when it passes none. Typed
|
|
34
|
+
* `any` because the module is generated: nothing here knows which .astro file it re-exports,
|
|
35
|
+
* and the Astro language server types real .astro imports on its own.
|
|
36
|
+
*/
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
const Component: any;
|
|
39
|
+
export default Component;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
declare module "virtual:orbytes-lab/user-css.mjs" {}
|