@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.
Files changed (227) hide show
  1. package/custom-elements.json +5565 -5519
  2. package/dist/accordion/item/accordion-item.css.js +1 -19
  3. package/dist/accordion/root/accordion-root.css.js +1 -1
  4. package/dist/accordion/root/accordion-root.d.ts +1 -1
  5. package/dist/accordion/root/accordion-root.js +1 -1
  6. package/dist/announcement/root/announcement-root.css.js +1 -7
  7. package/dist/app-header/root/app-header-root.css.js +1 -7
  8. package/dist/app-header/root/app-header-root.d.ts +20 -23
  9. package/dist/app-header/root/app-header-root.js +4 -4
  10. package/dist/aura/root/aura-axis.d.ts +5 -7
  11. package/dist/aura/root/aura-axis.js +5 -7
  12. package/dist/aura/root/aura-root.css.js +1 -1
  13. package/dist/aura/root/aura-root.d.ts +75 -87
  14. package/dist/aura/root/aura-root.js +100 -109
  15. package/dist/aura/root/aura-shader.d.ts +10 -13
  16. package/dist/aura/root/aura-shader.js +165 -238
  17. package/dist/avatar/group/avatar-group.css.js +1 -1
  18. package/dist/avatar/root/avatar-root.css.js +1 -1
  19. package/dist/badge/root/badge-root.css.js +1 -13
  20. package/dist/badge/root/badge-root.d.ts +4 -5
  21. package/dist/bar-chart/root/bar-chart-root.css.js +1 -13
  22. package/dist/bar-chart/root/bar-chart-root.d.ts +51 -60
  23. package/dist/bar-chart/root/bar-chart-root.js +10 -17
  24. package/dist/blockquote/root/blockquote-root.css.js +1 -1
  25. package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +1 -7
  26. package/dist/breadcrumbs/root/breadcrumbs-root.css.js +1 -1
  27. package/dist/button/root/button-root.css.js +1 -7
  28. package/dist/button/root/button-root.d.ts +16 -25
  29. package/dist/button/root/button-root.js +3 -3
  30. package/dist/button-group/root/button-group-root.css.js +1 -1
  31. package/dist/button-group/root/button-group-root.d.ts +5 -7
  32. package/dist/callout/root/callout-root.css.js +1 -1
  33. package/dist/callout/root/callout-root.d.ts +4 -4
  34. package/dist/callout/root/callout-root.js +4 -4
  35. package/dist/card/root/card-root.css.js +2 -2
  36. package/dist/card/root/card-root.d.ts +38 -48
  37. package/dist/card/root/card-root.js +8 -11
  38. package/dist/carousel/root/carousel-root.css.js +1 -11
  39. package/dist/carousel/root/carousel-root.d.ts +39 -43
  40. package/dist/carousel/root/carousel-root.js +7 -7
  41. package/dist/chat/composer/chat-composer.css.js +1 -1
  42. package/dist/chat/message/chat-message.css.js +1 -7
  43. package/dist/chat/message/chat-message.d.ts +8 -13
  44. package/dist/chat/root/chat-root.css.js +1 -1
  45. package/dist/checkbox/root/checkbox-root.css.js +1 -14
  46. package/dist/checkbox-group/root/checkbox-group-root.css.js +1 -1
  47. package/dist/code/root/code-root.css.js +9 -7
  48. package/dist/code/root/code-root.d.ts +4 -0
  49. package/dist/code/root/code-root.js +4 -0
  50. package/dist/code-block/root/code-block-root.css.js +1 -1
  51. package/dist/color-input/root/color-input-root.css.js +2 -2
  52. package/dist/color-input/root/color-input-root.js +3 -3
  53. package/dist/color-picker/root/color-picker-root.css.js +1 -9
  54. package/dist/color-picker/root/color-picker-root.js +3 -3
  55. package/dist/combobox/root/combobox-root.css.js +1 -8
  56. package/dist/combobox/root/combobox-root.js +1 -1
  57. package/dist/command/root/command-root.css.js +1 -1
  58. package/dist/copy-button/root/copy-button-root.css.js +1 -1
  59. package/dist/data-table/root/data-table-root.css.js +9 -3
  60. package/dist/data-table/root/data-table-root.d.ts +4 -1
  61. package/dist/data-table/root/data-table-root.js +4 -1
  62. package/dist/date-input/root/date-input-root.css.js +1 -1
  63. package/dist/date-picker/root/date-picker-root.css.js +1 -7
  64. package/dist/date-picker/root/date-picker-root.d.ts +1 -1
  65. package/dist/date-picker/root/date-picker-root.js +1 -1
  66. package/dist/dialog/root/dialog-root.css.js +1 -1
  67. package/dist/dialog/root/dialog-root.d.ts +15 -20
  68. package/dist/dialog/root/dialog-root.js +2 -2
  69. package/dist/divider/root/divider-root.css.js +1 -1
  70. package/dist/donut-chart/root/donut-chart-root.css.js +2 -20
  71. package/dist/donut-chart/root/donut-chart-root.d.ts +14 -19
  72. package/dist/donut-chart/root/donut-chart-root.js +6 -7
  73. package/dist/drawer/root/drawer-root.css.js +1 -11
  74. package/dist/drawer/root/drawer-root.d.ts +3 -7
  75. package/dist/drilldown/item/drilldown-item.css.js +1 -1
  76. package/dist/drilldown/root/drilldown-root.css.js +1 -1
  77. package/dist/element-events.generated.js +1 -1
  78. package/dist/empty/root/empty-root.css.js +1 -1
  79. package/dist/file-input/root/file-input-root.css.js +1 -1
  80. package/dist/file-input/root/file-input-root.js +1 -2
  81. package/dist/flex/root/flex-root.css.js +1 -1
  82. package/dist/flex/root/flex-root.d.ts +6 -6
  83. package/dist/flex/root/flex-root.js +9 -9
  84. package/dist/format-date/root/format-date-root.css.js +1 -1
  85. package/dist/grid/root/grid-root.css.js +1 -1
  86. package/dist/grid/root/grid-root.d.ts +8 -8
  87. package/dist/grid/root/grid-root.js +8 -9
  88. package/dist/heatmap/root/heatmap-root.css.js +2 -2
  89. package/dist/heatmap/root/heatmap-root.d.ts +11 -12
  90. package/dist/heatmap/root/heatmap-root.js +11 -12
  91. package/dist/icon/glyph.css.js +1 -1
  92. package/dist/icon/root/icon-root.css.js +1 -1
  93. package/dist/icon-button/root/icon-button-root.css.js +1 -7
  94. package/dist/icon-button/root/icon-button-root.d.ts +10 -10
  95. package/dist/icon-button/root/icon-button-root.js +4 -4
  96. package/dist/image/root/image-root.css.js +1 -7
  97. package/dist/input/root/input-root.css.js +1 -9
  98. package/dist/kbd/root/kbd-root.css.js +1 -1
  99. package/dist/legend/root/legend-root.css.js +1 -1
  100. package/dist/legend/root/legend-root.d.ts +34 -37
  101. package/dist/legend/root/legend-root.js +10 -10
  102. package/dist/line-chart/root/line-chart-root.css.js +1 -8
  103. package/dist/line-chart/root/line-chart-root.d.ts +6 -9
  104. package/dist/list/item/list-item.css.js +1 -1
  105. package/dist/list/root/list-root.css.js +1 -1
  106. package/dist/list/root/list-root.d.ts +4 -7
  107. package/dist/listbox/root/listbox-root.css.js +3 -3
  108. package/dist/listbox/root/listbox-root.d.ts +2 -0
  109. package/dist/listbox/root/listbox-root.js +2 -0
  110. package/dist/loader/root/loader-root.css.js +1 -1
  111. package/dist/loader/root/loader-root.d.ts +5 -9
  112. package/dist/loader/root/loader-root.js +2 -2
  113. package/dist/megamenu/root/megamenu-root.css.js +3 -2
  114. package/dist/menu/item/menu-item.css.js +1 -7
  115. package/dist/menu/root/menu-root.css.js +1 -1
  116. package/dist/meter/root/meter-root.css.js +1 -14
  117. package/dist/meter/root/meter-root.d.ts +18 -18
  118. package/dist/meter/root/meter-root.js +6 -8
  119. package/dist/mixins/mixin-control-surface/mixin-control-surface.d.ts +1 -1
  120. package/dist/navigation/root/navigation-root.css.js +1 -7
  121. package/dist/notifications/notification/notification.css.js +1 -7
  122. package/dist/notifications/root/notifications-root.css.js +1 -1
  123. package/dist/number-input/root/number-input-root.css.js +1 -9
  124. package/dist/option/group/option-group.css.js +1 -1
  125. package/dist/option/root/option-root.css.js +1 -1
  126. package/dist/outline/root/outline-root.css.js +1 -14
  127. package/dist/outline/root/outline-root.d.ts +1 -1
  128. package/dist/outline/root/outline-root.js +1 -1
  129. package/dist/pagination/root/pagination-root.css.js +1 -12
  130. package/dist/pagination/size/pagination-size.css.js +1 -1
  131. package/dist/pagination/summary/pagination-summary.css.js +1 -1
  132. package/dist/pin-input/root/pin-input-root.css.js +1 -7
  133. package/dist/popover/root/popover-root.css.js +4 -2
  134. package/dist/progress/root/progress-root.css.js +1 -7
  135. package/dist/progress/root/progress-root.d.ts +10 -9
  136. package/dist/qr-code/root/qr-code-root.css.js +1 -1
  137. package/dist/qr-code/root/qr-code-root.d.ts +1 -1
  138. package/dist/qr-code/root/qr-code-root.js +1 -1
  139. package/dist/quote/root/quote-root.css.js +1 -1
  140. package/dist/radio/group/radio-group.css.js +1 -1
  141. package/dist/radio/root/radio-root.css.js +1 -14
  142. package/dist/radio/root/radio-root.d.ts +20 -18
  143. package/dist/radio/root/radio-root.js +5 -6
  144. package/dist/rating/root/rating-root.css.js +1 -1
  145. package/dist/rating/root/rating-root.d.ts +4 -5
  146. package/dist/sandbox/preview/sandbox-preview.css.js +1 -1
  147. package/dist/sandbox/preview/sandbox-preview.d.ts +48 -44
  148. package/dist/sandbox/preview/sandbox-preview.js +63 -50
  149. package/dist/sandbox/root/sandbox-root.css.js +1 -2
  150. package/dist/sandbox/root/sandbox-root.d.ts +50 -59
  151. package/dist/sandbox/root/sandbox-root.js +75 -91
  152. package/dist/sandbox/source/sandbox-source.css.js +1 -1
  153. package/dist/sandbox/source/sandbox-source.d.ts +21 -29
  154. package/dist/sandbox/source/sandbox-source.js +26 -34
  155. package/dist/sandbox/status-bar/sandbox-status-bar.css.js +1 -1
  156. package/dist/sandbox/terminal/sandbox-terminal.css.js +1 -1
  157. package/dist/sandbox/toolbar/sandbox-toolbar.css.js +1 -1
  158. package/dist/scroll-area/root/scroll-area-root.css.js +5 -5
  159. package/dist/select/root/select-root.css.js +2 -15
  160. package/dist/select/root/select-root.d.ts +4 -4
  161. package/dist/select/root/select-root.js +5 -7
  162. package/dist/shared/chart/series.css.js +1 -1
  163. package/dist/shared/chart/terminus.css.js +1 -1
  164. package/dist/shared/field/field-inline.css.js +1 -1
  165. package/dist/shared/field/field-stacked.css.js +1 -1
  166. package/dist/shared/field/field.css.js +1 -1
  167. package/dist/skeleton/root/skeleton-root.css.js +1 -1
  168. package/dist/slider/root/slider-root.css.js +1 -3
  169. package/dist/sparkline/root/sparkline-root.css.js +1 -1
  170. package/dist/sparkline/root/sparkline-root.d.ts +22 -24
  171. package/dist/sparkline/root/sparkline-root.js +6 -6
  172. package/dist/speed-dial/item/speed-dial-item.css.js +1 -7
  173. package/dist/speed-dial/root/speed-dial-root.css.js +1 -1
  174. package/dist/splitter/root/splitter-root.css.js +1 -14
  175. package/dist/stat/group/stat-group.css.js +1 -1
  176. package/dist/stat/root/stat-root.css.js +1 -1
  177. package/dist/steps/root/steps-root.css.js +1 -1
  178. package/dist/steps/step/step.css.js +1 -8
  179. package/dist/steps/step/step.js +1 -1
  180. package/dist/switch/root/switch-root.css.js +1 -8
  181. package/dist/table/cell/table-cell.css.js +1 -1
  182. package/dist/table/column/table-column.css.js +1 -1
  183. package/dist/table/root/table-root.css.js +1 -1
  184. package/dist/table/row/table-row.css.js +1 -1
  185. package/dist/tabs/panel/tab-panel.css.js +1 -1
  186. package/dist/tabs/root/tabs-root.css.js +1 -7
  187. package/dist/tabs/tab/tab.css.js +2 -8
  188. package/dist/tag/root/tag-root.css.js +1 -1
  189. package/dist/tag/root/tag-root.d.ts +10 -19
  190. package/dist/tag/root/tag-root.js +3 -3
  191. package/dist/text/root/text-root.css.js +1 -1
  192. package/dist/text/root/text-root.d.ts +13 -14
  193. package/dist/text/root/text-root.js +6 -6
  194. package/dist/textarea/root/textarea-root.css.js +1 -7
  195. package/dist/time-input/root/time-input-root.css.js +1 -1
  196. package/dist/time-input/root/time-input-root.js +1 -1
  197. package/dist/time-picker/root/time-picker-root.css.js +1 -7
  198. package/dist/time-picker/root/time-picker-root.js +1 -1
  199. package/dist/timeline/item/timeline-item.css.js +1 -1
  200. package/dist/timeline/root/timeline-root.css.js +1 -1
  201. package/dist/toast/item/toast-item.css.js +1 -1
  202. package/dist/toast/root/toast-root.css.js +1 -1
  203. package/dist/toggle/group/toggle-group.css.js +1 -7
  204. package/dist/toggle/group/toggle-group.d.ts +6 -9
  205. package/dist/toggle/root/toggle-root.css.js +1 -1
  206. package/dist/toolbar/root/toolbar-root.css.js +1 -1
  207. package/dist/tooltip/root/tooltip-root.css.js +1 -1
  208. package/dist/tooltip/root/tooltip-root.d.ts +6 -7
  209. package/dist/tour/root/tour-root.css.js +1 -7
  210. package/dist/tour/stop/tour-stop.css.js +2 -2
  211. package/dist/tree/item/tree-item.css.js +1 -17
  212. package/dist/tree/root/tree-root.css.js +1 -1
  213. package/dist/tree/root/tree-root.d.ts +0 -2
  214. package/dist/trend/root/trend-root.css.js +1 -1
  215. package/dist/trend/root/trend-root.d.ts +4 -7
  216. package/dist/trend/root/trend-root.js +4 -7
  217. package/dist/video/root/video-root.css.js +1 -12
  218. package/dist/video/root/video-root.d.ts +3 -8
  219. package/dist/video-playlist/item/video-playlist-item.css.js +1 -7
  220. package/dist/video-playlist/menu/video-playlist-menu.css.js +1 -1
  221. package/dist/video-playlist/root/video-playlist-root.css.js +1 -1
  222. package/dist/virtual-list/root/virtual-list-root.css.js +1 -1
  223. package/elements.css +4 -5
  224. package/helix.css +31 -0
  225. package/jsx.d.ts +11625 -14561
  226. package/package.json +10 -8
  227. 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
