@fusion.dev/helix 0.205.0 → 0.205.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.json +1 -1
- package/custom-elements.json +54 -2
- package/dist/sandbox/frame.d.ts +2 -0
- package/dist/sandbox/frame.js +1 -0
- package/dist/sandbox/preview/sandbox-preview.css.js +1 -1
- package/dist/sandbox/preview/sandbox-preview.d.ts +14 -1
- package/dist/sandbox/preview/sandbox-preview.js +19 -0
- package/lint.json +1 -1
- package/package.json +6 -6
- package/skills/helix/SKILL.md +2 -2
- package/types/jsx.d.ts +2 -0
package/custom-elements.json
CHANGED
|
@@ -178501,7 +178501,7 @@
|
|
|
178501
178501
|
}
|
|
178502
178502
|
}
|
|
178503
178503
|
],
|
|
178504
|
-
"description": "Serves the frame side of a sandbox preview, in the document its `src` loads.\n\nCall it once from that document, after the elements your examples use are\ndefined. It does what the preview's protocol asks of a frame:\n\n- Posts `helix-preview-ready` once it listens.\n- Writes each `helix-preview-render` into the root: the markup, the\n stylesheet, the direction, the layout and the color mode. Scripts in the\n markup run.\n- Posts every console call, uncaught error, and unhandled promise rejection\n as `helix-preview-console`, an uncaught one marked `uncaught`, which marks\n the preview `failed`.\n- Posts `helix-preview-size` whenever what was drawn changes height.\n- Posts `helix-preview-press` on every press, so menus outside close.\n\nOnly a message from the parent window is rendered. Answers go to `*`, which\nis the only target a sandboxed frame can name, and carry only what the\nexample itself wrote."
|
|
178504
|
+
"description": "Serves the frame side of a sandbox preview, in the document its `src` loads.\n\nCall it once from that document, after the elements your examples use are\ndefined. It does what the preview's protocol asks of a frame:\n\n- Posts `helix-preview-ready` once it listens.\n- Writes each `helix-preview-render` into the root: the markup, the\n stylesheet, the direction, the layout and the color mode. Scripts in the\n markup run.\n- Posts every console call, uncaught error, and unhandled promise rejection\n as `helix-preview-console`, an uncaught one marked `uncaught`, which marks\n the preview `failed`.\n- Posts `helix-preview-rendered` after each render, which shows a frame\n the preview held transparent until it drew.\n- Posts `helix-preview-size` whenever what was drawn changes height.\n- Posts `helix-preview-press` on every press, so menus outside close.\n\nOnly a message from the parent window is rendered. Answers go to `*`, which\nis the only target a sandboxed frame can name, and carry only what the\nexample itself wrote."
|
|
178505
178505
|
},
|
|
178506
178506
|
{
|
|
178507
178507
|
"kind": "function",
|
|
@@ -179240,6 +179240,54 @@
|
|
|
179240
179240
|
"default": "new DelayController(this, { renders: false })",
|
|
179241
179241
|
"description": "Holds a coalesced send, so only one is ever queued, and drops it on\ndisconnect.\n\n**It renders nothing**, so it asks for no update when its wait starts or\nends. One that did sent the source at once from that update, ahead of the\nwait, and the send at the end of the wait then cleared `failed` after the\nerror it should have reported."
|
|
179242
179242
|
},
|
|
179243
|
+
{
|
|
179244
|
+
"kind": "field",
|
|
179245
|
+
"name": "patience",
|
|
179246
|
+
"privacy": "private",
|
|
179247
|
+
"readonly": true,
|
|
179248
|
+
"default": "new DelayController(this, { renders: false })",
|
|
179249
|
+
"description": "Shows a frame that was sent an example and never said it drew it."
|
|
179250
|
+
},
|
|
179251
|
+
{
|
|
179252
|
+
"kind": "field",
|
|
179253
|
+
"name": "blank",
|
|
179254
|
+
"type": {
|
|
179255
|
+
"text": "boolean"
|
|
179256
|
+
},
|
|
179257
|
+
"privacy": "private",
|
|
179258
|
+
"default": "false",
|
|
179259
|
+
"description": "Whether the frame has drawn nothing since its document started loading."
|
|
179260
|
+
},
|
|
179261
|
+
{
|
|
179262
|
+
"kind": "method",
|
|
179263
|
+
"name": "setBlank",
|
|
179264
|
+
"privacy": "private",
|
|
179265
|
+
"return": {
|
|
179266
|
+
"type": {
|
|
179267
|
+
"text": "void"
|
|
179268
|
+
}
|
|
179269
|
+
},
|
|
179270
|
+
"parameters": [
|
|
179271
|
+
{
|
|
179272
|
+
"name": "on",
|
|
179273
|
+
"type": {
|
|
179274
|
+
"text": "boolean"
|
|
179275
|
+
}
|
|
179276
|
+
}
|
|
179277
|
+
],
|
|
179278
|
+
"description": "Marks the frame `blank`, or shown."
|
|
179279
|
+
},
|
|
179280
|
+
{
|
|
179281
|
+
"kind": "method",
|
|
179282
|
+
"name": "drawn",
|
|
179283
|
+
"privacy": "private",
|
|
179284
|
+
"return": {
|
|
179285
|
+
"type": {
|
|
179286
|
+
"text": "void"
|
|
179287
|
+
}
|
|
179288
|
+
},
|
|
179289
|
+
"description": "The frame has drawn an example, so it is shown."
|
|
179290
|
+
},
|
|
179243
179291
|
{
|
|
179244
179292
|
"kind": "method",
|
|
179245
179293
|
"name": "scheduleSend",
|
|
@@ -179844,6 +179892,10 @@
|
|
|
179844
179892
|
}
|
|
179845
179893
|
],
|
|
179846
179894
|
"cssStates": [
|
|
179895
|
+
{
|
|
179896
|
+
"description": "From the moment the frame's document starts loading until it has drawn an example. The styled tier keeps the frame transparent meanwhile, so a document that has not yet drawn in the page's color mode does not show as a white flash.",
|
|
179897
|
+
"name": "blank"
|
|
179898
|
+
},
|
|
179847
179899
|
{
|
|
179848
179900
|
"description": "Since the example threw an error it did not catch, until the next source is sent.",
|
|
179849
179901
|
"name": "failed"
|
|
@@ -272893,6 +272945,6 @@
|
|
|
272893
272945
|
],
|
|
272894
272946
|
"helix": {
|
|
272895
272947
|
"package": "@fusion.dev/helix",
|
|
272896
|
-
"version": "0.205.
|
|
272948
|
+
"version": "0.205.1"
|
|
272897
272949
|
}
|
|
272898
272950
|
}
|
package/dist/sandbox/frame.d.ts
CHANGED
|
@@ -54,6 +54,8 @@ export declare const loggedText: (value: unknown) => string;
|
|
|
54
54
|
* - Posts every console call, uncaught error, and unhandled promise rejection
|
|
55
55
|
* as `helix-preview-console`, an uncaught one marked `uncaught`, which marks
|
|
56
56
|
* the preview `failed`.
|
|
57
|
+
* - Posts `helix-preview-rendered` after each render, which shows a frame
|
|
58
|
+
* the preview held transparent until it drew.
|
|
57
59
|
* - Posts `helix-preview-size` whenever what was drawn changes height.
|
|
58
60
|
* - Posts `helix-preview-press` on every press, so menus outside close.
|
|
59
61
|
*
|
package/dist/sandbox/frame.js
CHANGED
|
@@ -124,6 +124,7 @@ const serveWith = (tools, options = {}) => {
|
|
|
124
124
|
sheet.textContent = styles;
|
|
125
125
|
options.onRender?.(root, fresh);
|
|
126
126
|
measure();
|
|
127
|
+
post({ type: 'helix-preview-rendered' });
|
|
127
128
|
};
|
|
128
129
|
const watcher = new ResizeObserver(measure);
|
|
129
130
|
const watch = () => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createSheet } from '@fusion.dev/helix-core';
|
|
2
|
-
export const styles = createSheet(`:host {display: block;min-block-size: 0;position: relative}[part="frame"] {background-color: var(--helix-color-background);block-size: 100%;border: none;display: block;inline-size: 100%}[part="error"] {background-color: var(--helix-color-background);box-sizing: border-box;color: var(--helix-color-danger);font-family: var(--helix-font-mono);font-size: var(--helix-text-xs);inset: 0;line-height: var(--helix-leading-normal);margin: var(--helix-space-none);overflow: auto;padding: var(--helix-space-md);position: absolute;white-space: pre-wrap;word-break: break-word}[part="controls"] {display: flex;font-family: var(--helix-font-sans);font-size: var(--helix-text-xs);gap: var(--helix-space-2xs);inset-block-end: var(--helix-space-xs);inset-inline-end: var(--helix-space-xs);position: absolute}[part="reload"], [part="open"] {background-color: var(--helix-color-surface);border: var(--helix-border-thin) solid var(--helix-color-border);border-radius: var(--helix-radii-sm);color: var(--helix-color-foreground);cursor: pointer;font: inherit;padding: var(--helix-space-2xs) var(--helix-space-xs)}[part="reload"]:hover, [part="open"]:hover {background-color: var(--helix-color-surface-sunken)}[part="reload"]:focus-visible, [part="open"]:focus-visible {outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);outline-offset: var(--helix-size-focus-offset)}`);
|
|
2
|
+
export const styles = createSheet(`:host {display: block;min-block-size: 0;position: relative}[part="frame"] {background-color: var(--helix-color-background);block-size: 100%;border: none;display: block;inline-size: 100%}[part="error"] {background-color: var(--helix-color-background);box-sizing: border-box;color: var(--helix-color-danger);font-family: var(--helix-font-mono);font-size: var(--helix-text-xs);inset: 0;line-height: var(--helix-leading-normal);margin: var(--helix-space-none);overflow: auto;padding: var(--helix-space-md);position: absolute;white-space: pre-wrap;word-break: break-word}[part="controls"] {display: flex;font-family: var(--helix-font-sans);font-size: var(--helix-text-xs);gap: var(--helix-space-2xs);inset-block-end: var(--helix-space-xs);inset-inline-end: var(--helix-space-xs);position: absolute}[part="reload"], [part="open"] {background-color: var(--helix-color-surface);border: var(--helix-border-thin) solid var(--helix-color-border);border-radius: var(--helix-radii-sm);color: var(--helix-color-foreground);cursor: pointer;font: inherit;padding: var(--helix-space-2xs) var(--helix-space-xs)}[part="reload"]:hover, [part="open"]:hover {background-color: var(--helix-color-surface-sunken)}[part="reload"]:focus-visible, [part="open"]:focus-visible {outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);outline-offset: var(--helix-size-focus-offset)}:host(:state(blank)) [part="frame"] {opacity: 0}`);
|
|
@@ -35,12 +35,16 @@ export interface PreviewConsole {
|
|
|
35
35
|
export interface PreviewPress {
|
|
36
36
|
type: 'helix-preview-press';
|
|
37
37
|
}
|
|
38
|
+
/** The frame saying it has drawn the example it was sent. */
|
|
39
|
+
export interface PreviewRendered {
|
|
40
|
+
type: 'helix-preview-rendered';
|
|
41
|
+
}
|
|
38
42
|
/** How tall the frame says its content is, in CSS pixels. */
|
|
39
43
|
export interface PreviewSize {
|
|
40
44
|
size: number;
|
|
41
45
|
type: 'helix-preview-size';
|
|
42
46
|
}
|
|
43
|
-
export type PreviewMessage = PreviewConsole | PreviewFetch | PreviewPress | PreviewReady | PreviewRender | PreviewSize;
|
|
47
|
+
export type PreviewMessage = PreviewConsole | PreviewFetch | PreviewPress | PreviewReady | PreviewRender | PreviewRendered | PreviewSize;
|
|
44
48
|
/**
|
|
45
49
|
* @summary A frame that renders sandbox source in a separate document.
|
|
46
50
|
*
|
|
@@ -140,6 +144,7 @@ export type PreviewMessage = PreviewConsole | PreviewFetch | PreviewPress | Prev
|
|
|
140
144
|
* @csspart open - The button that opens the example in a new tab, under `controls`.
|
|
141
145
|
* @csspart reload - The button that reloads the frame's document, under `controls`.
|
|
142
146
|
*
|
|
147
|
+
* @cssstate blank - From the moment the frame's document starts loading until it has drawn an example. The styled tier keeps the frame transparent meanwhile, so a document that has not yet drawn in the page's color mode does not show as a white flash.
|
|
143
148
|
* @cssstate failed - Since the example threw an error it did not catch, until the next source is sent.
|
|
144
149
|
* @cssstate loading - While the frame's document loads, until it can take the example.
|
|
145
150
|
*/
|
|
@@ -368,6 +373,14 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
368
373
|
* error it should have reported.
|
|
369
374
|
*/
|
|
370
375
|
private readonly settle;
|
|
376
|
+
/** Shows a frame that was sent an example and never said it drew it. */
|
|
377
|
+
private readonly patience;
|
|
378
|
+
/** Whether the frame has drawn nothing since its document started loading. */
|
|
379
|
+
private blank;
|
|
380
|
+
/** Marks the frame `blank`, or shown. */
|
|
381
|
+
private setBlank;
|
|
382
|
+
/** The frame has drawn an example, so it is shown. */
|
|
383
|
+
private drawn;
|
|
371
384
|
/**
|
|
372
385
|
* Sends once the typing stops, replacing anything already waiting.
|
|
373
386
|
*
|
|
@@ -2,6 +2,7 @@ var HelixSandboxPreview_1;
|
|
|
2
2
|
import { __decorate } from "tslib";
|
|
3
3
|
import { customElement, DelayController, HelixConsoleEvent, HelixElement, HelixResizeEvent, words, } from '@fusion.dev/helix-core';
|
|
4
4
|
const SETTLE = 120;
|
|
5
|
+
const PAINT_PATIENCE = 1000;
|
|
5
6
|
import { html, nothing } from 'lit';
|
|
6
7
|
import { property, state } from 'lit/decorators.js';
|
|
7
8
|
import { COMPILED, compile } from '../compile.js';
|
|
@@ -47,6 +48,9 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
47
48
|
this.handleFrameLoad();
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
51
|
+
if (data?.type === 'helix-preview-rendered' || data?.type === 'helix-preview-size') {
|
|
52
|
+
this.drawn();
|
|
53
|
+
}
|
|
50
54
|
if (data?.type === 'helix-preview-console') {
|
|
51
55
|
this.dispatchEvent(new HelixConsoleEvent({ level: data.level, text: data.text }));
|
|
52
56
|
if (data.uncaught) {
|
|
@@ -62,6 +66,8 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
68
|
this.settle = new DelayController(this, { renders: false });
|
|
69
|
+
this.patience = new DelayController(this, { renders: false });
|
|
70
|
+
this.blank = false;
|
|
65
71
|
this.loadedMap = '';
|
|
66
72
|
}
|
|
67
73
|
static { HelixSandboxPreview_1 = this; }
|
|
@@ -139,6 +145,14 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
139
145
|
});
|
|
140
146
|
}
|
|
141
147
|
static { this.target = '*'; }
|
|
148
|
+
setBlank(on) {
|
|
149
|
+
this.blank = on;
|
|
150
|
+
this.toggleState('blank', on);
|
|
151
|
+
}
|
|
152
|
+
drawn() {
|
|
153
|
+
this.patience.cancel();
|
|
154
|
+
this.setBlank(false);
|
|
155
|
+
}
|
|
142
156
|
scheduleSend() {
|
|
143
157
|
this.settle.start(SETTLE, () => {
|
|
144
158
|
if (this.sending !== this.failedSource) {
|
|
@@ -163,6 +177,9 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
163
177
|
}
|
|
164
178
|
this.frame?.contentWindow?.postMessage(this.message, HelixSandboxPreview_1.target);
|
|
165
179
|
this.sentSource = this.sending;
|
|
180
|
+
if (this.blank) {
|
|
181
|
+
this.patience.start(PAINT_PATIENCE, () => this.drawn());
|
|
182
|
+
}
|
|
166
183
|
}
|
|
167
184
|
open() {
|
|
168
185
|
const tab = window.open('', '_blank');
|
|
@@ -223,7 +240,9 @@ frame.onload = () => frame.contentWindow.postMessage(${JSON.stringify(this.messa
|
|
|
223
240
|
this.sentSource = undefined;
|
|
224
241
|
this.failedSource = undefined;
|
|
225
242
|
this.fail();
|
|
243
|
+
this.patience.cancel();
|
|
226
244
|
this.toggleState('loading', true);
|
|
245
|
+
this.setBlank(true);
|
|
227
246
|
}
|
|
228
247
|
willUpdate(changed) {
|
|
229
248
|
super.willUpdate(changed);
|