@fusion.dev/helix-headless 0.103.2 → 0.104.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 +9259 -712
- package/dist/announcement/root/announcement-root.d.ts +9 -2
- package/dist/announcement/root/announcement-root.js +9 -6
- package/dist/badge/root/badge-root.js +2 -3
- package/dist/canvas/edge/canvas-edge.d.ts +112 -0
- package/dist/canvas/edge/canvas-edge.js +66 -0
- package/dist/canvas/index.d.ts +4 -0
- package/dist/canvas/index.js +3 -0
- package/dist/canvas/node/canvas-node.d.ts +211 -0
- package/dist/canvas/node/canvas-node.js +148 -0
- package/dist/canvas/root/canvas-document.d.ts +215 -0
- package/dist/canvas/root/canvas-document.js +284 -0
- package/dist/canvas/root/canvas-root.d.ts +912 -0
- package/dist/canvas/root/canvas-root.js +1814 -0
- package/dist/carousel/root/carousel-root.d.ts +53 -16
- package/dist/carousel/root/carousel-root.js +46 -11
- package/dist/chat/root/chat-root.d.ts +4 -0
- package/dist/chat/root/chat-root.js +11 -7
- package/dist/checkbox/root/checkbox-root.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +10 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +5 -0
- package/dist/color-input/root/color-input-root.js +21 -5
- package/dist/color-picker/root/color-picker-root.d.ts +55 -0
- package/dist/color-picker/root/color-picker-root.js +61 -12
- package/dist/combobox/root/combobox-root.d.ts +21 -2
- package/dist/combobox/root/combobox-root.js +23 -9
- package/dist/command/root/command-root.d.ts +1 -0
- package/dist/command/root/command-root.js +1 -1
- package/dist/data-table/root/data-table-root.d.ts +43 -42
- package/dist/data-table/root/data-table-root.js +35 -34
- package/dist/date-input/root/date-input-root.d.ts +27 -0
- package/dist/date-input/root/date-input-root.js +38 -9
- package/dist/date-picker/root/date-picker-root.d.ts +28 -16
- package/dist/date-picker/root/date-picker-root.js +17 -15
- package/dist/drilldown/root/drilldown-root.d.ts +1 -0
- package/dist/drilldown/root/drilldown-root.js +5 -2
- package/dist/element-events.generated.js +15 -0
- package/dist/empty/root/empty-root.d.ts +12 -7
- package/dist/empty/root/empty-root.js +13 -10
- package/dist/file-input/root/file-input-root.d.ts +5 -1
- package/dist/file-input/root/file-input-root.js +6 -4
- package/dist/filter-input/menu/filter-menu.d.ts +1 -0
- package/dist/filter-input/menu/filter-menu.js +1 -1
- package/dist/filter-input/root/filter-input-root.js +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/input/root/input-root.js +1 -1
- package/dist/lightbox/root/lightbox-root.d.ts +9 -1
- package/dist/lightbox/root/lightbox-root.js +17 -7
- package/dist/listbox/root/listbox-root.d.ts +16 -14
- package/dist/listbox/root/listbox-root.js +24 -15
- package/dist/map/root/map-root.d.ts +19 -127
- package/dist/map/root/map-root.js +10 -138
- package/dist/menu/root/menu-root.d.ts +1 -0
- package/dist/menu/root/menu-root.js +1 -1
- package/dist/notifications/group/notification-group.js +5 -4
- package/dist/notifications/notification/notification.d.ts +10 -10
- package/dist/notifications/notification/notification.js +3 -3
- package/dist/notifications/root/notifications-root.d.ts +1 -0
- package/dist/notifications/root/notifications-root.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -0
- package/dist/number-input/root/number-input-root.js +22 -6
- package/dist/object-inspector/root/object-inspector-root.d.ts +10 -0
- package/dist/object-inspector/root/object-inspector-root.js +10 -2
- package/dist/outline/root/outline-root.d.ts +15 -0
- package/dist/outline/root/outline-root.js +12 -7
- package/dist/pagination/root/pagination-root.d.ts +18 -18
- package/dist/pagination/root/pagination-root.js +5 -5
- package/dist/pagination/size/pagination-size.d.ts +10 -9
- package/dist/pagination/size/pagination-size.js +4 -4
- package/dist/pagination/summary/pagination-summary.js +6 -5
- package/dist/pin-input/root/pin-input-root.d.ts +5 -0
- package/dist/pin-input/root/pin-input-root.js +10 -6
- package/dist/rating/root/rating-root.js +3 -2
- package/dist/select/root/select-root.d.ts +1 -0
- package/dist/select/root/select-root.js +8 -3
- package/dist/slider/root/slider-root.d.ts +12 -0
- package/dist/slider/root/slider-root.js +13 -1
- package/dist/splitter/root/splitter-root.d.ts +44 -35
- package/dist/splitter/root/splitter-root.js +27 -22
- package/dist/switch/root/switch-root.js +1 -0
- package/dist/table/column/table-column.d.ts +17 -0
- package/dist/table/column/table-column.js +16 -4
- package/dist/table/root/table-root.d.ts +1 -0
- package/dist/table/root/table-root.js +1 -1
- package/dist/textarea/root/textarea-root.js +1 -1
- package/dist/time-input/root/time-input-root.d.ts +29 -0
- package/dist/time-input/root/time-input-root.js +31 -10
- package/dist/time-picker/root/time-picker-root.d.ts +14 -0
- package/dist/time-picker/root/time-picker-root.js +16 -14
- package/dist/toast/item/toast-item.d.ts +12 -11
- package/dist/toast/item/toast-item.js +11 -5
- package/dist/toolbar/root/toolbar-root.js +2 -16
- package/dist/tooltip/root/tooltip-root.d.ts +1 -0
- package/dist/tooltip/root/tooltip-root.js +6 -0
- package/dist/tour/root/tour-root.d.ts +10 -10
- package/dist/tour/root/tour-root.js +5 -5
- package/dist/tree/root/tree-root.d.ts +1 -0
- package/dist/tree/root/tree-root.js +1 -1
- package/dist/video/root/video-root.d.ts +84 -0
- package/dist/video/root/video-root.js +116 -41
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +1 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +4 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +5753 -1076
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1668 -282
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ArrivalController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@fusion.dev/helix-core").DismissibleElement) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -19,6 +19,12 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
19
19
|
* does not change that, because an error that was always there is still not an
|
|
20
20
|
* interruption.
|
|
21
21
|
*
|
|
22
|
+
* **The region is its own, and there before its words.** The host was the
|
|
23
|
+
* region, and a banner raised mid-session arrives with its message already in
|
|
24
|
+
* it, which a screen reader reads inconsistently at best. So the message is said
|
|
25
|
+
* from a region filled a frame after the banner appears, and one that came with
|
|
26
|
+
* the page is filled at once and says nothing, being no news.
|
|
27
|
+
*
|
|
22
28
|
* Dismissing is a request. The announcement does not remove itself, because the
|
|
23
29
|
* consumer owns the markup and taking the node out from under them would put
|
|
24
30
|
* their state and the document out of step. `preventDefault()` on the
|
|
@@ -40,6 +46,7 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
40
46
|
* @csspart content - The message region.
|
|
41
47
|
* @csspart dismiss - The control that asks to close.
|
|
42
48
|
* @csspart dismiss-mark - The glyph on the dismiss control, where none is slotted.
|
|
49
|
+
* @csspart live - The message again, in a region a screen reader hears when the band appears mid-session. Visually hidden in the styled tier.
|
|
43
50
|
*/
|
|
44
51
|
export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement_base {
|
|
45
52
|
/**
|
|
@@ -66,7 +73,7 @@ export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement
|
|
|
66
73
|
* axes, which is the test the registry answers to.
|
|
67
74
|
*/
|
|
68
75
|
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
69
|
-
protected
|
|
76
|
+
protected readonly arrival: ArrivalController;
|
|
70
77
|
protected updated(changed: PropertyValues): void;
|
|
71
78
|
/**
|
|
72
79
|
* Says on the `actions` region whether anything is in it.
|
|
@@ -4,16 +4,18 @@ 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, HelixElement,
|
|
7
|
+
import { ArrivalController, customElement, HelixElement, MixinDismissible, markRegion, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { x } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
11
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
12
|
let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDismissible(HelixElement) {
|
|
13
|
-
|
|
14
|
-
super
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.arrival = new ArrivalController(this, {
|
|
16
|
+
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
17
|
+
text: () => slottedWords(this, ['']),
|
|
18
|
+
});
|
|
17
19
|
}
|
|
18
20
|
updated(changed) {
|
|
19
21
|
super.updated(changed);
|
|
@@ -30,7 +32,8 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
|
|
|
30
32
|
</slot>`;
|
|
31
33
|
}
|
|
32
34
|
render() {
|
|
33
|
-
return html `<div part="content"><slot></slot></div>
|
|
35
|
+
return html `<div part="content"><slot @slotchange=${() => this.arrival.say()}></slot></div>
|
|
36
|
+
<span part="live" role="status">${this.arrival.said}</span>
|
|
34
37
|
<div part="actions"><slot name="actions"></slot></div>
|
|
35
38
|
${this.dismissible
|
|
36
39
|
? html `<button
|
|
@@ -35,10 +35,9 @@ let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
|
|
|
35
35
|
part="indicator"
|
|
36
36
|
data-blank=${blank ? '' : nothing}
|
|
37
37
|
data-single=${text.length <= 1 ? '' : nothing}
|
|
38
|
-
role
|
|
38
|
+
role="status"
|
|
39
39
|
aria-label=${this.label !== '' && announced ? this.label : nothing}
|
|
40
|
-
|
|
41
|
-
>${text}</span
|
|
40
|
+
>${blank ? html `<span aria-hidden="true">${text}</span>` : text}</span
|
|
42
41
|
>`;
|
|
43
42
|
}
|
|
44
43
|
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
import type { CanvasEnd, CanvasSide } from '../root/canvas-document.js';
|
|
4
|
+
/**
|
|
5
|
+
* @summary A connector between two cards on a canvas.
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* **A declaration rather than a drawing**, which is the shape `Table.Column`
|
|
9
|
+
* has: this element renders nothing at all and the board draws the line,
|
|
10
|
+
* because a connector is geometry between two other elements and neither end of
|
|
11
|
+
* it belongs here. What this carries is which cards, which sides, and what sits
|
|
12
|
+
* at the ends.
|
|
13
|
+
*
|
|
14
|
+
* Written as markup for the reason its cards are: an array of edges handed to a
|
|
15
|
+
* custom element does not survive React's hydration, and a connector a consumer
|
|
16
|
+
* can write is one they can also put a condition around.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.100.0
|
|
19
|
+
* @status experimental
|
|
20
|
+
* @category media
|
|
21
|
+
* @aliases CanvasConnector, BoardEdge
|
|
22
|
+
* @documentation https://fusion.dev/helix/components/canvas
|
|
23
|
+
*/
|
|
24
|
+
export declare class HelixHeadlessCanvasEdge extends HelixElement {
|
|
25
|
+
/** The card it leaves. */
|
|
26
|
+
from: string;
|
|
27
|
+
/**
|
|
28
|
+
* What sits at the end it leaves from.
|
|
29
|
+
*
|
|
30
|
+
* Absent is nothing, which is the format's own default and what makes an
|
|
31
|
+
* ordinary connector a one-way arrow.
|
|
32
|
+
*/
|
|
33
|
+
fromEnd?: CanvasEnd;
|
|
34
|
+
/** Which side of that card it leaves, where the document says. */
|
|
35
|
+
fromSide?: CanvasSide | undefined;
|
|
36
|
+
/** What the connector says, drawn at its middle. */
|
|
37
|
+
label?: string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* What a request calls this connection, unique on its board.
|
|
40
|
+
*
|
|
41
|
+
* Optional, unlike a card's: a connection is also known by its two ends,
|
|
42
|
+
* which `helix-remove` carries beside this, so a page that names none of its
|
|
43
|
+
* connections can still find the one a reader asked to take away.
|
|
44
|
+
*/
|
|
45
|
+
name: string;
|
|
46
|
+
/**
|
|
47
|
+
* How it travels: `straight`, or `step` for right angles.
|
|
48
|
+
*
|
|
49
|
+
* Absent is whatever the board says, and a curve where the board says
|
|
50
|
+
* nothing. Not part of JSON Canvas, which draws every edge one way; a
|
|
51
|
+
* document read from one keeps its curves.
|
|
52
|
+
*
|
|
53
|
+
* **`path` rather than `shape`**, which is a word this library already
|
|
54
|
+
* spends on how an element looks in the styled tier: this changes the line
|
|
55
|
+
* the connector is drawn along, which the board computes. Nor `route`, which
|
|
56
|
+
* every element here already has, as the method that sends a child to a slot.
|
|
57
|
+
*/
|
|
58
|
+
path?: 'straight' | 'step';
|
|
59
|
+
/**
|
|
60
|
+
* Keeps this connection: a reader cannot remove it.
|
|
61
|
+
*
|
|
62
|
+
* The board's `readonly` still wins. A connection is still removed with a
|
|
63
|
+
* card at either end of it, since a line to a card that has gone is not one
|
|
64
|
+
* the board can draw.
|
|
65
|
+
*/
|
|
66
|
+
readOnly: boolean;
|
|
67
|
+
/** The card it arrives at. */
|
|
68
|
+
to: string;
|
|
69
|
+
/** What sits at the end it arrives at. Absent is an arrow, as the format says. */
|
|
70
|
+
toEnd?: CanvasEnd;
|
|
71
|
+
/**
|
|
72
|
+
* What the connection means, in the words every Helix component uses.
|
|
73
|
+
*
|
|
74
|
+
* A color with no meaning is `--canvas-edge-color`, written in the edge's own
|
|
75
|
+
* `style`: the line is drawn by the board rather than by this element, so the
|
|
76
|
+
* board carries the value across from where it was written.
|
|
77
|
+
*/
|
|
78
|
+
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
79
|
+
/** Which side of that card it arrives at, where the document says. */
|
|
80
|
+
toSide?: CanvasSide | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* How the line is drawn: `dashed` or `dotted`, and solid where it says
|
|
83
|
+
* neither.
|
|
84
|
+
*
|
|
85
|
+
* **A variant rather than an axis**, which is what the registry keeps it for:
|
|
86
|
+
* no other family draws a line whose stroke says something, and a dashed
|
|
87
|
+
* connection is the ordinary way to draw a weaker or an optional one. On the
|
|
88
|
+
* headless tier because the board that draws the line is.
|
|
89
|
+
*/
|
|
90
|
+
variant?: 'dashed' | 'dotted';
|
|
91
|
+
/**
|
|
92
|
+
* Tells the board the connector changed, since the board is what draws it.
|
|
93
|
+
*
|
|
94
|
+
* Every property here is one the line is drawn from, so any change is one
|
|
95
|
+
* the board has to hear: a label written after the first paint otherwise
|
|
96
|
+
* never appeared.
|
|
97
|
+
*/
|
|
98
|
+
protected updated(changed: PropertyValues): void;
|
|
99
|
+
/**
|
|
100
|
+
* Nothing, and deliberately so.
|
|
101
|
+
*
|
|
102
|
+
* The board draws every connector into one layer under the cards, which is
|
|
103
|
+
* the only place a line between two of them can be drawn. This element exists
|
|
104
|
+
* to be read.
|
|
105
|
+
*/
|
|
106
|
+
protected render(): TemplateResult;
|
|
107
|
+
}
|
|
108
|
+
declare global {
|
|
109
|
+
interface HTMLElementTagNameMap {
|
|
110
|
+
'helix-headless-canvas-edge': HelixHeadlessCanvasEdge;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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 } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
let HelixHeadlessCanvasEdge = class HelixHeadlessCanvasEdge extends HelixElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.from = '';
|
|
14
|
+
this.name = '';
|
|
15
|
+
this.readOnly = false;
|
|
16
|
+
this.to = '';
|
|
17
|
+
}
|
|
18
|
+
updated(changed) {
|
|
19
|
+
super.updated(changed);
|
|
20
|
+
const board = this.parentElement;
|
|
21
|
+
board?.requestUpdate?.();
|
|
22
|
+
}
|
|
23
|
+
render() {
|
|
24
|
+
return html ``;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
__decorate([
|
|
28
|
+
property()
|
|
29
|
+
], HelixHeadlessCanvasEdge.prototype, "from", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
property({ attribute: 'from-end' })
|
|
32
|
+
], HelixHeadlessCanvasEdge.prototype, "fromEnd", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
property({ attribute: 'from-side' })
|
|
35
|
+
], HelixHeadlessCanvasEdge.prototype, "fromSide", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
property()
|
|
38
|
+
], HelixHeadlessCanvasEdge.prototype, "label", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
property()
|
|
41
|
+
], HelixHeadlessCanvasEdge.prototype, "name", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
property()
|
|
44
|
+
], HelixHeadlessCanvasEdge.prototype, "path", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
47
|
+
], HelixHeadlessCanvasEdge.prototype, "readOnly", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
property()
|
|
50
|
+
], HelixHeadlessCanvasEdge.prototype, "to", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
property({ attribute: 'to-end' })
|
|
53
|
+
], HelixHeadlessCanvasEdge.prototype, "toEnd", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
property({ reflect: true })
|
|
56
|
+
], HelixHeadlessCanvasEdge.prototype, "tone", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
property({ attribute: 'to-side' })
|
|
59
|
+
], HelixHeadlessCanvasEdge.prototype, "toSide", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
property({ reflect: true })
|
|
62
|
+
], HelixHeadlessCanvasEdge.prototype, "variant", void 0);
|
|
63
|
+
HelixHeadlessCanvasEdge = __decorate([
|
|
64
|
+
customElement('helix-headless-canvas-edge')
|
|
65
|
+
], HelixHeadlessCanvasEdge);
|
|
66
|
+
export { HelixHeadlessCanvasEdge };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { HelixHeadlessCanvasEdge } from './edge/canvas-edge.js';
|
|
2
|
+
export { HelixHeadlessCanvasNode } from './node/canvas-node.js';
|
|
3
|
+
export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasSide, CanvasTone, } from './root/canvas-root.js';
|
|
4
|
+
export { fromJsonCanvas, HelixHeadlessCanvas } from './root/canvas-root.js';
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary One card or group on a canvas.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* **Markup rather than an entry in an array**, which is the rule
|
|
8
|
+
* `VideoPlaylist` writes out: an array handed to a custom element is missing
|
|
9
|
+
* from the first paint of every server-rendered React page, because React skips
|
|
10
|
+
* the properties it would have to apply imperatively while hydrating. A card
|
|
11
|
+
* written as an element is in the served HTML whichever renderer wrote it, and
|
|
12
|
+
* what is inside it is the consumer's own DOM rather than a string this
|
|
13
|
+
* component parses.
|
|
14
|
+
*
|
|
15
|
+
* **Where it sits is data**, which is what makes a canvas a canvas: somebody
|
|
16
|
+
* placed this card and the placement carries meaning, so `x` and `y` are given
|
|
17
|
+
* rather than computed. The board reads them and places the card; a page with
|
|
18
|
+
* no JavaScript has the cards and their text and not the arrangement, which is
|
|
19
|
+
* the honest half of what a board can promise before it hydrates.
|
|
20
|
+
*
|
|
21
|
+
* **Named by `name`, which only has to be unique on its board**, the way a
|
|
22
|
+
* form control's is in its form. An `id` has to be unique on the whole page,
|
|
23
|
+
* and two boards written from one template, or one board shown twice, would
|
|
24
|
+
* each have a card called `write` with no way to say which one a connection
|
|
25
|
+
* meant. `id` is left for the page, which can still use it.
|
|
26
|
+
*
|
|
27
|
+
* **What it holds is the consumer's**, which is why there is no card type any
|
|
28
|
+
* more: a card of text is text, a link is a link they put inside it, a file is
|
|
29
|
+
* whatever they show for one. The one kind the board treats differently is a
|
|
30
|
+
* group, a box drawn behind the cards inside it, and `group` says so. JSON
|
|
31
|
+
* Canvas's four types are mapped by `fromJsonCanvas` on the way in.
|
|
32
|
+
*
|
|
33
|
+
* **The card is the way around the board, for a reader who cannot see it.** The
|
|
34
|
+
* board keeps one tab stop among its cards, arrow keys walk them in reading
|
|
35
|
+
* order, and the one a reader lands on is brought into view. What it connects
|
|
36
|
+
* to is read out with it, so the arrows between cards are heard as well as
|
|
37
|
+
* seen. That replaced a list of every card under the board, which said the same
|
|
38
|
+
* thing twice to a sighted reader and took a row from the board to do it.
|
|
39
|
+
*
|
|
40
|
+
* @since 0.100.0
|
|
41
|
+
* @status experimental
|
|
42
|
+
* @category media
|
|
43
|
+
* @aliases CanvasCard, BoardNode
|
|
44
|
+
* @documentation https://fusion.dev/helix/components/canvas
|
|
45
|
+
*
|
|
46
|
+
* @slot - What the card holds, which is anything: text, a picture, a chart.
|
|
47
|
+
* @slot description - A quieter line under it.
|
|
48
|
+
*
|
|
49
|
+
* @csspart grip - A corner a selected card is resized from, on every one of the four.
|
|
50
|
+
* @csspart grip-bottom-left - The bottom left corner.
|
|
51
|
+
* @csspart grip-bottom-right - The bottom right corner.
|
|
52
|
+
* @csspart grip-top-left - The top left corner.
|
|
53
|
+
* @csspart grip-top-right - The top right corner.
|
|
54
|
+
* @csspart handle - A point on a side a connection is drawn from, on every one of the four.
|
|
55
|
+
* @csspart handle-bottom - The point on the bottom side.
|
|
56
|
+
* @csspart handle-left - The point on the left side.
|
|
57
|
+
* @csspart handle-right - The point on the right side.
|
|
58
|
+
* @csspart handle-top - The point on the top side.
|
|
59
|
+
* @csspart move - The handle a selected card is moved by, a click to pick it up and another to put it down, as well as a drag.
|
|
60
|
+
* @csspart node - The box the content sits in.
|
|
61
|
+
* @csspart outline - The drawn outline of a card whose shape a box cannot draw, a diamond.
|
|
62
|
+
*
|
|
63
|
+
* @cssstate candidate - While a connection is being drawn and this card is somewhere it could arrive.
|
|
64
|
+
* @cssstate current - While this is the card a reader lands on when they tab into the board.
|
|
65
|
+
* @cssstate selected - While this is the card the reader selected, until they select something else or nothing.
|
|
66
|
+
* @cssstate target - While a connection being drawn would arrive here if it were let go.
|
|
67
|
+
*/
|
|
68
|
+
export declare class HelixHeadlessCanvasNode extends HelixElement {
|
|
69
|
+
/**
|
|
70
|
+
* A box drawn behind the cards inside it rather than a card.
|
|
71
|
+
*
|
|
72
|
+
* The board works out what is inside it from the geometry, which is what the
|
|
73
|
+
* format does too, and moves them with it. Its `label` is drawn above it.
|
|
74
|
+
*/
|
|
75
|
+
group: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* @internal Whether a connection being drawn could arrive here, written by
|
|
78
|
+
* the board. Not a consumer's to set: whether a card can take one is the
|
|
79
|
+
* board's arithmetic over its own read-only switches and this card's.
|
|
80
|
+
*/
|
|
81
|
+
candidate: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* @internal Whether the board lets a reader move, connect or remove this
|
|
84
|
+
* card, written by the board. Not a consumer's to set: `readonly` is theirs,
|
|
85
|
+
* and this is what the board makes of it and of its own.
|
|
86
|
+
*/
|
|
87
|
+
connectable: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* @internal Whether this card holds the board's one tab stop, written by the
|
|
90
|
+
* board. One card at a time, so a board of forty cards is one press of Tab to
|
|
91
|
+
* get past rather than forty.
|
|
92
|
+
*/
|
|
93
|
+
current: boolean;
|
|
94
|
+
/** How tall the card is, in the document's own units. */
|
|
95
|
+
height: number;
|
|
96
|
+
/**
|
|
97
|
+
* What the card is called, for a group and wherever another card names it.
|
|
98
|
+
*
|
|
99
|
+
* A group needs one because it has no text of its own; a card that has text
|
|
100
|
+
* is named by it, and one holding a picture or a figure is named by nothing
|
|
101
|
+
* short enough to read out in another card's connections.
|
|
102
|
+
*/
|
|
103
|
+
label: string;
|
|
104
|
+
/**
|
|
105
|
+
* What connections and requests call this card, unique on its board.
|
|
106
|
+
*
|
|
107
|
+
* Required: a card with no name is drawn but nothing can connect to it, and
|
|
108
|
+
* the board has nothing to say when a reader asks for it to go.
|
|
109
|
+
*/
|
|
110
|
+
name: string;
|
|
111
|
+
/**
|
|
112
|
+
* @internal What the card connects to, as a sentence, written by the board.
|
|
113
|
+
* Read out after the card's own content rather than as its name, so a reader
|
|
114
|
+
* hears what the card says first and where it leads second.
|
|
115
|
+
*/
|
|
116
|
+
links: string;
|
|
117
|
+
/**
|
|
118
|
+
* Keeps this card where it is: not moved, not connected, not removed.
|
|
119
|
+
*
|
|
120
|
+
* **The board's own word, meaning the same thing one card at a time.** A
|
|
121
|
+
* board of cards a reader rearranges often has one that anchors it, a start
|
|
122
|
+
* or a title, and this is that card. The board's `readonly` still wins, so a
|
|
123
|
+
* read-only board is read-only whatever its cards say.
|
|
124
|
+
*/
|
|
125
|
+
readOnly: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* The card's outline: `circle`, `diamond`, `pill` or `square`, and a rounded
|
|
128
|
+
* box where it says none.
|
|
129
|
+
*
|
|
130
|
+
* **A flowchart's vocabulary, and the reason it is on this tier**: a diamond
|
|
131
|
+
* is drawn as an outline the card renders, because a border follows a box
|
|
132
|
+
* and a diamond is not one, so the markup differs before any rule is
|
|
133
|
+
* written. Every shape here meets the middle of each side of its box, which
|
|
134
|
+
* is where a connection arrives, so a connection to a diamond lands on its
|
|
135
|
+
* point and one to a circle on its curve without the board knowing which.
|
|
136
|
+
*/
|
|
137
|
+
shape?: 'circle' | 'diamond' | 'pill' | 'square';
|
|
138
|
+
/**
|
|
139
|
+
* @internal Whether this is the card the reader selected, written by the
|
|
140
|
+
* board. Kept apart from focus, so a reader who clicks a button beside the
|
|
141
|
+
* board to act on the selection has not cleared it by clicking.
|
|
142
|
+
*/
|
|
143
|
+
selected: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* @internal Whether the board lets a reader move this card with its handle,
|
|
146
|
+
* written by the board: the card is selected, and nothing holds it.
|
|
147
|
+
*/
|
|
148
|
+
movable: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* @internal Whether the board lets a reader resize this card now, written by
|
|
151
|
+
* the board: the card is the one selected, and nothing holds it.
|
|
152
|
+
*/
|
|
153
|
+
resizable: boolean;
|
|
154
|
+
/**
|
|
155
|
+
* What the card means, in the words every Helix component uses for it.
|
|
156
|
+
*
|
|
157
|
+
* **`tone` rather than the format's `color`**, which was a second word for
|
|
158
|
+
* the same thing on this family alone: JSON Canvas writes `1` to `6` and
|
|
159
|
+
* leaves the meaning to the application, and this board had already pinned
|
|
160
|
+
* each to a tone. `fromJsonCanvas` maps the six to tones on the way in. A
|
|
161
|
+
* color with no meaning, a hex a document chose, is a custom property on the
|
|
162
|
+
* card, `--canvas-node-color`, which is a style rather than a statement.
|
|
163
|
+
*
|
|
164
|
+
* On the headless tier because meaning survives having no stylesheet.
|
|
165
|
+
*/
|
|
166
|
+
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
167
|
+
/**
|
|
168
|
+
* @internal Whether a connection being drawn would arrive here if it were
|
|
169
|
+
* let go, written by the board.
|
|
170
|
+
*/
|
|
171
|
+
target: boolean;
|
|
172
|
+
/** How wide the card is, in the document's own units. */
|
|
173
|
+
width: number;
|
|
174
|
+
/** Where its left edge sits, in the document's own units. */
|
|
175
|
+
x: number;
|
|
176
|
+
/** Where its top edge sits, in the document's own units. */
|
|
177
|
+
y: number;
|
|
178
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
179
|
+
/**
|
|
180
|
+
* Tells the board when anything it draws from has changed.
|
|
181
|
+
*
|
|
182
|
+
* **This is what makes a controlled board work.** A consumer holding the
|
|
183
|
+
* positions refuses `helix-before-move` and writes `x` and `y` themselves, and
|
|
184
|
+
* React writes them as properties: neither reaches the board, which drew the
|
|
185
|
+
* connectors from the old ones and left them pointing at where the card was.
|
|
186
|
+
* The board is the parent by construction, so asking it to update is one call
|
|
187
|
+
* and it batches whatever else changed in the same turn.
|
|
188
|
+
*/
|
|
189
|
+
protected updated(changed: PropertyValues): void;
|
|
190
|
+
/**
|
|
191
|
+
* Focuses the card rather than the host, which draws no box of its own.
|
|
192
|
+
*
|
|
193
|
+
* The board calls this to walk the cards, and a consumer can too: the part is
|
|
194
|
+
* what holds the tab stop and what a focus ring is drawn around.
|
|
195
|
+
*/
|
|
196
|
+
focus(options?: FocusOptions): void;
|
|
197
|
+
/**
|
|
198
|
+
* The card, and the sentence that says where it leads.
|
|
199
|
+
*
|
|
200
|
+
* **`aria-describedby` at a hidden element, which is allowed and is the
|
|
201
|
+
* point.** A description is computed from its target whether or not the
|
|
202
|
+
* target is rendered, so the connections are read out and never drawn: the
|
|
203
|
+
* arrows already draw them.
|
|
204
|
+
*/
|
|
205
|
+
protected render(): TemplateResult;
|
|
206
|
+
}
|
|
207
|
+
declare global {
|
|
208
|
+
interface HTMLElementTagNameMap {
|
|
209
|
+
'helix-headless-canvas-node': HelixHeadlessCanvasNode;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
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 } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
|
+
const DRAWN = [
|
|
11
|
+
'group',
|
|
12
|
+
'height',
|
|
13
|
+
'label',
|
|
14
|
+
'name',
|
|
15
|
+
'readOnly',
|
|
16
|
+
'shape',
|
|
17
|
+
'tone',
|
|
18
|
+
'width',
|
|
19
|
+
'x',
|
|
20
|
+
'y',
|
|
21
|
+
];
|
|
22
|
+
let HelixHeadlessCanvasNode = class HelixHeadlessCanvasNode extends HelixElement {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.group = false;
|
|
26
|
+
this.candidate = false;
|
|
27
|
+
this.connectable = false;
|
|
28
|
+
this.current = false;
|
|
29
|
+
this.height = 0;
|
|
30
|
+
this.label = '';
|
|
31
|
+
this.name = '';
|
|
32
|
+
this.links = '';
|
|
33
|
+
this.readOnly = false;
|
|
34
|
+
this.selected = false;
|
|
35
|
+
this.movable = false;
|
|
36
|
+
this.resizable = false;
|
|
37
|
+
this.target = false;
|
|
38
|
+
this.width = 0;
|
|
39
|
+
this.x = 0;
|
|
40
|
+
this.y = 0;
|
|
41
|
+
}
|
|
42
|
+
willUpdate(changed) {
|
|
43
|
+
super.willUpdate(changed);
|
|
44
|
+
this.toggleState('candidate', this.candidate);
|
|
45
|
+
this.toggleState('current', this.current);
|
|
46
|
+
this.toggleState('selected', this.selected);
|
|
47
|
+
this.toggleState('target', this.target);
|
|
48
|
+
}
|
|
49
|
+
updated(changed) {
|
|
50
|
+
super.updated(changed);
|
|
51
|
+
if (DRAWN.some((name) => changed.has(name))) {
|
|
52
|
+
const board = this.parentElement;
|
|
53
|
+
board?.requestUpdate?.();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
focus(options) {
|
|
57
|
+
this.partNamed('node')?.focus(options);
|
|
58
|
+
}
|
|
59
|
+
render() {
|
|
60
|
+
return html `${this.shape === 'diamond' && !this.group
|
|
61
|
+
? html `<svg part="outline" aria-hidden="true" preserveAspectRatio="none" viewBox="0 0 100 100">
|
|
62
|
+
<polygon points="50,0 100,50 50,100 0,50" vector-effect="non-scaling-stroke" />
|
|
63
|
+
</svg>`
|
|
64
|
+
: nothing}<div
|
|
65
|
+
part="node"
|
|
66
|
+
aria-describedby=${this.links ? 'links' : nothing}
|
|
67
|
+
aria-label=${this.group ? this.label || nothing : nothing}
|
|
68
|
+
aria-keyshortcuts=${this.connectable ? 'Enter F2 Space Shift+ArrowRight Shift+ArrowDown Alt+ArrowRight Alt+ArrowDown C Delete' : nothing}
|
|
69
|
+
role=${this.group ? 'group' : 'article'}
|
|
70
|
+
tabindex=${this.current ? '0' : '-1'}
|
|
71
|
+
>
|
|
72
|
+
<slot></slot>
|
|
73
|
+
<slot name="description"></slot>
|
|
74
|
+
<span id="links" hidden>${this.links}</span>
|
|
75
|
+
</div>
|
|
76
|
+
${this.connectable
|
|
77
|
+
? html `<span part="handle handle-top" aria-hidden="true" data-side="top"></span>
|
|
78
|
+
<span part="handle handle-right" aria-hidden="true" data-side="right"></span>
|
|
79
|
+
<span part="handle handle-bottom" aria-hidden="true" data-side="bottom"></span>
|
|
80
|
+
<span part="handle handle-left" aria-hidden="true" data-side="left"></span>`
|
|
81
|
+
: nothing}
|
|
82
|
+
${this.movable ? html `<span part="move" aria-hidden="true" data-move></span>` : nothing}
|
|
83
|
+
${this.resizable
|
|
84
|
+
? html `<span part="grip grip-top-left" aria-hidden="true" data-corner="top-left"></span>
|
|
85
|
+
<span part="grip grip-top-right" aria-hidden="true" data-corner="top-right"></span>
|
|
86
|
+
<span part="grip grip-bottom-right" aria-hidden="true" data-corner="bottom-right"></span>
|
|
87
|
+
<span part="grip grip-bottom-left" aria-hidden="true" data-corner="bottom-left"></span>`
|
|
88
|
+
: nothing}`;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
__decorate([
|
|
92
|
+
property({ reflect: true, type: Boolean })
|
|
93
|
+
], HelixHeadlessCanvasNode.prototype, "group", void 0);
|
|
94
|
+
__decorate([
|
|
95
|
+
state()
|
|
96
|
+
], HelixHeadlessCanvasNode.prototype, "candidate", void 0);
|
|
97
|
+
__decorate([
|
|
98
|
+
state()
|
|
99
|
+
], HelixHeadlessCanvasNode.prototype, "connectable", void 0);
|
|
100
|
+
__decorate([
|
|
101
|
+
state()
|
|
102
|
+
], HelixHeadlessCanvasNode.prototype, "current", void 0);
|
|
103
|
+
__decorate([
|
|
104
|
+
property({ type: Number })
|
|
105
|
+
], HelixHeadlessCanvasNode.prototype, "height", void 0);
|
|
106
|
+
__decorate([
|
|
107
|
+
property()
|
|
108
|
+
], HelixHeadlessCanvasNode.prototype, "label", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
property()
|
|
111
|
+
], HelixHeadlessCanvasNode.prototype, "name", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
state()
|
|
114
|
+
], HelixHeadlessCanvasNode.prototype, "links", void 0);
|
|
115
|
+
__decorate([
|
|
116
|
+
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
117
|
+
], HelixHeadlessCanvasNode.prototype, "readOnly", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
property({ reflect: true })
|
|
120
|
+
], HelixHeadlessCanvasNode.prototype, "shape", void 0);
|
|
121
|
+
__decorate([
|
|
122
|
+
state()
|
|
123
|
+
], HelixHeadlessCanvasNode.prototype, "selected", void 0);
|
|
124
|
+
__decorate([
|
|
125
|
+
state()
|
|
126
|
+
], HelixHeadlessCanvasNode.prototype, "movable", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
state()
|
|
129
|
+
], HelixHeadlessCanvasNode.prototype, "resizable", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
property({ reflect: true })
|
|
132
|
+
], HelixHeadlessCanvasNode.prototype, "tone", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
state()
|
|
135
|
+
], HelixHeadlessCanvasNode.prototype, "target", void 0);
|
|
136
|
+
__decorate([
|
|
137
|
+
property({ type: Number })
|
|
138
|
+
], HelixHeadlessCanvasNode.prototype, "width", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
property({ type: Number })
|
|
141
|
+
], HelixHeadlessCanvasNode.prototype, "x", void 0);
|
|
142
|
+
__decorate([
|
|
143
|
+
property({ type: Number })
|
|
144
|
+
], HelixHeadlessCanvasNode.prototype, "y", void 0);
|
|
145
|
+
HelixHeadlessCanvasNode = __decorate([
|
|
146
|
+
customElement('helix-headless-canvas-node')
|
|
147
|
+
], HelixHeadlessCanvasNode);
|
|
148
|
+
export { HelixHeadlessCanvasNode };
|