- * That is what lets a sandbox hold markup a reader pasted from somewhere, or
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 colours a chart reads.
105
+ * including every one of the 24 series colors a chart reads.
101
106
  */
102
107
  colorMode?: 'dark' | 'light';
103
108
  /**
104
- * Document the frame loads, which brings the styles and the elements.
109
+ * Writing direction inside the frame.
105
110
  */
106
- src: string;
111
+ direction?: 'rtl';
107
112
  /**
108
- * Markup to render.
113
+ * Accessible name for the frame.
109
114
  */
110
- source: string;
115
+ label: string;
111
116
  /**
112
- * Stylesheet applied inside the frame, alongside the markup.
117
+ * How the example is placed in the frame.
113
118
  */
114
- styles: string;
119
+ layout?: 'padded' | 'centered' | 'fullscreen' | 'hug';
115
120
  /**
116
- * Accessible name for the frame.
121
+ * Markup to render.
117
122
  */
118
- label: string;
123
+ source: string;
119
124
  /**
120
- * Writing direction inside the frame.
125
+ * Document the frame loads, which brings the styles and the elements.
121
126
  */
122
- direction?: 'rtl';
127
+ src: string;
123
128
  /**
124
- * How the example is placed in the frame.
129
+ * Stylesheet applied inside the frame, alongside the markup.
125
130
  */
