@fusion.dev/helix-headless 0.117.0 → 0.119.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.
@@ -1,4 +1,4 @@
1
- import { type CanvasView, HelixElement, type ViewportPanDetail, type ViewportWay, type ViewportZoomDetail } from '@fusion.dev/helix-core';
1
+ import { type CanvasView, HelixElement, type ViewportGestureLabels, type ViewportPanDetail, type ViewportWay, type ViewportZoomDetail } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import { type CanvasDocument, type CanvasTone } from './canvas-document.js';
4
4
  export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasSide, CanvasTone, } from './canvas-document.js';
@@ -100,6 +100,8 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
100
100
  * @csspart edges - The layer the connectors are drawn in.
101
101
  * @csspart footer - The strip below the board.
102
102
  * @csspart fullscreen - The button that makes the board fill the screen.
103
+ * @csspart gesture-hint - Words over the board for a moment when it lets a gesture pass to the page, such as how to zoom it.
104
+ * @csspart gesture-status - The line shown while a board with `gestures="activate"` has the gestures.
103
105
  * @csspart header - The strip above the board.
104
106
  * @csspart label - The label on a connector.
105
107
  * @csspart label-editor - The field for editing a connection's label or a group's name, placed over that text.
@@ -121,6 +123,8 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
121
123
  * @cssstate holding - An item picked up with a click follows the pointer until the next press puts it down.
122
124
  * @cssstate idle - The user has been still for `idle-delay` milliseconds. The board's own controls stay; select on it to hide chrome of your own.
123
125
  * @cssstate pressing - While a press on the board, its cards or its connections is under way.
126
+ * @cssstate sharing - The page keeps the plain wheel and one finger, with `gestures="cooperative"` or while a board with `gestures="activate"` waits to be pressed.
127
+ * @cssstate using - A board with `gestures="activate"` has been pressed and has the gestures.
124
128
  */
125
129
  export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
126
130
  /** The text read with a card to say where its connections come from, with `{cards}`. */
@@ -373,6 +377,8 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
373
377
  protected panEvent(detail: ViewportPanDetail): Event;
374
378
  protected zoomEvent(detail: ViewportZoomDetail): Event;
375
379
  protected get restingControlsLabel(): string;
380
+ /** What the board says about its gestures where the page does not say it. */
381
+ protected get restingGestureLabels(): ViewportGestureLabels;
376
382
  /**
377
383
  * Zoom and fullscreen, without the pad.
378
384
  *
@@ -703,6 +709,13 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
703
709
  * the wheel is the board's.
704
710
  */
705
711
  private readonly handleWheel;
