@fusion.dev/helix-headless 0.104.0 → 0.105.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 +4401 -1255
- package/dist/canvas/root/canvas-root.d.ts +12 -0
- package/dist/canvas/root/canvas-root.js +20 -3
- package/dist/color-input/root/color-input-root.d.ts +10 -0
- package/dist/color-input/root/color-input-root.js +3 -0
- package/dist/color-picker/root/color-picker-root.d.ts +12 -0
- package/dist/color-picker/root/color-picker-root.js +4 -0
- package/dist/command/root/command-root.d.ts +5 -0
- package/dist/command/root/command-root.js +1 -0
- package/dist/element-events.generated.js +12 -1
- package/dist/map/area/map-area.d.ts +42 -0
- package/dist/map/area/map-area.js +37 -0
- package/dist/map/index.d.ts +7 -0
- package/dist/map/index.js +5 -0
- package/dist/map/marker/map-marker.d.ts +113 -0
- package/dist/map/marker/map-marker.js +97 -0
- package/dist/map/points/map-points.d.ts +133 -0
- package/dist/map/points/map-points.js +158 -0
- package/dist/map/position/map-position.d.ts +70 -0
- package/dist/map/position/map-position.js +89 -0
- package/dist/map/root/map-root.d.ts +109 -54
- package/dist/map/root/map-root.js +124 -4
- package/dist/map/route/map-route.d.ts +67 -0
- package/dist/map/route/map-route.js +49 -0
- package/package.json +5 -5
- package/types/jsx.d.ts +3921 -2736
- package/types/svelte.d.ts +5 -0
- package/types/vue.d.ts +710 -472
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, HelixActivateEvent, HelixElement, HelixMapClusterEvent, HelixMapPartChangeEvent, isRtl, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
11
|
+
let HelixHeadlessMapPoints = class HelixHeadlessMapPoints extends HelixElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.cluster = false;
|
|
15
|
+
this.countLabel = '{count} places';
|
|
16
|
+
this.isMapLayer = true;
|
|
17
|
+
this.layerKind = 'points';
|
|
18
|
+
this.nameKey = 'name';
|
|
19
|
+
this.walk = [];
|
|
20
|
+
this.handleKeydown = (event) => {
|
|
21
|
+
const key = event.composedPath()[0]?.dataset?.key;
|
|
22
|
+
const at = this.walk.findIndex((one) => one.key === key);
|
|
23
|
+
const here = this.walk[at];
|
|
24
|
+
if (!here) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const forward = isRtl(this) ? 'ArrowLeft' : 'ArrowRight';
|
|
28
|
+
const back = isRtl(this) ? 'ArrowRight' : 'ArrowLeft';
|
|
29
|
+
const last = this.walk.length - 1;
|
|
30
|
+
const to = event.key === forward || event.key === 'ArrowDown'
|
|
31
|
+
? Math.min(at + 1, last)
|
|
32
|
+
: event.key === back || event.key === 'ArrowUp'
|
|
33
|
+
? Math.max(at - 1, 0)
|
|
34
|
+
: event.key === 'Home'
|
|
35
|
+
? 0
|
|
36
|
+
: event.key === 'End'
|
|
37
|
+
? last
|
|
38
|
+
: undefined;
|
|
39
|
+
if (to !== undefined) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
this.reach(this.walk[to]);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
if (event.key === 'Enter' && !event.repeat) {
|
|
47
|
+
this.press(here);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
this.handleKeyup = (event) => {
|
|
52
|
+
const key = event.composedPath()[0]?.dataset?.key;
|
|
53
|
+
const here = this.walk.find((one) => one.key === key);
|
|
54
|
+
if (here && event.key === ' ') {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
this.press(here);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.handleFocusin = (event) => {
|
|
60
|
+
const key = event.composedPath()[0]?.dataset?.key;
|
|
61
|
+
if (key !== undefined) {
|
|
62
|
+
this.stop = key;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
nameOf(one) {
|
|
67
|
+
if (one.count !== undefined) {
|
|
68
|
+
const lang = this.closest('[lang]')?.getAttribute('lang') || undefined;
|
|
69
|
+
return this.countLabel.replace('{count}', new Intl.NumberFormat(lang).format(one.count));
|
|
70
|
+
}
|
|
71
|
+
return one.label || one.value || '';
|
|
72
|
+
}
|
|
73
|
+
buttonOf(key) {
|
|
74
|
+
return key === undefined
|
|
75
|
+
? null
|
|
76
|
+
: (this.renderRoot.querySelector(`[data-key="${CSS.escape(key)}"]`) ?? null);
|
|
77
|
+
}
|
|
78
|
+
reach(one) {
|
|
79
|
+
if (!one) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.stop = one.key;
|
|
83
|
+
void this.updateComplete.then(() => this.buttonOf(one.key)?.focus());
|
|
84
|
+
}
|
|
85
|
+
press(one) {
|
|
86
|
+
if (one.count !== undefined) {
|
|
87
|
+
this.dispatchEvent(new HelixMapClusterEvent({ key: one.key, labels: [] }));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.dispatchEvent(new HelixActivateEvent({ value: one.value || one.label || '' }));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
willUpdate(changed) {
|
|
94
|
+
super.willUpdate(changed);
|
|
95
|
+
if (changed.has('walk')) {
|
|
96
|
+
const key = this.shadowRoot?.activeElement?.dataset?.key;
|
|
97
|
+
const was = changed.get('walk') ?? [];
|
|
98
|
+
this.held = was.find((one) => one.key === key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
updated(changed) {
|
|
102
|
+
super.updated(changed);
|
|
103
|
+
const held = this.held;
|
|
104
|
+
this.held = undefined;
|
|
105
|
+
if (held && !this.walk.some((one) => one.key === held.key)) {
|
|
106
|
+
const nearest = [...this.walk].sort((a, b) => Math.hypot(a.x - held.x, a.y - held.y) - Math.hypot(b.x - held.x, b.y - held.y))[0];
|
|
107
|
+
this.reach(nearest);
|
|
108
|
+
}
|
|
109
|
+
if ([...changed.keys()].some((key) => key !== 'walk' && key !== 'stop')) {
|
|
110
|
+
this.dispatchEvent(new HelixMapPartChangeEvent({ kind: 'layer' }));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
render() {
|
|
114
|
+
if (this.walk.length === 0) {
|
|
115
|
+
return nothing;
|
|
116
|
+
}
|
|
117
|
+
const stop = this.walk.some((one) => one.key === this.stop) ? this.stop : this.walk[0]?.key;
|
|
118
|
+
return html `<span part="places" role="group" aria-label=${this.label ?? ''} @focusin=${this.handleFocusin} @keydown=${this.handleKeydown} @keyup=${this.handleKeyup}>${repeat(this.walk, (one) => one.key, (one) => {
|
|
119
|
+
const tabindex = one.key === stop ? '0' : '-1';
|
|
120
|
+
const at = `--_map-place-x: ${one.x}px; --_map-place-y: ${one.y}px`;
|
|
121
|
+
const name = html `<span part="label">${this.nameOf(one)}</span>`;
|
|
122
|
+
return one.count === undefined
|
|
123
|
+
? html `<span part="place" role="button" data-key=${one.key} tabindex=${tabindex} style=${at}>${name}</span>`
|
|
124
|
+
: html `<span part="place count" role="button" data-key=${one.key} tabindex=${tabindex} style=${at}>${name}</span>`;
|
|
125
|
+
})}</span>`;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
__decorate([
|
|
129
|
+
property({ type: Boolean })
|
|
130
|
+
], HelixHeadlessMapPoints.prototype, "cluster", void 0);
|
|
131
|
+
__decorate([
|
|
132
|
+
property({ attribute: 'count-label' })
|
|
133
|
+
], HelixHeadlessMapPoints.prototype, "countLabel", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
property({ attribute: false })
|
|
136
|
+
], HelixHeadlessMapPoints.prototype, "data", void 0);
|
|
137
|
+
__decorate([
|
|
138
|
+
property()
|
|
139
|
+
], HelixHeadlessMapPoints.prototype, "description", void 0);
|
|
140
|
+
__decorate([
|
|
141
|
+
property()
|
|
142
|
+
], HelixHeadlessMapPoints.prototype, "label", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
property({ attribute: 'name-key' })
|
|
145
|
+
], HelixHeadlessMapPoints.prototype, "nameKey", void 0);
|
|
146
|
+
__decorate([
|
|
147
|
+
property()
|
|
148
|
+
], HelixHeadlessMapPoints.prototype, "src", void 0);
|
|
149
|
+
__decorate([
|
|
150
|
+
state()
|
|
151
|
+
], HelixHeadlessMapPoints.prototype, "walk", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
state()
|
|
154
|
+
], HelixHeadlessMapPoints.prototype, "stop", void 0);
|
|
155
|
+
HelixHeadlessMapPoints = __decorate([
|
|
156
|
+
customElement('helix-headless-map-points')
|
|
157
|
+
], HelixHeadlessMapPoints);
|
|
158
|
+
export { HelixHeadlessMapPoints };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary A moving point on a map, such as a vehicle or a person.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* `lat` and `lng` set where it is, `heading` points it in a direction, in
|
|
8
|
+
* degrees clockwise from north, and `accuracy` draws a ring with a radius of
|
|
9
|
+
* that many meters. `connectMap` positions it and resizes the ring as the map
|
|
10
|
+
* zooms.
|
|
11
|
+
*
|
|
12
|
+
* Screen readers announce its `description` when it changes, at most once
|
|
13
|
+
* every `announce-every` milliseconds. Its movement is not announced. Set the
|
|
14
|
+
* description when something worth hearing happens, such as "Two stops away".
|
|
15
|
+
*
|
|
16
|
+
* @since 0.105.0
|
|
17
|
+
* @status experimental
|
|
18
|
+
* @category media
|
|
19
|
+
* @aliases Current location, Live position, Tracker, You are here
|
|
20
|
+
* @documentation https://fusion.dev/helix/components/map
|
|
21
|
+
*
|
|
22
|
+
* @event {HelixMapPartChangeEvent} helix-map-part-change - It moved, turned, or its accuracy changed. Used by `connectMap`; pages do not need to listen for it.
|
|
23
|
+
*
|
|
24
|
+
* @csspart accuracy - The ring that shows how accurate the position is.
|
|
25
|
+
* @csspart arrow - The arrow shown when the position has a heading.
|
|
26
|
+
* @csspart dot - The point shown when the position has no heading.
|
|
27
|
+
* @csspart heading - The cone that shows its direction.
|
|
28
|
+
* @csspart position - The image of the position, named by its label.
|
|
29
|
+
* @csspart pulse - A ring that spreads out from the point, showing that the position is live.
|
|
30
|
+
* @csspart status - The description, announced when it changes.
|
|
31
|
+
*/
|
|
32
|
+
export declare class HelixHeadlessMapPosition extends HelixElement {
|
|
33
|
+
/** How accurate the position is, in meters. Drawn as a ring with this radius. */
|
|
34
|
+
accuracy?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The least time between announcements, in milliseconds. A change during the
|
|
37
|
+
* wait is announced when the wait ends.
|
|
38
|
+
*/
|
|
39
|
+
announceEvery: number;
|
|
40
|
+
/** What screen readers announce when it changes, such as "Two stops away". */
|
|
41
|
+
description?: string;
|
|
42
|
+
/** The direction it faces, in degrees clockwise from north. Shows an arrow. */
|
|
43
|
+
heading?: number;
|
|
44
|
+
/** Marks this as a position for the connector, whatever its tag. */
|
|
45
|
+
readonly isMapPosition = true;
|
|
46
|
+
/** What it is, such as "Van 12". Read by screen readers. */
|
|
47
|
+
label?: string;
|
|
48
|
+
/** Latitude, in degrees. */
|
|
49
|
+
lat?: number;
|
|
50
|
+
/** Longitude, in degrees. */
|
|
51
|
+
lng?: number;
|
|
52
|
+
/** The words last spoken, which is what the status holds. */
|
|
53
|
+
private spoken;
|
|
54
|
+
/** When they were spoken, for the interval. */
|
|
55
|
+
private spokenAt;
|
|
56
|
+
/** The latest words, waiting out the interval. */
|
|
57
|
+
private waiting;
|
|
58
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
59
|
+
/** Tells the connector it moved, turned or grew less sure: not what it said, which is its own. */
|
|
60
|
+
protected updated(changed: PropertyValues): void;
|
|
61
|
+
/** Puts the latest words in the status, which is what makes them heard. */
|
|
62
|
+
private speak;
|
|
63
|
+
disconnectedCallback(): void;
|
|
64
|
+
protected render(): TemplateResult;
|
|
65
|
+
}
|
|
66
|
+
declare global {
|
|
67
|
+
interface HTMLElementTagNameMap {
|
|
68
|
+
'helix-headless-map-position': HelixHeadlessMapPosition;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, HelixElement, HelixMapPartChangeEvent } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html } from 'lit';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
|
+
let HelixHeadlessMapPosition = class HelixHeadlessMapPosition extends HelixElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.announceEvery = 5000;
|
|
14
|
+
this.isMapPosition = true;
|
|
15
|
+
this.spoken = '';
|
|
16
|
+
this.spokenAt = Number.NEGATIVE_INFINITY;
|
|
17
|
+
}
|
|
18
|
+
willUpdate(changed) {
|
|
19
|
+
super.willUpdate(changed);
|
|
20
|
+
if (!changed.has('description') || !this.hasUpdated) {
|
|
21
|
+
if (!this.hasUpdated) {
|
|
22
|
+
this.spoken = this.description ?? '';
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const wait = this.spokenAt + this.announceEvery - Date.now();
|
|
27
|
+
if (wait <= 0) {
|
|
28
|
+
this.speak();
|
|
29
|
+
}
|
|
30
|
+
else if (this.waiting === undefined) {
|
|
31
|
+
this.waiting = setTimeout(() => this.speak(), wait);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
updated(changed) {
|
|
35
|
+
super.updated(changed);
|
|
36
|
+
if ([...changed.keys()].some((key) => key !== 'spoken' && key !== 'announceEvery')) {
|
|
37
|
+
this.dispatchEvent(new HelixMapPartChangeEvent({ kind: 'place' }));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
speak() {
|
|
41
|
+
clearTimeout(this.waiting);
|
|
42
|
+
this.waiting = undefined;
|
|
43
|
+
this.spokenAt = Date.now();
|
|
44
|
+
this.spoken = this.description ?? '';
|
|
45
|
+
}
|
|
46
|
+
disconnectedCallback() {
|
|
47
|
+
super.disconnectedCallback();
|
|
48
|
+
clearTimeout(this.waiting);
|
|
49
|
+
this.waiting = undefined;
|
|
50
|
+
}
|
|
51
|
+
render() {
|
|
52
|
+
return html `<span part="position" role="img" aria-label=${this.label ?? ''}>
|
|
53
|
+
<span part="accuracy"></span>
|
|
54
|
+
<span part="heading"></span>
|
|
55
|
+
<span part="pulse"></span>
|
|
56
|
+
<span part="dot"></span>
|
|
57
|
+
<svg part="arrow" viewBox="0 0 24 24"><path d="M12 2.5 20.5 20.5 12 16.5 3.5 20.5Z"></path></svg>
|
|
58
|
+
</span>
|
|
59
|
+
<span part="status" role="status">${this.spoken}</span>`;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
__decorate([
|
|
63
|
+
property({ type: Number })
|
|
64
|
+
], HelixHeadlessMapPosition.prototype, "accuracy", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
property({ attribute: 'announce-every', type: Number })
|
|
67
|
+
], HelixHeadlessMapPosition.prototype, "announceEvery", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
property()
|
|
70
|
+
], HelixHeadlessMapPosition.prototype, "description", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
property({ reflect: true, type: Number })
|
|
73
|
+
], HelixHeadlessMapPosition.prototype, "heading", void 0);
|
|
74
|
+
__decorate([
|
|
75
|
+
property()
|
|
76
|
+
], HelixHeadlessMapPosition.prototype, "label", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
property({ type: Number })
|
|
79
|
+
], HelixHeadlessMapPosition.prototype, "lat", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
property({ type: Number })
|
|
82
|
+
], HelixHeadlessMapPosition.prototype, "lng", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
state()
|
|
85
|
+
], HelixHeadlessMapPosition.prototype, "spoken", void 0);
|
|
86
|
+
HelixHeadlessMapPosition = __decorate([
|
|
87
|
+
customElement('helix-headless-map-position')
|
|
88
|
+
], HelixHeadlessMapPosition);
|
|
89
|
+
export { HelixHeadlessMapPosition };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HelixElement, type ViewportControlsPlacement, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
1
|
+
import { HelixElement, KeyboardNavigationController, type ViewportControlsPlacement, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* What `ViewportControlsPlacement` is called for a map.
|
|
5
5
|
*
|
|
@@ -9,32 +9,19 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
9
9
|
export type MapControlsPlacement = ViewportControlsPlacement;
|
|
10
10
|
declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.dev/helix-core").ViewportElement) & typeof HelixElement;
|
|
11
11
|
/**
|
|
12
|
-
* @summary A frame around
|
|
12
|
+
* @summary A frame around a map drawn by another library.
|
|
13
13
|
*
|
|
14
14
|
* @description
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* their map and this owns the box, the name, the controls and the way out,
|
|
19
|
-
* which is the shape `VideoPlaylist` uses for a player it never renders.
|
|
15
|
+
* Wraps a map drawn by MapLibre, Leaflet, or another renderer. The frame adds
|
|
16
|
+
* a name for the map, pan and zoom buttons, a fullscreen button, and a strip
|
|
17
|
+
* for the map credit. Helix does not draw the map itself.
|
|
20
18
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* using a screen reader does not walk past it so much as never meet it. A named
|
|
25
|
-
* region with controls in it is the whole of the difference.
|
|
19
|
+
* The pan and zoom buttons and the arrow keys send `helix-map-pan` and
|
|
20
|
+
* `helix-map-zoom`. Move your map in response, or connect it with
|
|
21
|
+
* `connectMap` from `@fusion.dev/helix-map`, which does this for you.
|
|
26
22
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* ours to decide: macOS passes them through, Windows readers hold them for
|
|
30
|
-
* their own reading mode unless a page takes `role="application"`, which costs
|
|
31
|
-
* the reader their normal way of reading everything else in the frame. A button
|
|
32
|
-
* is findable and operable in every screen reader on every platform without
|
|
33
|
-
* that bargain, so panning and zooming are buttons first and keys second.
|
|
34
|
-
*
|
|
35
|
-
* **Nothing here moves the map.** Both controls ask, through `helix-map-pan`
|
|
36
|
-
* and `helix-map-zoom`, and the consumer answers against whatever they slotted.
|
|
37
|
-
* A frame that moved the map would have to know whose map it was.
|
|
23
|
+
* Markers, routes, areas, live positions, and points layers go inside the
|
|
24
|
+
* frame as child elements.
|
|
38
25
|
*
|
|
39
26
|
* @since 0.100.0
|
|
40
27
|
* @status experimental
|
|
@@ -42,47 +29,100 @@ declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.de
|
|
|
42
29
|
* @aliases Map frame, Map container, Geo
|
|
43
30
|
* @documentation https://fusion.dev/helix/components/map
|
|
44
31
|
*
|
|
45
|
-
* @slot - The map,
|
|
46
|
-
* @slot attribution -
|
|
47
|
-
* @slot footer -
|
|
48
|
-
* @slot header -
|
|
32
|
+
* @slot - The element your renderer draws the map in, and the map's markers, routes, areas, positions, and points layers.
|
|
33
|
+
* @slot attribution - The map credit, which most tile licenses require.
|
|
34
|
+
* @slot footer - Content below the map, such as a legend or a scale.
|
|
35
|
+
* @slot header - Content above the map, such as a title or a search field.
|
|
49
36
|
*
|
|
50
|
-
* @event {
|
|
51
|
-
* @event {
|
|
37
|
+
* @event {HelixActivateEvent} helix-activate - A marker was pressed. The value is the marker's `name`, or its `label` if it has no name. A cluster sends `helix-map-cluster` instead.
|
|
38
|
+
* @event {HelixMapClusterEvent} helix-map-cluster - A cluster was pressed. Sent from the marker that shows the cluster, with the names of its places.
|
|
39
|
+
* @event {HelixMapPanEvent} helix-map-pan - A pan button or arrow key was pressed. Move your map in response.
|
|
40
|
+
* @event {HelixMapPartChangeEvent} helix-map-part-change - Clustering was turned on or off. Used by `connectMap`; pages do not need to listen for it.
|
|
41
|
+
* @event {HelixMapZoomEvent} helix-map-zoom - A zoom button or key was pressed, with a direction. Zoom your map in response.
|
|
52
42
|
*
|
|
53
|
-
* @csspart attribution - The strip the
|
|
54
|
-
* @csspart controls - The group
|
|
55
|
-
* @csspart footer - The strip below the map
|
|
56
|
-
* @csspart fullscreen - The button that
|
|
57
|
-
* @csspart header - The strip above the map
|
|
58
|
-
* @csspart
|
|
59
|
-
* @csspart
|
|
60
|
-
* @csspart pan-
|
|
61
|
-
* @csspart pan-
|
|
62
|
-
* @csspart
|
|
43
|
+
* @csspart attribution - The strip under the map that holds the credit.
|
|
44
|
+
* @csspart controls - The group of pan and zoom buttons.
|
|
45
|
+
* @csspart footer - The strip below the map.
|
|
46
|
+
* @csspart fullscreen - The button that makes the map fill the screen.
|
|
47
|
+
* @csspart header - The strip above the map.
|
|
48
|
+
* @csspart layer - One entry in the list of routes, areas, and points layers.
|
|
49
|
+
* @csspart layers - The list of routes, areas, and points layers, read by screen readers.
|
|
50
|
+
* @csspart pan-down - The button that pans the map down.
|
|
51
|
+
* @csspart pan-end - The button that pans toward the end of a line of text: right in English.
|
|
52
|
+
* @csspart pan-start - The button that pans toward the start of a line of text: left in English.
|
|
53
|
+
* @csspart pan-up - The button that pans the map up.
|
|
54
|
+
* @csspart region - The named region the map sits in.
|
|
63
55
|
* @csspart viewport - The box the map is drawn in.
|
|
64
56
|
* @csspart zoom-in - The button that zooms in.
|
|
65
57
|
* @csspart zoom-out - The button that zooms out.
|
|
66
58
|
*
|
|
67
|
-
* @cssstate fullscreen -
|
|
68
|
-
* @cssstate idle -
|
|
59
|
+
* @cssstate fullscreen - The map fills the screen.
|
|
60
|
+
* @cssstate idle - The user has been still long enough for the header and footer to fade.
|
|
69
61
|
*/
|
|
70
62
|
export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
|
|
71
63
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* are configured: the listener is on the region, and without a stop of its own
|
|
80
|
-
* a frame at `controls="none"` around a map with nothing focusable in it had
|
|
81
|
-
* arrow keys no reader could ever press. `aria-keyshortcuts` says which keys
|
|
82
|
-
* rather than spelling them into the name, which would otherwise be read out
|
|
83
|
-
* at every encounter.
|
|
64
|
+
* Combines markers that would overlap into one count. Counts split apart as
|
|
65
|
+
* the map zooms in, and pressing one zooms in to its places.
|
|
66
|
+
*/
|
|
67
|
+
cluster: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* The map's name, read by screen readers. Name the place, such as "Delivery
|
|
70
|
+
* area", so that several maps on one page can be told apart. Required.
|
|
84
71
|
*/
|
|
85
72
|
label: string;
|
|
73
|
+
/**
|
|
74
|
+
* The name of the list of routes, areas, and points layers, read by screen
|
|
75
|
+
* readers.
|
|
76
|
+
*/
|
|
77
|
+
layersLabel: string;
|
|
78
|
+
/**
|
|
79
|
+
* The routes and areas among the frame's children, in the order they are
|
|
80
|
+
* written, which is the order the list names them in.
|
|
81
|
+
*/
|
|
82
|
+
private get layers();
|
|
83
|
+
/**
|
|
84
|
+
* A route or area renamed, or its description changed, which the list says
|
|
85
|
+
* and a slot change does not report.
|
|
86
|
+
*/
|
|
87
|
+
private readonly handlePartChange;
|
|
88
|
+
/**
|
|
89
|
+
* The markers among the frame's children, in the order they are written,
|
|
90
|
+
* which is the order the arrow keys walk them in.
|
|
91
|
+
*/
|
|
92
|
+
private get markers();
|
|
93
|
+
/**
|
|
94
|
+
* The marker the map's one tab stop is on, by position among the markers:
|
|
95
|
+
* the one a reader last reached, and the first before they have reached any.
|
|
96
|
+
*/
|
|
97
|
+
private stop;
|
|
98
|
+
protected readonly keys: KeyboardNavigationController;
|
|
99
|
+
/** The marker a press or a click came from, where it came from one. */
|
|
100
|
+
private markerOf;
|
|
101
|
+
/** Moves the tab stop to the marker focus arrived at. */
|
|
102
|
+
private readonly handleFocusIn;
|
|
103
|
+
/**
|
|
104
|
+
* Says a marker was pressed, by click, Enter or Space: a place by its name,
|
|
105
|
+
* and a cluster as a cluster, from the marker it is drawn as.
|
|
106
|
+
*/
|
|
107
|
+
private activate;
|
|
108
|
+
private readonly handleClick;
|
|
109
|
+
/**
|
|
110
|
+
* **Enter on the press and Space on the release**, as a native button
|
|
111
|
+
* takes them, and a key held down says it once: auto-repeat sent a travel
|
|
112
|
+
* thirty times a second, each restarting the last.
|
|
113
|
+
*/
|
|
114
|
+
private readonly handleMarkerKeydown;
|
|
115
|
+
private readonly handleMarkerKeyup;
|
|
116
|
+
/** A marker added or taken away is a walk of a different length. */
|
|
117
|
+
private readonly handleSlotChange;
|
|
118
|
+
connectedCallback(): void;
|
|
119
|
+
disconnectedCallback(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Puts the tab stop on one marker and takes it off the rest, the roving
|
|
122
|
+
* pattern the toolbar uses: every marker at `-1` is a map whose places the
|
|
123
|
+
* keyboard cannot reach, and every one at `0` is a Tab press per place.
|
|
124
|
+
*/
|
|
125
|
+
protected updated(changed: PropertyValues): void;
|
|
86
126
|
/** The events this family names, the surface naming none of its own. */
|
|
87
127
|
protected panEvent(detail: ViewportPanDetail): Event;
|
|
88
128
|
protected zoomEvent(detail: ViewportZoomDetail): Event;
|
|
@@ -95,6 +135,21 @@ export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
|
|
|
95
135
|
*/
|
|
96
136
|
protected get restingControlsLabel(): string;
|
|
97
137
|
protected willUpdate(changed: PropertyValues): void;
|
|
138
|
+
/**
|
|
139
|
+
* The routes and areas, named, for a reader who cannot see the map.
|
|
140
|
+
*
|
|
141
|
+
* **What the renderer draws is a picture to a screen reader**, so a route
|
|
142
|
+
* from the depot or a delivery zone is not on the page at all until this
|
|
143
|
+
* says it is. A list rather than a live region, because the reader should
|
|
144
|
+
* find it when they come to the map rather than be told about it as it
|
|
145
|
+
* changes. Nothing where there are none, so a map with only markers says
|
|
146
|
+
* no more than it did.
|
|
147
|
+
*
|
|
148
|
+
* **Written once the frame knows its children**, which is in the browser:
|
|
149
|
+
* the server renders the frame before it has any, and a route is only on
|
|
150
|
+
* the page once a renderer has drawn it, which is later still.
|
|
151
|
+
*/
|
|
152
|
+
protected renderLayers(): TemplateResult | typeof nothing;
|
|
98
153
|
/**
|
|
99
154
|
* The frame, with each region in a box of its own.
|
|
100
155
|
*
|