126
- layout?: 'padded' | 'centered' | 'fullscreen' | 'hug';
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
- * posts `helix-preview-ready` at the end of its own module evaluation and
135
- * never repeats it, and `handleMessage` drops anything whose `source` is not
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. A frame that loads before that
138
- * render commits therefore announces into a guard that refuses it, `ready`
139
- * stays false, and `send` returns early forever: the source is set, the
140
- * markup is correct, and the preview is blank with nothing logged.
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 was tried first and is the wrong unit. Keystrokes arrive fifty to a
190
- * hundred and fifty milliseconds apart, so each one lands in a frame of its
191
- * own and coalescing by frame coalesces nothing: the example was still being
192
- * rebuilt per character. The delay has to be longer than the gap between
193
- * keystrokes to catch a burst, and short enough to read as immediate when the
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
- * That is what lets a sandbox hold markup a reader pasted from somewhere, or
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
- * Document the frame loads, which brings the styles and the elements.
74
+ * Accessible name for the frame.
82
75
  */
83
- this.src = '';
76
+ this.label = 'Preview';
84
77
  /**
85
78
  * Markup to render.
86
79
  */
87
80
  this.source = '';
88
81
  /**
89
- * Stylesheet applied inside the frame, alongside the markup.
82
+ * Document the frame loads, which brings the styles and the elements.
90
83
  */
