@fusion.dev/helix 0.2.0 → 0.3.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.
- package/custom-elements.json +256 -256
- package/dist/accordion/item/accordion-item.css.js +0 -1
- package/dist/accordion/item/accordion-item.js +0 -29
- package/dist/accordion/root/accordion-root.css.js +0 -1
- package/dist/accordion/root/accordion-root.js +0 -20
- package/dist/announcement/root/announcement-root.css.js +0 -1
- package/dist/announcement/root/announcement-root.js +0 -16
- package/dist/app-header/root/app-header-root.css.js +0 -1
- package/dist/app-header/root/app-header-root.js +0 -45
- package/dist/aura/root/aura-axis.js +0 -58
- package/dist/aura/root/aura-root.css.js +0 -1
- package/dist/aura/root/aura-root.js +0 -520
- package/dist/aura/root/aura-shader.js +0 -35
- package/dist/avatar/group/avatar-group.css.js +0 -1
- package/dist/avatar/group/avatar-group.js +0 -24
- package/dist/avatar/root/avatar-root.css.js +0 -1
- package/dist/avatar/root/avatar-root.js +0 -23
- package/dist/badge/root/badge-root.css.js +0 -1
- package/dist/badge/root/badge-root.d.ts +2 -6
- package/dist/badge/root/badge-root.js +0 -18
- package/dist/bar-chart/root/bar-chart-root.css.js +0 -1
- package/dist/bar-chart/root/bar-chart-root.js +0 -50
- package/dist/blockquote/root/blockquote-root.css.js +0 -1
- package/dist/blockquote/root/blockquote-root.js +0 -17
- package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +0 -1
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +0 -28
- package/dist/breadcrumbs/root/breadcrumbs-root.css.js +0 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +0 -19
- package/dist/button/root/button-root.css.js +0 -1
- package/dist/button/root/button-root.js +0 -38
- package/dist/button-group/root/button-group-root.css.js +0 -1
- package/dist/button-group/root/button-group-root.js +0 -24
- package/dist/callout/root/callout-root.css.js +0 -1
- package/dist/callout/root/callout-root.js +0 -26
- package/dist/card/root/card-root.css.js +0 -1
- package/dist/card/root/card-root.js +0 -45
- package/dist/carousel/root/carousel-root.css.js +0 -1
- package/dist/carousel/root/carousel-root.js +0 -24
- package/dist/chat/composer/chat-composer.css.js +0 -1
- package/dist/chat/composer/chat-composer.js +0 -26
- package/dist/chat/message/chat-message.css.js +0 -1
- package/dist/chat/message/chat-message.js +0 -29
- package/dist/chat/root/chat-root.css.js +0 -1
- package/dist/chat/root/chat-root.js +0 -38
- package/dist/checkbox/root/checkbox-root.css.js +0 -1
- package/dist/checkbox/root/checkbox-root.js +0 -26
- package/dist/checkbox-group/root/checkbox-group-root.css.js +0 -1
- package/dist/checkbox-group/root/checkbox-group-root.js +0 -15
- package/dist/code/root/code-root.css.js +0 -1
- package/dist/code/root/code-root.js +0 -21
- package/dist/code-block/root/code-block-root.css.js +0 -1
- package/dist/code-block/root/code-block-root.js +0 -19
- package/dist/color-input/root/color-input-root.css.js +0 -1
- package/dist/color-input/root/color-input-root.js +0 -42
- package/dist/color-picker/root/color-picker-root.css.js +0 -1
- package/dist/color-picker/root/color-picker-root.js +0 -42
- package/dist/combobox/root/combobox-root.css.js +0 -1
- package/dist/combobox/root/combobox-root.js +0 -28
- package/dist/command/root/command-root.css.js +0 -1
- package/dist/command/root/command-root.js +0 -21
- package/dist/copy-button/root/copy-button-root.css.js +0 -1
- package/dist/copy-button/root/copy-button-root.js +0 -14
- package/dist/data-table/root/data-table-root.css.js +0 -1
- package/dist/data-table/root/data-table-root.js +0 -39
- package/dist/date-input/root/date-input-root.css.js +0 -1
- package/dist/date-input/root/date-input-root.js +0 -38
- package/dist/date-picker/root/date-picker-root.css.js +0 -1
- package/dist/date-picker/root/date-picker-root.js +0 -28
- package/dist/dialog/root/dialog-root.css.js +0 -1
- package/dist/dialog/root/dialog-root.js +0 -31
- package/dist/divider/root/divider-root.css.js +0 -1
- package/dist/divider/root/divider-root.js +0 -24
- package/dist/donut-chart/root/donut-chart-root.css.js +0 -1
- package/dist/donut-chart/root/donut-chart-root.js +0 -49
- package/dist/drawer/root/drawer-root.css.js +0 -1
- package/dist/drawer/root/drawer-root.js +0 -38
- package/dist/drilldown/item/drilldown-item.css.js +0 -1
- package/dist/drilldown/item/drilldown-item.js +0 -15
- package/dist/drilldown/root/drilldown-root.css.js +0 -1
- package/dist/drilldown/root/drilldown-root.js +0 -23
- package/dist/element-events.generated.js +0 -5
- package/dist/empty/root/empty-root.css.js +0 -1
- package/dist/empty/root/empty-root.js +0 -16
- package/dist/file-input/root/file-input-root.css.js +0 -1
- package/dist/file-input/root/file-input-root.js +0 -30
- package/dist/flex/root/flex-root.css.js +0 -1
- package/dist/flex/root/flex-root.js +0 -32
- package/dist/format-date/root/format-date-root.css.js +0 -1
- package/dist/format-date/root/format-date-root.js +0 -17
- package/dist/grid/root/grid-root.css.js +0 -1
- package/dist/grid/root/grid-root.js +0 -69
- package/dist/heatmap/root/heatmap-root.css.js +0 -1
- package/dist/heatmap/root/heatmap-root.d.ts +9 -11
- package/dist/heatmap/root/heatmap-root.js +0 -73
- package/dist/icon/glyph.css.js +0 -1
- package/dist/icon/root/icon-root.css.js +0 -1
- package/dist/icon/root/icon-root.js +0 -19
- package/dist/icon-button/root/icon-button-root.css.js +0 -1
- package/dist/icon-button/root/icon-button-root.js +0 -35
- package/dist/image/root/image-root.css.js +0 -1
- package/dist/image/root/image-root.js +0 -28
- package/dist/index.js +0 -5
- package/dist/input/root/input-root.css.js +0 -1
- package/dist/input/root/input-root.js +0 -28
- package/dist/kbd/root/kbd-root.css.js +0 -1
- package/dist/kbd/root/kbd-root.js +0 -20
- package/dist/legend/root/legend-root.css.js +0 -1
- package/dist/legend/root/legend-root.js +0 -35
- package/dist/line-chart/root/line-chart-root.css.js +0 -1
- package/dist/line-chart/root/line-chart-root.js +0 -47
- package/dist/list/item/list-item.css.js +0 -1
- package/dist/list/item/list-item.js +0 -38
- package/dist/list/root/list-root.css.js +0 -1
- package/dist/list/root/list-root.js +0 -23
- package/dist/listbox/root/listbox-root.css.js +0 -1
- package/dist/listbox/root/listbox-root.js +0 -22
- package/dist/loader/root/loader-root.css.js +0 -1
- package/dist/loader/root/loader-root.js +0 -19
- package/dist/megamenu/root/megamenu-root.css.js +0 -1
- package/dist/megamenu/root/megamenu-root.js +0 -24
- package/dist/menu/item/menu-item.css.js +0 -1
- package/dist/menu/item/menu-item.js +0 -16
- package/dist/menu/root/menu-root.css.js +0 -1
- package/dist/menu/root/menu-root.js +0 -26
- package/dist/meter/root/meter-root.css.js +0 -1
- package/dist/meter/root/meter-root.js +0 -50
- package/dist/mixins/mixin-control-surface/mixin-control-surface.js +0 -3
- package/dist/navigation/root/navigation-root.css.js +0 -1
- package/dist/navigation/root/navigation-root.js +0 -18
- package/dist/notifications/notification/notification.css.js +0 -1
- package/dist/notifications/notification/notification.js +0 -53
- package/dist/notifications/root/notifications-root.css.js +0 -1
- package/dist/notifications/root/notifications-root.js +0 -31
- package/dist/number-input/root/number-input-root.css.js +0 -1
- package/dist/number-input/root/number-input-root.js +0 -31
- package/dist/option/group/option-group.css.js +0 -1
- package/dist/option/group/option-group.js +0 -13
- package/dist/option/root/option-root.css.js +0 -1
- package/dist/option/root/option-root.js +0 -20
- package/dist/outline/root/outline-root.css.js +0 -1
- package/dist/outline/root/outline-root.js +0 -21
- package/dist/pagination/root/pagination-root.css.js +0 -1
- package/dist/pagination/root/pagination-root.js +0 -49
- package/dist/pagination/size/pagination-size.css.js +0 -1
- package/dist/pagination/size/pagination-size.js +0 -25
- package/dist/pagination/summary/pagination-summary.css.js +0 -1
- package/dist/pagination/summary/pagination-summary.js +0 -13
- package/dist/pin-input/root/pin-input-root.css.js +0 -1
- package/dist/pin-input/root/pin-input-root.js +0 -27
- package/dist/popover/root/popover-root.css.js +0 -1
- package/dist/popover/root/popover-root.js +0 -30
- package/dist/progress/root/progress-root.css.js +0 -1
- package/dist/progress/root/progress-root.js +0 -25
- package/dist/qr-code/root/qr-code-root.css.js +0 -1
- package/dist/qr-code/root/qr-code-root.js +0 -27
- package/dist/quote/root/quote-root.css.js +0 -1
- package/dist/quote/root/quote-root.js +0 -15
- package/dist/radio/group/radio-group.css.js +0 -1
- package/dist/radio/group/radio-group.js +0 -16
- package/dist/radio/root/radio-root.css.js +0 -1
- package/dist/radio/root/radio-root.js +0 -46
- package/dist/rating/root/rating-root.css.js +0 -1
- package/dist/rating/root/rating-root.js +0 -22
- package/dist/sandbox/index.js +0 -14
- package/dist/sandbox/preview/sandbox-preview.css.js +0 -1
- package/dist/sandbox/preview/sandbox-preview.js +0 -182
- package/dist/sandbox/root/sandbox-root.css.js +0 -1
- package/dist/sandbox/root/sandbox-root.js +1 -295
- package/dist/sandbox/source/sandbox-source.css.js +0 -1
- package/dist/sandbox/source/sandbox-source.js +0 -77
- package/dist/sandbox/status-bar/sandbox-status-bar.css.js +0 -1
- package/dist/sandbox/status-bar/sandbox-status-bar.js +0 -38
- package/dist/sandbox/terminal/sandbox-terminal.css.js +0 -1
- package/dist/sandbox/terminal/sandbox-terminal.js +0 -54
- package/dist/sandbox/toolbar/sandbox-toolbar.css.js +0 -1
- package/dist/sandbox/toolbar/sandbox-toolbar.js +0 -29
- package/dist/scroll-area/root/scroll-area-root.css.js +0 -1
- package/dist/scroll-area/root/scroll-area-root.js +0 -24
- package/dist/select/root/select-root.css.js +0 -1
- package/dist/select/root/select-root.js +0 -33
- package/dist/shared/chart/series.css.js +0 -1
- package/dist/shared/chart/terminus.css.js +0 -1
- package/dist/shared/field/field-inline.css.js +0 -1
- package/dist/shared/field/field-stacked.css.js +0 -1
- package/dist/shared/field/field.css.js +0 -1
- package/dist/skeleton/root/skeleton-root.css.js +0 -1
- package/dist/skeleton/root/skeleton-root.js +0 -18
- package/dist/slider/root/slider-root.css.js +0 -1
- package/dist/slider/root/slider-root.js +0 -32
- package/dist/sparkline/root/sparkline-root.css.js +0 -1
- package/dist/sparkline/root/sparkline-root.js +0 -40
- package/dist/speed-dial/item/speed-dial-item.css.js +0 -1
- package/dist/speed-dial/item/speed-dial-item.js +0 -16
- package/dist/speed-dial/root/speed-dial-root.css.js +0 -1
- package/dist/speed-dial/root/speed-dial-root.js +0 -16
- package/dist/splitter/root/splitter-root.css.js +0 -1
- package/dist/splitter/root/splitter-root.js +0 -50
- package/dist/stat/group/stat-group.css.js +0 -1
- package/dist/stat/group/stat-group.js +0 -19
- package/dist/stat/root/stat-root.css.js +0 -1
- package/dist/stat/root/stat-root.js +0 -17
- package/dist/steps/root/steps-root.css.js +0 -1
- package/dist/steps/root/steps-root.js +0 -26
- package/dist/steps/step/step.css.js +0 -1
- package/dist/steps/step/step.js +0 -12
- package/dist/switch/root/switch-root.css.js +0 -1
- package/dist/switch/root/switch-root.js +0 -32
- package/dist/table/cell/table-cell.css.js +0 -1
- package/dist/table/cell/table-cell.js +0 -14
- package/dist/table/column/table-column.css.js +0 -1
- package/dist/table/column/table-column.js +0 -13
- package/dist/table/root/table-root.css.js +0 -1
- package/dist/table/root/table-root.js +0 -19
- package/dist/table/row/table-row.css.js +0 -1
- package/dist/table/row/table-row.js +0 -14
- package/dist/tabs/panel/tab-panel.css.js +0 -1
- package/dist/tabs/panel/tab-panel.js +0 -16
- package/dist/tabs/root/tabs-root.css.js +0 -1
- package/dist/tabs/root/tabs-root.js +0 -19
- package/dist/tabs/tab/tab.css.js +0 -1
- package/dist/tabs/tab/tab.js +0 -16
- package/dist/tag/root/tag-root.css.js +0 -1
- package/dist/tag/root/tag-root.js +0 -25
- package/dist/text/root/text-root.css.js +0 -1
- package/dist/text/root/text-root.js +0 -48
- package/dist/textarea/root/textarea-root.css.js +0 -1
- package/dist/textarea/root/textarea-root.js +0 -17
- package/dist/time-input/root/time-input-root.css.js +0 -1
- package/dist/time-input/root/time-input-root.js +0 -31
- package/dist/time-picker/root/time-picker-root.css.js +0 -1
- package/dist/time-picker/root/time-picker-root.js +0 -29
- package/dist/timeline/item/timeline-item.css.js +0 -1
- package/dist/timeline/item/timeline-item.js +0 -17
- package/dist/timeline/root/timeline-root.css.js +0 -1
- package/dist/timeline/root/timeline-root.js +0 -15
- package/dist/toast/item/toast-item.css.js +0 -1
- package/dist/toast/item/toast-item.js +0 -21
- package/dist/toast/root/toast-root.css.js +0 -1
- package/dist/toast/root/toast-root.js +0 -27
- package/dist/toggle/group/toggle-group.css.js +0 -1
- package/dist/toggle/group/toggle-group.js +0 -25
- package/dist/toggle/root/toggle-root.css.js +0 -1
- package/dist/toggle/root/toggle-root.js +0 -18
- package/dist/toolbar/root/toolbar-root.css.js +0 -1
- package/dist/toolbar/root/toolbar-root.js +0 -19
- package/dist/tooltip/root/tooltip-root.css.js +0 -1
- package/dist/tooltip/root/tooltip-root.js +0 -22
- package/dist/tour/root/tour-root.css.js +0 -1
- package/dist/tour/root/tour-root.js +0 -14
- package/dist/tour/stop/tour-stop.css.js +0 -1
- package/dist/tour/stop/tour-stop.js +0 -22
- package/dist/tree/item/tree-item.css.js +0 -1
- package/dist/tree/item/tree-item.js +0 -34
- package/dist/tree/root/tree-root.css.js +0 -1
- package/dist/tree/root/tree-root.js +0 -27
- package/dist/trend/root/trend-root.css.js +0 -1
- package/dist/trend/root/trend-root.js +0 -34
- package/dist/video/root/video-root.css.js +0 -1
- package/dist/video/root/video-root.js +0 -37
- package/dist/video-playlist/item/video-playlist-item.css.js +0 -1
- package/dist/video-playlist/item/video-playlist-item.js +0 -15
- package/dist/video-playlist/menu/video-playlist-menu.css.js +0 -1
- package/dist/video-playlist/menu/video-playlist-menu.js +0 -36
- package/dist/video-playlist/root/video-playlist-root.css.js +0 -1
- package/dist/video-playlist/root/video-playlist-root.js +0 -16
- package/dist/virtual-list/root/virtual-list-root.css.js +0 -1
- package/dist/virtual-list/root/virtual-list-root.js +0 -21
- package/jsx.d.ts +1538 -2818
- package/package.json +7 -7
- 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>
|
|
@@ -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)) {
|
|
@@ -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;
|