@fusion.dev/helix 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/custom-elements.json +256 -256
  2. package/dist/accordion/item/accordion-item.css.js +0 -1
  3. package/dist/accordion/item/accordion-item.js +0 -29
  4. package/dist/accordion/root/accordion-root.css.js +0 -1
  5. package/dist/accordion/root/accordion-root.js +0 -20
  6. package/dist/announcement/root/announcement-root.css.js +0 -1
  7. package/dist/announcement/root/announcement-root.js +0 -16
  8. package/dist/app-header/root/app-header-root.css.js +0 -1
  9. package/dist/app-header/root/app-header-root.js +0 -45
  10. package/dist/aura/root/aura-axis.js +0 -58
  11. package/dist/aura/root/aura-root.css.js +0 -1
  12. package/dist/aura/root/aura-root.js +0 -520
  13. package/dist/aura/root/aura-shader.js +0 -35
  14. package/dist/avatar/group/avatar-group.css.js +0 -1
  15. package/dist/avatar/group/avatar-group.js +0 -24
  16. package/dist/avatar/root/avatar-root.css.js +0 -1
  17. package/dist/avatar/root/avatar-root.js +0 -23
  18. package/dist/badge/root/badge-root.css.js +0 -1
  19. package/dist/badge/root/badge-root.d.ts +2 -6
  20. package/dist/badge/root/badge-root.js +0 -18
  21. package/dist/bar-chart/root/bar-chart-root.css.js +0 -1
  22. package/dist/bar-chart/root/bar-chart-root.js +0 -50
  23. package/dist/blockquote/root/blockquote-root.css.js +0 -1
  24. package/dist/blockquote/root/blockquote-root.js +0 -17
  25. package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +0 -1
  26. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +0 -28
  27. package/dist/breadcrumbs/root/breadcrumbs-root.css.js +0 -1
  28. package/dist/breadcrumbs/root/breadcrumbs-root.js +0 -19
  29. package/dist/button/root/button-root.css.js +0 -1
  30. package/dist/button/root/button-root.js +0 -38
  31. package/dist/button-group/root/button-group-root.css.js +0 -1
  32. package/dist/button-group/root/button-group-root.js +0 -24
  33. package/dist/callout/root/callout-root.css.js +0 -1
  34. package/dist/callout/root/callout-root.js +0 -26
  35. package/dist/card/root/card-root.css.js +0 -1
  36. package/dist/card/root/card-root.js +0 -45
  37. package/dist/carousel/root/carousel-root.css.js +0 -1
  38. package/dist/carousel/root/carousel-root.js +0 -24
  39. package/dist/chat/composer/chat-composer.css.js +0 -1
  40. package/dist/chat/composer/chat-composer.js +0 -26
  41. package/dist/chat/message/chat-message.css.js +0 -1
  42. package/dist/chat/message/chat-message.js +0 -29
  43. package/dist/chat/root/chat-root.css.js +0 -1
  44. package/dist/chat/root/chat-root.js +0 -38
  45. package/dist/checkbox/root/checkbox-root.css.js +0 -1
  46. package/dist/checkbox/root/checkbox-root.js +0 -26
  47. package/dist/checkbox-group/root/checkbox-group-root.css.js +0 -1
  48. package/dist/checkbox-group/root/checkbox-group-root.js +0 -15
  49. package/dist/code/root/code-root.css.js +0 -1
  50. package/dist/code/root/code-root.js +0 -21
  51. package/dist/code-block/root/code-block-root.css.js +0 -1
  52. package/dist/code-block/root/code-block-root.js +0 -19
  53. package/dist/color-input/root/color-input-root.css.js +0 -1
  54. package/dist/color-input/root/color-input-root.js +0 -42
  55. package/dist/color-picker/root/color-picker-root.css.js +0 -1
  56. package/dist/color-picker/root/color-picker-root.js +0 -42
  57. package/dist/combobox/root/combobox-root.css.js +0 -1
  58. package/dist/combobox/root/combobox-root.js +0 -28
  59. package/dist/command/root/command-root.css.js +0 -1
  60. package/dist/command/root/command-root.js +0 -21
  61. package/dist/copy-button/root/copy-button-root.css.js +0 -1
  62. package/dist/copy-button/root/copy-button-root.js +0 -14
  63. package/dist/data-table/root/data-table-root.css.js +0 -1
  64. package/dist/data-table/root/data-table-root.js +0 -39
  65. package/dist/date-input/root/date-input-root.css.js +0 -1
  66. package/dist/date-input/root/date-input-root.js +0 -38
  67. package/dist/date-picker/root/date-picker-root.css.js +0 -1
  68. package/dist/date-picker/root/date-picker-root.js +0 -28
  69. package/dist/dialog/root/dialog-root.css.js +0 -1
  70. package/dist/dialog/root/dialog-root.js +0 -31
  71. package/dist/divider/root/divider-root.css.js +0 -1
  72. package/dist/divider/root/divider-root.js +0 -24
  73. package/dist/donut-chart/root/donut-chart-root.css.js +0 -1
  74. package/dist/donut-chart/root/donut-chart-root.js +0 -49
  75. package/dist/drawer/root/drawer-root.css.js +0 -1
  76. package/dist/drawer/root/drawer-root.js +0 -38
  77. package/dist/drilldown/item/drilldown-item.css.js +0 -1
  78. package/dist/drilldown/item/drilldown-item.js +0 -15
  79. package/dist/drilldown/root/drilldown-root.css.js +0 -1
  80. package/dist/drilldown/root/drilldown-root.js +0 -23
  81. package/dist/element-events.generated.js +0 -5
  82. package/dist/empty/root/empty-root.css.js +0 -1
  83. package/dist/empty/root/empty-root.js +0 -16
  84. package/dist/file-input/root/file-input-root.css.js +0 -1
  85. package/dist/file-input/root/file-input-root.js +0 -30
  86. package/dist/flex/root/flex-root.css.js +0 -1
  87. package/dist/flex/root/flex-root.js +0 -32
  88. package/dist/format-date/root/format-date-root.css.js +0 -1
  89. package/dist/format-date/root/format-date-root.js +0 -17
  90. package/dist/grid/root/grid-root.css.js +0 -1
  91. package/dist/grid/root/grid-root.js +0 -69
  92. package/dist/heatmap/root/heatmap-root.css.js +0 -1
  93. package/dist/heatmap/root/heatmap-root.d.ts +9 -11
  94. package/dist/heatmap/root/heatmap-root.js +0 -73
  95. package/dist/icon/glyph.css.js +0 -1
  96. package/dist/icon/root/icon-root.css.js +0 -1
  97. package/dist/icon/root/icon-root.js +0 -19
  98. package/dist/icon-button/root/icon-button-root.css.js +0 -1
  99. package/dist/icon-button/root/icon-button-root.js +0 -35
  100. package/dist/image/root/image-root.css.js +0 -1
  101. package/dist/image/root/image-root.js +0 -28
  102. package/dist/index.js +0 -5
  103. package/dist/input/root/input-root.css.js +0 -1
  104. package/dist/input/root/input-root.js +0 -28
  105. package/dist/kbd/root/kbd-root.css.js +0 -1
  106. package/dist/kbd/root/kbd-root.js +0 -20
  107. package/dist/legend/root/legend-root.css.js +0 -1
  108. package/dist/legend/root/legend-root.js +0 -35
  109. package/dist/line-chart/root/line-chart-root.css.js +0 -1
  110. package/dist/line-chart/root/line-chart-root.js +0 -47
  111. package/dist/list/item/list-item.css.js +0 -1
  112. package/dist/list/item/list-item.js +0 -38
  113. package/dist/list/root/list-root.css.js +0 -1
  114. package/dist/list/root/list-root.js +0 -23
  115. package/dist/listbox/root/listbox-root.css.js +0 -1
  116. package/dist/listbox/root/listbox-root.js +0 -22
  117. package/dist/loader/root/loader-root.css.js +0 -1
  118. package/dist/loader/root/loader-root.js +0 -19
  119. package/dist/megamenu/root/megamenu-root.css.js +0 -1
  120. package/dist/megamenu/root/megamenu-root.js +0 -24
  121. package/dist/menu/item/menu-item.css.js +0 -1
  122. package/dist/menu/item/menu-item.js +0 -16
  123. package/dist/menu/root/menu-root.css.js +0 -1
  124. package/dist/menu/root/menu-root.js +0 -26
  125. package/dist/meter/root/meter-root.css.js +0 -1
  126. package/dist/meter/root/meter-root.js +0 -50
  127. package/dist/mixins/mixin-control-surface/mixin-control-surface.js +0 -3
  128. package/dist/navigation/root/navigation-root.css.js +0 -1
  129. package/dist/navigation/root/navigation-root.js +0 -18
  130. package/dist/notifications/notification/notification.css.js +0 -1
  131. package/dist/notifications/notification/notification.js +0 -53
  132. package/dist/notifications/root/notifications-root.css.js +0 -1
  133. package/dist/notifications/root/notifications-root.js +0 -31
  134. package/dist/number-input/root/number-input-root.css.js +0 -1
  135. package/dist/number-input/root/number-input-root.js +0 -31
  136. package/dist/option/group/option-group.css.js +0 -1
  137. package/dist/option/group/option-group.js +0 -13
  138. package/dist/option/root/option-root.css.js +0 -1
  139. package/dist/option/root/option-root.js +0 -20
  140. package/dist/outline/root/outline-root.css.js +0 -1
  141. package/dist/outline/root/outline-root.js +0 -21
  142. package/dist/pagination/root/pagination-root.css.js +0 -1
  143. package/dist/pagination/root/pagination-root.js +0 -49
  144. package/dist/pagination/size/pagination-size.css.js +0 -1
  145. package/dist/pagination/size/pagination-size.js +0 -25
  146. package/dist/pagination/summary/pagination-summary.css.js +0 -1
  147. package/dist/pagination/summary/pagination-summary.js +0 -13
  148. package/dist/pin-input/root/pin-input-root.css.js +0 -1
  149. package/dist/pin-input/root/pin-input-root.js +0 -27
  150. package/dist/popover/root/popover-root.css.js +0 -1
  151. package/dist/popover/root/popover-root.js +0 -30
  152. package/dist/progress/root/progress-root.css.js +0 -1
  153. package/dist/progress/root/progress-root.js +0 -25
  154. package/dist/qr-code/root/qr-code-root.css.js +0 -1
  155. package/dist/qr-code/root/qr-code-root.js +0 -27
  156. package/dist/quote/root/quote-root.css.js +0 -1
  157. package/dist/quote/root/quote-root.js +0 -15
  158. package/dist/radio/group/radio-group.css.js +0 -1
  159. package/dist/radio/group/radio-group.js +0 -16
  160. package/dist/radio/root/radio-root.css.js +0 -1
  161. package/dist/radio/root/radio-root.js +0 -46
  162. package/dist/rating/root/rating-root.css.js +0 -1
  163. package/dist/rating/root/rating-root.js +0 -22
  164. package/dist/sandbox/index.js +0 -14
  165. package/dist/sandbox/preview/sandbox-preview.css.js +0 -1
  166. package/dist/sandbox/preview/sandbox-preview.js +0 -182
  167. package/dist/sandbox/root/sandbox-root.css.js +0 -1
  168. package/dist/sandbox/root/sandbox-root.js +1 -295
  169. package/dist/sandbox/source/sandbox-source.css.js +0 -1
  170. package/dist/sandbox/source/sandbox-source.js +0 -77
  171. package/dist/sandbox/status-bar/sandbox-status-bar.css.js +0 -1
  172. package/dist/sandbox/status-bar/sandbox-status-bar.js +0 -38
  173. package/dist/sandbox/terminal/sandbox-terminal.css.js +0 -1
  174. package/dist/sandbox/terminal/sandbox-terminal.js +0 -54
  175. package/dist/sandbox/toolbar/sandbox-toolbar.css.js +0 -1
  176. package/dist/sandbox/toolbar/sandbox-toolbar.js +0 -29
  177. package/dist/scroll-area/root/scroll-area-root.css.js +0 -1
  178. package/dist/scroll-area/root/scroll-area-root.js +0 -24
  179. package/dist/select/root/select-root.css.js +0 -1
  180. package/dist/select/root/select-root.js +0 -33
  181. package/dist/shared/chart/series.css.js +0 -1
  182. package/dist/shared/chart/terminus.css.js +0 -1
  183. package/dist/shared/field/field-inline.css.js +0 -1
  184. package/dist/shared/field/field-stacked.css.js +0 -1
  185. package/dist/shared/field/field.css.js +0 -1
  186. package/dist/skeleton/root/skeleton-root.css.js +0 -1
  187. package/dist/skeleton/root/skeleton-root.js +0 -18
  188. package/dist/slider/root/slider-root.css.js +0 -1
  189. package/dist/slider/root/slider-root.js +0 -32
  190. package/dist/sparkline/root/sparkline-root.css.js +0 -1
  191. package/dist/sparkline/root/sparkline-root.js +0 -40
  192. package/dist/speed-dial/item/speed-dial-item.css.js +0 -1
  193. package/dist/speed-dial/item/speed-dial-item.js +0 -16
  194. package/dist/speed-dial/root/speed-dial-root.css.js +0 -1
  195. package/dist/speed-dial/root/speed-dial-root.js +0 -16
  196. package/dist/splitter/root/splitter-root.css.js +0 -1
  197. package/dist/splitter/root/splitter-root.js +0 -50
  198. package/dist/stat/group/stat-group.css.js +0 -1
  199. package/dist/stat/group/stat-group.js +0 -19
  200. package/dist/stat/root/stat-root.css.js +0 -1
  201. package/dist/stat/root/stat-root.js +0 -17
  202. package/dist/steps/root/steps-root.css.js +0 -1
  203. package/dist/steps/root/steps-root.js +0 -26
  204. package/dist/steps/step/step.css.js +0 -1
  205. package/dist/steps/step/step.js +0 -12
  206. package/dist/switch/root/switch-root.css.js +0 -1
  207. package/dist/switch/root/switch-root.js +0 -32
  208. package/dist/table/cell/table-cell.css.js +0 -1
  209. package/dist/table/cell/table-cell.js +0 -14
  210. package/dist/table/column/table-column.css.js +0 -1
  211. package/dist/table/column/table-column.js +0 -13
  212. package/dist/table/root/table-root.css.js +0 -1
  213. package/dist/table/root/table-root.js +0 -19
  214. package/dist/table/row/table-row.css.js +0 -1
  215. package/dist/table/row/table-row.js +0 -14
  216. package/dist/tabs/panel/tab-panel.css.js +0 -1
  217. package/dist/tabs/panel/tab-panel.js +0 -16
  218. package/dist/tabs/root/tabs-root.css.js +0 -1
  219. package/dist/tabs/root/tabs-root.js +0 -19
  220. package/dist/tabs/tab/tab.css.js +0 -1
  221. package/dist/tabs/tab/tab.js +0 -16
  222. package/dist/tag/root/tag-root.css.js +0 -1
  223. package/dist/tag/root/tag-root.js +0 -25
  224. package/dist/text/root/text-root.css.js +0 -1
  225. package/dist/text/root/text-root.js +0 -48
  226. package/dist/textarea/root/textarea-root.css.js +0 -1
  227. package/dist/textarea/root/textarea-root.js +0 -17
  228. package/dist/time-input/root/time-input-root.css.js +0 -1
  229. package/dist/time-input/root/time-input-root.js +0 -31
  230. package/dist/time-picker/root/time-picker-root.css.js +0 -1
  231. package/dist/time-picker/root/time-picker-root.js +0 -29
  232. package/dist/timeline/item/timeline-item.css.js +0 -1
  233. package/dist/timeline/item/timeline-item.js +0 -17
  234. package/dist/timeline/root/timeline-root.css.js +0 -1
  235. package/dist/timeline/root/timeline-root.js +0 -15
  236. package/dist/toast/item/toast-item.css.js +0 -1
  237. package/dist/toast/item/toast-item.js +0 -21
  238. package/dist/toast/root/toast-root.css.js +0 -1
  239. package/dist/toast/root/toast-root.js +0 -27
  240. package/dist/toggle/group/toggle-group.css.js +0 -1
  241. package/dist/toggle/group/toggle-group.js +0 -25
  242. package/dist/toggle/root/toggle-root.css.js +0 -1
  243. package/dist/toggle/root/toggle-root.js +0 -18
  244. package/dist/toolbar/root/toolbar-root.css.js +0 -1
  245. package/dist/toolbar/root/toolbar-root.js +0 -19
  246. package/dist/tooltip/root/tooltip-root.css.js +0 -1
  247. package/dist/tooltip/root/tooltip-root.js +0 -22
  248. package/dist/tour/root/tour-root.css.js +0 -1
  249. package/dist/tour/root/tour-root.js +0 -14
  250. package/dist/tour/stop/tour-stop.css.js +0 -1
  251. package/dist/tour/stop/tour-stop.js +0 -22
  252. package/dist/tree/item/tree-item.css.js +0 -1
  253. package/dist/tree/item/tree-item.js +0 -34
  254. package/dist/tree/root/tree-root.css.js +0 -1
  255. package/dist/tree/root/tree-root.js +0 -27
  256. package/dist/trend/root/trend-root.css.js +0 -1
  257. package/dist/trend/root/trend-root.js +0 -34
  258. package/dist/video/root/video-root.css.js +0 -1
  259. package/dist/video/root/video-root.js +0 -37
  260. package/dist/video-playlist/item/video-playlist-item.css.js +0 -1
  261. package/dist/video-playlist/item/video-playlist-item.js +0 -15
  262. package/dist/video-playlist/menu/video-playlist-menu.css.js +0 -1
  263. package/dist/video-playlist/menu/video-playlist-menu.js +0 -36
  264. package/dist/video-playlist/root/video-playlist-root.css.js +0 -1
  265. package/dist/video-playlist/root/video-playlist-root.js +0 -16
  266. package/dist/virtual-list/root/virtual-list-root.css.js +0 -1
  267. package/dist/virtual-list/root/virtual-list-root.js +0 -21
  268. package/jsx.d.ts +1538 -2818
  269. package/package.json +7 -7
  270. package/vue.d.ts +3 -7
