@fusion.dev/helix 0.0.0-dev → 0.0.3
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/custom-elements.json +5565 -5519
- package/dist/accordion/item/accordion-item.css.js +1 -19
- package/dist/accordion/root/accordion-root.css.js +1 -1
- package/dist/accordion/root/accordion-root.d.ts +1 -1
- package/dist/accordion/root/accordion-root.js +1 -1
- package/dist/announcement/root/announcement-root.css.js +1 -7
- package/dist/app-header/root/app-header-root.css.js +1 -7
- package/dist/app-header/root/app-header-root.d.ts +20 -23
- package/dist/app-header/root/app-header-root.js +4 -4
- package/dist/aura/root/aura-axis.d.ts +5 -7
- package/dist/aura/root/aura-axis.js +5 -7
- package/dist/aura/root/aura-root.css.js +1 -1
- package/dist/aura/root/aura-root.d.ts +75 -87
- package/dist/aura/root/aura-root.js +100 -109
- package/dist/aura/root/aura-shader.d.ts +10 -13
- package/dist/aura/root/aura-shader.js +165 -238
- package/dist/avatar/group/avatar-group.css.js +1 -1
- package/dist/avatar/root/avatar-root.css.js +1 -1
- package/dist/badge/root/badge-root.css.js +1 -13
- package/dist/badge/root/badge-root.d.ts +4 -5
- package/dist/bar-chart/root/bar-chart-root.css.js +1 -13
- package/dist/bar-chart/root/bar-chart-root.d.ts +51 -60
- package/dist/bar-chart/root/bar-chart-root.js +10 -17
- package/dist/blockquote/root/blockquote-root.css.js +1 -1
- package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +1 -7
- package/dist/breadcrumbs/root/breadcrumbs-root.css.js +1 -1
- package/dist/button/root/button-root.css.js +1 -7
- package/dist/button/root/button-root.d.ts +16 -25
- package/dist/button/root/button-root.js +3 -3
- package/dist/button-group/root/button-group-root.css.js +1 -1
- package/dist/button-group/root/button-group-root.d.ts +5 -7
- package/dist/callout/root/callout-root.css.js +1 -1
- package/dist/callout/root/callout-root.d.ts +4 -4
- package/dist/callout/root/callout-root.js +4 -4
- package/dist/card/root/card-root.css.js +2 -2
- package/dist/card/root/card-root.d.ts +38 -48
- package/dist/card/root/card-root.js +8 -11
- package/dist/carousel/root/carousel-root.css.js +1 -11
- package/dist/carousel/root/carousel-root.d.ts +39 -43
- package/dist/carousel/root/carousel-root.js +7 -7
- package/dist/chat/composer/chat-composer.css.js +1 -1
- package/dist/chat/message/chat-message.css.js +1 -7
- package/dist/chat/message/chat-message.d.ts +8 -13
- package/dist/chat/root/chat-root.css.js +1 -1
- package/dist/checkbox/root/checkbox-root.css.js +1 -14
- package/dist/checkbox-group/root/checkbox-group-root.css.js +1 -1
- package/dist/code/root/code-root.css.js +9 -7
- package/dist/code/root/code-root.d.ts +4 -0
- package/dist/code/root/code-root.js +4 -0
- package/dist/code-block/root/code-block-root.css.js +1 -1
- package/dist/color-input/root/color-input-root.css.js +2 -2
- package/dist/color-input/root/color-input-root.js +3 -3
- package/dist/color-picker/root/color-picker-root.css.js +1 -9
- package/dist/color-picker/root/color-picker-root.js +3 -3
- package/dist/combobox/root/combobox-root.css.js +1 -8
- package/dist/combobox/root/combobox-root.js +1 -1
- package/dist/command/root/command-root.css.js +1 -1
- package/dist/copy-button/root/copy-button-root.css.js +1 -1
- package/dist/data-table/root/data-table-root.css.js +9 -3
- package/dist/data-table/root/data-table-root.d.ts +4 -1
- package/dist/data-table/root/data-table-root.js +4 -1
- package/dist/date-input/root/date-input-root.css.js +1 -1
- package/dist/date-picker/root/date-picker-root.css.js +1 -7
- package/dist/date-picker/root/date-picker-root.d.ts +1 -1
- package/dist/date-picker/root/date-picker-root.js +1 -1
- package/dist/dialog/root/dialog-root.css.js +1 -1
- package/dist/dialog/root/dialog-root.d.ts +15 -20
- package/dist/dialog/root/dialog-root.js +2 -2
- package/dist/divider/root/divider-root.css.js +1 -1
- package/dist/donut-chart/root/donut-chart-root.css.js +2 -20
- package/dist/donut-chart/root/donut-chart-root.d.ts +14 -19
- package/dist/donut-chart/root/donut-chart-root.js +6 -7
- package/dist/drawer/root/drawer-root.css.js +1 -11
- package/dist/drawer/root/drawer-root.d.ts +3 -7
- package/dist/drilldown/item/drilldown-item.css.js +1 -1
- package/dist/drilldown/root/drilldown-root.css.js +1 -1
- package/dist/element-events.generated.js +1 -1
- package/dist/empty/root/empty-root.css.js +1 -1
- package/dist/file-input/root/file-input-root.css.js +1 -1
- package/dist/file-input/root/file-input-root.js +1 -2
- package/dist/flex/root/flex-root.css.js +1 -1
- package/dist/flex/root/flex-root.d.ts +6 -6
- package/dist/flex/root/flex-root.js +9 -9
- package/dist/format-date/root/format-date-root.css.js +1 -1
- package/dist/grid/root/grid-root.css.js +1 -1
- package/dist/grid/root/grid-root.d.ts +8 -8
- package/dist/grid/root/grid-root.js +8 -9
- package/dist/heatmap/root/heatmap-root.css.js +2 -2
- package/dist/heatmap/root/heatmap-root.d.ts +11 -12
- package/dist/heatmap/root/heatmap-root.js +11 -12
- package/dist/icon/glyph.css.js +1 -1
- package/dist/icon/root/icon-root.css.js +1 -1
- package/dist/icon-button/root/icon-button-root.css.js +1 -7
- package/dist/icon-button/root/icon-button-root.d.ts +10 -10
- package/dist/icon-button/root/icon-button-root.js +4 -4
- package/dist/image/root/image-root.css.js +1 -7
- package/dist/input/root/input-root.css.js +1 -9
- package/dist/kbd/root/kbd-root.css.js +1 -1
- package/dist/legend/root/legend-root.css.js +1 -1
- package/dist/legend/root/legend-root.d.ts +34 -37
- package/dist/legend/root/legend-root.js +10 -10
- package/dist/line-chart/root/line-chart-root.css.js +1 -8
- package/dist/line-chart/root/line-chart-root.d.ts +6 -9
- package/dist/list/item/list-item.css.js +1 -1
- package/dist/list/root/list-root.css.js +1 -1
- package/dist/list/root/list-root.d.ts +4 -7
- package/dist/listbox/root/listbox-root.css.js +3 -3
- package/dist/listbox/root/listbox-root.d.ts +2 -0
- package/dist/listbox/root/listbox-root.js +2 -0
- package/dist/loader/root/loader-root.css.js +1 -1
- package/dist/loader/root/loader-root.d.ts +5 -9
- package/dist/loader/root/loader-root.js +2 -2
- package/dist/megamenu/root/megamenu-root.css.js +3 -2
- package/dist/menu/item/menu-item.css.js +1 -7
- package/dist/menu/root/menu-root.css.js +1 -1
- package/dist/meter/root/meter-root.css.js +1 -14
- package/dist/meter/root/meter-root.d.ts +18 -18
- package/dist/meter/root/meter-root.js +6 -8
- package/dist/mixins/mixin-control-surface/mixin-control-surface.d.ts +1 -1
- package/dist/navigation/root/navigation-root.css.js +1 -7
- package/dist/notifications/notification/notification.css.js +1 -7
- package/dist/notifications/root/notifications-root.css.js +1 -1
- package/dist/number-input/root/number-input-root.css.js +1 -9
- package/dist/option/group/option-group.css.js +1 -1
- package/dist/option/root/option-root.css.js +1 -1
- package/dist/outline/root/outline-root.css.js +1 -14
- package/dist/outline/root/outline-root.d.ts +1 -1
- package/dist/outline/root/outline-root.js +1 -1
- package/dist/pagination/root/pagination-root.css.js +1 -12
- package/dist/pagination/size/pagination-size.css.js +1 -1
- package/dist/pagination/summary/pagination-summary.css.js +1 -1
- package/dist/pin-input/root/pin-input-root.css.js +1 -7
- package/dist/popover/root/popover-root.css.js +4 -2
- package/dist/progress/root/progress-root.css.js +1 -7
- package/dist/progress/root/progress-root.d.ts +10 -9
- package/dist/qr-code/root/qr-code-root.css.js +1 -1
- package/dist/qr-code/root/qr-code-root.d.ts +1 -1
- package/dist/qr-code/root/qr-code-root.js +1 -1
- package/dist/quote/root/quote-root.css.js +1 -1
- package/dist/radio/group/radio-group.css.js +1 -1
- package/dist/radio/root/radio-root.css.js +1 -14
- package/dist/radio/root/radio-root.d.ts +20 -18
- package/dist/radio/root/radio-root.js +5 -6
- package/dist/rating/root/rating-root.css.js +1 -1
- package/dist/rating/root/rating-root.d.ts +4 -5
- package/dist/sandbox/preview/sandbox-preview.css.js +1 -1
- package/dist/sandbox/preview/sandbox-preview.d.ts +48 -44
- package/dist/sandbox/preview/sandbox-preview.js +63 -50
- package/dist/sandbox/root/sandbox-root.css.js +1 -2
- package/dist/sandbox/root/sandbox-root.d.ts +50 -59
- package/dist/sandbox/root/sandbox-root.js +75 -91
- package/dist/sandbox/source/sandbox-source.css.js +1 -1
- package/dist/sandbox/source/sandbox-source.d.ts +21 -29
- package/dist/sandbox/source/sandbox-source.js +26 -34
- package/dist/sandbox/status-bar/sandbox-status-bar.css.js +1 -1
- package/dist/sandbox/terminal/sandbox-terminal.css.js +1 -1
- package/dist/sandbox/toolbar/sandbox-toolbar.css.js +1 -1
- package/dist/scroll-area/root/scroll-area-root.css.js +5 -5
- package/dist/select/root/select-root.css.js +2 -15
- package/dist/select/root/select-root.d.ts +4 -4
- package/dist/select/root/select-root.js +5 -7
- package/dist/shared/chart/series.css.js +1 -1
- package/dist/shared/chart/terminus.css.js +1 -1
- package/dist/shared/field/field-inline.css.js +1 -1
- package/dist/shared/field/field-stacked.css.js +1 -1
- package/dist/shared/field/field.css.js +1 -1
- package/dist/skeleton/root/skeleton-root.css.js +1 -1
- package/dist/slider/root/slider-root.css.js +1 -3
- package/dist/sparkline/root/sparkline-root.css.js +1 -1
- package/dist/sparkline/root/sparkline-root.d.ts +22 -24
- package/dist/sparkline/root/sparkline-root.js +6 -6
- package/dist/speed-dial/item/speed-dial-item.css.js +1 -7
- package/dist/speed-dial/root/speed-dial-root.css.js +1 -1
- package/dist/splitter/root/splitter-root.css.js +1 -14
- package/dist/stat/group/stat-group.css.js +1 -1
- package/dist/stat/root/stat-root.css.js +1 -1
- package/dist/steps/root/steps-root.css.js +1 -1
- package/dist/steps/step/step.css.js +1 -8
- package/dist/steps/step/step.js +1 -1
- package/dist/switch/root/switch-root.css.js +1 -8
- package/dist/table/cell/table-cell.css.js +1 -1
- package/dist/table/column/table-column.css.js +1 -1
- package/dist/table/root/table-root.css.js +1 -1
- package/dist/table/row/table-row.css.js +1 -1
- package/dist/tabs/panel/tab-panel.css.js +1 -1
- package/dist/tabs/root/tabs-root.css.js +1 -7
- package/dist/tabs/tab/tab.css.js +2 -8
- package/dist/tag/root/tag-root.css.js +1 -1
- package/dist/tag/root/tag-root.d.ts +10 -19
- package/dist/tag/root/tag-root.js +3 -3
- package/dist/text/root/text-root.css.js +1 -1
- package/dist/text/root/text-root.d.ts +13 -14
- package/dist/text/root/text-root.js +6 -6
- package/dist/textarea/root/textarea-root.css.js +1 -7
- package/dist/time-input/root/time-input-root.css.js +1 -1
- package/dist/time-input/root/time-input-root.js +1 -1
- package/dist/time-picker/root/time-picker-root.css.js +1 -7
- package/dist/time-picker/root/time-picker-root.js +1 -1
- package/dist/timeline/item/timeline-item.css.js +1 -1
- package/dist/timeline/root/timeline-root.css.js +1 -1
- package/dist/toast/item/toast-item.css.js +1 -1
- package/dist/toast/root/toast-root.css.js +1 -1
- package/dist/toggle/group/toggle-group.css.js +1 -7
- package/dist/toggle/group/toggle-group.d.ts +6 -9
- package/dist/toggle/root/toggle-root.css.js +1 -1
- package/dist/toolbar/root/toolbar-root.css.js +1 -1
- package/dist/tooltip/root/tooltip-root.css.js +1 -1
- package/dist/tooltip/root/tooltip-root.d.ts +6 -7
- package/dist/tour/root/tour-root.css.js +1 -7
- package/dist/tour/stop/tour-stop.css.js +2 -2
- package/dist/tree/item/tree-item.css.js +1 -17
- package/dist/tree/root/tree-root.css.js +1 -1
- package/dist/tree/root/tree-root.d.ts +0 -2
- package/dist/trend/root/trend-root.css.js +1 -1
- package/dist/trend/root/trend-root.d.ts +4 -7
- package/dist/trend/root/trend-root.js +4 -7
- package/dist/video/root/video-root.css.js +1 -12
- package/dist/video/root/video-root.d.ts +3 -8
- package/dist/video-playlist/item/video-playlist-item.css.js +1 -7
- package/dist/video-playlist/menu/video-playlist-menu.css.js +1 -1
- package/dist/video-playlist/root/video-playlist-root.css.js +1 -1
- package/dist/virtual-list/root/virtual-list-root.css.js +1 -1
- package/elements.css +4 -5
- package/helix.css +31 -0
- package/jsx.d.ts +11625 -14561
- package/package.json +10 -8
- package/vue.d.ts +3594 -4231
|
@@ -20,12 +20,24 @@ export interface PreviewConsole {
|
|
|
20
20
|
text: string;
|
|
21
21
|
type: 'helix-preview-console';
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* A press inside the frame, which is the one event the page cannot see for
|
|
25
|
+
* itself.
|
|
26
|
+
*
|
|
27
|
+
* Carries nothing. What the page needs to know is that a reader pressed
|
|
28
|
+
* something here, not where: every overlay outside is dismissed by the fact of
|
|
29
|
+
* the press, and coordinates in the frame's viewport would not mean anything in
|
|
30
|
+
* the page's anyway.
|
|
31
|
+
*/
|
|
32
|
+
export interface PreviewPress {
|
|
33
|
+
type: 'helix-preview-press';
|
|
34
|
+
}
|
|
23
35
|
/** How tall the frame says its content is, in CSS pixels. */
|
|
24
36
|
export interface PreviewSize {
|
|
25
37
|
size: number;
|
|
26
38
|
type: 'helix-preview-size';
|
|
27
39
|
}
|
|
28
|
-
export type PreviewMessage = PreviewConsole | PreviewReady | PreviewRender | PreviewSize;
|
|
40
|
+
export type PreviewMessage = PreviewConsole | PreviewPress | PreviewReady | PreviewRender | PreviewSize;
|
|
29
41
|
/**
|
|
30
42
|
* @summary Renders sandbox source in a frame of its own.
|
|
31
43
|
*
|
|
@@ -47,32 +59,25 @@ export type PreviewMessage = PreviewConsole | PreviewReady | PreviewRender | Pre
|
|
|
47
59
|
* consumer's document rather than something guessed at here.
|
|
48
60
|
*
|
|
49
61
|
* **The source is not trusted, and the frame is what makes that safe.**
|
|
50
|
-
* `fullscreen` is granted for the same reason and found the same way: a video
|
|
51
|
-
* in the preview offered a fullscreen button that did nothing at all, because
|
|
52
|
-
* the policy default is `self`, this frame is not `self`, and a denied request
|
|
53
|
-
* rejects a promise nobody was watching. Two capabilities now, both explicit,
|
|
54
|
-
* both starred.
|
|
55
|
-
*
|
|
56
|
-
* `allow="clipboard-write *"` is granted explicitly, and the star matters: the
|
|
57
|
-
* policy defaults to `self` and this frame has an opaque origin, so it is not
|
|
58
|
-
* `self` and the default denies it. A component inside the preview that copies
|
|
59
|
-
* to the clipboard is otherwise a control that silently does nothing, which is
|
|
60
|
-
* how this was found. Nothing else is granted, and a copy still needs the
|
|
61
|
-
* reader's own gesture.
|
|
62
|
-
*
|
|
63
62
|
* `sandbox="allow-scripts"` and no `allow-same-origin`, so the document runs on
|
|
64
63
|
* an opaque origin: script in an example cannot reach this page, its storage,
|
|
65
64
|
* its cookies, or the editor the source was typed into. Without it they could,
|
|
66
65
|
* measured, through an `onerror` handler on an image that fails to load, which
|
|
67
|
-
* `innerHTML` does not strip the way it refuses a `<script>` tag.
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* one day arrived in a shared link, rather than only what its owner typed.
|
|
66
|
+
* `innerHTML` does not strip the way it refuses a `<script>` tag. That is what
|
|
67
|
+
* lets a sandbox hold markup a reader pasted from somewhere, or one day arrived
|
|
68
|
+
* in a shared link, rather than only what its owner typed.
|
|
71
69
|
*
|
|
72
70
|
* `allow-forms` is granted because examples have forms in them and a submit
|
|
73
71
|
* that silently does nothing is a worse lie than one that navigates a frame
|
|
74
72
|
* nobody is looking at. Top-level navigation, popups and modals are not.
|
|
75
73
|
*
|
|
74
|
+
* **`allow="clipboard-write *; fullscreen *"`, and the stars matter.** Both
|
|
75
|
+
* policies default to `self`, and a frame on an opaque origin is not `self`, so
|
|
76
|
+
* the default denies both: a component that copies to the clipboard and a video
|
|
77
|
+
* offering a fullscreen button each become a control that silently does nothing,
|
|
78
|
+
* a denied request rejecting a promise nobody was watching. Nothing else is
|
|
79
|
+
* granted, and a copy still needs the reader's own gesture.
|
|
80
|
+
*
|
|
76
81
|
* @since 0.1.0
|
|
77
82
|
* @status experimental
|
|
78
83
|
* @aliases Result, Output
|
|
@@ -97,47 +102,47 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
97
102
|
* It matters more than a background: `light-dark()` is compiled to a shim
|
|
98
103
|
* keyed on this attribute, and of the 56 tokens that differ by scheme the
|
|
99
104
|
* theme engine emits 19. The other 37 would stay light in a dark preview,
|
|
100
|
-
* including every one of the 24 series
|
|
105
|
+
* including every one of the 24 series colors a chart reads.
|
|
101
106
|
*/
|
|
102
107
|
colorMode?: 'dark' | 'light';
|
|
103
108
|
/**
|
|
104
|
-
*
|
|
109
|
+
* Writing direction inside the frame.
|
|
105
110
|
*/
|
|
106
|
-
|
|
111
|
+
direction?: 'rtl';
|
|
107
112
|
/**
|
|
108
|
-
*
|
|
113
|
+
* Accessible name for the frame.
|
|
109
114
|
*/
|
|
110
|
-
|
|
115
|
+
label: string;
|
|
111
116
|
/**
|
|
112
|
-
*
|
|
117
|
+
* How the example is placed in the frame.
|
|
113
118
|
*/
|
|
114
|
-
|
|
119
|
+
layout?: 'padded' | 'centered' | 'fullscreen' | 'hug';
|
|
115
120
|
/**
|
|
116
|
-
*
|
|
121
|
+
* Markup to render.
|
|
117
122
|
*/
|
|
118
|
-
|
|
123
|
+
source: string;
|
|
119
124
|
/**
|
|
120
|
-
*
|
|
125
|
+
* Document the frame loads, which brings the styles and the elements.
|
|
121
126
|
*/
|
|
122
|
-
|
|
127
|
+
src: string;
|
|
123
128
|
/**
|
|
124
|
-
*
|
|
129
|
+
* Stylesheet applied inside the frame, alongside the markup.
|
|
125
130
|
*/
|
|
126
|
-
|
|
131
|
+
styles: string;
|
|
127
132
|
/** Whether the frame has said it is listening. */
|
|
128
133
|
private ready;
|
|
129
134
|
private get frame();
|
|
130
135
|
/**
|
|
131
136
|
* The frame's document has finished loading, so its listener exists.
|
|
132
137
|
*
|
|
133
|
-
* **The announcement is one shot and the parent can miss it.** The frame
|
|
134
|
-
*
|
|
135
|
-
*
|
|
138
|
+
* **The announcement is one shot and the parent can miss it.** The frame posts
|
|
139
|
+
* `helix-preview-ready` at the end of its own module evaluation and never
|
|
140
|
+
* repeats it, and `handleMessage` drops anything whose `source` is not
|
|
136
141
|
* `this.frame?.contentWindow`. That getter reads the render root, so it is
|
|
137
|
-
* null until this element has rendered once
|
|
138
|
-
* render commits
|
|
139
|
-
*
|
|
140
|
-
*
|
|
142
|
+
* null until this element has rendered once: a frame that loads before that
|
|
143
|
+
* render commits announces into a guard that refuses it, `ready` stays false,
|
|
144
|
+
* and `send` returns early forever, leaving the source set, the markup
|
|
145
|
+
* correct, and the preview blank with nothing logged.
|
|
141
146
|
*
|
|
142
147
|
* **It is a race, so it hides in the one place nobody looks.** The frame is
|
|
143
148
|
* only fast enough to win when its document and its bundle are already in the
|
|
@@ -186,12 +191,11 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
186
191
|
/**
|
|
187
192
|
* Sends once the typing stops, replacing anything already waiting.
|
|
188
193
|
*
|
|
189
|
-
* A frame
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* typing stops.
|
|
194
|
+
* A frame is the wrong unit. Keystrokes arrive fifty to a hundred and fifty
|
|
195
|
+
* milliseconds apart, so each one lands in a frame of its own and coalescing
|
|
196
|
+
* by frame coalesces nothing, leaving the example rebuilt per character. The
|
|
197
|
+
* delay has to be longer than the gap between keystrokes to catch a burst, and
|
|
198
|
+
* short enough to read as immediate when the typing stops.
|
|
195
199
|
*/
|
|
196
200
|
private scheduleSend;
|
|
197
201
|
/** Sends the current source to the frame, once it is listening. */
|
|
@@ -38,32 +38,25 @@ import { styles as sheet } from './sandbox-preview.css.js';
|
|
|
38
38
|
* consumer's document rather than something guessed at here.
|
|
39
39
|
*
|
|
40
40
|
* **The source is not trusted, and the frame is what makes that safe.**
|
|
41
|
-
* `fullscreen` is granted for the same reason and found the same way: a video
|
|
42
|
-
* in the preview offered a fullscreen button that did nothing at all, because
|
|
43
|
-
* the policy default is `self`, this frame is not `self`, and a denied request
|
|
44
|
-
* rejects a promise nobody was watching. Two capabilities now, both explicit,
|
|
45
|
-
* both starred.
|
|
46
|
-
*
|
|
47
|
-
* `allow="clipboard-write *"` is granted explicitly, and the star matters: the
|
|
48
|
-
* policy defaults to `self` and this frame has an opaque origin, so it is not
|
|
49
|
-
* `self` and the default denies it. A component inside the preview that copies
|
|
50
|
-
* to the clipboard is otherwise a control that silently does nothing, which is
|
|
51
|
-
* how this was found. Nothing else is granted, and a copy still needs the
|
|
52
|
-
* reader's own gesture.
|
|
53
|
-
*
|
|
54
41
|
* `sandbox="allow-scripts"` and no `allow-same-origin`, so the document runs on
|
|
55
42
|
* an opaque origin: script in an example cannot reach this page, its storage,
|
|
56
43
|
* its cookies, or the editor the source was typed into. Without it they could,
|
|
57
44
|
* measured, through an `onerror` handler on an image that fails to load, which
|
|
58
|
-
* `innerHTML` does not strip the way it refuses a `<script>` tag.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* one day arrived in a shared link, rather than only what its owner typed.
|
|
45
|
+
* `innerHTML` does not strip the way it refuses a `<script>` tag. That is what
|
|
46
|
+
* lets a sandbox hold markup a reader pasted from somewhere, or one day arrived
|
|
47
|
+
* in a shared link, rather than only what its owner typed.
|
|
62
48
|
*
|
|
63
49
|
* `allow-forms` is granted because examples have forms in them and a submit
|
|
64
50
|
* that silently does nothing is a worse lie than one that navigates a frame
|
|
65
51
|
* nobody is looking at. Top-level navigation, popups and modals are not.
|
|
66
52
|
*
|
|
53
|
+
* **`allow="clipboard-write *; fullscreen *"`, and the stars matter.** Both
|
|
54
|
+
* policies default to `self`, and a frame on an opaque origin is not `self`, so
|
|
55
|
+
* the default denies both: a component that copies to the clipboard and a video
|
|
56
|
+
* offering a fullscreen button each become a control that silently does nothing,
|
|
57
|
+
* a denied request rejecting a promise nobody was watching. Nothing else is
|
|
58
|
+
* granted, and a copy still needs the reader's own gesture.
|
|
59
|
+
*
|
|
67
60
|
* @since 0.1.0
|
|
68
61
|
* @status experimental
|
|
69
62
|
* @aliases Result, Output
|
|
@@ -78,34 +71,34 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
78
71
|
constructor() {
|
|
79
72
|
super(...arguments);
|
|
80
73
|
/**
|
|
81
|
-
*
|
|
74
|
+
* Accessible name for the frame.
|
|
82
75
|
*/
|
|
83
|
-
this.
|
|
76
|
+
this.label = 'Preview';
|
|
84
77
|
/**
|
|
85
78
|
* Markup to render.
|
|
86
79
|
*/
|
|
87
80
|
this.source = '';
|
|
88
81
|
/**
|
|
89
|
-
*
|
|
82
|
+
* Document the frame loads, which brings the styles and the elements.
|
|
90
83
|
*/
|
|
91
|
-
this.
|
|
84
|
+
this.src = '';
|
|
92
85
|
/**
|
|
93
|
-
*
|
|
86
|
+
* Stylesheet applied inside the frame, alongside the markup.
|
|
94
87
|
*/
|
|
95
|
-
this.
|
|
88
|
+
this.styles = '';
|
|
96
89
|
/** Whether the frame has said it is listening. */
|
|
97
90
|
this.ready = false;
|
|
98
91
|
/**
|
|
99
92
|
* The frame's document has finished loading, so its listener exists.
|
|
100
93
|
*
|
|
101
|
-
* **The announcement is one shot and the parent can miss it.** The frame
|
|
102
|
-
*
|
|
103
|
-
*
|
|
94
|
+
* **The announcement is one shot and the parent can miss it.** The frame posts
|
|
95
|
+
* `helix-preview-ready` at the end of its own module evaluation and never
|
|
96
|
+
* repeats it, and `handleMessage` drops anything whose `source` is not
|
|
104
97
|
* `this.frame?.contentWindow`. That getter reads the render root, so it is
|
|
105
|
-
* null until this element has rendered once
|
|
106
|
-
* render commits
|
|
107
|
-
*
|
|
108
|
-
*
|
|
98
|
+
* null until this element has rendered once: a frame that loads before that
|
|
99
|
+
* render commits announces into a guard that refuses it, `ready` stays false,
|
|
100
|
+
* and `send` returns early forever, leaving the source set, the markup
|
|
101
|
+
* correct, and the preview blank with nothing logged.
|
|
109
102
|
*
|
|
110
103
|
* **It is a race, so it hides in the one place nobody looks.** The frame is
|
|
111
104
|
* only fast enough to win when its document and its bundle are already in the
|
|
@@ -152,6 +145,29 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
152
145
|
if (event.data?.type === 'helix-preview-console') {
|
|
153
146
|
this.dispatchEvent(new HelixConsoleEvent({ level: event.data.level, text: event.data.text }));
|
|
154
147
|
}
|
|
148
|
+
/* **A press in the frame, put back into the page as a press.**
|
|
149
|
+
*
|
|
150
|
+
* The frame is on an opaque origin, which is the point of it, and a
|
|
151
|
+
* consequence is that a press inside is invisible outside: the event does
|
|
152
|
+
* not cross the boundary, the document cannot listen to a document it may
|
|
153
|
+
* not touch, and in WebKit the press moves no focus and blurs no window
|
|
154
|
+
* either, so there is nothing at all to infer it from. Measured: with the
|
|
155
|
+
* sandbox's settings menu open, pressing the component it configures left
|
|
156
|
+
* the menu standing over it, and the only way out was Escape or the trigger.
|
|
157
|
+
*
|
|
158
|
+
* So the frame reports it and this element re-states it where the page can
|
|
159
|
+
* hear it. A real `pointerdown` rather than a name of our own, because
|
|
160
|
+
* every light-dismiss in the library — and every one a consumer wrote —
|
|
161
|
+
* already listens for exactly that, and what happened *was* a press. It
|
|
162
|
+
* carries no coordinates for the reason the message does not: this element
|
|
163
|
+
* is where it happened, as far as the page is concerned.
|
|
164
|
+
*
|
|
165
|
+
* `composed` so it leaves whatever shadow root this element sits in, which
|
|
166
|
+
* is how those listeners find it in the path.
|
|
167
|
+
*/
|
|
168
|
+
if (event.data?.type === 'helix-preview-press') {
|
|
169
|
+
this.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, composed: true }));
|
|
170
|
+
}
|
|
155
171
|
/* Relayed rather than acted on. What the frame measured is a fact about the
|
|
156
172
|
example; how much room to give it is a decision, and it belongs to
|
|
157
173
|
whatever laid this element out. A preview that resized itself would be
|
|
@@ -180,12 +196,11 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
180
196
|
/**
|
|
181
197
|
* Sends once the typing stops, replacing anything already waiting.
|
|
182
198
|
*
|
|
183
|
-
* A frame
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* typing stops.
|
|
199
|
+
* A frame is the wrong unit. Keystrokes arrive fifty to a hundred and fifty
|
|
200
|
+
* milliseconds apart, so each one lands in a frame of its own and coalescing
|
|
201
|
+
* by frame coalesces nothing, leaving the example rebuilt per character. The
|
|
202
|
+
* delay has to be longer than the gap between keystrokes to catch a burst, and
|
|
203
|
+
* short enough to read as immediate when the typing stops.
|
|
189
204
|
*/
|
|
190
205
|
scheduleSend() {
|
|
191
206
|
clearTimeout(this.pending);
|
|
@@ -252,12 +267,10 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
252
267
|
*
|
|
253
268
|
* The frame renders by assigning `innerHTML`, which throws away the example
|
|
254
269
|
* and builds it again, and every custom element in it disconnects and
|
|
255
|
-
* upgrades a second time. Sent on each update
|
|
256
|
-
*
|
|
257
|
-
* every character, and the work grows with the example while the typing
|
|
258
|
-
* does not.
|
|
270
|
+
* upgrades a second time. Sent on each update that is once per keystroke,
|
|
271
|
+
* and the work grows with the example while the typing does not.
|
|
259
272
|
*
|
|
260
|
-
*
|
|
273
|
+
* `SETTLE` is short enough to feel immediate and long enough that a burst of
|
|
261
274
|
* keystrokes is one render. Layout, direction and the color mode go
|
|
262
275
|
* straight out: they arrive one at a time from a menu, there is nothing to
|
|
263
276
|
* coalesce, and a delay there is a delay a reader can see. */
|
|
@@ -282,24 +295,24 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
282
295
|
__decorate([
|
|
283
296
|
property({ attribute: 'color-mode' })
|
|
284
297
|
], HelixSandboxPreview.prototype, "colorMode", void 0);
|
|
298
|
+
__decorate([
|
|
299
|
+
property({ reflect: true })
|
|
300
|
+
], HelixSandboxPreview.prototype, "direction", void 0);
|
|
285
301
|
__decorate([
|
|
286
302
|
property()
|
|
287
|
-
], HelixSandboxPreview.prototype, "
|
|
303
|
+
], HelixSandboxPreview.prototype, "label", void 0);
|
|
304
|
+
__decorate([
|
|
305
|
+
property({ reflect: true })
|
|
306
|
+
], HelixSandboxPreview.prototype, "layout", void 0);
|
|
288
307
|
__decorate([
|
|
289
308
|
property()
|
|
290
309
|
], HelixSandboxPreview.prototype, "source", void 0);
|
|
291
310
|
__decorate([
|
|
292
311
|
property()
|
|
293
|
-
], HelixSandboxPreview.prototype, "
|
|
312
|
+
], HelixSandboxPreview.prototype, "src", void 0);
|
|
294
313
|
__decorate([
|
|
295
314
|
property()
|
|
296
|
-
], HelixSandboxPreview.prototype, "
|
|
297
|
-
__decorate([
|
|
298
|
-
property({ reflect: true })
|
|
299
|
-
], HelixSandboxPreview.prototype, "direction", void 0);
|
|
300
|
-
__decorate([
|
|
301
|
-
property({ reflect: true })
|
|
302
|
-
], HelixSandboxPreview.prototype, "layout", void 0);
|
|
315
|
+
], HelixSandboxPreview.prototype, "styles", void 0);
|
|
303
316
|
HelixSandboxPreview = HelixSandboxPreview_1 = __decorate([
|
|
304
317
|
customElement('helix-sandbox-preview')
|
|
305
318
|
], HelixSandboxPreview);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated from src/sandbox/root/sandbox-root.css by `
|
|
1
|
+
// Generated from src/sandbox/root/sandbox-root.css by `turbo run styles`. Do not edit.
|
|
2
2
|
import { createSheet } from '@fusion.dev/helix-core';
|
|
3
3
|
export const styles = createSheet(`:host {
|
|
4
4
|
background-color: var(--helix-color-background);
|
|
@@ -14,7 +14,6 @@ grid-row: 1;
|
|
|
14
14
|
|
|
15
15
|
[part="body"] {
|
|
16
16
|
grid-row: 2;
|
|
17
|
-
min-block-size: 0;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
::slotted([slot="status"]) {
|
|
@@ -18,12 +18,9 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
18
18
|
* a React component into the preview.
|
|
19
19
|
*
|
|
20
20
|
* **The dividers are two nested `helix-splitter`s, not a grid this element
|
|
21
|
-
* drags itself.**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* cell where two tracks met. All of it is the splitter's now, including the
|
|
25
|
-
* corner, which arrives on its own wherever a nested splitter crosses the one it
|
|
26
|
-
* is in.
|
|
21
|
+
* drags itself.** The pointer handling, the keyboard handling and the corner are
|
|
22
|
+
* all the splitter's, and the corner arrives on its own wherever a nested
|
|
23
|
+
* splitter crosses the one it is in.
|
|
27
24
|
*
|
|
28
25
|
* The panes are the inner splitter and the panel is the outer one, which is the
|
|
29
26
|
* order that makes the panel span the full width: the outer divider runs edge to
|
|
@@ -72,9 +69,29 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
72
69
|
*/
|
|
73
70
|
export declare class HelixSandbox extends HelixElement {
|
|
74
71
|
/**
|
|
75
|
-
*
|
|
72
|
+
* Accessible name for the divider that moves both at once.
|
|
76
73
|
*/
|
|
77
|
-
|
|
74
|
+
cornerLabel: string;
|
|
75
|
+
/**
|
|
76
|
+
* What a reset makes the panel, in pixels.
|
|
77
|
+
*
|
|
78
|
+
* The pair to `panel-size`.
|
|
79
|
+
*/
|
|
80
|
+
defaultPanelSize: number;
|
|
81
|
+
/**
|
|
82
|
+
* Where a reset puts the divider, where nothing declared it.
|
|
83
|
+
*
|
|
84
|
+
* Separate from `split` for the reason `Splitter` keeps `default-position`
|
|
85
|
+
* separate from `position`. Resetting to whatever `split` held on the first
|
|
86
|
+
* render is the declared arrangement only where nobody owns the property: the
|
|
87
|
+
* workbench does, and restores it from the address bar and from storage, so the
|
|
88
|
+
* first value it holds is the reader's last session and a reset puts the
|
|
89
|
+
* sandbox back to the size it already was.
|
|
90
|
+
*
|
|
91
|
+
* Declared rather than captured, so it is a number a consumer states and can
|
|
92
|
+
* change, and it needs no first frame to be read on.
|
|
93
|
+
*/
|
|
94
|
+
defaultSplit: number;
|
|
78
95
|
/**
|
|
79
96
|
* Which pane comes first, before the divider.
|
|
80
97
|
*
|
|
@@ -94,35 +111,9 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
94
111
|
*/
|
|
95
112
|
lead: 'source' | 'preview';
|
|
96
113
|
/**
|
|
97
|
-
*
|
|
98
|
-
*/
|
|
99
|
-
split: number;
|
|
100
|
-
/**
|
|
101
|
-
* Where a reset puts the divider, where nothing declared it.
|
|
102
|
-
*
|
|
103
|
-
* Separate from `split` for the reason `Splitter` keeps `default-position`
|
|
104
|
-
* separate from `position`, and the bug is worth recording because this
|
|
105
|
-
* element had it after that one was fixed. A double click reset to whatever
|
|
106
|
-
* `split` held on the first render, which is the declared arrangement only
|
|
107
|
-
* when nobody owns the property. The workbench owns it, restores it from the
|
|
108
|
-
* address bar and from storage, so the first value it ever held was the
|
|
109
|
-
* reader's last session: double clicking reset the sandbox to the size it
|
|
110
|
-
* already was, which is to say it did nothing at all.
|
|
111
|
-
*
|
|
112
|
-
* Declared rather than captured, so it is a number a consumer states and can
|
|
113
|
-
* change, and it needs no first frame to be read on.
|
|
114
|
-
*/
|
|
115
|
-
defaultSplit: number;
|
|
116
|
-
/**
|
|
117
|
-
* Height of the panel, in pixels.
|
|
118
|
-
*/
|
|
119
|
-
panelSize: number;
|
|
120
|
-
/**
|
|
121
|
-
* What a reset makes the panel, in pixels.
|
|
122
|
-
*
|
|
123
|
-
* The pair to `panel-size`.
|
|
114
|
+
* Whether the panes sit side by side or stacked.
|
|
124
115
|
*/
|
|
125
|
-
|
|
116
|
+
orientation?: 'horizontal' | 'vertical';
|
|
126
117
|
/**
|
|
127
118
|
* What the panel's height becomes when it is closed.
|
|
128
119
|
*
|
|
@@ -136,13 +127,17 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
136
127
|
*/
|
|
137
128
|
panelLabel: string;
|
|
138
129
|
/**
|
|
139
|
-
*
|
|
130
|
+
* Height of the panel, in pixels.
|
|
140
131
|
*/
|
|
141
|
-
|
|
132
|
+
panelSize: number;
|
|
142
133
|
/**
|
|
143
134
|
* Accessible name for the divider.
|
|
144
135
|
*/
|
|
145
136
|
separatorLabel: string;
|
|
137
|
+
/**
|
|
138
|
+
* Percentage of the sandbox given to the source pane.
|
|
139
|
+
*/
|
|
140
|
+
split: number;
|
|
146
141
|
/**
|
|
147
142
|
* Whether anything is in the panel region.
|
|
148
143
|
*
|
|
@@ -160,16 +155,14 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
160
155
|
* panel asked for at 192px quietly keeps whatever share of the old height that
|
|
161
156
|
* was.
|
|
162
157
|
*
|
|
163
|
-
* **Measured at render rather than cached from the observer
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* render leaves one source of truth, and the observer's only job is to say
|
|
169
|
-
* that a render is due.
|
|
158
|
+
* **Measured at render rather than cached from the observer.** A
|
|
159
|
+
* `ResizeObserver` callback is delivered from the rendering lifecycle and a
|
|
160
|
+
* background tab runs none, so a cached number goes stale with nothing to say
|
|
161
|
+
* so. Reading the box at render leaves one source of truth, and the observer's
|
|
162
|
+
* only job is to say that a render is due.
|
|
170
163
|
*
|
|
171
|
-
* Cheap, because renders are rare
|
|
172
|
-
*
|
|
164
|
+
* Cheap, because renders are rare: a drag does not go through this element at
|
|
165
|
+
* all, the splitter following the pointer itself and announcing once, when it
|
|
173
166
|
* settles.
|
|
174
167
|
*/
|
|
175
168
|
private bodyHeight;
|
|
@@ -198,12 +191,11 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
198
191
|
/**
|
|
199
192
|
* Whether a change came from inside this sandbox's source region.
|
|
200
193
|
*
|
|
201
|
-
* Structural rather than a type check.
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* about the tree, and the tree can answer it.
|
|
194
|
+
* Structural rather than a type check. There is more than one kind of pane and
|
|
195
|
+
* the editor is `@fusion.dev/helix-sandbox/editor`, on its own path because it
|
|
196
|
+
* carries CodeMirror, so naming its class here would pull that back into this
|
|
197
|
+
* module for every consumer. Where the event came from is a question about the
|
|
198
|
+
* tree, and the tree can answer it.
|
|
207
199
|
*/
|
|
208
200
|
private fromSource;
|
|
209
201
|
/**
|
|
@@ -266,11 +258,9 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
266
258
|
* wrote to storage on its own would be deciding for all of them under a key
|
|
267
259
|
* it chose.
|
|
268
260
|
*
|
|
269
|
-
* **A verb each,
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* them. It was the last caller of a field every request in the library carried
|
|
273
|
-
* for it. See 306.
|
|
261
|
+
* **A verb each, rather than one `helix-before-resize` naming which of the two
|
|
262
|
+
* moved.** Both dividers are this element's, so `composedPath()[0]` is the same
|
|
263
|
+
* host for either and the event name is the only thing that can separate them.
|
|
274
264
|
*/
|
|
275
265
|
private splitSettled;
|
|
276
266
|
/** As `splitSettled`, for the panel, whose value is pixels rather than a share. */
|
|
@@ -286,7 +276,8 @@ export declare class HelixSandbox extends HelixElement {
|
|
|
286
276
|
* `target` against `currentTarget`, because a source pane's own change bubbles
|
|
287
277
|
* up through these same elements on its way to the host. Only a splitter
|
|
288
278
|
* speaking for itself is one of ours, and only those are stopped: the sandbox
|
|
289
|
-
* announces `
|
|
279
|
+
* announces `helix-before-split` and `helix-before-panel-resize` in their
|
|
280
|
+
* place, and a consumer never sees the two splitters inside it.
|
|
290
281
|
*/
|
|
291
282
|
private readonly handlePanesChange;
|
|
292
283
|
private readonly handlePanelChange;
|