@nowline/preview-shell 0.0.0-dev.20260601071750.g04bdff9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/styles.js ADDED
@@ -0,0 +1,521 @@
1
+ // Stylesheet for `mountPreview()`. Uses neutral `--nl-preview-*` CSS
2
+ // custom properties throughout so consumers can re-skin the viewport
3
+ // without forking the package. Sensible defaults baked in so the
4
+ // viewport works out of the box on a blank page.
5
+ //
6
+ // Chrome (toolbar, menus, minimap) uses `--nl-chrome-*` tokens driven
7
+ // exclusively by the `data-nl-mode="light|dark"` attribute on the root
8
+ // element — these intentionally do NOT inherit VS Code workbench colors
9
+ // so the toolbar stays readable regardless of the active editor theme.
10
+ //
11
+ // VS Code consumers paste `VSCODE_THEME_BRIDGE_CSS` into their webview
12
+ // to map viewport/canvas `--nl-preview-*` tokens to `--vscode-*`
13
+ // variables. This bridge no longer touches chrome tokens.
14
+ /**
15
+ * Bridge CSS for VS Code webview consumers. Maps viewport and
16
+ * diagnostic `--nl-preview-*` tokens to `--vscode-*` variables.
17
+ * Does NOT map chrome (toolbar/menu) tokens — those are driven by
18
+ * `data-nl-mode` so the toolbar palette is independent of the
19
+ * workbench color theme.
20
+ *
21
+ * Inject as a `<style>` block after the preview-shell stylesheet.
22
+ */
23
+ export const VSCODE_THEME_BRIDGE_CSS = `
24
+ :root {
25
+ --nl-preview-bg: var(--vscode-editor-background, #1e1e1e);
26
+ --nl-preview-fg: var(--vscode-editor-foreground, #d4d4d4);
27
+ --nl-preview-font-family: var(--vscode-font-family, system-ui, sans-serif);
28
+ --nl-preview-font-size: var(--vscode-font-size, 13px);
29
+ --nl-preview-widget-bg: var(--vscode-editorWidget-background, rgba(40,40,40,0.9));
30
+ --nl-preview-widget-border: var(--vscode-editorWidget-border, rgba(255,255,255,0.1));
31
+ --nl-preview-description: var(--vscode-descriptionForeground, #999);
32
+ --nl-preview-error: var(--vscode-editorError-foreground, #f48771);
33
+ --nl-preview-warning: var(--vscode-editorWarning-foreground, #cca700);
34
+ --nl-preview-link: var(--vscode-textLink-foreground, #3794ff);
35
+ --nl-preview-focus: var(--vscode-focusBorder, #007acc);
36
+ --nl-preview-code-bg: var(--vscode-textBlockQuote-background, rgba(255,255,255,0.05));
37
+ --nl-preview-mono: var(--vscode-editor-font-family, monospace);
38
+ }
39
+ `;
40
+ /**
41
+ * Default stylesheet for the viewport. Provides reasonable defaults
42
+ * for every `--nl-preview-*` token and both dark/light `--nl-chrome-*`
43
+ * palettes so the viewport works on a blank page without any bridge CSS.
44
+ */
45
+ export const PREVIEW_SHELL_CSS = `
46
+ :root {
47
+ color-scheme: light dark;
48
+ --nl-preview-bg: #1e1e1e;
49
+ --nl-preview-fg: #d4d4d4;
50
+ --nl-preview-font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
51
+ --nl-preview-font-size: 13px;
52
+ --nl-preview-widget-bg: rgba(40,40,40,0.9);
53
+ --nl-preview-widget-border: rgba(255,255,255,0.1);
54
+ --nl-preview-description: #999;
55
+ --nl-preview-error: #f48771;
56
+ --nl-preview-warning: #cca700;
57
+ --nl-preview-link: #3794ff;
58
+ --nl-preview-focus: #007acc;
59
+ --nl-preview-code-bg: rgba(255,255,255,0.05);
60
+ --nl-preview-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
61
+ }
62
+ .nl-preview-root {
63
+ position: relative;
64
+ width: 100%; height: 100%;
65
+ background: var(--nl-preview-bg);
66
+ color: var(--nl-preview-fg);
67
+ font-family: var(--nl-preview-font-family);
68
+ font-size: var(--nl-preview-font-size);
69
+ overflow: hidden;
70
+ /* Shared positioning gutter for all floating elements */
71
+ --nl-preview-gutter: 8px;
72
+ /* Chrome palette — dark default */
73
+ --nl-chrome-bg: rgba(30, 30, 30, 0.93);
74
+ --nl-chrome-border: rgba(255, 255, 255, 0.11);
75
+ --nl-chrome-fg: #d4d4d4;
76
+ --nl-chrome-hover: rgba(255, 255, 255, 0.08);
77
+ --nl-chrome-active: rgba(255, 255, 255, 0.13);
78
+ --nl-chrome-muted: #888;
79
+ --nl-chrome-chip-bg: rgba(255, 255, 255, 0.07);
80
+ --nl-chrome-shadow: rgba(0, 0, 0, 0.32);
81
+ }
82
+ /* Chrome palette — light mode override (driven by data-nl-mode, never by workbench) */
83
+ .nl-preview-root[data-nl-mode="light"] {
84
+ --nl-chrome-bg: rgba(248, 248, 248, 0.96);
85
+ --nl-chrome-border: rgba(0, 0, 0, 0.13);
86
+ --nl-chrome-fg: #3c3c3c;
87
+ --nl-chrome-hover: rgba(0, 0, 0, 0.06);
88
+ --nl-chrome-active: rgba(0, 0, 0, 0.10);
89
+ --nl-chrome-muted: #717171;
90
+ --nl-chrome-chip-bg: rgba(0, 0, 0, 0.06);
91
+ --nl-chrome-shadow: rgba(0, 0, 0, 0.14);
92
+ }
93
+ .nl-preview-root .viewport {
94
+ position: absolute; inset: 0;
95
+ overflow: auto;
96
+ display: flex;
97
+ }
98
+ .nl-preview-root .canvas {
99
+ /* flex-shrink:0 + margin:auto: centers the diagram when it fits,
100
+ allows overflow scroll when it's larger than the viewport */
101
+ flex-shrink: 0;
102
+ margin: auto;
103
+ transform-origin: 0 0;
104
+ will-change: transform;
105
+ }
106
+ .nl-preview-root .canvas svg { display: block; max-width: none; height: auto; }
107
+ .nl-preview-root .canvas.dimmed { opacity: 0.25; pointer-events: none; }
108
+
109
+ /* === Toolbar (floating, repositionable) === */
110
+ .nl-preview-root .chrome {
111
+ position: absolute;
112
+ top: var(--nl-preview-gutter);
113
+ right: var(--nl-preview-gutter);
114
+ display: flex; gap: 4px;
115
+ /* Keep the toolbar at its natural width so a narrowing viewport
116
+ shifts it left (handled in JS) instead of squishing the row. */
117
+ width: max-content;
118
+ transition: opacity 200ms ease;
119
+ z-index: 10;
120
+ }
121
+ .nl-preview-root .chrome.faded { opacity: 0.2; pointer-events: none; }
122
+ .nl-preview-root .chrome:hover { opacity: 1; pointer-events: auto; }
123
+ .nl-preview-root .toolbar {
124
+ display: flex; align-items: center; gap: 2px;
125
+ flex-wrap: nowrap;
126
+ white-space: nowrap;
127
+ padding: 2px;
128
+ background: var(--nl-chrome-bg);
129
+ border: 1px solid var(--nl-chrome-border);
130
+ border-radius: 6px;
131
+ box-shadow: 0 2px 8px var(--nl-chrome-shadow);
132
+ color: var(--nl-chrome-fg);
133
+ user-select: none;
134
+ }
135
+
136
+ /* Collapsed puck: hide everything but the drag grip + restore arrow,
137
+ and dim it so it stays out of the way until hovered. */
138
+ .nl-preview-root .restore-btn { display: none; }
139
+ .nl-preview-root .chrome.collapsed .toolbar > :not(.toolbar-handle):not(.restore-btn) {
140
+ display: none;
141
+ }
142
+ .nl-preview-root .chrome.collapsed .restore-btn { display: inline-flex; }
143
+ .nl-preview-root .chrome.collapsed .toolbar { opacity: 0.55; }
144
+ .nl-preview-root .chrome.collapsed:hover .toolbar { opacity: 1; }
145
+ .nl-preview-root .toolbar .sep {
146
+ width: 1px; height: 18px;
147
+ background: var(--nl-chrome-border);
148
+ margin: 0 3px;
149
+ flex-shrink: 0;
150
+ }
151
+ .nl-preview-root .toolbar-handle {
152
+ display: flex; align-items: center; justify-content: center;
153
+ padding: 4px 5px;
154
+ cursor: grab;
155
+ color: var(--nl-chrome-muted);
156
+ font-size: 13px;
157
+ line-height: 1;
158
+ opacity: 0.7;
159
+ flex-shrink: 0;
160
+ touch-action: none;
161
+ }
162
+ .nl-preview-root .toolbar-handle:hover { opacity: 1; }
163
+ .nl-preview-root .chrome.dragging .toolbar-handle { cursor: grabbing; }
164
+ .nl-preview-root .btn {
165
+ appearance: none;
166
+ background: transparent;
167
+ color: inherit;
168
+ border: 0;
169
+ padding: 3px 7px;
170
+ border-radius: 4px;
171
+ font-family: inherit;
172
+ font-size: inherit;
173
+ cursor: pointer;
174
+ line-height: 1;
175
+ min-width: 20px;
176
+ flex-shrink: 0;
177
+ /* Suppress the sticky focus ring left behind after a mouse click;
178
+ keyboard focus is restored via :focus-visible below. */
179
+ outline: none;
180
+ }
181
+ .nl-preview-root .btn:hover { background: var(--nl-chrome-hover); }
182
+ .nl-preview-root .btn:active { background: var(--nl-chrome-active); }
183
+ .nl-preview-root .btn:focus-visible {
184
+ outline: 1px solid var(--nl-preview-focus);
185
+ outline-offset: -1px;
186
+ }
187
+ .nl-preview-root .btn.zoom-label {
188
+ min-width: 44px;
189
+ font-variant-numeric: tabular-nums;
190
+ }
191
+ .nl-preview-root .btn.glyph { font-size: 15px; line-height: 1; padding: 3px 5px; }
192
+ .nl-preview-root .dropdown { position: relative; }
193
+
194
+ /* === More-menu panel === */
195
+ .nl-preview-root .more-menu {
196
+ position: absolute; top: calc(100% + 4px); right: 0;
197
+ padding: 5px;
198
+ min-width: 210px;
199
+ background: var(--nl-chrome-bg);
200
+ border: 1px solid var(--nl-chrome-border);
201
+ border-radius: 6px;
202
+ box-shadow: 0 4px 14px var(--nl-chrome-shadow);
203
+ z-index: 20;
204
+ color: var(--nl-chrome-fg);
205
+ }
206
+ /* Opens right-aligned by default; flipped to left-aligned in JS when the
207
+ toolbar sits near the left edge and the menu would clip the gutter. */
208
+ .nl-preview-root .more-menu.flip { right: auto; left: 0; }
209
+ .nl-preview-root .more-row {
210
+ display: flex; align-items: center; justify-content: space-between;
211
+ padding: 2px 4px;
212
+ gap: 8px;
213
+ }
214
+ .nl-preview-root .more-row.action-row {
215
+ gap: 6px;
216
+ justify-content: stretch;
217
+ padding-top: 6px;
218
+ padding-bottom: 2px;
219
+ }
220
+ /* Copy / Export each take half the row and center their label+icon. */
221
+ .nl-preview-root .action-row .btn {
222
+ flex: 1 1 0;
223
+ display: inline-flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ gap: 5px;
227
+ }
228
+ .nl-preview-root .action-ico { display: inline-flex; line-height: 0; }
229
+ .nl-preview-root .action-ico svg { display: block; }
230
+ .nl-preview-root .more-label {
231
+ font-size: 0.88em;
232
+ color: var(--nl-chrome-muted);
233
+ white-space: nowrap;
234
+ flex-shrink: 0;
235
+ }
236
+ .nl-preview-root .more-divider {
237
+ height: 1px;
238
+ margin: 4px 0;
239
+ background: var(--nl-chrome-border);
240
+ }
241
+
242
+ /* === Sub-menus inside more-menu === */
243
+ .nl-preview-root .more-sub-toggle {
244
+ font-size: 0.88em;
245
+ padding: 3px 6px;
246
+ }
247
+ .nl-preview-root .more-sub-menu {
248
+ position: absolute; top: calc(100% + 2px); left: 0;
249
+ list-style: none; padding: 4px;
250
+ /* Size to the widest option (plus the checkmark gutter) rather than
251
+ a fixed min-width, so there's no dead whitespace to the right. */
252
+ width: max-content; min-width: 0; max-width: 280px;
253
+ background: var(--nl-chrome-bg);
254
+ border: 1px solid var(--nl-chrome-border);
255
+ border-radius: 6px;
256
+ box-shadow: 0 4px 12px var(--nl-chrome-shadow);
257
+ z-index: 25;
258
+ color: var(--nl-chrome-fg);
259
+ }
260
+ /* Flyout flipped to open toward the left (set in JS when the default
261
+ right-ward opening would overflow the viewport gutter). */
262
+ .nl-preview-root .more-sub-menu.flip { left: auto; right: 0; }
263
+ .nl-preview-root .more-sub-menu li { padding: 0; }
264
+ .nl-preview-root .more-sub-menu .btn {
265
+ display: block; width: 100%; text-align: left;
266
+ /* Generous left gutter keeps the checkmark off the label text. */
267
+ padding: 5px 12px 5px 26px;
268
+ position: relative;
269
+ font-size: 0.88em;
270
+ }
271
+ .nl-preview-root .more-sub-menu .btn[data-active="true"]::before {
272
+ content: '\\2713';
273
+ position: absolute;
274
+ left: 9px;
275
+ }
276
+
277
+ /* === Code-style chip for real theme/format tokens === */
278
+ .nl-preview-root .code-chip {
279
+ font-family: var(--nl-preview-mono);
280
+ font-size: 0.9em;
281
+ background: var(--nl-chrome-chip-bg);
282
+ border-radius: 3px;
283
+ padding: 1px 4px;
284
+ font-style: normal;
285
+ }
286
+
287
+ /* === Diagnostic overlay menu (for old .menu usage in diagnostics) === */
288
+ .nl-preview-root .menu {
289
+ position: absolute; top: 100%; right: 0; margin-top: 4px;
290
+ list-style: none; padding: 4px; min-width: 140px;
291
+ background: var(--nl-chrome-bg);
292
+ border: 1px solid var(--nl-chrome-border);
293
+ border-radius: 6px;
294
+ box-shadow: 0 4px 12px var(--nl-chrome-shadow);
295
+ z-index: 20;
296
+ color: var(--nl-chrome-fg);
297
+ }
298
+ .nl-preview-root .menu li { padding: 0; }
299
+ .nl-preview-root .menu .btn {
300
+ display: block; width: 100%; text-align: left;
301
+ padding: 6px 10px;
302
+ }
303
+ .nl-preview-root .menu li.menu-section {
304
+ padding: 4px 10px 2px;
305
+ font-size: 0.85em;
306
+ text-transform: uppercase;
307
+ letter-spacing: 0.05em;
308
+ color: var(--nl-chrome-muted);
309
+ }
310
+ .nl-preview-root .menu li.menu-divider {
311
+ height: 1px;
312
+ margin: 4px 6px;
313
+ background: var(--nl-chrome-border);
314
+ }
315
+
316
+ /* === Minimap (subordinate floating widget) === */
317
+ .nl-preview-root .minimap {
318
+ position: absolute;
319
+ bottom: var(--nl-preview-gutter);
320
+ right: var(--nl-preview-gutter);
321
+ width: 120px; max-height: 90px;
322
+ background: var(--nl-chrome-bg);
323
+ border: 1px solid var(--nl-chrome-border);
324
+ border-radius: 5px;
325
+ overflow: hidden;
326
+ box-shadow: 0 2px 6px var(--nl-chrome-shadow);
327
+ z-index: 8;
328
+ transition: opacity 200ms ease;
329
+ }
330
+ .nl-preview-root .minimap.hidden { display: none; }
331
+ .nl-preview-root .minimap.faded { opacity: 0.2; pointer-events: none; }
332
+ .nl-preview-root .minimap-canvas {
333
+ display: block;
334
+ cursor: pointer;
335
+ user-select: none;
336
+ }
337
+ .nl-preview-root .minimap-canvas svg {
338
+ display: block;
339
+ width: 100%;
340
+ height: auto;
341
+ pointer-events: none;
342
+ }
343
+ .nl-preview-root .minimap-rect {
344
+ position: absolute;
345
+ border: 2px solid var(--nl-preview-focus);
346
+ background-color: color-mix(in srgb, var(--nl-preview-focus) 18%, transparent);
347
+ pointer-events: none;
348
+ box-sizing: border-box;
349
+ }
350
+ .nl-preview-root .minimap-close {
351
+ position: absolute; top: 2px; right: 2px;
352
+ width: 16px; height: 16px; padding: 0;
353
+ border-radius: 3px;
354
+ line-height: 1;
355
+ font-size: 11px;
356
+ z-index: 1;
357
+ }
358
+
359
+ /* === Calendar picker === */
360
+ .nl-preview-root .now-picker {
361
+ position: absolute; top: calc(100% + 2px); left: 0;
362
+ padding: 8px;
363
+ min-width: 200px;
364
+ background: var(--nl-chrome-bg);
365
+ border: 1px solid var(--nl-chrome-border);
366
+ border-radius: 6px;
367
+ box-shadow: 0 4px 14px var(--nl-chrome-shadow);
368
+ z-index: 26;
369
+ color: var(--nl-chrome-fg);
370
+ }
371
+ /* Calendar flips to open toward the left when opening rightward would
372
+ push it past the viewport's right gutter (see placeFlyout). */
373
+ .nl-preview-root .now-picker.flip { left: auto; right: 0; }
374
+ .nl-preview-root .cal-nav {
375
+ display: flex; align-items: center; justify-content: space-between;
376
+ margin-bottom: 6px;
377
+ }
378
+ .nl-preview-root .cal-heading {
379
+ font-size: 0.85em;
380
+ font-weight: 600;
381
+ }
382
+ .nl-preview-root .cal-nav-btn {
383
+ padding: 2px 6px;
384
+ min-width: unset;
385
+ font-size: 14px;
386
+ }
387
+ .nl-preview-root .cal-grid {
388
+ display: grid; grid-template-columns: repeat(7, 1fr);
389
+ gap: 1px;
390
+ margin-bottom: 6px;
391
+ }
392
+ .nl-preview-root .cal-dow {
393
+ text-align: center;
394
+ font-size: 0.75em;
395
+ color: var(--nl-chrome-muted);
396
+ padding: 2px 0;
397
+ }
398
+ .nl-preview-root .cal-empty {
399
+ /* placeholder for days before the 1st of the month */
400
+ }
401
+ .nl-preview-root .cal-day {
402
+ padding: 3px 2px;
403
+ min-width: unset;
404
+ font-size: 0.8em;
405
+ text-align: center;
406
+ border-radius: 3px;
407
+ }
408
+ .nl-preview-root .cal-day.is-today { font-weight: 700; }
409
+ .nl-preview-root .cal-day.is-selected {
410
+ background: var(--nl-chrome-hover);
411
+ outline: 1px solid var(--nl-chrome-border);
412
+ }
413
+ .nl-preview-root .cal-footer {
414
+ display: flex; gap: 4px;
415
+ border-top: 1px solid var(--nl-chrome-border);
416
+ padding-top: 6px;
417
+ margin-top: 2px;
418
+ }
419
+ .nl-preview-root .cal-footer-btn {
420
+ flex: 1;
421
+ text-align: center;
422
+ font-size: 0.82em;
423
+ padding: 4px 6px;
424
+ min-width: unset;
425
+ }
426
+
427
+ /* === Diagnostics overlay === */
428
+ .nl-preview-root .diagnostics {
429
+ position: absolute; left: 0; right: 0; bottom: 0;
430
+ max-height: 60%;
431
+ background: var(--nl-preview-widget-bg);
432
+ border-top: 1px solid var(--nl-preview-widget-border);
433
+ overflow: auto;
434
+ z-index: 12;
435
+ padding: 0;
436
+ display: none;
437
+ }
438
+ .nl-preview-root .diagnostics.show { display: block; }
439
+ .nl-preview-root .diag-header {
440
+ position: sticky; top: 0;
441
+ display: flex; align-items: center; justify-content: space-between;
442
+ padding: 6px 12px;
443
+ background: inherit;
444
+ border-bottom: 1px solid var(--nl-preview-widget-border);
445
+ font-weight: 600;
446
+ }
447
+ .nl-preview-root .diag-summary {
448
+ color: var(--nl-preview-error);
449
+ }
450
+ .nl-preview-root .diag-summary.warn-only {
451
+ color: var(--nl-preview-warning);
452
+ }
453
+ .nl-preview-root .diag-summary.clean {
454
+ color: var(--nl-preview-description);
455
+ font-weight: normal;
456
+ }
457
+ .nl-preview-root .open-problems {
458
+ color: var(--nl-preview-link);
459
+ cursor: pointer;
460
+ text-decoration: none;
461
+ font-weight: normal;
462
+ }
463
+ .nl-preview-root .open-problems:hover { text-decoration: underline; }
464
+ .nl-preview-root .diag-table {
465
+ width: 100%;
466
+ border-collapse: collapse;
467
+ }
468
+ .nl-preview-root .diag-table tr {
469
+ cursor: pointer;
470
+ border-bottom: 1px solid var(--nl-preview-widget-border);
471
+ }
472
+ .nl-preview-root .diag-table tr:hover {
473
+ background: rgba(255,255,255,0.04);
474
+ }
475
+ .nl-preview-root .diag-table td {
476
+ padding: 6px 8px;
477
+ vertical-align: top;
478
+ }
479
+ .nl-preview-root .sev-cell {
480
+ width: 24px; text-align: center;
481
+ font-weight: bold;
482
+ }
483
+ .nl-preview-root .sev-error { color: var(--nl-preview-error); }
484
+ .nl-preview-root .sev-warning { color: var(--nl-preview-warning); }
485
+ .nl-preview-root .loc-cell {
486
+ white-space: nowrap;
487
+ color: var(--nl-preview-description);
488
+ font-variant-numeric: tabular-nums;
489
+ width: 90px;
490
+ }
491
+ .nl-preview-root .code-cell {
492
+ white-space: nowrap;
493
+ width: 1%;
494
+ }
495
+ .nl-preview-root .code-pill {
496
+ display: inline-block;
497
+ padding: 1px 6px;
498
+ border-radius: 3px;
499
+ background: var(--nl-preview-code-bg);
500
+ color: var(--nl-preview-description);
501
+ font-family: var(--nl-preview-mono);
502
+ font-size: 0.9em;
503
+ }
504
+ .nl-preview-root .msg-cell { word-break: break-word; }
505
+ .nl-preview-root .suggestion {
506
+ display: block; margin-top: 2px;
507
+ color: var(--nl-preview-description);
508
+ font-style: italic;
509
+ font-size: 0.95em;
510
+ }
511
+
512
+ /* === Empty state === */
513
+ .nl-preview-root .empty {
514
+ position: absolute; inset: 0;
515
+ display: flex; align-items: center; justify-content: center;
516
+ color: var(--nl-preview-description);
517
+ pointer-events: none;
518
+ }
519
+ .nl-preview-root .empty.hidden { display: none; }
520
+ `;
521
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qEAAqE;AACrE,iEAAiE;AACjE,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,wEAAwE;AACxE,uEAAuE;AACvE,EAAE;AACF,uEAAuE;AACvE,iEAAiE;AACjE,0DAA0D;AAE1D;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;CAgBtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2dhC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@nowline/preview-shell",
3
+ "version": "0.0.0-dev.20260601071750.g04bdff9",
4
+ "description": "Framework-agnostic preview viewport for Nowline SVGs: zoom, pan, fit, minimap, diagnostic table. Consumed by the VS Code extension's webview and any browser-side Nowline preview surface.",
5
+ "license": "Apache-2.0",
6
+ "engines": {
7
+ "node": ">=22",
8
+ "pnpm": ">=11"
9
+ },
10
+ "type": "module",
11
+ "sideEffects": false,
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist/",
22
+ "src/"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/lolay/nowline.git",
27
+ "directory": "packages/preview-shell"
28
+ },
29
+ "homepage": "https://github.com/lolay/nowline",
30
+ "bugs": {
31
+ "url": "https://github.com/lolay/nowline/issues"
32
+ },
33
+ "keywords": [
34
+ "nowline",
35
+ "preview",
36
+ "viewport",
37
+ "svg",
38
+ "zoom",
39
+ "pan",
40
+ "minimap"
41
+ ],
42
+ "dependencies": {
43
+ "@nowline/browser": "0.0.0-dev.20260601071750.g04bdff9"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^25.9.1",
47
+ "happy-dom": "^20.9.0",
48
+ "typescript": "^6.0.3",
49
+ "vitest": "^4.1.7"
50
+ },
51
+ "scripts": {
52
+ "build": "tsc -b tsconfig.json",
53
+ "watch": "tsc -b tsconfig.json --watch",
54
+ "typecheck": "tsc --noEmit -p tsconfig.json",
55
+ "test": "vitest run",
56
+ "test:watch": "vitest"
57
+ }
58
+ }
package/src/index.ts ADDED
@@ -0,0 +1,23 @@
1
+ // Public API for `@nowline/preview-shell`.
2
+ //
3
+ // Mounts a self-contained preview viewport (zoom, pan, fit, minimap,
4
+ // diagnostic table) into a host-supplied element and returns an
5
+ // imperative handle. Consumers feed in SVG + diagnostics; user
6
+ // interactions surface via callback options. No assumed text editor,
7
+ // no assumed message bus, no VS Code coupling.
8
+
9
+ export type { DiagnosticRow } from '@nowline/browser';
10
+ export {
11
+ __resetPreviewShellStylesheetForTests,
12
+ type DiagnosticGoto,
13
+ type ExportRequest,
14
+ type InitialFit,
15
+ type MountPreviewOptions,
16
+ mountPreview,
17
+ type NowOverride,
18
+ type PreviewHandle,
19
+ type ThemeOverride,
20
+ type ViewBaseline,
21
+ type ViewOptionsOverrides,
22
+ } from './mount.js';
23
+ export { PREVIEW_SHELL_CSS, VSCODE_THEME_BRIDGE_CSS } from './styles.js';