@@ -9,212 +9,33 @@ import '../../splitter/index.js';
9
9
  import { html } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { styles } from './sandbox-root.css.js';
12
- /** Where the divider sits, and how tall the panel is, before anyone moves them.
13
- Named because the properties default to them and the getters that reset them
14
- fall back to them, and two copies of a default drift. */
15
12
  const DEFAULT_SPLIT = 50;
16
- /* One hundred and sixty, not one hundred and ninety-two. At 192 the panel opened
17
- taking forty-two percent of the sandbox: the thing being previewed had less
18
- room than the log of it. Its own tab bar is forty-eight of that, so this
19
- leaves about five lines, which is what a console is read in. */
20
13
  const DEFAULT_PANEL = 160;
21
- /** The most of the sandbox the panel may take, leaving the panes above it. */
22
14
  const PANEL_MAX = 0.8;
23
- /**
24
- * @summary Pairs an editable source pane with a live preview.
25
- *
26
- * @description
27
- * Coordination is by event, the same way the accordion does it: a source pane
28
- * dispatches `helix-before-edit`, which bubbles, and the sandbox hands the value to
29
- * whatever preview is slotted into it. Neither child knows the other exists, so
30
- * either can be replaced or used alone.
31
- *
32
- * The event carries the pane's `name`, which is what lets one sandbox hold
33
- * several panes without the root identifying senders by reference. `html` is
34
- * the preview's markup and `css` is its stylesheet. A pane named anything else
35
- * is showing something rather than driving it, and is ignored: the sandbox has
36
- * a pane rendering the example as JSX, and guessing would have put the text of
37
- * a React component into the preview.
38
- *
39
- * **The dividers are two nested `helix-splitter`s, not a grid this element
40
- * drags itself.** The pointer handling, the keyboard handling and the corner are
41
- * all the splitter's, and the corner arrives on its own wherever a nested
42
- * splitter crosses the one it is in.
43
- *
44
- * The panes are the inner splitter and the panel is the outer one, which is the
45
- * order that makes the panel span the full width: the outer divider runs edge to
46
- * edge and the inner stops at it.
47
- *
48
- * **Both are controlled from here, so `split` and `panel-size` stay the truth.**
49
- * A splitter that owned its own position would leave this element reporting one
50
- * arrangement and showing another, and a consumer restoring a saved layout
51
- * writes to these two properties. Each splitter announces where it wants to go
52
- * and this answers, which is the same contract a form control has with a
53
- * framework.
54
- *
55
- * **The panel is in pixels here and a percentage in the splitter, and the
56
- * conversion belongs here.** A terminal wants a number of lines rather than a
57
- * share of the window, so its height should not change when the window does. A
58
- * splitter has no business knowing that, so it stays percentage-pure and this
59
- * element, which does know what is in the panel, holds the box and converts.
60
- * That is also what keeps a stored `panelSize` from a previous visit meaning
61
- * what it meant when it was written.
62
- *
63
- * @since 0.1.0
64
- * @status experimental
65
- * @category tooling
66
- * @aliases Playground, REPL, Editor
67
- * @documentation https://helix.fusion.dev/sandbox
68
- *
69
- * @slot panel - A panel under both panes, usually a terminal.
70
- * @slot preview - The live preview. Second unless `lead` says otherwise.
71
- * @slot source - The editable source pane. First unless `lead` says otherwise.
72
- * @slot status - A status bar, spanning both panes at the bottom.
73
- * @slot toolbar - A bar across the top, spanning both panes.
74
- *
75
- * @event {HelixBeforePanelResizeEvent} helix-before-panel-resize - Fired before the panel's divider is let go, with its height in pixels. Cancelable: refusing it takes the decision and nothing moves.
76
- * @event {HelixBeforeSplitEvent} helix-before-split - Fired before the panes' divider is let go, with the lead pane's share. Cancelable: refusing it takes the decision and nothing moves.
77
- *
78
- * @csspart body - The splitter holding the panes above the panel.
79
- * @csspart corner - The handle where the two dividers cross.
80
- * @csspart pane - Either pane.
81
- * @csspart panel - The box holding whatever was slotted as the panel.
82
- * @csspart panes - The splitter holding the source and preview panes.
83
- * @csspart separator - Either divider.
84
- *
85
- * @cssproperty --sandbox-grab - The invisible width of a divider's drag target.
86
- * @cssproperty --sandbox-min-block-size - Minimum height of the sandbox.
87
- * @cssproperty --sandbox-separator-color - Color of the divider.
88
- */
89
15
  let HelixSandbox = class HelixSandbox extends HelixElement {
90
16
  constructor() {
91
17
  super(...arguments);
92
- /**
93
- * Accessible name for the divider that moves both at once.
94
- */
95
18
  this.cornerLabel = 'Resize panes and panel';
96
- /**
97
- * What a reset makes the panel, in pixels.
98
- *
99
- * The pair to `panel-size`.
100
- */
101
19
  this.defaultPanelSize = DEFAULT_PANEL;
102
- /**
103
- * Where a reset puts the divider, where nothing declared it.
104
- *
105
- * Separate from `split` for the reason `Splitter` keeps `default-position`
106
- * separate from `position`. Resetting to whatever `split` held on the first
107
- * render is the declared arrangement only where nobody owns the property: the
108
- * workbench does, and restores it from the address bar and from storage, so the
109
- * first value it holds is the reader's last session and a reset puts the
110
- * sandbox back to the size it already was.
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
20
  this.defaultSplit = DEFAULT_SPLIT;
116
- /**
117
- * Which pane comes first, before the divider.
118
- *
119
- * A sandbox is read in one of two directions and the two are not a
120
- * preference. A workbench is a place to write, so the source leads and the
121
- * preview answers it. A reference page is a place to look, so the preview
122
- * leads and the source is what a reader opens if they want to know how it was
123
- * done. Same component, opposite reading order, and no consumer should have
124
- * to slot a preview into a hole named `source` to get it.
125
- *
126
- * Not reflected, because no rule selects on it: the panes already carry
127
- * `data-pane`, which is what the stylesheet reaches for, and swapping the
128
- * names below keeps that true whichever way round they sit.
129
- *
130
- * `split` follows the lead pane rather than the source, so `split="30"` means
131
- * the same thing in both directions: thirty percent to whatever comes first.
132
- */
133
21
  this.lead = 'source';
134
- /**
135
- * What the panel's height becomes when it is closed.
136
- *
137
- * Zero closes it outright. A panel whose contents include the control that
138
- * reopens it, a row of tabs being the usual one, wants that row left showing,
139
- * and only whoever slotted it knows how tall that is.
140
- */
141
22
  this.panelCollapsedSize = 0;
142
- /**
143
- * Accessible name for the panel's divider.
144
- */
145
23
  this.panelLabel = 'Resize panel';
146
- /**
147
- * Height of the panel, in pixels.
148
- */
149
24
  this.panelSize = DEFAULT_PANEL;
150
- /**
151
- * Accessible name for the divider.
152
- */
153
25
  this.separatorLabel = 'Resize source pane';
154
- /**
155
- * Percentage of the sandbox given to the source pane.
156
- */
157
26
  this.split = DEFAULT_SPLIT;
158
- /**
159
- * Whether anything is in the panel region.
160
- *
161
- * The divider above the panel is only meaningful when there is a panel to
162
- * size, and there is no way to ask in CSS: `:host(:has([slot="panel"]))` is
163
- * invalid, and the server has no children to look at. `slotchange` is the
164
- * platform answering on the client, which is where a divider is any use.
165
- */
166
27
  this.hasPanel = false;
167
- /**
168
- * The body's height, which is what a pixel panel is a fraction of.
169
- *
170
- * The panel is given in pixels and the splitter takes a percentage, so the two
171
- * only agree at one height: let the window change without recomputing and a
172
- * panel asked for at 192px quietly keeps whatever share of the old height that
173
- * was.
174
- *
175
- * **Measured at render rather than cached from the observer.** A
176
- * `ResizeObserver` callback is delivered from the rendering lifecycle and a
177
- * background tab runs none, so a cached number goes stale with nothing to say
178
- * so. Reading the box at render leaves one source of truth, and the observer's
179
- * only job is to say that a render is due.
180
- *
181
- * Cheap, because renders are rare: a drag does not go through this element at
182
- * all, the splitter following the pointer itself and announcing once, when it
183
- * settles.
184
- */
185
28
  this.bodyHeight = 0;
186
- /**
187
- * Asks for a render when the body changes size.
188
- *
189
- * The box watched is the splitter itself, not the panel. Its size changes when
190
- * the window does and not when the divider moves, so answering it cannot feed
191
- * back into the position that answered it.
192
- */
193
29
  this.watch = typeof ResizeObserver === 'undefined'
194
30
  ? undefined
195
31
  : new ResizeObserver(() => {
196
32
  this.requestUpdate();
197
33
  });
198
- /**
199
- * Takes a change from one of this sandbox's own source panes.
200
- *
201
- * The origin is checked, and has to be. `helix-before-edit` bubbles and composes,
202
- * so anything a consumer slots into a sandbox sends one up here too. A
203
- * sandbox hears a great deal that is not its source.
204
- */
205
34
  this.handleSourceChange = (event) => {
206
35
  if (!this.fromSource(event.target)) {
207
36
  return;
208
37
  }
209
38
  const { value } = event.detail;
210
- /* Which pane is the element, and the element is `composedPath()[0]` rather
211
- than `event.target`, which is retargeted to the outermost host once the
212
- event has crossed a shadow boundary.
213
-
214
- Named, not guessed. Treating anything that is not `css` as markup holds
215
- only while there are two panes: a pane showing the example as JSX
216
- announces itself the same way, and the preview renders the text of a React
217
- component as though it were markup. */
218
39
  const pane = event.composedPath()[0];
219
40
  if (pane?.name !== 'css' && pane?.name !== 'html') {
220
41
  return;
@@ -228,14 +49,6 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
228
49
  }
229
50
  }
230
51
  };
231
- /**
232
- * Writes the cursor position onto any status bar slotted here.
233
- *
234
- * The same shape as the source-to-preview hand-off, and for the same reason:
235
- * the editor and the bar never speak, so either can be absent. It goes
236
- * straight to the element rather than through a property a framework owns,
237
- * because this fires on every keystroke and every arrow press.
238
- */
239
52
  this.handleCaret = (event) => {
240
53
  if (!this.fromSource(event.target)) {
241
54
  return;
@@ -246,35 +59,12 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
246
59
  bar.line = line;
247
60
  }
248
61
  };
249
- /**
250
- * Hands a console line from the preview to any terminal slotted here.
251
- *
252
- * Every `helix-console` is forwarded, with no check on where it came from.
253
- * Unlike a change, which any form control in a sandbox emits, this event is
254
- * dispatched by exactly one thing: a preview relaying what the document
255
- * inside its frame wrote. There is nothing else here it could be confused
256
- * with.
257
- */
258
62
  this.handleConsole = (event) => {
259
63
  const detail = event.detail;
260
64
  for (const terminal of this.terminals) {
261
65
  terminal.write(detail);
262
66
  }
263
67
  };
264
- /**
265
- * Answers a divider that has asked to move.
266
- *
267
- * Both splitters are controlled from here, so neither applies anything on its
268
- * own: each announces where it wants to go and this decides. That is what
269
- * keeps `split` and `panelSize` the truth about the arrangement rather than a
270
- * stale copy of it.
271
- *
272
- * `target` against `currentTarget`, because a source pane's own change bubbles
273
- * up through these same elements on its way to the host. Only a splitter
274
- * speaking for itself is one of ours, and only those are stopped: the sandbox
275
- * announces `helix-before-split` and `helix-before-panel-resize` in their
276
- * place, and a consumer never sees the two splitters inside it.
277
- */
278
68
  this.handlePanesChange = (event) => {
279
69
  if (event.target !== event.currentTarget) {
280
70
  return;
@@ -293,27 +83,13 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
293
83
  if (this.bodyHeight <= 0) {
294
84
  return;
295
85
  }
296
- // Back into pixels, which is what this element promises and what a consumer
297
- // stored. The divider's position is the panes' share, so the panel is the
298
- // rest of it.
299
86
  this.panelSize = Math.max(0, ((100 - Number(value)) / 100) * this.bodyHeight);
300
87
  this.panelSettled();
301
88
  };
302
- /**
303
- * Notes whether there is a panel, which is what its dividers depend on.
304
- *
305
- * Asked of the light DOM rather than of the slot. `slotchange` is the event
306
- * that says it changed, and it is listened for, but it is not the only way
307
- * to know: a sandbox whose panel was in the markup all along has nothing to
308
- * change, and an environment that does not dispatch the event at all leaves
309
- * the dividers permanently absent. What is slotted into a named slot is a
310
- * question the host can answer directly.
311
- */
312
89
  this.readPanel = () => {
313
90
  this.hasPanel = this.querySelector(':scope > [slot="panel"]') !== null;
314
91
  };
315
92
  }
316
- /** The panel as a share of the body, which is what the splitter takes. */
317
93
  get panelShare() {
318
94
  const size = Number.isFinite(this.panelSize) ? this.panelSize : DEFAULT_PANEL;
319
95
  if (this.bodyHeight <= 0) {
@@ -321,17 +97,9 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
321
97
  }
322
98
  return Math.min(PANEL_MAX * 100, Math.max(0, (size / this.bodyHeight) * 100));
323
99
  }
324
- /**
325
- * Where the outer divider goes: everything the panel is not.
326
- *
327
- * A hundred with no panel, which puts the divider on the floor of the sandbox
328
- * with the panes filling it. The line itself is hidden by the stylesheet in
329
- * that case, because a boundary needs two sides.
330
- */
331
100
  get panelPosition() {
332
101
  return this.hasPanel ? 100 - this.panelShare : 100;
333
102
  }
334
- /** Where the panel divider goes on a reset, in the splitter's own units. */
335
103
  get homePanelPosition() {
336
104
  const panel = Number.isFinite(this.defaultPanelSize) ? this.defaultPanelSize : DEFAULT_PANEL;
337
105
  if (!this.hasPanel || this.bodyHeight <= 0) {
@@ -339,22 +107,12 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
339
107
  }
340
108
  return 100 - Math.min(PANEL_MAX * 100, Math.max(0, (panel / this.bodyHeight) * 100));
341
109
  }
342
- /** `panel-collapsed-size` in the units the splitter works in. */
343
110
  get panelSliver() {
344
111
  if (this.bodyHeight <= 0) {
345
112
  return 0;
346
113
  }
347
114
  return Math.min(100, Math.max(0, (this.panelCollapsedSize / this.bodyHeight) * 100));
348
115
  }
349
- /**
350
- * Whether a change came from inside this sandbox's source region.
351
- *
352
- * Structural rather than a type check. There is more than one kind of pane and
353
- * the editor is `@fusion.dev/helix-sandbox/editor`, on its own path because it
354
- * carries CodeMirror, so naming its class here would pull that back into this
355
- * module for every consumer. Where the event came from is a question about the
356
- * tree, and the tree can answer it.
357
- */
358
116
  fromSource(target) {
359
117
  if (!(target instanceof Node)) {
360
118
  return false;
@@ -362,16 +120,6 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
362
120
  const slot = this.renderRoot.querySelector('slot[name="source"]');
363
121
  return (slot?.assignedElements({ flatten: true }) ?? []).some((pane) => pane === target || pane.contains(target));
364
122
  }
365
- /**
366
- * The parts of this sandbox it drives, wherever they sit inside it.
367
- *
368
- * Descendants, not children. A preview and a status bar happen to be slotted
369
- * directly, but a terminal lives inside the tab set that holds the panel, so
370
- * a search of `children` found none and the console went nowhere. Where a
371
- * consumer nests a pane is their arrangement to make.
372
- *
373
- * Client only: the server has no children to read.
374
- */
375
123
  parts(selector) {
376
124
  return [...this.querySelectorAll(selector)];
377
125
  }
@@ -384,35 +132,12 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
384
132
  get statusBars() {
385
133
  return this.parts('helix-sandbox-status-bar');
386
134
  }
387
- /**
388
- * The orientation in force.
389
- *
390
- * Unset is horizontal, and stays unset: the default is the absent attribute,
391
- * so a reflected default cannot appear on the host after hydration.
392
- */
393
135
  get axis() {
394
136
  return this.orientation ?? 'horizontal';
395
137
  }
396
- /**
397
- * Says the panes' divider has settled, so a consumer can keep it.
398
- *
399
- * When it settles, not while it moves. A drag is a stream of positions and
400
- * only the one it ends at is a preference; announcing each would ask whoever
401
- * is listening to write to storage a hundred times to record one decision.
402
- *
403
- * The sandbox does not keep it. Where a preference lives, and whether it
404
- * should be kept at all, is the consumer's to decide, and a component that
405
- * wrote to storage on its own would be deciding for all of them under a key
406
- * it chose.
407
- *
408
- * **A verb each, rather than one `helix-before-resize` naming which of the two
409
- * moved.** Both dividers are this element's, so `composedPath()[0]` is the same
410
- * host for either and the event name is the only thing that can separate them.
411
- */
412
138
  splitSettled() {
413
139
  this.dispatchEvent(new HelixBeforeSplitEvent({ value: String(this.split) }));
414
140
  }
415
- /** As `splitSettled`, for the panel, whose value is pixels rather than a share. */
416
141
  panelSettled() {
417
142
  this.dispatchEvent(new HelixBeforePanelResizeEvent({ value: String(this.panelSize) }));
418
143
  }
@@ -421,16 +146,10 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
421
146
  this.addEventListener('helix-caret', this.handleCaret);
422
147
  this.addEventListener('helix-console', this.handleConsole);
423
148
  this.addEventListener('helix-before-edit', this.handleSourceChange);
424
- /* And the body is watched again, because `disconnectedCallback` stopped
425
- watching it. The observer itself survives, being a field rather than
426
- something `firstUpdated` built, but a disconnected one reports nothing
427
- until something calls `observe` again. Left to `firstUpdated` alone, a
428
- sandbox moved in the DOM comes back with its panel sizes frozen. */
429
149
  if (this.hasUpdated) {
430
150
  this.watchBody();
431
151
  }
432
152
  }
433
- /** Watches the body, whose height is what the pane sizes are computed from. */
434
153
  watchBody() {
435
154
  const body = this.renderRoot.querySelector('[part="body"]');
436
155
  if (!body) {
@@ -440,13 +159,6 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
440
159
  this.watch?.observe(body);
441
160
  this.requestUpdate();
442
161
  }
443
- /**
444
- * Takes the body's height before each render, so the conversion is current.
445
- *
446
- * Guarded on `hasUpdated`, because there is no shadow root to measure before
447
- * the first render, and on the method existing, because the server's element
448
- * shim carries attributes but not tree traversal.
449
- */
450
162
  willUpdate(changed) {
451
163
  super.willUpdate(changed);
452
164
  if (!this.hasUpdated || typeof this.renderRoot?.querySelector !== 'function') {
@@ -498,13 +210,7 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
498
210
  .position=${split}
499
211
  @helix-before-resize=${this.handlePanesChange}
500
212
  >
501
- ${
502
- /* The slot names swap with the panes, so each pane keeps its own
503
- `data-pane` and the stylesheet needs to know nothing about the
504
- order. Rendering both slots in both positions would be two
505
- elements answering to one name, and an assignment goes to the
506
- first. */
507
- ''}
213
+ ${''}
508
214
  <div part="pane" data-pane=${first} slot="start"><slot name=${first}></slot></div>
509
215
  <div part="pane" data-pane=${second} slot="end"><slot name=${second}></slot></div>
510
216
  </helix-splitter>
@@ -1,4 +1,3 @@
1
- // Generated from src/sandbox/source/sandbox-source.css by `turbo run styles`. Do not edit.
2
1
  import { createSheet } from '@fusion.dev/helix-core';
3
2
  export const styles = createSheet(`:host {
4
3
  display: block;
@@ -8,74 +8,14 @@ import { customElement, HelixBeforeEditEvent, HelixCaretEvent, HelixElement, onU
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { styles } from './sandbox-source.css.js';
11
- /**
12
- * @summary Editable source for a sandbox preview.
13
- *
14
- * @description
15
- * A real `<textarea>`, not a contenteditable div with a syntax highlighter over
16
- * it. Undo, selection, spellcheck suppression, mobile keyboards, and screen
17
- * reader support all come from the platform, and every one of them is
18
- * expensive to rebuild and easy to get subtly wrong.
19
- *
20
- * Tab inserts two spaces rather than leaving the field, because a code pane
21
- * that cannot indent is not one. Escape then Tab still moves focus out, which
22
- * is the documented escape hatch for exactly this trade.
23
- *
24
- * @since 0.1.0
25
- * @status experimental
26
- * @aliases Editor, Code pane
27
- * @documentation https://helix.fusion.dev/sandbox/source
28
- *
29
- * @event {HelixBeforeEditEvent} helix-before-edit - Fired before the source is edited. Cancelable: refusing it takes the decision and nothing moves.
30
- * @event {HelixCaretEvent} helix-caret - Fired when the cursor moves.
31
- *
32
- * @csspart source - The editable region.
33
- *
34
- * @cssproperty --sandbox-source-background-color - Fill behind the source.
35
- * @cssproperty --sandbox-source-min-block-size - Minimum height of the pane.
36
- */
37
11
  let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
38
12
  constructor() {
39
13
  super(...arguments);
40
- /**
41
- * Accessible name for the editable region.
42
- */
43
14
  this.fieldLabel = 'Example source';
44
- /**
45
- * Which source this pane holds, echoed in every `helix-before-edit`.
46
- *
47
- * `html` and `css` are what the sandbox root routes on; any other name is
48
- * passed through untouched for a consumer wiring their own panes.
49
- *
50
- * Not reflected: nothing selects on it, so it keeps a real default instead.
51
- */
52
15
  this.name = 'html';
53
- /**
54
- * Whether Tab indents rather than moving focus.
55
- */
56
16
  this.tabIndents = true;
57
- /**
58
- * The source being edited.
59
- */
60
17
  this.value = '';
61
- /** Set by Escape, so the next Tab leaves the field. */
62
18
  this.escaped = false;
63
- /**
64
- * Reports where the cursor is, for a status bar to read.
65
- *
66
- * **This pane has to send it, not only `SandboxEditor`.** `SandboxRoot` binds
67
- * a `helix-caret` listener and writes `line` and `column` onto every slotted
68
- * status bar, and `SandboxStatusBar` renders a `caret` part as soon as it has
69
- * both; all of that ships from `@fusion.dev/helix`, while the editor is in
70
- * `@fusion.dev/helix-sandbox` and is `private` while Helix is pre-release. A
71
- * consumer taking the published shell and this pane would otherwise get a
72
- * status bar that can never show a position, fixable only with a package they
73
- * cannot install.
74
- *
75
- * The textarea is the only thing that knows, so this is where it belongs.
76
- * One-based on both axes, which is what an editor shows and what the detail's
77
- * own documentation says.
78
- */
79
19
  this.reportCaret = (event) => {
80
20
  const field = event.target;
81
21
  const at = field.selectionStart ?? 0;
@@ -85,19 +25,6 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
85
25
  line: before.split('\n').length,
86
26
  }));
87
27
  };
88
- /**
89
- * Announces the edit, then applies it if nobody refused.
90
- *
91
- * **Never the other way round.** Assigning the value and dispatching the
92
- * request after it accepts `preventDefault()` and ignores it: a consumer
93
- * refusing an edit keeps the old value in their handler while the pane holds
94
- * the new one, and `helix-before-edit` becomes a `before` event that has
95
- * already happened.
96
- *
97
- * `restoreValue` because the textarea has already taken the character
98
- * whichever way it goes, so a refusal has to put the text back, and it does so
99
- * without sending the caret to the end. Exactly what `Input` does with the
100
- * same helper for the same reason. */
101
28
  this.handleInput = (event) => {
102
29
  const field = event.target;
103
30
  this.edit(field, field.value);
@@ -121,10 +48,6 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
121
48
  this.edit(field, field.value);
122
49
  };
123
50
  }
124
- /**
125
- * The one place an edit is taken, so a refusal cannot be forgotten at one of
126
- * them. Two paths reach it, a keystroke and the tab that indents.
127
- */
128
51
  edit(field, next) {
129
52
  const request = new HelixBeforeEditEvent({ value: next });
130
53
  if (this.dispatchEvent(request)) {
@@ -1,4 +1,3 @@
1
- // Generated from src/sandbox/status-bar/sandbox-status-bar.css by `turbo run styles`. Do not edit.
2
1
  import { createSheet } from '@fusion.dev/helix-core';
3
2
  export const styles = createSheet(`:host {
4
3
  align-items: center;
@@ -8,51 +8,13 @@ import { customElement, HelixElement } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { styles } from './sandbox-status-bar.css.js';
11
- /**
12
- * How a language is written out, for the ones an editor knows.
13
- *
14
- * A map rather than the raw value, because `html` in a status bar reads as a
15
- * variable name where `HTML` reads as a language. Anything unlisted shows as
16
- * given, so a consumer naming their own language is not silently blanked.
17
- */
18
11
  const LABELS = {
19
12
  css: 'CSS',
20
13
  html: 'HTML',
21
14
  javascript: 'JavaScript',
22
15
  tsx: 'TSX',
23
16
  };
24
- /**
25
- * @summary Reports where the cursor is and what is being edited.
26
- *
27
- * @description
28
- * Slotted into a sandbox, which feeds it: the editor dispatches `helix-caret`
29
- * on every keystroke and every arrow press, the sandbox hears it and writes the
30
- * position here. Nothing about that reaches the consumer's framework, which is
31
- * the point. A caret position routed through React state would re-render the
32
- * workbench on every cursor move, to update two numbers.
33
- *
34
- * **Not a live region.** The readout changes on every keystroke, so announcing
35
- * it would talk over the reader continuously while they type. It is text they
36
- * can navigate to, which is what a status bar is in every editor that has one.
37
- *
38
- * A readout with nothing to say is not rendered at all rather than rendered
39
- * empty, or the bar keeps a gap where a value is not.
40
- *
41
- * @since 0.1.0
42
- * @status experimental
43
- * @aliases Status line
44
- * @documentation https://helix.fusion.dev/sandbox/status-bar
45
- *
46
- * @slot - Items at the start of the bar.
47
- * @slot end - Items after the readouts, at the end of the bar.
48
- *
49
- * @csspart caret - The line and column readout.
50
- * @csspart language - The language readout.
51
- *
52
- * @cssproperty --sandbox-status-bar-color - Color of the bar's text.
53
- */
54
17
  let HelixSandboxStatusBar = class HelixSandboxStatusBar extends HelixElement {
55
- /** How the position reads, or nothing when there is no cursor to report. */
56
18
  get position() {
57
19
  if (this.line === undefined || this.column === undefined) {
58
20
  return undefined;
@@ -1,4 +1,3 @@
1
- // Generated from src/sandbox/terminal/sandbox-terminal.css by `turbo run styles`. Do not edit.
2
1
  import { createSheet } from '@fusion.dev/helix-core';
3
2
  export const styles = createSheet(`:host {
4
3