712
+ /**
713
+ * A second finger on a cooperative board, which would otherwise go on
714
+ * scrolling the page the first finger started: stopped at the start, so
715
+ * the two fingers pinch and move the board. **Not passive**, which is the
716
+ * only way a start can be stopped.
717
+ */
718
+ private readonly handleTouchStart;
706
719
  /**
707
720
  * The keys on a card or a connection.
708
721
  *
@@ -63,6 +63,9 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
63
63
  this.keying = undefined;
64
64
  this.edgeKeys = new WeakMap();
65
65
  this.handlePointerDown = (event) => {
66
+ if (!this.gestureAllowed(event)) {
67
+ return;
68
+ }
66
69
  const path = event.composedPath();
67
70
  const on = (name) => path.some((one) => one instanceof Element && (one.getAttribute('part') ?? '').split(' ').includes(name));
68
71
  const card = this.cardOf(event);
@@ -77,6 +80,9 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
77
80
  }
78
81
  return;
79
82
  }
83
+ if (this.gestureMode === 'cooperative') {
84
+ return;
85
+ }
80
86
  }
81
87
  if (this.held) {
82
88
  event.preventDefault();
@@ -388,13 +394,17 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
388
394
  }
389
395
  };
390
396
  this.handleWheel = (event) => {
391
- if (!event.ctrlKey && !this.filled) {
397
+ const zooming = event.ctrlKey || event.metaKey;
398
+ if (!this.gestureAllowed(event)) {
399
+ return;
400
+ }
401
+ if (!zooming && !this.filled && this.gestures !== 'always') {
392
402
  return;
393
403
  }
394
404
  event.preventDefault();
395
405
  this.touched = true;
396
406
  this.direct = true;
397
- if (event.ctrlKey) {
407
+ if (zooming) {
398
408
  const box = event.currentTarget.getBoundingClientRect();
399
409
  const about = { x: event.clientX - box.left, y: event.clientY - box.top };
400
410
  this.zoomAbout(event.deltaY < 0 ? 1.1 : 1 / 1.1, about);
@@ -402,6 +412,11 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
402
412
  }
403
413
  this.at = { ...this.at, x: this.at.x - event.deltaX, y: this.at.y - event.deltaY };
404
414
  };
415
+ this.handleTouchStart = (event) => {
416
+ if (this.gestureMode === 'cooperative' && event.touches.length > 1) {
417
+ event.preventDefault();
418
+ }
419
+ };
405
420
  this.handleStopKeydown = (event) => {
406
421
  const origin = event.composedPath()[0];
407
422
  const edge = this.edgeOf(event);
@@ -703,6 +718,14 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
703
718
  get restingControlsLabel() {
704
719
  return 'Board controls';
705
720
  }
721
+ get restingGestureLabels() {
722
+ return {
723
+ activate: 'Press the board to use it',
724
+ twoFinger: 'Use two fingers to move the board',
725
+ using: 'Using the board. Press Escape to scroll the page again.',
726
+ wheel: 'Use {key} and scroll to zoom the board',
727
+ };
728
+ }
706
729
  get restingControls() {
707
730
  return 'zoom fullscreen';
708
731
  }
@@ -1615,6 +1638,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
1615
1638
  this.addEventListener('pointerdown', this.handlePointerDown);
1616
1639
  this.addEventListener('pointermove', this.handlePointerMove);
1617
1640
  this.addEventListener('pointerup', this.handlePointerUp);
1641
+ this.addEventListener('touchstart', this.handleTouchStart, { passive: false });
1618
1642
  }
1619
1643
  disconnectedCallback() {
1620
1644
  super.disconnectedCallback();
@@ -1632,6 +1656,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
1632
1656
  this.removeEventListener('pointerdown', this.handlePointerDown);
1633
1657
  this.removeEventListener('pointermove', this.handlePointerMove);
1634
1658
  this.removeEventListener('pointerup', this.handlePointerUp);
1659
+ this.removeEventListener('touchstart', this.handleTouchStart);
1635
1660
  }
1636
1661
  willUpdate(changed) {
1637
1662
  this.keying = this.keyAll();
@@ -1840,7 +1865,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
1840
1865
  tabindex="0"
1841
1866
  @focusin=${this.idle.stir}
1842
1867
  @keydown=${this.handleKeydown}
1843
- @pointerleave=${this.idle.leave}
1868
+ @pointerleave=${this.handlePointerLeave}
1844
1869
  @pointermove=${this.idle.stir}
1845
1870
  >
1846
1871
  <div part="header">
@@ -1875,6 +1900,7 @@ let HelixHeadlessCanvas = class HelixHeadlessCanvas extends MixinViewport(HelixE
1875
1900
  ${this.renderMarquee(origin)}
1876
1901
  </div>
1877
1902
  <slot name="empty"></slot>
1903
+ ${this.renderGestures()}
1878
1904
  </div>
1879
1905
  ${this.renderControls()}
1880
1906
  <span part="live" role="status">${this.said}</span>
@@ -90,7 +90,9 @@ registerElementEvents({
90
90
  'helix-headless-graph': [
91
91
  'helix-activate',
92
92
  'helix-before-activate',
93
+ 'helix-graph-layout',
93
94
  'helix-graph-pan',
95
+ 'helix-graph-part-change',
94
96
  'helix-graph-ready',
95
97
  'helix-graph-zoom',
96
98
  ],
@@ -1,4 +1,4 @@
1
- import { HelixElement, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
1
+ import { HelixElement, type ViewportGestureLabels, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import { type GraphLink, type GraphNode } from './graph-model.js';
4
4
  declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.dev/helix-core").ViewportElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerActiveInterface) & typeof HelixElement;
@@ -8,8 +8,8 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
8
8
  * @description
9
9
  * Helix draws no graph. A force layout of thousands of notes is physics and
10
10
  * WebGL, which a renderer such as Sigma.js does. Put the renderer's box in the
11
- * frame, draw `nodes` and `links` in it, and answer the frame's pan and zoom
12
- * events by moving the drawing.
11
+ * frame, and `connectGraph` from `@fusion.dev/helix-graph` draws `nodes` and
12
+ * `links` in it and keeps it in step with the frame.
13
13
  *
14
14
  * What the frame adds is what a drawing of a graph cannot do: a list of every
15
15
  * note beside it, which is the graph for a screen reader and a quick way to
@@ -41,9 +41,11 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
41
41
  *
42
42
  * @event {HelixActivateEvent} helix-activate - A note was selected, in the list or in the drawing. The detail's `value` is its `id`.
43
43
  * @event {HelixBeforeActivateEvent} helix-before-activate - A note is about to be selected. Cancelable: cancel it to keep the selection in your own state.
44
- * @event {HelixGraphPanEvent} helix-graph-pan - A pan button or arrow key was pressed. Move the drawing.
44
+ * @event {HelixGraphLayoutEvent} helix-graph-layout - A layout settled, with where it put each note, sent by `laidOut()`. Keep the positions and pass them back as each note's `x` and `y`.
45
+ * @event {HelixGraphPanEvent} helix-graph-pan - A pan button or arrow key was pressed. `connectGraph` moves the drawing.
46
+ * @event {HelixGraphPartChangeEvent} helix-graph-part-change - The notes, the links, the selection, the depth or the gestures changed. Used by `connectGraph`; pages do not need to listen for it.
45
47
  * @event {HelixGraphReadyEvent} helix-graph-ready - The graph has been drawn whole, laid out and settled. Sent each time `drawn()` says it is drawn after it was not.
46
- * @event {HelixGraphZoomEvent} helix-graph-zoom - A zoom button or key was pressed. Zoom the drawing.
48
+ * @event {HelixGraphZoomEvent} helix-graph-zoom - A zoom button or key was pressed. `connectGraph` zooms the drawing.
47
49
  *
48
50
  * @csspart after - The room the notes after those drawn would take, so the list scrolls its whole length.
49
51
  * @csspart before - The room the notes before those drawn would take.
@@ -54,6 +56,8 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
54
56
  * @csspart filter-mark - The default icon beside the search field, shown when none is slotted.
55
57
  * @csspart footer - The strip below the graph.
56
58
  * @csspart fullscreen - The button that makes the graph fill the screen.
59
+ * @csspart gesture-hint - Words over the graph for a moment when it lets a gesture pass to the page, such as how to zoom it.
60
+ * @csspart gesture-status - The line shown while a graph with `gestures="activate"` has the gestures.
57
61
  * @csspart header - The strip above the graph.
58
62
  * @csspart list - The list of notes, which draws only the rows in view.
59
63
  * @csspart live - What screen readers hear when a search changes how many notes there are.
@@ -79,6 +83,8 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
79
83
  * @cssstate fullscreen - The graph fills the screen.
80
84
  * @cssstate idle - The user has been still long enough for the header and footer to fade.
81
85
  * @cssstate ready - The graph has been drawn whole, after `helix-graph-ready`.
86
+ * @cssstate sharing - The page keeps the plain wheel and one finger, with `gestures="cooperative"` or while a graph with `gestures="activate"` waits to be pressed.
87
+ * @cssstate using - A graph with `gestures="activate"` has been pressed and has the gestures.
82
88
  */
