create-obsidian-arrow 0.2.2 → 0.4.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/README.md +10 -7
- package/index.mjs +29 -10
- package/package.json +1 -1
- package/template/AGENTS.md +31 -5
- package/template/README.md +47 -5
- package/template/_gitignore +3 -0
- package/template/docs/prompts/agent-setup.md +26 -13
- package/template/docs/prompts/update-existing.md +13 -9
- package/template/docs/workflow.md +21 -8
- package/template/package.json +6 -2
- package/template/pnpm-lock.yaml +197 -0
- package/template/src/components/DiffViewer.ts +42 -0
- package/template/src/components/SettingsPanel.ts +1 -1
- package/template/src/main.ts +4 -3
- package/template/src/utilities.css +205 -0
- package/template/stories/DiffViewer.stories.ts +75 -0
- package/template/stories/SettingsPanel.stories.ts +11 -0
- package/template/stories/Toggle.stories.ts +28 -0
- package/template/test/token-utils.test.mjs +65 -0
- package/template/test/viewer-derive.test.mjs +65 -0
- package/template/test/viewer-stories.test.mjs +44 -0
- package/template/{src → tools}/router/client.ts +15 -2
- package/template/tools/router/routeToPage.ts +104 -0
- package/template/{src → tools}/sandbox/home.ts +55 -26
- package/template/tools/sandbox/sandbox.css +474 -0
- package/template/tools/viewer/ClassesPage.ts +37 -0
- package/template/tools/viewer/ComponentsIndex.ts +56 -0
- package/template/tools/viewer/StoryPage.ts +73 -0
- package/template/tools/viewer/TokensPage.ts +82 -0
- package/template/tools/viewer/derive.ts +91 -0
- package/template/tools/viewer/discovery.ts +64 -0
- package/template/tools/viewer/obsidian-classes.ts +269 -0
- package/template/tools/viewer/sidebar.ts +55 -0
- package/template/tools/viewer/stories.ts +83 -0
- package/template/tools/viewer/token-utils.ts +84 -0
- package/template/tools/viewer/tokens.ts +30 -0
- package/template/src/examples/ExamplesIndex.ts +0 -36
- package/template/src/examples/registry.ts +0 -26
- package/template/src/router/routeToPage.ts +0 -57
- package/template/src/sandbox/sandbox.css +0 -130
- /package/template/{src → tools}/sandbox/frame.ts +0 -0
- /package/template/{src → tools}/sandbox/layout.ts +0 -0
- /package/template/{src → tools}/sandbox/shell.ts +0 -0
- /package/template/{src → tools}/sandbox/theme.ts +0 -0
- /package/template/{src → tools}/sandbox/toolbar.ts +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Sandbox-only chrome. NOT ported into the plugin.
|
|
3
|
+
*
|
|
4
|
+
* Per the arrow-js-obsidian CSS-specificity lesson, every custom rule is scoped
|
|
5
|
+
* under a container class + element type so it can't lose to Obsidian's global
|
|
6
|
+
* rules (e.g. `button:not(.clickable-icon)`) and can't leak. All values use
|
|
7
|
+
* Obsidian tokens so the sandbox tracks the active theme.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
html,
|
|
11
|
+
body {
|
|
12
|
+
margin: 0;
|
|
13
|
+
height: 100%;
|
|
14
|
+
background: var(--background-primary);
|
|
15
|
+
color: var(--text-normal);
|
|
16
|
+
font-family: var(--font-interface);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#app {
|
|
20
|
+
height: 100vh;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Shell: width-control toolbar on top, pane stage below. */
|
|
24
|
+
.oas-shell {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
height: 100vh;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.oas-toolbar {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: var(--size-4-2);
|
|
34
|
+
padding: var(--size-4-1) var(--size-4-3);
|
|
35
|
+
background: var(--background-secondary);
|
|
36
|
+
border-bottom: 1px solid var(--background-modifier-border);
|
|
37
|
+
color: var(--text-muted);
|
|
38
|
+
font-size: var(--font-ui-small);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.oas-toolbar .oas-toolbar-label {
|
|
42
|
+
font-weight: var(--font-medium);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.oas-toolbar .oas-width-range {
|
|
46
|
+
flex: 0 1 220px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.oas-toolbar .oas-width-readout {
|
|
50
|
+
min-width: 52px;
|
|
51
|
+
font-family: var(--font-monospace);
|
|
52
|
+
color: var(--text-normal);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.oas-toolbar button.oas-preset {
|
|
56
|
+
height: var(--size-4-5);
|
|
57
|
+
padding: 0 var(--size-4-2);
|
|
58
|
+
font-size: var(--font-ui-smaller);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Stage: left-aligned so the edge drag handle resizes width 1:1. */
|
|
62
|
+
.oas-stage {
|
|
63
|
+
flex: 1;
|
|
64
|
+
display: flex;
|
|
65
|
+
justify-content: flex-start;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
background: var(--background-secondary);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.oas-frame.workspace-leaf {
|
|
71
|
+
position: relative;
|
|
72
|
+
flex: 0 0 auto;
|
|
73
|
+
height: 100%;
|
|
74
|
+
min-width: 240px;
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
background: var(--background-primary);
|
|
78
|
+
border-right: 1px solid var(--background-modifier-border);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.oas-frame .oas-view-content {
|
|
82
|
+
flex: 1;
|
|
83
|
+
min-height: 0;
|
|
84
|
+
overflow-y: auto;
|
|
85
|
+
padding: var(--size-4-3);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.oas-frame .view-header {
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: space-between;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.oas-frame .oas-view-header-left {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
gap: var(--size-4-2);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.oas-frame .view-header .oas-theme-toggle,
|
|
101
|
+
.oas-frame .view-header .oas-home {
|
|
102
|
+
font-size: var(--font-ui-medium);
|
|
103
|
+
line-height: 1;
|
|
104
|
+
text-decoration: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.oas-frame a.oas-open-link {
|
|
108
|
+
text-decoration: none;
|
|
109
|
+
display: inline-flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.oas-frame .setting-item-control button.oas-recheck {
|
|
114
|
+
margin-left: var(--size-4-2);
|
|
115
|
+
font-size: var(--font-ui-smaller);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Drag-to-resize handle on the pane's right edge (Obsidian-like). */
|
|
119
|
+
.oas-frame .oas-resize-handle {
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: 0;
|
|
122
|
+
right: 0;
|
|
123
|
+
width: 6px;
|
|
124
|
+
height: 100%;
|
|
125
|
+
cursor: ew-resize;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.oas-frame .oas-resize-handle:hover {
|
|
129
|
+
background: var(--interactive-accent);
|
|
130
|
+
opacity: 0.5;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Collapsible card — Getting Started accordion and other expandable sections. */
|
|
134
|
+
.oas-card {
|
|
135
|
+
border-bottom: 1px solid var(--background-modifier-border);
|
|
136
|
+
border-left: 3px solid var(--background-modifier-border-hover);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.oas-card.is-expanded {
|
|
140
|
+
border-left-color: var(--interactive-accent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.oas-card-header {
|
|
144
|
+
display: flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
justify-content: space-between;
|
|
147
|
+
gap: var(--size-4-2);
|
|
148
|
+
padding: var(--size-4-3) var(--size-4-3);
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
font-size: var(--font-ui-small);
|
|
151
|
+
font-weight: var(--font-semibold);
|
|
152
|
+
color: var(--text-normal);
|
|
153
|
+
user-select: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.oas-card-header:hover {
|
|
157
|
+
background: var(--background-modifier-hover);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.oas-card-title {
|
|
161
|
+
flex: 1;
|
|
162
|
+
min-width: 0;
|
|
163
|
+
overflow: hidden;
|
|
164
|
+
text-overflow: ellipsis;
|
|
165
|
+
white-space: nowrap;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.oas-card-chevron {
|
|
169
|
+
flex-shrink: 0;
|
|
170
|
+
color: var(--text-faint);
|
|
171
|
+
transition: transform 0.15s;
|
|
172
|
+
font-size: var(--font-ui-medium);
|
|
173
|
+
line-height: 1;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.oas-card.is-expanded .oas-card-chevron {
|
|
177
|
+
transform: rotate(90deg);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.oas-card-body {
|
|
181
|
+
display: none;
|
|
182
|
+
border-top: 1px solid var(--background-modifier-border);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.oas-card.is-expanded .oas-card-body {
|
|
186
|
+
display: block;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.oas-card-desc {
|
|
190
|
+
margin: 0;
|
|
191
|
+
padding: var(--size-4-2) var(--size-4-3);
|
|
192
|
+
color: var(--text-muted);
|
|
193
|
+
font-size: var(--font-ui-smaller);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.oas-card-note {
|
|
197
|
+
margin: 0;
|
|
198
|
+
padding: 0 var(--size-4-3) var(--size-4-2);
|
|
199
|
+
color: var(--text-muted);
|
|
200
|
+
font-size: var(--font-ui-smaller);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.oas-card-children {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: baseline;
|
|
206
|
+
flex-wrap: wrap;
|
|
207
|
+
gap: var(--size-4-1);
|
|
208
|
+
padding: var(--size-4-1) var(--size-4-3);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.oas-card-children-label {
|
|
212
|
+
color: var(--text-faint);
|
|
213
|
+
font-size: var(--font-ui-smaller);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.oas-card-actions {
|
|
217
|
+
padding: var(--size-4-2) var(--size-4-3);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Gallery: vertical stack of cards below the heading */
|
|
221
|
+
.oas-gallery {
|
|
222
|
+
border-top: 1px solid var(--background-modifier-border);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Status badges for story live/draft state */
|
|
226
|
+
.oas-badge {
|
|
227
|
+
display: inline-flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
padding: 1px var(--size-4-1);
|
|
230
|
+
border-radius: var(--radius-s);
|
|
231
|
+
font-size: var(--font-ui-smaller);
|
|
232
|
+
font-weight: var(--font-medium);
|
|
233
|
+
vertical-align: middle;
|
|
234
|
+
margin-left: var(--size-4-1);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.oas-badge.is-live {
|
|
238
|
+
background: var(--background-modifier-success);
|
|
239
|
+
color: var(--text-success);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.oas-badge.is-draft {
|
|
243
|
+
background: var(--background-modifier-hover);
|
|
244
|
+
color: var(--text-faint);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Component viewer: sidebar (first child of the stage) + story page chrome. */
|
|
248
|
+
.oas-shell nav.oas-sidebar {
|
|
249
|
+
flex: 0 0 220px;
|
|
250
|
+
overflow-y: auto;
|
|
251
|
+
padding: var(--size-4-3) 0;
|
|
252
|
+
background: var(--background-secondary);
|
|
253
|
+
border-right: 1px solid var(--background-modifier-border);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.oas-shell nav.oas-sidebar a.oas-nav-item {
|
|
257
|
+
display: block;
|
|
258
|
+
text-decoration: none;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.oas-shell nav.oas-sidebar .oas-nav-invalid {
|
|
262
|
+
color: var(--text-error);
|
|
263
|
+
font-size: var(--font-ui-smaller);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.oas-frame .oas-story-meta {
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
gap: var(--size-4-1);
|
|
270
|
+
margin: var(--size-4-2) 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.oas-frame .oas-story-path {
|
|
274
|
+
display: flex;
|
|
275
|
+
align-items: center;
|
|
276
|
+
gap: var(--size-4-2);
|
|
277
|
+
font-size: var(--font-ui-smaller);
|
|
278
|
+
color: var(--text-muted);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.oas-frame .oas-story-path code {
|
|
282
|
+
font-family: var(--font-monospace);
|
|
283
|
+
color: var(--text-normal);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.oas-frame button.oas-copy {
|
|
287
|
+
height: var(--size-4-5);
|
|
288
|
+
padding: 0 var(--size-4-2);
|
|
289
|
+
font-size: var(--font-ui-smaller);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.oas-frame .oas-variants {
|
|
293
|
+
display: flex;
|
|
294
|
+
flex-wrap: wrap;
|
|
295
|
+
gap: var(--size-4-1);
|
|
296
|
+
margin: var(--size-4-2) 0;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.oas-frame a.oas-variant {
|
|
300
|
+
padding: var(--size-4-1) var(--size-4-2);
|
|
301
|
+
border-radius: var(--radius-s);
|
|
302
|
+
background: var(--background-modifier-hover);
|
|
303
|
+
color: var(--text-normal);
|
|
304
|
+
font-size: var(--font-ui-smaller);
|
|
305
|
+
text-decoration: none;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.oas-frame a.oas-variant.is-active {
|
|
309
|
+
background: var(--interactive-accent);
|
|
310
|
+
color: var(--text-on-accent);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.oas-frame .oas-story-notes {
|
|
314
|
+
margin: var(--size-4-2) 0;
|
|
315
|
+
color: var(--text-muted);
|
|
316
|
+
font-size: var(--font-ui-small);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.oas-frame .oas-story-children {
|
|
320
|
+
display: flex;
|
|
321
|
+
flex-wrap: wrap;
|
|
322
|
+
gap: var(--size-4-2);
|
|
323
|
+
margin: var(--size-4-2) 0;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.oas-frame a.oas-child {
|
|
327
|
+
color: var(--text-accent);
|
|
328
|
+
font-size: var(--font-ui-small);
|
|
329
|
+
text-decoration: none;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.oas-frame .oas-child-missing {
|
|
333
|
+
color: var(--text-error);
|
|
334
|
+
font-size: var(--font-ui-small);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.oas-frame .oas-story-canvas {
|
|
338
|
+
margin-top: var(--size-4-3);
|
|
339
|
+
padding-top: var(--size-4-3);
|
|
340
|
+
border-top: 1px solid var(--background-modifier-border);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.oas-frame .oas-story-missing {
|
|
344
|
+
color: var(--text-error);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* Reference index: token rows and class previews. */
|
|
348
|
+
.oas-frame input.oas-token-filter {
|
|
349
|
+
width: 100%;
|
|
350
|
+
margin: var(--size-4-2) 0 var(--size-4-3) 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.oas-frame .oas-token-group {
|
|
354
|
+
margin-bottom: var(--size-4-3);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.oas-frame .oas-token-row {
|
|
358
|
+
display: grid;
|
|
359
|
+
grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) 48px auto;
|
|
360
|
+
align-items: center;
|
|
361
|
+
gap: var(--size-4-2);
|
|
362
|
+
padding: var(--size-4-1) 0;
|
|
363
|
+
border-bottom: 1px solid var(--background-modifier-border);
|
|
364
|
+
font-size: var(--font-ui-smaller);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.oas-frame .oas-token-name {
|
|
368
|
+
font-family: var(--font-monospace);
|
|
369
|
+
overflow-wrap: anywhere;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.oas-frame .oas-token-value {
|
|
373
|
+
color: var(--text-muted);
|
|
374
|
+
overflow-wrap: anywhere;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.oas-frame .oas-swatch {
|
|
378
|
+
width: var(--size-4-4);
|
|
379
|
+
height: var(--size-4-4);
|
|
380
|
+
border-radius: var(--radius-s);
|
|
381
|
+
border: 1px solid var(--background-modifier-border);
|
|
382
|
+
justify-self: start;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.oas-frame .oas-sizebar {
|
|
386
|
+
height: var(--size-4-2);
|
|
387
|
+
max-width: 48px;
|
|
388
|
+
background: var(--text-accent);
|
|
389
|
+
border-radius: var(--radius-s);
|
|
390
|
+
justify-self: start;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.oas-frame .oas-swatch-none {
|
|
394
|
+
width: var(--size-4-4);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.oas-frame .oas-class-group {
|
|
398
|
+
margin-bottom: var(--size-4-4);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.oas-frame .oas-class-entry {
|
|
402
|
+
margin: var(--size-4-3) 0;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.oas-frame .oas-class-head {
|
|
406
|
+
display: flex;
|
|
407
|
+
align-items: center;
|
|
408
|
+
gap: var(--size-4-2);
|
|
409
|
+
font-family: var(--font-monospace);
|
|
410
|
+
font-size: var(--font-ui-small);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.oas-frame .oas-class-when {
|
|
414
|
+
margin: var(--size-4-1) 0;
|
|
415
|
+
color: var(--text-muted);
|
|
416
|
+
font-size: var(--font-ui-smaller);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/* transform creates a containing block, so position:fixed descendants (e.g.
|
|
420
|
+
.modal) stay inside the preview box instead of covering the viewport. */
|
|
421
|
+
.oas-frame .oas-class-preview {
|
|
422
|
+
padding: var(--size-4-3);
|
|
423
|
+
border: 1px dashed var(--background-modifier-border);
|
|
424
|
+
border-radius: var(--radius-m);
|
|
425
|
+
transform: translate(0);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.oas-frame .modal.oas-modal-preview {
|
|
429
|
+
position: static;
|
|
430
|
+
width: auto;
|
|
431
|
+
max-width: 100%;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* DiffViewer — CodeMirror 6 MergeView container */
|
|
435
|
+
.oas-diff-viewer {
|
|
436
|
+
height: 480px;
|
|
437
|
+
overflow: hidden;
|
|
438
|
+
border: 1px solid var(--background-modifier-border);
|
|
439
|
+
border-radius: var(--radius-m);
|
|
440
|
+
font-family: var(--font-monospace);
|
|
441
|
+
font-size: var(--font-ui-small);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.oas-diff-viewer .cm-mergeView {
|
|
445
|
+
height: 100%;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.oas-diff-viewer .cm-editor {
|
|
449
|
+
height: 100%;
|
|
450
|
+
background: var(--background-primary);
|
|
451
|
+
color: var(--text-normal);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.oas-diff-viewer .cm-scroller {
|
|
455
|
+
overflow: auto;
|
|
456
|
+
font-family: var(--font-monospace);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.oas-diff-viewer .cm-mergeViewEditor {
|
|
460
|
+
border-right: 1px solid var(--background-modifier-border);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.oas-diff-viewer .cm-mergeViewEditor:last-child {
|
|
464
|
+
border-right: none;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.oas-diff-viewer .cm-deletedChunk {
|
|
468
|
+
background: color-mix(in srgb, var(--color-red) 15%, transparent);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.oas-diff-viewer .cm-insertedChunk,
|
|
472
|
+
.oas-diff-viewer .cm-changedLine {
|
|
473
|
+
background: color-mix(in srgb, var(--color-green) 12%, transparent);
|
|
474
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { component, html } from "@arrow-js/core";
|
|
2
|
+
import { copyText } from "./StoryPage";
|
|
3
|
+
import { classGroups } from "./obsidian-classes";
|
|
4
|
+
|
|
5
|
+
export const ClassesPage = component(() => {
|
|
6
|
+
return html`
|
|
7
|
+
<div class="oas-reference">
|
|
8
|
+
<div class="setting-item setting-item-heading">
|
|
9
|
+
<div class="setting-item-info">
|
|
10
|
+
<div class="setting-item-name">Obsidian classes</div>
|
|
11
|
+
<div class="setting-item-description">
|
|
12
|
+
Curated pattern classes worth leveraging, rendered live against app.css.
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
${classGroups.map(
|
|
17
|
+
(group) => html`
|
|
18
|
+
<div class="oas-class-group">
|
|
19
|
+
<div class="vertical-tab-header-group-title">${group.label}</div>
|
|
20
|
+
${group.entries.map(
|
|
21
|
+
(entry) => html`
|
|
22
|
+
<div class="oas-class-entry">
|
|
23
|
+
<div class="oas-class-head">
|
|
24
|
+
<code>${entry.className}</code>
|
|
25
|
+
<button class="oas-copy" @click="${() => copyText(entry.className)}">Copy</button>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="oas-class-when">${entry.whenToUse}</div>
|
|
28
|
+
<div class="oas-class-preview">${entry.preview()}</div>
|
|
29
|
+
</div>
|
|
30
|
+
`
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
`
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
`;
|
|
37
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { html } from "@arrow-js/core";
|
|
2
|
+
import type { ArrowExpression } from "@arrow-js/core";
|
|
3
|
+
import { stories } from "./discovery";
|
|
4
|
+
|
|
5
|
+
export function ComponentsIndex(): ArrowExpression {
|
|
6
|
+
if (stories.length === 0) {
|
|
7
|
+
return html`
|
|
8
|
+
<div class="oas-settings">
|
|
9
|
+
<div class="setting-item setting-item-heading">
|
|
10
|
+
<div class="setting-item-info">
|
|
11
|
+
<div class="setting-item-name">Components</div>
|
|
12
|
+
<div class="setting-item-description">
|
|
13
|
+
No stories found. Create a <code>*.stories.ts</code> file next to a component.
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
return html`
|
|
21
|
+
<div class="oas-settings">
|
|
22
|
+
<div class="setting-item setting-item-heading">
|
|
23
|
+
<div class="setting-item-info">
|
|
24
|
+
<div class="setting-item-name">Components</div>
|
|
25
|
+
<div class="setting-item-description">
|
|
26
|
+
${stories.length} ${stories.length === 1 ? "story" : "stories"} — click to open.
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
${stories.map((story) => {
|
|
31
|
+
const path = `/components/${story.slug}`;
|
|
32
|
+
const badge =
|
|
33
|
+
story.status === "live"
|
|
34
|
+
? html`<span class="oas-badge is-live">live</span>`
|
|
35
|
+
: html`<span class="oas-badge is-draft">draft</span>`;
|
|
36
|
+
return html`
|
|
37
|
+
<div class="setting-item">
|
|
38
|
+
<div class="setting-item-info">
|
|
39
|
+
<div class="setting-item-name">
|
|
40
|
+
<a href="${path}">${story.title}</a> ${badge}
|
|
41
|
+
</div>
|
|
42
|
+
${
|
|
43
|
+
story.description
|
|
44
|
+
? html`<div class="setting-item-description">${story.description}</div>`
|
|
45
|
+
: ""
|
|
46
|
+
}
|
|
47
|
+
</div>
|
|
48
|
+
<div class="setting-item-control">
|
|
49
|
+
<a class="mod-cta oas-open-link" href="${path}">Open →</a>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`.key(story.slug);
|
|
53
|
+
})}
|
|
54
|
+
</div>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { html } from "@arrow-js/core";
|
|
2
|
+
import type { ArrowExpression } from "@arrow-js/core";
|
|
3
|
+
import type { DiscoveredStory } from "./discovery";
|
|
4
|
+
import { findStory } from "./discovery";
|
|
5
|
+
|
|
6
|
+
/** Copy to clipboard, best-effort (clipboard API needs a secure context). */
|
|
7
|
+
export function copyText(text: string): void {
|
|
8
|
+
void navigator.clipboard?.writeText(text);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function pathRow(label: string, path: string): ArrowExpression {
|
|
12
|
+
return html`
|
|
13
|
+
<div class="oas-story-path">
|
|
14
|
+
<span class="oas-path-label">${label}</span>
|
|
15
|
+
<code>${path}</code>
|
|
16
|
+
<button class="oas-copy" @click="${() => copyText(path)}">Copy</button>
|
|
17
|
+
</div>
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function StoryPage(story: DiscoveredStory, variantName: string): ArrowExpression {
|
|
22
|
+
const variant = story.variants[variantName];
|
|
23
|
+
const variantNames = Object.keys(story.variants);
|
|
24
|
+
const badge =
|
|
25
|
+
story.status === "live"
|
|
26
|
+
? html`<span class="oas-badge is-live">live</span>`
|
|
27
|
+
: html`<span class="oas-badge is-draft">draft</span>`;
|
|
28
|
+
return html`
|
|
29
|
+
<div class="oas-story">
|
|
30
|
+
<div class="setting-item setting-item-heading">
|
|
31
|
+
<div class="setting-item-info">
|
|
32
|
+
<div class="setting-item-name">${story.title} ${badge}</div>
|
|
33
|
+
${
|
|
34
|
+
story.description
|
|
35
|
+
? html`<div class="setting-item-description">${story.description}</div>`
|
|
36
|
+
: ""
|
|
37
|
+
}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="oas-story-meta">
|
|
41
|
+
${pathRow("component", story.componentPath)}
|
|
42
|
+
${pathRow("stories", story.storiesPath)}
|
|
43
|
+
</div>
|
|
44
|
+
<div class="oas-variants">
|
|
45
|
+
${variantNames.map((name) => {
|
|
46
|
+
const cls = name === variantName ? "oas-variant is-active" : "oas-variant";
|
|
47
|
+
const href = `/components/${story.slug}?variant=${encodeURIComponent(name)}`;
|
|
48
|
+
return html`<a class="${cls}" href="${href}">${name}</a>`;
|
|
49
|
+
})}
|
|
50
|
+
</div>
|
|
51
|
+
${variant?.notes ? html`<div class="oas-story-notes">${variant.notes}</div>` : ""}
|
|
52
|
+
${
|
|
53
|
+
story.children.length > 0
|
|
54
|
+
? html`<div class="oas-story-children">
|
|
55
|
+
${story.children.map((slug) => {
|
|
56
|
+
const child = findStory(slug);
|
|
57
|
+
return child
|
|
58
|
+
? html`<a class="oas-child" href="${`/components/${slug}`}">${child.title} →</a>`
|
|
59
|
+
: html`<span class="oas-child-missing">${slug} (missing story)</span>`;
|
|
60
|
+
})}
|
|
61
|
+
</div>`
|
|
62
|
+
: ""
|
|
63
|
+
}
|
|
64
|
+
<div class="oas-story-canvas">
|
|
65
|
+
${
|
|
66
|
+
variant
|
|
67
|
+
? variant.render()
|
|
68
|
+
: html`<div class="oas-story-missing">No variant "${variantName}" — pick one above.</div>`
|
|
69
|
+
}
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
`;
|
|
73
|
+
}
|