91
- this.styles = '';
84
+ this.src = '';
92
85
  /**
93
- * Accessible name for the frame.
86
+ * Stylesheet applied inside the frame, alongside the markup.
94
87
  */
95
- this.label = 'Preview';
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
- * posts `helix-preview-ready` at the end of its own module evaluation and
103
- * never repeats it, and `handleMessage` drops anything whose `source` is not
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. A frame that loads before that
106
- * render commits therefore announces into a guard that refuses it, `ready`
107
- * stays false, and `send` returns early forever: the source is set, the
108
- * markup is correct, and the preview is blank with nothing logged.
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 was tried first and is the wrong unit. Keystrokes arrive fifty to a
184
- * hundred and fifty milliseconds apart, so each one lands in a frame of its
185
- * own and coalescing by frame coalesces nothing: the example was still being
186
- * rebuilt per character. The delay has to be longer than the gap between
187
- * keystrokes to catch a burst, and short enough to read as immediate when the
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, that happened once per
256
- * keystroke: an example of any size was being torn down and rebuilt for
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
- * A frame is short enough to feel immediate and long enough that a burst of
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, "src", void 0);
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, "styles", void 0);
312
+ ], HelixSandboxPreview.prototype, "src", void 0);
294
313
  __decorate([
295
314
  property()
296
- ], HelixSandboxPreview.prototype, "label", void 0);
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 `bun run styles`. Do not edit.
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.** It had its own: a five row grid, a stylesheet written to on
22
- * every pointer move, three pointer handlers, a keyboard handler reading which
23
- * axes each divider was allowed to move, and a corner placed by hand into the
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
- * Whether the panes sit side by side or stacked.
72
+ * Accessible name for the divider that moves both at once.
76
73
  */
77
- orientation?: 'horizontal' | 'vertical';
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
- * Percentage of the sandbox given to the source pane.
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
- defaultPanelSize: number;
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
- * Accessible name for the divider that moves both at once.
130
+ * Height of the panel, in pixels.
140
131
  */
141
- cornerLabel: string;
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**, which is the
164
- * second design here. The first held the number the observer last reported and
165
- * was correct only while the observer was firing, and a `ResizeObserver`
166
- * callback is delivered from the rendering lifecycle: a background tab runs
167
- * none, so the value went stale with nothing to say so. Reading the box at
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. A drag no longer goes through this element
172
- * at all: the splitter follows the pointer itself and announces once, when it
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. It was `instanceof
202
- * HelixSandboxSource`, which was right until there was a second kind of
203
- * pane: the editor is `@fusion.dev/helix-sandbox/editor`, on its own path because it
204
- * carries CodeMirror, and naming its class here would pull that back into
205
- * this module for every consumer. Where the event came from is a question
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, where this was one `helix-before-resize` carrying which of the
270
- * two had moved.** Both dividers are this element's, so `composedPath()[0]` is
271
- * the same host for either and the name is the only thing that can separate
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 `arrangement` and a consumer never sees the two inside it.
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;