83
89
  export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
84
90
  /** What the list says of a note's count, with `{count}`. */
@@ -127,7 +133,7 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
127
133
  private said;
128
134
  private readonly virtualize;
129
135
  /**
130
- * @internal The notes the drawing shows, for the code that draws it: those
136
+ * @internal The notes the drawing shows, which `connectGraph` reads: those
131
137
  * within `depth` of the selected note, or `undefined` for every note.
132
138
  */
133
139
  get shown(): ReadonlySet<string> | undefined;
@@ -135,18 +141,32 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
135
141
  get ready(): boolean;
136
142
  /**
137
143
  * Says the graph has been drawn whole, or with `false`, that it no longer
138
- * is. Call it when the renderer's layout has settled and the graph is
139
- * finished. The first call after
144
+ * is. Called by `connectGraph` once its layout has settled; a page drawing
145
+ * its own graph calls it when that graph is finished. The first call after
140
146
  * the graph was not drawn sends `helix-graph-ready` and turns on
141
147
  * `:state(ready)`.
142
148
  */
143
149
  drawn(whole?: boolean): void;
150
+ /**
151
+ * Says where a layout put each note, by its `id`: sends
152
+ * `helix-graph-layout` for the page to keep. Called by `connectGraph` once
153
+ * its layout has settled; a page laying out its own graph calls it the same
154
+ * way.
155
+ */
156
+ laidOut(positions: Record<string, {
157
+ x: number;
158
+ y: number;
159
+ }>): void;
144
160
  protected willUpdate(changed: PropertyValues): void;
145
161
  protected updated(changed: PropertyValues): void;
146
162
  protected panEvent(detail: ViewportPanDetail): Event;
147
163
  protected zoomEvent(detail: ViewportZoomDetail): Event;
148
164
  protected get restingControls(): string;
149
165
  protected get restingControlsLabel(): string;
