@fusion.dev/helix-headless 0.116.0 → 0.118.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 +3530 -429
- package/dist/canvas/root/canvas-root.d.ts +14 -1
- package/dist/canvas/root/canvas-root.js +29 -3
- package/dist/element-events.generated.js +9 -0
- package/dist/graph/index.d.ts +3 -0
- package/dist/graph/index.js +2 -0
- package/dist/graph/root/graph-model.d.ts +63 -0
- package/dist/graph/root/graph-model.js +75 -0
- package/dist/graph/root/graph-root.d.ts +209 -0
- package/dist/graph/root/graph-root.js +342 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/map/root/map-root.d.ts +6 -76
- package/dist/map/root/map-root.js +12 -136
- package/package.json +5 -5
- package/types/jsx.d.ts +1384 -108
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +380 -37
|
@@ -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
|
-
|
|
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 (
|
|
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.
|
|
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>
|
|
@@ -87,6 +87,15 @@ registerElementEvents({
|
|
|
87
87
|
'toggle',
|
|
88
88
|
],
|
|
89
89
|
'helix-headless-filter-menu': ['helix-facet'],
|
|
90
|
+
'helix-headless-graph': [
|
|
91
|
+
'helix-activate',
|
|
92
|
+
'helix-before-activate',
|
|
93
|
+
'helix-graph-layout',
|
|
94
|
+
'helix-graph-pan',
|
|
95
|
+
'helix-graph-part-change',
|
|
96
|
+
'helix-graph-ready',
|
|
97
|
+
'helix-graph-zoom',
|
|
98
|
+
],
|
|
90
99
|
'helix-headless-heatmap': ['helix-resize'],
|
|
91
100
|
'helix-headless-image': ['error', 'load'],
|
|
92
101
|
'helix-headless-input': ['change', 'helix-before-change', 'input'],
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** One note in a graph. */
|
|
2
|
+
export interface GraphNode {
|
|
3
|
+
/** Unique in the graph, and what `active` and a link's ends name. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** What the note is called. Its `id` where it has none. */
|
|
6
|
+
label?: string | undefined;
|
|
7
|
+
/** A kind the note belongs to, such as a tag, which a renderer colors it by. */
|
|
8
|
+
group?: string | undefined;
|
|
9
|
+
/** How large the renderer draws it, relative to the others. */
|
|
10
|
+
size?: number | undefined;
|
|
11
|
+
/** Where the note stands, where the page already knows. Laid out where it does not. */
|
|
12
|
+
x?: number | undefined;
|
|
13
|
+
/** Where the note stands, where the page already knows. Laid out where it does not. */
|
|
14
|
+
y?: number | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** One link between two notes, from `source` to `target`. */
|
|
17
|
+
export interface GraphLink {
|
|
18
|
+
source: string;
|
|
19
|
+
target: string;
|
|
20
|
+
/** What the link says, such as "cites". */
|
|
21
|
+
label?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** Which notes each note links to and is linked from. */
|
|
24
|
+
export type Adjacency = Map<string, {
|
|
25
|
+
from: Set<string>;
|
|
26
|
+
to: Set<string>;
|
|
27
|
+
}>;
|
|
28
|
+
/** How a note in the list stands to the selected one. */
|
|
29
|
+
export type Relation = 'both' | 'from' | 'selected' | 'to';
|
|
30
|
+
/** One row of the list: a note, and how it stands to the selected one where it does. */
|
|
31
|
+
export interface Entry {
|
|
32
|
+
node: GraphNode;
|
|
33
|
+
relation?: Relation | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** A note's name, its `id` where it has no label. */
|
|
36
|
+
export declare const nameOf: (node: GraphNode) => string;
|
|
37
|
+
/**
|
|
38
|
+
* Which notes each note links to and is linked from, in one pass over the
|
|
39
|
+
* links. A link naming a note that is not in the graph is kept: the list
|
|
40
|
+
* shows notes and not links, so it does no harm, and a page adding the note a
|
|
41
|
+
* moment later finds its links already counted.
|
|
42
|
+
*/
|
|
43
|
+
export declare const adjacencyOf: (links: readonly GraphLink[]) => Adjacency;
|
|
44
|
+
/**
|
|
45
|
+
* The notes within `depth` links of `from`, whichever way each link runs, the
|
|
46
|
+
* note itself included: the local graph.
|
|
47
|
+
*
|
|
48
|
+
* **Both ways, as a reader thinks of a note's neighborhood**: a note that
|
|
49
|
+
* cites this one is as near to it as one this one cites.
|
|
50
|
+
*/
|
|
51
|
+
export declare const within: (adjacency: Adjacency, from: string, depth: number) => Set<string>;
|
|
52
|
+
/**
|
|
53
|
+
* The list's rows, in the order a reader wants them: the selected note, then
|
|
54
|
+
* the notes it links to and from, then every other note, each part in the
|
|
55
|
+
* order of its names, and only the notes `shown` holds and `query` matches.
|
|
56
|
+
*
|
|
57
|
+
* **The neighborhood first**, because it is what a reader came to the graph
|
|
58
|
+
* for and what a picture of it shows by its lines, which a list has to say in
|
|
59
|
+
* its order instead.
|
|
60
|
+
*/
|
|
61
|
+
export declare const entriesOf: (sorted: readonly GraphNode[], adjacency: Adjacency, active: string, query: string, shown?: ReadonlySet<string>) => Entry[];
|
|
62
|
+
/** The notes in the order of their names, as the page's language orders words. */
|
|
63
|
+
export declare const sortedOf: (nodes: readonly GraphNode[], lang?: string) => GraphNode[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export const nameOf = (node) => node.label || node.id;
|
|
2
|
+
export const adjacencyOf = (links) => {
|
|
3
|
+
const adjacency = new Map();
|
|
4
|
+
const at = (id) => {
|
|
5
|
+
let found = adjacency.get(id);
|
|
6
|
+
if (!found) {
|
|
7
|
+
found = { from: new Set(), to: new Set() };
|
|
8
|
+
adjacency.set(id, found);
|
|
9
|
+
}
|
|
10
|
+
return found;
|
|
11
|
+
};
|
|
12
|
+
for (const { source, target } of links) {
|
|
13
|
+
if (source === target) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
at(source).to.add(target);
|
|
17
|
+
at(target).from.add(source);
|
|
18
|
+
}
|
|
19
|
+
return adjacency;
|
|
20
|
+
};
|
|
21
|
+
export const within = (adjacency, from, depth) => {
|
|
22
|
+
const reached = new Set([from]);
|
|
23
|
+
let edge = [from];
|
|
24
|
+
for (let step = 0; step < depth && edge.length > 0; step++) {
|
|
25
|
+
const next = [];
|
|
26
|
+
for (const id of edge) {
|
|
27
|
+
const near = adjacency.get(id);
|
|
28
|
+
for (const one of [...(near?.to ?? []), ...(near?.from ?? [])]) {
|
|
29
|
+
if (!reached.has(one)) {
|
|
30
|
+
reached.add(one);
|
|
31
|
+
next.push(one);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
edge = next;
|
|
36
|
+
}
|
|
37
|
+
return reached;
|
|
38
|
+
};
|
|
39
|
+
export const entriesOf = (sorted, adjacency, active, query, shown) => {
|
|
40
|
+
const wanted = query.trim().toLocaleLowerCase();
|
|
41
|
+
const kept = (node) => (!shown || shown.has(node.id)) &&
|
|
42
|
+
(wanted === '' || nameOf(node).toLocaleLowerCase().includes(wanted));
|
|
43
|
+
const near = adjacency.get(active);
|
|
44
|
+
const relationOf = (id) => {
|
|
45
|
+
if (id === active) {
|
|
46
|
+
return 'selected';
|
|
47
|
+
}
|
|
48
|
+
const to = near?.to.has(id) === true;
|
|
49
|
+
const from = near?.from.has(id) === true;
|
|
50
|
+
return to && from ? 'both' : to ? 'to' : from ? 'from' : undefined;
|
|
51
|
+
};
|
|
52
|
+
const first = [];
|
|
53
|
+
const neighbors = [];
|
|
54
|
+
const rest = [];
|
|
55
|
+
for (const node of sorted) {
|
|
56
|
+
if (!kept(node)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const relation = relationOf(node.id);
|
|
60
|
+
if (relation === 'selected') {
|
|
61
|
+
first.push({ node, relation });
|
|
62
|
+
}
|
|
63
|
+
else if (relation) {
|
|
64
|
+
neighbors.push({ node, relation });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
rest.push({ node });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return [...first, ...neighbors, ...rest];
|
|
71
|
+
};
|
|
72
|
+
export const sortedOf = (nodes, lang) => {
|
|
73
|
+
const collator = new Intl.Collator(lang || undefined, { numeric: true, sensitivity: 'base' });
|
|
74
|
+
return [...nodes].sort((one, other) => collator.compare(nameOf(one), nameOf(other)));
|
|
75
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { HelixElement, type ViewportGestureLabels, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
import { type GraphLink, type GraphNode } from './graph-model.js';
|
|
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;
|
|
5
|
+
/**
|
|
6
|
+
* @summary A frame around a graph of notes drawn by another library, and the list that makes it readable.
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* Helix draws no graph. A force layout of thousands of notes is physics and
|
|
10
|
+
* WebGL, which a renderer such as Sigma.js does. Put the renderer's box in the
|
|
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
|
+
*
|
|
14
|
+
* What the frame adds is what a drawing of a graph cannot do: a list of every
|
|
15
|
+
* note beside it, which is the graph for a screen reader and a quick way to
|
|
16
|
+
* find a note for anyone. The selected note comes first, then the notes it
|
|
17
|
+
* links to and from, then every other note, and the search field narrows it.
|
|
18
|
+
* Selecting a note in the list or in the drawing is the same selection.
|
|
19
|
+
*
|
|
20
|
+
* Set `depth` to show the local graph: only the notes within that many links
|
|
21
|
+
* of the selected one.
|
|
22
|
+
*
|
|
23
|
+
* `nodes` and `links` are properties, never markup: a graph of ten thousand
|
|
24
|
+
* notes as ten thousand elements would cost what the renderer exists to save.
|
|
25
|
+
* The list draws only the rows in view.
|
|
26
|
+
*
|
|
27
|
+
* The list scrolls on this tier. It carries `data-scroller`, and `core` ships
|
|
28
|
+
* `[data-scroller] { overflow: auto }` into every shadow root. You still need
|
|
29
|
+
* to set a block size on the list, or it grows to hold every row.
|
|
30
|
+
*
|
|
31
|
+
* @since 0.116.0
|
|
32
|
+
* @status experimental
|
|
33
|
+
* @category media
|
|
34
|
+
* @aliases Knowledge graph, Network, Note graph, Second brain
|
|
35
|
+
* @documentation https://fusion.dev/helix/components/graph
|
|
36
|
+
*
|
|
37
|
+
* @slot - The renderer's box, which the drawing is made in.
|
|
38
|
+
* @slot filter-icon - The icon in the search field. Defaults to a magnifying glass.
|
|
39
|
+
* @slot footer - Content below the graph.
|
|
40
|
+
* @slot header - Content above the graph.
|
|
41
|
+
*
|
|
42
|
+
* @event {HelixActivateEvent} helix-activate - A note was selected, in the list or in the drawing. The detail's `value` is its `id`.
|
|
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 {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.
|
|
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.
|
|
48
|
+
* @event {HelixGraphZoomEvent} helix-graph-zoom - A zoom button or key was pressed. `connectGraph` zooms the drawing.
|
|
49
|
+
*
|
|
50
|
+
* @csspart after - The room the notes after those drawn would take, so the list scrolls its whole length.
|
|
51
|
+
* @csspart before - The room the notes before those drawn would take.
|
|
52
|
+
* @csspart body - The drawing beside the list, or above it where the frame is narrow.
|
|
53
|
+
* @csspart controls - The group the pan and zoom buttons sit in.
|
|
54
|
+
* @csspart count - How many notes the list holds, which a search narrows, at the end of the search bar.
|
|
55
|
+
* @csspart filter-icon - The icon beside the search field.
|
|
56
|
+
* @csspart filter-mark - The default icon beside the search field, shown when none is slotted.
|
|
57
|
+
* @csspart footer - The strip below the graph.
|
|
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.
|
|
61
|
+
* @csspart header - The strip above the graph.
|
|
62
|
+
* @csspart list - The list of notes, which draws only the rows in view.
|
|
63
|
+
* @csspart live - What screen readers hear when a search changes how many notes there are.
|
|
64
|
+
* @csspart note - One note in the list.
|
|
65
|
+
* @csspart note-cursor - The note the keyboard is on in the list.
|
|
66
|
+
* @csspart note-linked - A note linked to or from the selected one.
|
|
67
|
+
* @csspart note-name - A note's name in the list.
|
|
68
|
+
* @csspart note-relation - How a note stands to the selected one, such as "Linked from Alpha".
|
|
69
|
+
* @csspart note-selected - The selected note, first in the list.
|
|
70
|
+
* @csspart pan-down - The button that moves the graph down.
|
|
71
|
+
* @csspart pan-end - The button that moves the graph toward the end of a line of text: right in English.
|
|
72
|
+
* @csspart pan-start - The button that moves the graph toward the start of a line of text: left in English.
|
|
73
|
+
* @csspart pan-up - The button that moves the graph up.
|
|
74
|
+
* @csspart panel - The search field and the list, beside the drawing or below it.
|
|
75
|
+
* @csspart region - The frame: the drawing, its controls and the list.
|
|
76
|
+
* @csspart search - The bar holding the icon, the search field and the count.
|
|
77
|
+
* @csspart search-field - The field that finds a note by its name.
|
|
78
|
+
* @csspart stage - The drawing and its controls.
|
|
79
|
+
* @csspart viewport - The box the renderer draws in.
|
|
80
|
+
* @csspart zoom-in - The zoom in button.
|
|
81
|
+
* @csspart zoom-out - The zoom out button.
|
|
82
|
+
*
|
|
83
|
+
* @cssstate fullscreen - The graph fills the screen.
|
|
84
|
+
* @cssstate idle - The user has been still long enough for the header and footer to fade.
|
|
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.
|
|
88
|
+
*/
|
|
89
|
+
export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
90
|
+
/** What the list says of a note's count, with `{count}`. */
|
|
91
|
+
countLabel: string;
|
|
92
|
+
/**
|
|
93
|
+
* How many links from the selected note to show, for its local graph. Unset
|
|
94
|
+
* shows every note. The list holds what the drawing shows.
|
|
95
|
+
*/
|
|
96
|
+
depth?: number;
|
|
97
|
+
/**
|
|
98
|
+
* The graph's name, read by screen readers, such as "Research notes".
|
|
99
|
+
* Required.
|
|
100
|
+
*/
|
|
101
|
+
label: string;
|
|
102
|
+
/** How a note linked both to and from the selected one is described, with `{note}`. */
|
|
103
|
+
linkedBothLabel: string;
|
|
104
|
+
/** How a note the selected one links to is described, with `{note}`, the selected note's name. */
|
|
105
|
+
linkedFromLabel: string;
|
|
106
|
+
/** The links between notes, each from `source` to `target`. A property, never an attribute. */
|
|
107
|
+
links: readonly GraphLink[];
|
|
108
|
+
/** How a note that links to the selected one is described, with `{note}`. */
|
|
109
|
+
linksToLabel: string;
|
|
110
|
+
/** The notes. A property, never an attribute. */
|
|
111
|
+
nodes: readonly GraphNode[];
|
|
112
|
+
/** The list's name, read by screen readers. */
|
|
113
|
+
notesLabel: string;
|
|
114
|
+
/** The search field's name. */
|
|
115
|
+
searchLabel: string;
|
|
116
|
+
/** How the selected note is described in the list. */
|
|
117
|
+
selectedLabel: string;
|
|
118
|
+
/** What the search field holds. */
|
|
119
|
+
private query;
|
|
120
|
+
/** The row the keyboard is on, as an index into the list. */
|
|
121
|
+
private cursor;
|
|
122
|
+
/** Which notes link to and from each, read again when `links` changes. */
|
|
123
|
+
private adjacency;
|
|
124
|
+
/** The notes in the order of their names, read again when `nodes` changes. */
|
|
125
|
+
private sorted;
|
|
126
|
+
/** The list's rows, read again when anything they come from changes. */
|
|
127
|
+
private entries;
|
|
128
|
+
/** The notes the local graph keeps, or every note where there is no `depth`. */
|
|
129
|
+
private kept;
|
|
130
|
+
/** Whether the graph has been drawn whole, which `drawn()` says. */
|
|
131
|
+
private whole;
|
|
132
|
+
/** How many notes there were when the count was last said. */
|
|
133
|
+
private said;
|
|
134
|
+
private readonly virtualize;
|
|
135
|
+
/**
|
|
136
|
+
* @internal The notes the drawing shows, which `connectGraph` reads: those
|
|
137
|
+
* within `depth` of the selected note, or `undefined` for every note.
|
|
138
|
+
*/
|
|
139
|
+
get shown(): ReadonlySet<string> | undefined;
|
|
140
|
+
/** Whether the graph has been drawn whole. For code that runs after `helix-graph-ready`. */
|
|
141
|
+
get ready(): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Says the graph has been drawn whole, or with `false`, that it no longer
|
|
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
|
|
146
|
+
* the graph was not drawn sends `helix-graph-ready` and turns on
|
|
147
|
+
* `:state(ready)`.
|
|
148
|
+
*/
|
|
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;
|
|
160
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
161
|
+
protected updated(changed: PropertyValues): void;
|
|
162
|
+
protected panEvent(detail: ViewportPanDetail): Event;
|
|
163
|
+
protected zoomEvent(detail: ViewportZoomDetail): Event;
|
|
164
|
+
protected get restingControls(): string;
|
|
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;
|
|
170
|
+
/** How many notes the list holds, in the page's numbers. */
|
|
171
|
+
private countText;
|
|
172
|
+
/** How a row stands to the selected note, in words, or nothing where it does not. */
|
|
173
|
+
private relationText;
|
|
174
|
+
/** Selects the note a row names, through the request a page can refuse. */
|
|
175
|
+
private choose;
|
|
176
|
+
/**
|
|
177
|
+
* Moves the keyboard to a row, and the list to show it.
|
|
178
|
+
*
|
|
179
|
+
* **Scrolled by the row's own box where it is drawn, and by the estimate
|
|
180
|
+
* where it is not**, so a jump to the end of ten thousand notes lands there
|
|
181
|
+
* and the row is drawn by the update the scroll asks for.
|
|
182
|
+
*/
|
|
183
|
+
private moveTo;
|
|
184
|
+
/**
|
|
185
|
+
* The keys in the list. **Kept from the frame**, whose arrows pan the
|
|
186
|
+
* drawing: a reader moving through the list was moving the graph under it.
|
|
187
|
+
*/
|
|
188
|
+
private readonly handleListKeydown;
|
|
189
|
+
/**
|
|
190
|
+
* The search field's keys, which belong to the field and never pan the
|
|
191
|
+
* graph. Escape empties a search that has words in it, and passes through
|
|
192
|
+
* an empty one to whatever the page does with it.
|
|
193
|
+
*/
|
|
194
|
+
private readonly handleSearchKeydown;
|
|
195
|
+
private readonly handleSearch;
|
|
196
|
+
/**
|
|
197
|
+
* The mark in the search field, behind a seam: a slot for the page, and a
|
|
198
|
+
* method for the tier above, as the listbox's filter has.
|
|
199
|
+
*/
|
|
200
|
+
protected renderFilterIcon(): TemplateResult;
|
|
201
|
+
private renderRows;
|
|
202
|
+
protected render(): TemplateResult;
|
|
203
|
+
}
|
|
204
|
+
declare global {
|
|
205
|
+
interface HTMLElementTagNameMap {
|
|
206
|
+
'helix-headless-graph': HelixHeadlessGraph;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
export {};
|