@fusion.dev/helix-headless 0.146.0 → 0.148.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 +9287 -1084
- package/dist/accordion/item/accordion-item.d.ts +43 -21
- package/dist/accordion/item/accordion-item.js +37 -11
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +6 -8
- package/dist/announcement/root/announcement-root.d.ts +66 -6
- package/dist/announcement/root/announcement-root.js +144 -13
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +14 -7
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +77 -8
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +28 -4
- package/dist/chat/root/chat-root.js +12 -7
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
- package/dist/checkbox-group/select-all.d.ts +9 -4
- package/dist/checkbox-group/select-all.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +41 -18
- package/dist/code-block/root/code-block-root.js +21 -6
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +99 -55
- package/dist/color-picker/wheel.d.ts +28 -0
- package/dist/color-picker/wheel.js +15 -0
- package/dist/combobox/root/combobox-root.d.ts +83 -11
- package/dist/combobox/root/combobox-root.js +81 -18
- package/dist/command/root/command-root.d.ts +7 -4
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +29 -50
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +22 -4
- package/dist/description-list/item/description-list-item.js +14 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +38 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/empty/root/empty-root.d.ts +46 -2
- package/dist/empty/root/empty-root.js +50 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +55 -21
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +11 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +10 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +5 -5
- package/dist/format-date/options.js +10 -39
- package/dist/format-date/root/format-date-root.d.ts +53 -4
- package/dist/format-date/root/format-date-root.js +38 -50
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +76 -3
- package/dist/heatmap/root/heatmap-root.js +105 -20
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +20 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +23 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +25 -26
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +31 -24
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +125 -26
- package/dist/listbox/root/listbox-root.js +156 -166
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +29 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +5 -2
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +48 -3
- package/dist/notifications/root/notifications-root.js +36 -6
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
- package/dist/object-inspector/root/object-inspector-root.js +31 -20
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +51 -1
- package/dist/pin-input/code.js +37 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +151 -156
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +31 -9
- package/dist/qr-code/root/qr-code-root.js +29 -17
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +115 -11
- package/dist/select/root/select-root.js +104 -20
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
- package/dist/speed-dial/item/speed-dial-item.js +43 -5
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
- package/dist/speed-dial/root/speed-dial-root.js +123 -6
- package/dist/splitter/root/splitter-root.d.ts +9 -2
- package/dist/splitter/root/splitter-root.js +18 -3
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +93 -29
- package/dist/table/row/table-row.d.ts +36 -0
- package/dist/table/row/table-row.js +52 -2
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +23 -20
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +12 -14
- package/dist/time-picker/root/time-picker-root.js +18 -23
- package/dist/toast/item/toast-item.d.ts +9 -6
- package/dist/toast/item/toast-item.js +1 -1
- package/dist/toast/root/toast-root.d.ts +40 -4
- package/dist/toast/root/toast-root.js +68 -16
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -43
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +52 -5
- package/dist/toolbar/root/toolbar-root.js +88 -13
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -2
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +16 -1
- package/dist/video/root/video-root.js +15 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +53 -41
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4934 -954
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +946 -253
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -4,12 +4,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { capturePointer, customElement, fillTemplate, HelixBeforeMoveEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixConnectEvent, HelixElement, HelixMoveEvent, HelixReconnectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixSelectEvent, hostAria, inlineStep, isRtl, MixinViewport, wordsConverter, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { assignSlots, capturePointer, customElement, fillTemplate, formatNumbers, HelixBeforeMoveEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixConnectEvent, HelixElement, HelixMoveEvent, HelixReconnectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixSelectEvent, hostAria, inlineStep, isRtl, MixinViewport, wordsConverter, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessCanvasEdge } from '../edge/canvas-edge.js';
|
|
11
|
+
import { EdgePan } from '../edge-pan.js';
|
|
11
12
|
import { HelixHeadlessCanvasNode } from '../node/canvas-node.js';
|
|
12
|
-
import {
|
|
13
|
+
import { snapBox, snapTo, stepTo } from '../snap.js';
|
|
14
|
+
import { colorOf, connector, distanceTo, ends, extent, inside, port, reading, sideNear, } from './canvas-document.js';
|
|
13
15
|
export { fromJsonCanvas } from './canvas-document.js';
|
|
14
16
|
const MARGIN = 32;
|
|
15
17
|
const ARROW = 'canvas-arrow';
|
|
@@ -20,6 +22,7 @@ const ZOOM_MIN = 0.1;
|
|
|
20
22
|
const ZOOM_MAX = 8;
|
|
21
23
|
const ruling = (zoom) => zoom >= 0.5 ? zoom : zoom * 2 ** Math.ceil(Math.log2(0.5 / zoom));
|
|
22
24
|
const SLOP = 3;
|
|
25
|
+
const REACH = 20;
|
|
23
26
|
const heads = (edge) => ({
|
|
24
27
|
end: (edge.toEnd ?? 'arrow') === 'arrow',
|
|
25
28
|
start: edge.fromEnd === 'arrow',
|
|
@@ -44,11 +47,16 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
44
47
|
this.label = '';
|
|
45
48
|
this.labelEditorLabel = 'Label for {name}';
|
|
46
49
|
this.leadsToLabel = 'leads to {cards}';
|
|
50
|
+
this.movedLabel = '{name} moved to {x}, {y}';
|
|
47
51
|
this.readOnly = false;
|
|
48
52
|
this.reconnectingLabel = 'Moving the end of the connection from {from} to {to}. Move to a card and press Enter, or Escape to stop.';
|
|
53
|
+
this.resizedLabel = '{name} resized to {width} by {height}';
|
|
49
54
|
this.selected = '';
|
|
55
|
+
this.selectedLabel = 'selected';
|
|
56
|
+
this.selectionLabel = '{count} selected';
|
|
50
57
|
this.stoppedLabel = 'Stopped connecting.';
|
|
51
58
|
this.toneLabels = {};
|
|
59
|
+
this.zoomedLabel = 'Zoom {zoom}';
|
|
52
60
|
this.said = '';
|
|
53
61
|
this.at = { x: 0, y: 0, zoom: 1 };
|
|
54
62
|
this.direct = false;
|
|
@@ -62,6 +70,11 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
62
70
|
this.fingers = new Map();
|
|
63
71
|
this.keying = undefined;
|
|
64
72
|
this.edgeKeys = new WeakMap();
|
|
73
|
+
this.edgePan = new EdgePan(() => this.partNamed('viewport')?.getBoundingClientRect(), (by) => this.panCarrying(by), () => {
|
|
74
|
+
if (!this.dragging) {
|
|
75
|
+
this.direct = false;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
65
78
|
this.handlePointerDown = (event) => {
|
|
66
79
|
if (!this.gestureAllowed(event)) {
|
|
67
80
|
return;
|
|
@@ -212,17 +225,19 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
212
225
|
}
|
|
213
226
|
const sizing = this.sizing;
|
|
214
227
|
if (sizing && (sizing.held || sizing.pointer === event.pointerId)) {
|
|
215
|
-
const box = this.resized(sizing.start, sizing.corner, (event.clientX - sizing.from.x) / this.at.zoom, (event.clientY - sizing.from.y) / this.at.zoom);
|
|
228
|
+
const box = snapBox(this.resized(sizing.start, sizing.corner, (event.clientX - sizing.from.x) / this.at.zoom, (event.clientY - sizing.from.y) / this.at.zoom), sizing.start, sizing.corner, this.snap, { height: MIN_HEIGHT, width: MIN_WIDTH });
|
|
216
229
|
const detail = { nodes: [{ name: sizing.card.name, ...box }] };
|
|
217
230
|
this.touched = true;
|
|
218
231
|
sizing.asked = true;
|
|
219
232
|
if (this.requestMove(detail)) {
|
|
220
233
|
sizing.moved = detail;
|
|
221
234
|
}
|
|
235
|
+
this.carryOn(event);
|
|
222
236
|
return;
|
|
223
237
|
}
|
|
224
238
|
if (this.marquee?.pointer === event.pointerId) {
|
|
225
239
|
this.marquee = { ...this.marquee, to: this.toDocument(event) };
|
|
240
|
+
this.carryOn(event);
|
|
226
241
|
return;
|
|
227
242
|
}
|
|
228
243
|
if (this.linking && (this.linking.held || this.linking.pointer === event.pointerId)) {
|
|
@@ -234,7 +249,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
234
249
|
capturePointer(this, event.pointerId);
|
|
235
250
|
}
|
|
236
251
|
const at = this.toDocument(event);
|
|
237
|
-
const over = this.cardAt(at);
|
|
252
|
+
const over = this.cardAt(at, REACH / this.at.zoom);
|
|
238
253
|
const to = this.arrival(over?.id);
|
|
239
254
|
this.linking = {
|
|
240
255
|
...this.linking,
|
|
@@ -244,6 +259,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
244
259
|
to,
|
|
245
260
|
toSide: to !== undefined && over ? sideNear(over, at) : undefined,
|
|
246
261
|
};
|
|
262
|
+
this.carryOn(event);
|
|
247
263
|
return;
|
|
248
264
|
}
|
|
249
265
|
const carry = this.carrying;
|
|
@@ -258,17 +274,22 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
258
274
|
}
|
|
259
275
|
carry.started = true;
|
|
260
276
|
this.touched = true;
|
|
277
|
+
const lead = carry.cards.find(({ card }) => card.name === carry.pressed) ?? carry.cards[0];
|
|
278
|
+
const shift = (from, by) => from === undefined ? by : snapTo(from + by, this.snap) - from;
|
|
279
|
+
const right = shift(lead?.x, across / this.at.zoom);
|
|
280
|
+
const lower = shift(lead?.y, down / this.at.zoom);
|
|
261
281
|
const detail = {
|
|
262
282
|
nodes: carry.cards.map(({ card, x, y }) => ({
|
|
263
283
|
name: card.name,
|
|
264
|
-
x: Math.round(x +
|
|
265
|
-
y: Math.round(y +
|
|
284
|
+
x: Math.round(x + right),
|
|
285
|
+
y: Math.round(y + lower),
|
|
266
286
|
})),
|
|
267
287
|
};
|
|
268
288
|
carry.asked = true;
|
|
269
289
|
if (this.requestMove(detail)) {
|
|
270
290
|
carry.moved = detail;
|
|
271
291
|
}
|
|
292
|
+
this.carryOn(event);
|
|
272
293
|
return;
|
|
273
294
|
}
|
|
274
295
|
const drag = this.dragging;
|
|
@@ -303,6 +324,8 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
303
324
|
if (finger && !owner && this.fingers.size > 0) {
|
|
304
325
|
return;
|
|
305
326
|
}
|
|
327
|
+
this.edgePan.stop();
|
|
328
|
+
this.carryPointer = undefined;
|
|
306
329
|
this.pressing = false;
|
|
307
330
|
const pointing = this.pointing;
|
|
308
331
|
this.pointing = false;
|
|
@@ -322,7 +345,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
322
345
|
if (marquee?.pointer === event.pointerId) {
|
|
323
346
|
this.marquee = undefined;
|
|
324
347
|
if (event.type !== 'pointercancel') {
|
|
325
|
-
this.choose([...marquee.base, ...this.within(marquee)]);
|
|
348
|
+
this.choose([...marquee.base, ...this.within(marquee)], true);
|
|
326
349
|
}
|
|
327
350
|
return;
|
|
328
351
|
}
|
|
@@ -433,15 +456,23 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
433
456
|
if (this.fixed(card)) {
|
|
434
457
|
return;
|
|
435
458
|
}
|
|
459
|
+
const step = this.snap;
|
|
460
|
+
const right = step ? stepTo(card.x, along, step) - card.x : along * NUDGE;
|
|
461
|
+
const lower = step ? stepTo(card.y, down, step) - card.y : down * NUDGE;
|
|
436
462
|
const detail = {
|
|
437
463
|
nodes: this.carriedAll(card).map((one) => ({
|
|
438
464
|
name: one.name,
|
|
439
|
-
x: one.x +
|
|
440
|
-
y: one.y +
|
|
465
|
+
x: one.x + right,
|
|
466
|
+
y: one.y + lower,
|
|
441
467
|
})),
|
|
442
468
|
};
|
|
443
469
|
if (this.requestMove(detail)) {
|
|
444
470
|
this.dispatchEvent(new HelixMoveEvent(detail));
|
|
471
|
+
this.say(fillTemplate(this.movedLabel, {
|
|
472
|
+
name: this.nameOf(card.name),
|
|
473
|
+
x: this.numbers(card.x),
|
|
474
|
+
y: this.numbers(card.y),
|
|
475
|
+
}));
|
|
445
476
|
}
|
|
446
477
|
void this.updateComplete.then(() => this.reveal(card.name));
|
|
447
478
|
return;
|
|
@@ -451,10 +482,17 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
451
482
|
if (this.fixed(card)) {
|
|
452
483
|
return;
|
|
453
484
|
}
|
|
454
|
-
const
|
|
485
|
+
const step = this.snap;
|
|
486
|
+
const edge = { x: card.x + card.width, y: card.y + card.height };
|
|
487
|
+
const box = this.resized({ height: card.height, width: card.width, x: card.x, y: card.y }, 'bottom-right', step ? stepTo(edge.x, along, step) - edge.x : along * NUDGE, step ? stepTo(edge.y, down, step) - edge.y : down * NUDGE);
|
|
455
488
|
const detail = { nodes: [{ name: card.name, ...box }] };
|
|
456
489
|
if (this.requestMove(detail)) {
|
|
457
490
|
this.dispatchEvent(new HelixMoveEvent(detail));
|
|
491
|
+
this.say(fillTemplate(this.resizedLabel, {
|
|
492
|
+
height: this.numbers(box.height),
|
|
493
|
+
name: this.nameOf(card.name),
|
|
494
|
+
width: this.numbers(box.width),
|
|
495
|
+
}));
|
|
458
496
|
}
|
|
459
497
|
return;
|
|
460
498
|
}
|
|
@@ -465,7 +503,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
465
503
|
}
|
|
466
504
|
if ((event.metaKey || event.ctrlKey) && (event.key === 'a' || event.key === 'A')) {
|
|
467
505
|
event.preventDefault();
|
|
468
|
-
this.choose(this.walk.map((one) => one.key));
|
|
506
|
+
this.choose(this.walk.map((one) => one.key), true);
|
|
469
507
|
return;
|
|
470
508
|
}
|
|
471
509
|
if (event.key === 'Escape') {
|
|
@@ -477,7 +515,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
477
515
|
this.focusStop(back);
|
|
478
516
|
return;
|
|
479
517
|
}
|
|
480
|
-
this.choose(undefined);
|
|
518
|
+
this.choose(undefined, true);
|
|
481
519
|
this.partNamed('region')?.focus();
|
|
482
520
|
return;
|
|
483
521
|
}
|
|
@@ -593,7 +631,28 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
593
631
|
if (key !== undefined) {
|
|
594
632
|
event.preventDefault();
|
|
595
633
|
this.editStop(key);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
const viewport = this.partNamed('viewport');
|
|
637
|
+
if (!viewport || !this.gestureAllowed(event)) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const box = viewport.getBoundingClientRect();
|
|
641
|
+
const inside = event.clientX >= box.left &&
|
|
642
|
+
event.clientX <= box.right &&
|
|
643
|
+
event.clientY >= box.top &&
|
|
644
|
+
event.clientY <= box.bottom;
|
|
645
|
+
const onControls = path.some((one) => one instanceof Element && (one.getAttribute('part') ?? '').split(' ').includes('controls'));
|
|
646
|
+
if (!inside || onControls) {
|
|
647
|
+
return;
|
|
596
648
|
}
|
|
649
|
+
event.preventDefault();
|
|
650
|
+
this.touched = true;
|
|
651
|
+
this.direct = false;
|
|
652
|
+
this.zoomAbout(event.shiftKey ? 1 / 2 : 2, {
|
|
653
|
+
x: event.clientX - box.left,
|
|
654
|
+
y: event.clientY - box.top,
|
|
655
|
+
});
|
|
597
656
|
};
|
|
598
657
|
this.handleEditorKeydown = (event) => {
|
|
599
658
|
event.stopPropagation();
|
|
@@ -614,6 +673,12 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
614
673
|
...HelixElement.shadowRootOptions,
|
|
615
674
|
slotAssignment: 'manual',
|
|
616
675
|
}; }
|
|
676
|
+
say(words) {
|
|
677
|
+
this.said = words !== '' && words === this.said ? `${words}\u00a0` : words;
|
|
678
|
+
}
|
|
679
|
+
get numbers() {
|
|
680
|
+
return formatNumbers(this.closest('[lang]')?.getAttribute('lang') ?? '');
|
|
681
|
+
}
|
|
617
682
|
get box() {
|
|
618
683
|
const viewport = this.renderRoot?.querySelector('[part="viewport"]');
|
|
619
684
|
return {
|
|
@@ -752,6 +817,10 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
752
817
|
this.direct = false;
|
|
753
818
|
this.touched = true;
|
|
754
819
|
this.zoomAbout(by > 0 ? 1.25 : 1 / 1.25, { x: this.box.width / 2, y: this.box.height / 2 });
|
|
820
|
+
const lang = this.closest('[lang]')?.getAttribute('lang') || undefined;
|
|
821
|
+
this.say(fillTemplate(this.zoomedLabel, {
|
|
822
|
+
zoom: new Intl.NumberFormat(lang, { maximumFractionDigits: 0, style: 'percent' }).format(this.at.zoom),
|
|
823
|
+
}));
|
|
755
824
|
super.zoom(by);
|
|
756
825
|
}
|
|
757
826
|
show(name) {
|
|
@@ -815,13 +884,20 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
815
884
|
y: origin.y + (event.clientY - (box?.top ?? 0) - this.at.y) / this.at.zoom,
|
|
816
885
|
};
|
|
817
886
|
}
|
|
818
|
-
cardAt(point) {
|
|
819
|
-
|
|
887
|
+
cardAt(point, reach = 0) {
|
|
888
|
+
const under = this.nodes
|
|
820
889
|
.filter((one) => point.x >= one.x &&
|
|
821
890
|
point.x <= one.x + one.width &&
|
|
822
891
|
point.y >= one.y &&
|
|
823
892
|
point.y <= one.y + one.height)
|
|
824
893
|
.sort((a, b) => a.width * a.height - b.width * b.height)[0];
|
|
894
|
+
if (under || reach <= 0) {
|
|
895
|
+
return under;
|
|
896
|
+
}
|
|
897
|
+
return this.nodes
|
|
898
|
+
.map((one) => ({ away: distanceTo(one, point), one }))
|
|
899
|
+
.filter(({ away }) => away <= reach)
|
|
900
|
+
.sort((a, b) => a.away - b.away)[0]?.one;
|
|
825
901
|
}
|
|
826
902
|
nameOf(id) {
|
|
827
903
|
const node = this.byId.get(id);
|
|
@@ -1099,7 +1175,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1099
1175
|
.map((one) => this.keyNamed(one.trim()))
|
|
1100
1176
|
.filter((one) => one !== undefined));
|
|
1101
1177
|
}
|
|
1102
|
-
choose(keys) {
|
|
1178
|
+
choose(keys, said = false) {
|
|
1103
1179
|
const list = keys === undefined ? [] : typeof keys === 'string' ? [keys] : [...new Set(keys)];
|
|
1104
1180
|
const value = list.map((one) => this.publicName(one)).join(',');
|
|
1105
1181
|
if (value === this.selected) {
|
|
@@ -1107,11 +1183,14 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1107
1183
|
}
|
|
1108
1184
|
if (this.dispatchEvent(new HelixSelectEvent({ value }))) {
|
|
1109
1185
|
this.selected = value;
|
|
1186
|
+
if (said) {
|
|
1187
|
+
this.say(fillTemplate(this.selectionLabel, { count: this.numbers(list.length) }));
|
|
1188
|
+
}
|
|
1110
1189
|
}
|
|
1111
1190
|
}
|
|
1112
1191
|
toggle(key) {
|
|
1113
1192
|
const picked = this.picked;
|
|
1114
|
-
this.choose(picked.includes(key) ? picked.filter((one) => one !== key) : [...picked, key]);
|
|
1193
|
+
this.choose(picked.includes(key) ? picked.filter((one) => one !== key) : [...picked, key], true);
|
|
1115
1194
|
}
|
|
1116
1195
|
get pickedCards() {
|
|
1117
1196
|
const picked = new Set(this.picked);
|
|
@@ -1138,6 +1217,26 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1138
1217
|
this.requestUpdate();
|
|
1139
1218
|
return true;
|
|
1140
1219
|
}
|
|
1220
|
+
panCarrying(by) {
|
|
1221
|
+
const last = this.carryPointer;
|
|
1222
|
+
if (!last) {
|
|
1223
|
+
this.edgePan.stop();
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
this.touched = true;
|
|
1227
|
+
this.direct = true;
|
|
1228
|
+
this.at = { ...this.at, x: this.at.x - by.x, y: this.at.y - by.y };
|
|
1229
|
+
for (const gesture of [this.carrying, this.sizing]) {
|
|
1230
|
+
if (gesture) {
|
|
1231
|
+
gesture.from = { x: gesture.from.x - by.x, y: gesture.from.y - by.y };
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
this.handlePointerMove(last);
|
|
1235
|
+
}
|
|
1236
|
+
carryOn(event) {
|
|
1237
|
+
this.carryPointer = event;
|
|
1238
|
+
this.edgePan.follow({ x: event.clientX, y: event.clientY });
|
|
1239
|
+
}
|
|
1141
1240
|
picksUp(gesture, event, from) {
|
|
1142
1241
|
if (gesture.held || this.putting || event.type === 'pointercancel') {
|
|
1143
1242
|
return false;
|
|
@@ -1200,6 +1299,8 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1200
1299
|
this.letGo();
|
|
1201
1300
|
}
|
|
1202
1301
|
letGo() {
|
|
1302
|
+
this.edgePan.stop();
|
|
1303
|
+
this.carryPointer = undefined;
|
|
1203
1304
|
this.holding = false;
|
|
1204
1305
|
this.toggleState('holding', false);
|
|
1205
1306
|
document.removeEventListener('keydown', this.handleHeldKey, true);
|
|
@@ -1655,6 +1756,8 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1655
1756
|
if (this.held) {
|
|
1656
1757
|
this.putBack();
|
|
1657
1758
|
}
|
|
1759
|
+
this.edgePan.stop();
|
|
1760
|
+
this.carryPointer = undefined;
|
|
1658
1761
|
this.sizes?.disconnect();
|
|
1659
1762
|
this.watched = undefined;
|
|
1660
1763
|
this.words?.disconnect();
|
|
@@ -1719,6 +1822,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1719
1822
|
card.meaning = card.tone ? (this.toneLabels[card.tone] ?? '') : '';
|
|
1720
1823
|
card.current = card.name === stop;
|
|
1721
1824
|
card.selected = picked.has(card.name);
|
|
1825
|
+
card.status = card.selected ? this.selectedLabel : '';
|
|
1722
1826
|
card.resizable = alone === card.name && !this.fixed(card);
|
|
1723
1827
|
card.movable = picked.has(card.name) && !this.fixed(card);
|
|
1724
1828
|
card.connectable = !this.fixed(card);
|
|
@@ -1807,7 +1911,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1807
1911
|
const ends = heads(edge);
|
|
1808
1912
|
return svg `<path
|
|
1809
1913
|
part="edge-target"
|
|
1810
|
-
aria-description=${[element?.tone ? this.toneLabels[element.tone] : undefined, edge.label].filter(Boolean).join(', ') || nothing}
|
|
1914
|
+
aria-description=${[pickedKeys.has(key) ? this.selectedLabel : undefined, element?.tone ? this.toneLabels[element.tone] : undefined, edge.label].filter(Boolean).join(', ') || nothing}
|
|
1811
1915
|
aria-label=${fillTemplate(this.connectionLabel, { from: this.textOf(from), to: this.textOf(to) })}
|
|
1812
1916
|
d=${drawn.d}
|
|
1813
1917
|
data-edge=${key}
|
|
@@ -1855,25 +1959,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
|
|
|
1855
1959
|
}
|
|
1856
1960
|
return;
|
|
1857
1961
|
}
|
|
1858
|
-
|
|
1859
|
-
const rest = [];
|
|
1860
|
-
const named = new Map();
|
|
1861
|
-
for (const child of this.knownChildren) {
|
|
1862
|
-
const name = placed.get(child) ?? child.getAttribute('slot') ?? undefined;
|
|
1863
|
-
if (name === undefined) {
|
|
1864
|
-
rest.push(child);
|
|
1865
|
-
}
|
|
1866
|
-
else {
|
|
1867
|
-
named.set(name, [...(named.get(name) ?? []), child]);
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
for (const slot of root?.querySelectorAll?.('slot') ?? []) {
|
|
1871
|
-
const wanted = slot.name === '' ? rest : (named.get(slot.name) ?? []);
|
|
1872
|
-
const had = slot.assignedNodes();
|
|
1873
|
-
if (had.length !== wanted.length || had.some((one, at) => one !== wanted[at])) {
|
|
1874
|
-
slot.assign?.(...wanted);
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1962
|
+
assignSlots(this.renderRoot, this.knownChildren, (child) => placed.get(child));
|
|
1877
1963
|
}
|
|
1878
1964
|
renderLabels(origin) {
|
|
1879
1965
|
return this.edges.map((edge) => {
|
|
@@ -2021,6 +2107,9 @@ __decorate([
|
|
|
2021
2107
|
__decorate([
|
|
2022
2108
|
property({ attribute: 'leads-to-label' })
|
|
2023
2109
|
], HelixHeadlessCanvas.prototype, "leadsToLabel", void 0);
|
|
2110
|
+
__decorate([
|
|
2111
|
+
property({ attribute: 'moved-label' })
|
|
2112
|
+
], HelixHeadlessCanvas.prototype, "movedLabel", void 0);
|
|
2024
2113
|
__decorate([
|
|
2025
2114
|
property({ reflect: true })
|
|
2026
2115
|
], HelixHeadlessCanvas.prototype, "order", void 0);
|
|
@@ -2033,9 +2122,21 @@ __decorate([
|
|
|
2033
2122
|
__decorate([
|
|
2034
2123
|
property({ attribute: 'reconnecting-label' })
|
|
2035
2124
|
], HelixHeadlessCanvas.prototype, "reconnectingLabel", void 0);
|
|
2125
|
+
__decorate([
|
|
2126
|
+
property({ attribute: 'resized-label' })
|
|
2127
|
+
], HelixHeadlessCanvas.prototype, "resizedLabel", void 0);
|
|
2036
2128
|
__decorate([
|
|
2037
2129
|
property()
|
|
2038
2130
|
], HelixHeadlessCanvas.prototype, "selected", void 0);
|
|
2131
|
+
__decorate([
|
|
2132
|
+
property({ attribute: 'selected-label' })
|
|
2133
|
+
], HelixHeadlessCanvas.prototype, "selectedLabel", void 0);
|
|
2134
|
+
__decorate([
|
|
2135
|
+
property({ attribute: 'selection-label' })
|
|
2136
|
+
], HelixHeadlessCanvas.prototype, "selectionLabel", void 0);
|
|
2137
|
+
__decorate([
|
|
2138
|
+
property({ type: Number })
|
|
2139
|
+
], HelixHeadlessCanvas.prototype, "snap", void 0);
|
|
2039
2140
|
__decorate([
|
|
2040
2141
|
state()
|
|
2041
2142
|
], HelixHeadlessCanvas.prototype, "editing", void 0);
|
|
@@ -2045,6 +2146,9 @@ __decorate([
|
|
|
2045
2146
|
__decorate([
|
|
2046
2147
|
property({ attribute: 'tone-labels', converter: wordsConverter })
|
|
2047
2148
|
], HelixHeadlessCanvas.prototype, "toneLabels", void 0);
|
|
2149
|
+
__decorate([
|
|
2150
|
+
property({ attribute: 'zoomed-label' })
|
|
2151
|
+
], HelixHeadlessCanvas.prototype, "zoomedLabel", void 0);
|
|
2048
2152
|
__decorate([
|
|
2049
2153
|
state()
|
|
2050
2154
|
], HelixHeadlessCanvas.prototype, "stop", void 0);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a card lands on a board that snaps: the arithmetic of a ruling, kept
|
|
3
|
+
* apart from the board that applies it.
|
|
4
|
+
*
|
|
5
|
+
* Every value is in the document's own units, and a step of nothing, zero or
|
|
6
|
+
* less is no snapping at all, so a board without `snap` moves exactly as it
|
|
7
|
+
* did before there was one.
|
|
8
|
+
*/
|
|
9
|
+
/** A box on the board, in the document's own units. */
|
|
10
|
+
export interface SnapBox {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A value at the nearest multiple of `step`, or the value as it is where there
|
|
18
|
+
* is no step. A drag lets go wherever the hand is, and lands on the line
|
|
19
|
+
* nearest it.
|
|
20
|
+
*/
|
|
21
|
+
export declare const snapTo: (value: number, step: number | undefined) => number;
|
|
22
|
+
/**
|
|
23
|
+
* The next multiple of `step` from `value`, the way a key points: `way` is `1`
|
|
24
|
+
* or `-1`.
|
|
25
|
+
*
|
|
26
|
+
* **On to the next line, and never back onto the same one.** A card sitting
|
|
27
|
+
* between two lines goes to the line ahead of it, and one on a line goes a
|
|
28
|
+
* whole step, so every press moves the card and every press lands on a line.
|
|
29
|
+
*/
|
|
30
|
+
export declare const stepTo: (value: number, way: number, step: number) => number;
|
|
31
|
+
/**
|
|
32
|
+
* A box resized from a corner, with the edges that corner moves snapped, and
|
|
33
|
+
* held to a least size.
|
|
34
|
+
*
|
|
35
|
+
* Only the moving edges: the corner opposite the one in hand stays where it
|
|
36
|
+
* was, as it does without a ruling. Where the line nearest is inside the least
|
|
37
|
+
* size, the box stays at the least size rather than turning inside out.
|
|
38
|
+
*/
|
|
39
|
+
export declare const snapBox: (box: SnapBox, start: SnapBox, corner: string, step: number | undefined, least: {
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
}) => SnapBox;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const snaps = (step) => step !== undefined && Number.isFinite(step) && step > 0;
|
|
2
|
+
export const snapTo = (value, step) => snaps(step) ? Math.round(value / step) * step : value;
|
|
3
|
+
export const stepTo = (value, way, step) => {
|
|
4
|
+
if (way === 0) {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
const at = value / step;
|
|
8
|
+
const near = Math.round(at);
|
|
9
|
+
const on = Math.abs(at - near) < 1e-9 ? near : at;
|
|
10
|
+
return (way > 0 ? Math.floor(on) + 1 : Math.ceil(on) - 1) * step;
|
|
11
|
+
};
|
|
12
|
+
export const snapBox = (box, start, corner, step, least) => {
|
|
13
|
+
if (!snaps(step)) {
|
|
14
|
+
return box;
|
|
15
|
+
}
|
|
16
|
+
const left = corner.endsWith('left');
|
|
17
|
+
const top = corner.startsWith('top');
|
|
18
|
+
const right = start.x + start.width;
|
|
19
|
+
const bottom = start.y + start.height;
|
|
20
|
+
const width = left
|
|
21
|
+
? Math.max(least.width, right - snapTo(box.x, step))
|
|
22
|
+
: Math.max(least.width, snapTo(box.x + box.width, step) - start.x);
|
|
23
|
+
const height = top
|
|
24
|
+
? Math.max(least.height, bottom - snapTo(box.y, step))
|
|
25
|
+
: Math.max(least.height, snapTo(box.y + box.height, step) - start.y);
|
|
26
|
+
return {
|
|
27
|
+
height,
|
|
28
|
+
width,
|
|
29
|
+
x: left ? right - width : start.x,
|
|
30
|
+
y: top ? bottom - height : start.y,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -31,6 +31,12 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
31
31
|
* is no wrapper and every region is a bare slot. A server cannot see slotted
|
|
32
32
|
* content, so served actions sit on their own line until the script runs.
|
|
33
33
|
*
|
|
34
|
+
* **The card says which regions it holds**, as `:state(has-media)`,
|
|
35
|
+
* `:state(has-header)` and `:state(has-footer)`, so a sheet can draw a card
|
|
36
|
+
* with a header differently, as Web Awesome's `with-header` does, with no
|
|
37
|
+
* attribute written onto the card. Read in the browser, so a served card
|
|
38
|
+
* carries none until the script runs.
|
|
39
|
+
*
|
|
34
40
|
* @since 0.1.0
|
|
35
41
|
* @status stable
|
|
36
42
|
* @category layout
|
|
@@ -52,6 +58,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
52
58
|
* @csspart header-actions - The slot the header's controls arrive through, drawing no box, as `body` does.
|
|
53
59
|
* @csspart header-row - The line holding `header` and `header-actions`, drawn only while `header-actions` holds something.
|
|
54
60
|
* @csspart media - The slot the media arrives through, drawing no box, as `body` does.
|
|
61
|
+
*
|
|
62
|
+
* @cssstate has-footer - Something is slotted into `footer` or `footer-actions`.
|
|
63
|
+
* @cssstate has-header - Something is slotted into `header` or `header-actions`.
|
|
64
|
+
* @cssstate has-media - Something is slotted into `media`.
|
|
55
65
|
*/
|
|
56
66
|
export declare class HelixHeadlessCard extends HelixElement {
|
|
57
67
|
/**
|
|
@@ -92,7 +102,8 @@ export declare class HelixHeadlessCard extends HelixElement {
|
|
|
92
102
|
private headerActions;
|
|
93
103
|
protected willUpdate(changed: PropertyValues): void;
|
|
94
104
|
protected updated(changed: PropertyValues): void;
|
|
95
|
-
|
|
105
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
106
|
+
private readonly readRegions;
|
|
96
107
|
protected render(): TemplateResult;
|
|
97
108
|
}
|
|
98
109
|
declare global {
|
|
@@ -15,10 +15,13 @@ let HelixHeadlessCard = class HelixHeadlessCard extends HelixElement {
|
|
|
15
15
|
this.namedBy = null;
|
|
16
16
|
this.footerActions = false;
|
|
17
17
|
this.headerActions = false;
|
|
18
|
-
this.
|
|
18
|
+
this.readRegions = () => {
|
|
19
19
|
const filled = (name) => slotFilled(this.renderRoot?.querySelector(`slot[name="${name}"]`));
|
|
20
20
|
this.headerActions = filled('header-actions');
|
|
21
21
|
this.footerActions = filled('footer-actions');
|
|
22
|
+
this.toggleState('has-media', filled('media'));
|
|
23
|
+
this.toggleState('has-header', this.headerActions || filled('header'));
|
|
24
|
+
this.toggleState('has-footer', this.footerActions || filled('footer'));
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
willUpdate(changed) {
|
|
@@ -28,20 +31,24 @@ let HelixHeadlessCard = class HelixHeadlessCard extends HelixElement {
|
|
|
28
31
|
}
|
|
29
32
|
updated(changed) {
|
|
30
33
|
super.updated(changed);
|
|
31
|
-
this.
|
|
34
|
+
this.readRegions();
|
|
35
|
+
}
|
|
36
|
+
firstUpdated(changed) {
|
|
37
|
+
super.firstUpdated(changed);
|
|
38
|
+
this.renderRoot.addEventListener('slotchange', this.readRegions);
|
|
32
39
|
}
|
|
33
40
|
render() {
|
|
34
41
|
const header = html `<slot name="header" part="header"></slot
|
|
35
42
|
><slot
|
|
36
43
|
name="header-actions"
|
|
37
44
|
part="header-actions"
|
|
38
|
-
@slotchange=${this.
|
|
45
|
+
@slotchange=${this.readRegions}
|
|
39
46
|
></slot>`;
|
|
40
47
|
const footer = html `<slot name="footer" part="footer"></slot
|
|
41
48
|
><slot
|
|
42
49
|
name="footer-actions"
|
|
43
50
|
part="footer-actions"
|
|
44
|
-
@slotchange=${this.
|
|
51
|
+
@slotchange=${this.readRegions}
|
|
45
52
|
></slot>`;
|
|
46
53
|
return html `
|
|
47
54
|
<slot name="media" part="media"></slot>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary Shows one slide of several, with controls to move between them.
|
|
@@ -727,9 +727,10 @@ export declare class HelixHeadlessCarousel extends HelixElement {
|
|
|
727
727
|
* that changes an assignment is this component calling `assign`, so a slide
|
|
728
728
|
* appended by a consumer would reach no slot, render nowhere and be counted by
|
|
729
729
|
* nothing. A default slot needs no watcher, taking whatever is there; a manual
|
|
730
|
-
* one does. `Chat` watches for the same reason
|
|
730
|
+
* one does. `Chat` watches for the same reason, through the same core
|
|
731
|
+
* controller.
|
|
731
732
|
*/
|
|
732
|
-
|
|
733
|
+
protected readonly childWatch: ChildrenController;
|
|
733
734
|
connectedCallback(): void;
|
|
734
735
|
disconnectedCallback(): void;
|
|
735
736
|
/** Pauses without forgetting that the reader wanted it running. */
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { capturePointer, customElement, fillTemplate, HelixActivateEvent, HelixElement, HelixSelectEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ChildrenController, capturePointer, customElement, fillTemplate, HelixActivateEvent, HelixElement, HelixSelectEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft, caretRight, play, stop } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -185,7 +185,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
185
185
|
};
|
|
186
186
|
this.scrollFrame = 0;
|
|
187
187
|
this.stopped = false;
|
|
188
|
-
this.
|
|
188
|
+
this.childWatch = new ChildrenController(this);
|
|
189
189
|
this.pause = () => {
|
|
190
190
|
if (!this.stopped) {
|
|
191
191
|
this.rotating = false;
|
|
@@ -388,8 +388,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
388
388
|
super.connectedCallback();
|
|
389
389
|
this.addEventListener('focusin', this.pause);
|
|
390
390
|
this.addEventListener('pointerenter', this.pause);
|
|
391
|
-
this.watcher = new MutationObserver(() => this.requestUpdate());
|
|
392
|
-
this.watcher.observe(this, { childList: true });
|
|
393
391
|
this.watchPane();
|
|
394
392
|
if (this.hasUpdated) {
|
|
395
393
|
this.runTimer();
|
|
@@ -403,8 +401,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
403
401
|
}
|
|
404
402
|
this.removeEventListener('focusin', this.pause);
|
|
405
403
|
this.removeEventListener('pointerenter', this.pause);
|
|
406
|
-
this.watcher?.disconnect();
|
|
407
|
-
this.watcher = undefined;
|
|
408
404
|
this.sizes?.disconnect();
|
|
409
405
|
this.sizes = undefined;
|
|
410
406
|
this.watched = undefined;
|