166
+ /** Which gestures the renderer takes, which `connectGraph` hears from here. */
167
+ protected gesturesChanged(): void;
168
+ /** What the graph says about its gestures where the page does not say it. */
169
+ protected get restingGestureLabels(): ViewportGestureLabels;
150
170
  /** How many notes the list holds, in the page's numbers. */
151
171
  private countText;
152
172
  /** How a row stands to the selected note, in words, or nothing where it does not. */
@@ -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 { customElement, fillTemplate, formatNumbers, HelixElement, HelixGraphPanEvent, HelixGraphReadyEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, VirtualizeController, } from '@fusion.dev/helix-core';
7
+ import { customElement, fillTemplate, formatNumbers, HelixElement, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, VirtualizeController, } from '@fusion.dev/helix-core';
8
8
  import { magnifyingGlass } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -95,6 +95,9 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
95
95
  this.dispatchEvent(new HelixGraphReadyEvent());
96
96
  }
97
97
  }
98
+ laidOut(positions) {
99
+ this.dispatchEvent(new HelixGraphLayoutEvent({ positions }));
100
+ }
98
101
  willUpdate(changed) {
99
102
  super.willUpdate(changed);
100
103
  this.toggleState('fullscreen', this.filled);
@@ -123,6 +126,12 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
123
126
  updated(changed) {
124
127
  super.updated(changed);
125
128
  this.virtualize.measure();
129
+ if (changed.has('nodes') || changed.has('links')) {
130
+ this.dispatchEvent(new HelixGraphPartChangeEvent({ kind: 'data' }));
131
+ }
132
+ else if (changed.has('active') || changed.has('depth')) {
133
+ this.dispatchEvent(new HelixGraphPartChangeEvent({ kind: 'focus' }));
134
+ }
126
135
  if (changed.has('query') && changed.get('query') !== undefined) {
127
136
  this.said = this.countText();
128
137
  }
@@ -139,6 +148,17 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
139
148
  get restingControlsLabel() {
140
149
  return 'Graph controls';
141
150
  }
151
+ gesturesChanged() {
152
+ this.dispatchEvent(new HelixGraphPartChangeEvent({ kind: 'gestures' }));
153
+ }
154
+ get restingGestureLabels() {
155
+ return {
156
+ activate: 'Press the graph to use it',
157
+ twoFinger: 'Use two fingers to move the graph',
158
+ using: 'Using the graph. Press Escape to scroll the page again.',
159
+ wheel: 'Use {key} and scroll to zoom the graph',
160
+ };
161
+ }
142
162
  countText() {
143
163
  const lang = this.closest?.('[lang]')?.getAttribute('lang') ?? '';
144
164
  return fillTemplate(this.countLabel, { count: formatNumbers(lang)(this.entries.length) });
@@ -224,7 +244,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
224
244
  tabindex="0"
225
245
  @focusin=${this.idle.stir}
226
246
  @keydown=${this.handleKeydown}
227
- @pointerleave=${this.idle.leave}
247
+ @pointerleave=${this.handlePointerLeave}
228
248
  @pointermove=${this.idle.stir}
229
249
  >
230
250
  <div part="header">
@@ -234,6 +254,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
234
254
  <div part="stage">
235
255
  <div part="viewport">
236
256
  <slot></slot>
257
+ ${this.renderGestures()}
237
258
  </div>
238
259
  ${this.renderControls()}
239
260
  </div>
@@ -1,4 +1,4 @@
1
- import { HelixElement, KeyboardNavigationController, type ViewportControlsPlacement, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
1
+ import { HelixElement, KeyboardNavigationController, type ViewportControlsPlacement, type ViewportGestureLabels, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
2
2
  import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * What `ViewportControlsPlacement` is called for a map.
@@ -115,14 +115,10 @@ declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.de
115
115
  * @cssstate fullscreen - The map fills the screen.
116
116
  * @cssstate idle - The user has been still long enough for the header and footer to fade.
117
117
  * @cssstate ready - The map has been drawn whole, after `helix-map-ready`.
118
+ * @cssstate sharing - The page keeps the plain wheel and one finger, with `gestures="cooperative"` or while a map with `gestures="activate"` waits to be pressed.
118
119
  * @cssstate using - A map with `gestures="activate"` has been pressed and has the gestures.
119
120
  */
120
121
  export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
121
- /**
122
- * The hint shown when a map waiting to be pressed is scrolled or swiped
123
- * over, with `gestures="activate"`.
124
- */
125
- activateHintLabel: string;
126
122
  /**
127
123
  * The map's rotation, in degrees clockwise from north. `connectMap` keeps it
128
124
  * current, and the Face north button's needle turns with it.
@@ -137,21 +133,6 @@ export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
137
133
  faceNorthLabel: string;
138
134
  /** What screen readers hear when the map is tilted back to looking straight down. */
139
135
  flatLabel: string;
140
- /**
141
- * Which gestures the map takes from the page.
142
- *
143
- * - `always`, which unset is: the wheel zooms the map and one finger pans
144
- * it, for a map that is the page, such as a full-screen view.
145
- * - `cooperative`: the wheel and one finger scroll the page, and the map
146
- * takes Ctrl or ⌘ with the wheel, and two fingers. The frame says so
147
- * when a gesture passes to the page. Best for a map embedded in a page.
148
- * - `activate`: the map takes nothing until it is pressed, and gives it
149
- * back on Escape, when the pointer leaves it, or on a press elsewhere.
150
- *
151
- * The keyboard and the frame's buttons work in every mode. The renderer is
152
- * told through the connector, so MapLibre and Leaflet behave alike.
153
- */
154
- gestures?: 'activate' | 'always' | 'cooperative';
155
136
  /** The Hybrid map type's name. */
156
137
  hybridLabel: string;
157
138
  /**
@@ -213,16 +194,6 @@ export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
213
194
  * top of the map faces, clockwise from north.
214
195
  */
215
196
  turnedLabel: string;
216
- /** The hint shown when one finger swipes over a map with `gestures="cooperative"`. */
217
- twoFingerHintLabel: string;
218
- /** The line shown while a map with `gestures="activate"` has the gestures. */
219
- usingLabel: string;
220
- /**
221
- * The hint shown when the wheel scrolls past a map with
222
- * `gestures="cooperative"`, with `{key}`, which is ⌘ on a Mac and Ctrl
223
- * elsewhere, as the renderer reads it.
224
- */
225
- wheelHintLabel: string;
226
197
  /**
227
198
  * What screen readers hear after a zoom. `{level}` is the zoom level.
228
199
  */
@@ -348,51 +319,10 @@ export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
348
319
  */
349
320
  private readonly handleMarkerKeydown;
350
321
  private readonly handleMarkerKeyup;
351
- /** The hint on the map while one shows, put there by a gesture the map let pass. */
352
- private hint;
353
- /** When the hint goes. */
354
- private hinting;
355
- /**
356
- * Where the gesture was, in the map's box, which the hint is shown at:
357
- * where the reader is looking, and on the map wherever a page laid its own
358
- * content over the rest of it.
359
- */
360
- private hintAt;
361
- /** Whether a map with `gestures="activate"` has been pressed, and has the gestures. */
362
- private taken;
363
- /**
364
- * @internal Which gestures the renderer takes, which `connectMap` tells it:
365
- * all of them, the cooperative set, or none, while an `activate` map waits
366
- * to be pressed.
367
- */
368
- get gestureMode(): 'cooperative' | 'free' | 'off';
369
- /** Shows a hint over the map for a moment, where the gesture was. */
370
- private showHint;
371
- /**
372
- * A wheel the map let pass to the page, which is said: a reader scrolling
373
- * the page past a map that did not zoom is told why, and how to zoom it.
374
- * **Ctrl or ⌘ with the wheel is the map's**, and is what a trackpad's pinch
375
- * arrives as.
376
- */
377
- private readonly handleWheel;
378
- /** One finger moving over the map, which scrolls the page, and is said. */
379
- private readonly handleTouchMove;
380
- /** A press on the map itself, which hands a waiting map the gestures. */
381
- private readonly handleTake;
382
- /** Escape, which gives the page its scroll back. */
383
- private readonly handleGiveBackKey;
384
- /** A press anywhere else on the page, which gives it its scroll back. */
385
- private readonly handleGiveBackOutside;
386
- /** The window losing focus, as a reader switching away does. */
387
- private readonly handleGiveBackBlur;
388
- /**
389
- * The pointer leaving the frame. **Heard on the frame and not the map's
390
- * canvas**, which a pointer resting on a marker has left, since markers
391
- * stand outside it. **A mouse or a pen and never a finger**, whose
392
- * `pointerleave` is the finger lifting: a tap took the map and gave it back
393
- * in one.
394
- */
395
- private readonly handleLeave;
322
+ /** What the map says about its gestures where the page does not say it. */
323
+ protected get restingGestureLabels(): ViewportGestureLabels;
324
+ /** Which gestures the renderer takes, which `connectMap` hears from here. */
325
+ protected gesturesChanged(): void;
396
326
  /** A marker added or taken away is a walk of a different length. */
397
327
  private readonly handleSlotChange;
398
328
  connectedCallback(): void;