@fusion.dev/helix-core 0.148.0 → 0.149.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 +8518 -6050
- package/dist/controllers/aria-forward-controller/aria-forward-controller.js +1 -1
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +2 -2
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +5 -4
- package/dist/controllers/machine-controller/machine-controller.d.ts +69 -0
- package/dist/controllers/machine-controller/machine-controller.js +78 -0
- package/dist/controllers/machine-controller/machine.d.ts +93 -0
- package/dist/controllers/machine-controller/machine.js +20 -0
- package/dist/controllers/reorder-controller/reorder-controller.d.ts +285 -0
- package/dist/controllers/reorder-controller/reorder-controller.js +497 -0
- package/dist/controllers/source-controller/source-controller.js +1 -1
- package/dist/controllers/virtualize-controller/heights.js +1 -1
- package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +117 -3
- package/dist/controllers/virtualize-controller/virtualize-controller.js +134 -32
- package/dist/events/before-reorder.d.ts +14 -0
- package/dist/events/before-reorder.js +11 -0
- package/dist/events/details.d.ts +28 -0
- package/dist/events/events.d.ts +4 -2
- package/dist/events/events.js +3 -1
- package/dist/events/names.js +1 -1
- package/dist/events/reorder.d.ts +18 -12
- package/dist/events/reordered.d.ts +4 -4
- package/dist/helix-element/helix-element.js +2 -1
- package/dist/helix-element/react-audit-off.d.ts +11 -0
- package/dist/helix-element/react-audit-off.js +1 -0
- package/dist/helix-element/react-audit.d.ts +20 -0
- package/dist/helix-element/react-audit.js +56 -0
- package/dist/helix-element/react-bridge.d.ts +2 -22
- package/dist/helix-element/react-bridge.js +1 -56
- package/dist/index.d.ts +10 -4
- package/dist/index.js +10 -4
- package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +2 -2
- package/dist/mixins/mixin-chart-source/mixin-chart-source.js +3 -0
- package/dist/mixins/mixin-collection/mixin-collection.js +4 -0
- package/dist/mixins/mixin-dismissible/mixin-dismissible.js +3 -0
- package/dist/mixins/mixin-field/mixin-field.js +1 -1
- package/dist/mixins/mixin-segmented-field/mixin-segmented-field.d.ts +12 -0
- package/dist/mixins/mixin-segmented-field/mixin-segmented-field.js +15 -2
- package/dist/mixins/mixin-tokens/mixin-tokens.d.ts +5 -0
- package/dist/mixins/mixin-tokens/mixin-tokens.js +13 -2
- package/dist/mixins/mixin-viewport/mixin-viewport.d.ts +17 -15
- package/dist/mixins/mixin-viewport/mixin-viewport.js +15 -34
- package/dist/utils/calendar/calendar.d.ts +27 -0
- package/dist/utils/calendar/calendar.js +17 -0
- package/dist/utils/count-label/count-label.d.ts +7 -4
- package/dist/utils/count-label/count-label.js +2 -5
- package/dist/utils/date-segments/date-segments.d.ts +2 -1
- package/dist/utils/date-segments/date-segments.js +10 -0
- package/dist/utils/locale-of/locale-of.d.ts +5 -0
- package/dist/utils/locale-of/locale-of.js +8 -2
- package/dist/utils/reorder/drag-preview.d.ts +46 -0
- package/dist/utils/reorder/drag-preview.js +58 -0
- package/dist/utils/reorder/reorder.d.ts +178 -0
- package/dist/utils/reorder/reorder.js +112 -0
- package/dist/utils/report-runtime/report-runtime.d.ts +7 -4
- package/dist/utils/slotted-words/slotted-words.d.ts +3 -2
- package/dist/utils/slotted-words/slotted-words.js +3 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/words/index.d.ts +3 -0
- package/dist/words/index.js +3 -0
- package/dist/words/message.d.ts +47 -0
- package/dist/words/message.js +152 -0
- package/dist/words/registry.d.ts +89 -0
- package/dist/words/registry.js +101 -0
- package/dist/words/words-locale.d.ts +34 -0
- package/dist/words/words-locale.js +30 -0
- package/dist/words/words.d.ts +52 -0
- package/dist/words/words.js +100 -0
- package/package.json +40 -25
|
@@ -2,6 +2,7 @@ import { endInSight } from '../../utils/load-more/load-more.js';
|
|
|
2
2
|
import { reportRuntime } from '../../utils/report-runtime/report-runtime.js';
|
|
3
3
|
import { Heights } from './heights.js';
|
|
4
4
|
const UNSTABLE = 10;
|
|
5
|
+
const REST = 150;
|
|
5
6
|
export class VirtualizeController {
|
|
6
7
|
constructor(host, options) {
|
|
7
8
|
this.watching = false;
|
|
@@ -10,13 +11,45 @@ export class VirtualizeController {
|
|
|
10
11
|
this.window = { after: 0, before: 0, first: 0, last: 0 };
|
|
11
12
|
this.owed = 0;
|
|
12
13
|
this.askedAt = -1;
|
|
14
|
+
this.drift = 0;
|
|
15
|
+
this.lastTop = 0;
|
|
16
|
+
this.heading = 0;
|
|
17
|
+
this.touching = false;
|
|
18
|
+
this.uneven = false;
|
|
13
19
|
this.handleScroll = () => {
|
|
20
|
+
const top = this.options.container()?.scrollTop ?? 0;
|
|
21
|
+
if (top !== this.lastTop) {
|
|
22
|
+
this.heading = top > this.lastTop ? 1 : -1;
|
|
23
|
+
this.lastTop = top;
|
|
24
|
+
this.target = undefined;
|
|
25
|
+
clearTimeout(this.resting);
|
|
26
|
+
this.resting = setTimeout(this.rest, REST);
|
|
27
|
+
}
|
|
28
|
+
this.settling = 0;
|
|
29
|
+
this.measure();
|
|
30
|
+
};
|
|
31
|
+
this.handleTouchStart = () => {
|
|
32
|
+
this.touching = true;
|
|
33
|
+
};
|
|
34
|
+
this.handleTouchEnd = () => {
|
|
35
|
+
this.touching = false;
|
|
36
|
+
if (this.resting === undefined) {
|
|
37
|
+
this.rest();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.rest = () => {
|
|
41
|
+
this.resting = undefined;
|
|
42
|
+
if (this.touching || this.drift === 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.square();
|
|
14
46
|
this.settling = 0;
|
|
15
47
|
this.measure();
|
|
48
|
+
this.host.requestUpdate();
|
|
16
49
|
};
|
|
17
50
|
this.host = host;
|
|
18
51
|
this.options = options;
|
|
19
|
-
this.heights = new Heights(() => this.
|
|
52
|
+
this.heights = new Heights(() => this.line());
|
|
20
53
|
host.addController(this);
|
|
21
54
|
host.constructor.disableWarning?.('change-in-update');
|
|
22
55
|
}
|
|
@@ -29,7 +62,15 @@ export class VirtualizeController {
|
|
|
29
62
|
this.observer?.disconnect();
|
|
30
63
|
this.observer = undefined;
|
|
31
64
|
this.watching = false;
|
|
32
|
-
this.options.container()
|
|
65
|
+
const box = this.options.container();
|
|
66
|
+
box?.removeEventListener('scroll', this.handleScroll, { capture: true });
|
|
67
|
+
box?.removeEventListener('touchstart', this.handleTouchStart);
|
|
68
|
+
box?.removeEventListener('touchend', this.handleTouchEnd);
|
|
69
|
+
box?.removeEventListener('touchcancel', this.handleTouchEnd);
|
|
70
|
+
box?.removeEventListener('scrollend', this.handleTouchEnd);
|
|
71
|
+
clearTimeout(this.resting);
|
|
72
|
+
this.resting = undefined;
|
|
73
|
+
this.touching = false;
|
|
33
74
|
}
|
|
34
75
|
watch() {
|
|
35
76
|
if (this.watching) {
|
|
@@ -40,10 +81,38 @@ export class VirtualizeController {
|
|
|
40
81
|
return;
|
|
41
82
|
}
|
|
42
83
|
this.observer.observe(box);
|
|
43
|
-
box.addEventListener('scroll', this.handleScroll, { passive: true });
|
|
84
|
+
box.addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
|
|
85
|
+
box.addEventListener('touchstart', this.handleTouchStart, { passive: true });
|
|
86
|
+
box.addEventListener('touchend', this.handleTouchEnd, { passive: true });
|
|
87
|
+
box.addEventListener('touchcancel', this.handleTouchEnd, { passive: true });
|
|
88
|
+
box.addEventListener('scrollend', this.handleTouchEnd, { passive: true });
|
|
89
|
+
this.lastTop = box.scrollTop;
|
|
44
90
|
box.setAttribute('data-virtual', '');
|
|
45
91
|
this.watching = true;
|
|
46
92
|
}
|
|
93
|
+
scrolling() {
|
|
94
|
+
return (this.touching ||
|
|
95
|
+
this.resting !== undefined ||
|
|
96
|
+
(this.options.container()?.scrollTop ?? this.lastTop) !== this.lastTop);
|
|
97
|
+
}
|
|
98
|
+
square() {
|
|
99
|
+
const box = this.options.container();
|
|
100
|
+
if (this.drift > 0 && box) {
|
|
101
|
+
box.scrollTop -= this.drift;
|
|
102
|
+
this.lastTop = box.scrollTop;
|
|
103
|
+
}
|
|
104
|
+
else if (this.drift !== 0) {
|
|
105
|
+
this.owed -= this.drift;
|
|
106
|
+
this.host.requestUpdate();
|
|
107
|
+
}
|
|
108
|
+
this.drift = 0;
|
|
109
|
+
}
|
|
110
|
+
offset(box) {
|
|
111
|
+
return box.scrollTop + this.owed - this.drift;
|
|
112
|
+
}
|
|
113
|
+
lead(box) {
|
|
114
|
+
return this.heading === 0 ? 0 : box.clientHeight;
|
|
115
|
+
}
|
|
47
116
|
measure() {
|
|
48
117
|
this.watch();
|
|
49
118
|
const box = this.options.container();
|
|
@@ -53,9 +122,15 @@ export class VirtualizeController {
|
|
|
53
122
|
return;
|
|
54
123
|
}
|
|
55
124
|
const overscan = this.options.overscan ?? 4;
|
|
56
|
-
|
|
125
|
+
let next = this.measuring()
|
|
57
126
|
? this.placed(box, total, overscan)
|
|
58
127
|
: this.uniform(box, total, size, overscan);
|
|
128
|
+
if (this.drift !== 0 && (next.before < 0 || next.first === 0)) {
|
|
129
|
+
this.square();
|
|
130
|
+
next = this.measuring()
|
|
131
|
+
? this.placed(box, total, overscan)
|
|
132
|
+
: this.uniform(box, total, size, overscan);
|
|
133
|
+
}
|
|
59
134
|
if (this.last?.count !== total || this.last.estimate !== size) {
|
|
60
135
|
this.last = { count: total, estimate: size };
|
|
61
136
|
this.settling = 0;
|
|
@@ -77,8 +152,10 @@ export class VirtualizeController {
|
|
|
77
152
|
this.host.requestUpdate();
|
|
78
153
|
}
|
|
79
154
|
uniform(box, total, size, overscan) {
|
|
80
|
-
const
|
|
81
|
-
const
|
|
155
|
+
const extra = Math.ceil(this.lead(box) / size);
|
|
156
|
+
const at = Math.min(Math.floor(this.offset(box) / size), total);
|
|
157
|
+
const first = Math.max(0, at - overscan - (this.heading < 0 ? extra : 0));
|
|
158
|
+
const fits = Math.ceil(box.clientHeight / size) + overscan * 2 + (this.heading === 0 ? 0 : extra);
|
|
82
159
|
const last = Math.min(total, first + fits);
|
|
83
160
|
return { after: Math.max(0, (total - last) * size), before: first * size, first, last };
|
|
84
161
|
}
|
|
@@ -88,9 +165,6 @@ export class VirtualizeController {
|
|
|
88
165
|
}
|
|
89
166
|
sampleRows() {
|
|
90
167
|
const estimate = Math.max(1, this.options.estimate());
|
|
91
|
-
if (this.sample?.estimate === estimate) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
168
|
const heights = new Map();
|
|
95
169
|
for (const { element, index } of this.options.rows?.() ?? []) {
|
|
96
170
|
heights.set(index, (heights.get(index) ?? 0) + element.getBoundingClientRect().height);
|
|
@@ -99,33 +173,45 @@ export class VirtualizeController {
|
|
|
99
173
|
if (seen.length === 0) {
|
|
100
174
|
return;
|
|
101
175
|
}
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
176
|
+
const uneven = Math.max(...seen) - Math.min(...seen) > 1;
|
|
177
|
+
if (this.sample?.estimate !== estimate) {
|
|
178
|
+
const was = this.line();
|
|
179
|
+
const size = Math.max(1, seen.reduce((sum, height) => sum + height, 0) / seen.length);
|
|
180
|
+
this.sample = { estimate, size };
|
|
181
|
+
if (Math.abs(size - was) >= 0.5) {
|
|
182
|
+
const box = this.options.container();
|
|
183
|
+
if (box && box.scrollTop > 0) {
|
|
184
|
+
box.scrollTop = (box.scrollTop / was) * size;
|
|
185
|
+
this.lastTop = box.scrollTop;
|
|
186
|
+
}
|
|
187
|
+
this.settling = 0;
|
|
188
|
+
if (!uneven) {
|
|
189
|
+
this.measure();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
107
192
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
193
|
+
if (uneven) {
|
|
194
|
+
this.uneven = true;
|
|
195
|
+
this.settle();
|
|
111
196
|
}
|
|
112
|
-
this.settling = 0;
|
|
113
|
-
this.measure();
|
|
114
197
|
}
|
|
115
198
|
measuring() {
|
|
116
|
-
return this.options.rows !== undefined && (this.options.measured?.() ?? true);
|
|
199
|
+
return this.options.rows !== undefined && (this.uneven || (this.options.measured?.() ?? true));
|
|
117
200
|
}
|
|
118
201
|
placed(box, total, overscan) {
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
|
|
202
|
+
const top = this.offset(box);
|
|
203
|
+
const lead = this.lead(box);
|
|
204
|
+
const from = this.heading < 0 ? top - lead : top;
|
|
205
|
+
const first = Math.max(0, this.heights.indexAt(from, total) - overscan);
|
|
206
|
+
const bottom = top + box.clientHeight + (this.heading > 0 ? lead : 0);
|
|
207
|
+
let last = this.heights.indexAt(top, total);
|
|
122
208
|
while (last < total && this.heights.before(last, total) < bottom) {
|
|
123
209
|
last += 1;
|
|
124
210
|
}
|
|
125
211
|
last = Math.min(total, last + overscan);
|
|
126
212
|
return {
|
|
127
213
|
after: Math.max(0, this.heights.total(total) - this.heights.before(last, total)),
|
|
128
|
-
before: this.heights.before(first, total),
|
|
214
|
+
before: this.heights.before(first, total) + this.drift,
|
|
129
215
|
first,
|
|
130
216
|
last,
|
|
131
217
|
};
|
|
@@ -136,7 +222,7 @@ export class VirtualizeController {
|
|
|
136
222
|
if (!box || total === 0) {
|
|
137
223
|
return { first: 0, last: 0 };
|
|
138
224
|
}
|
|
139
|
-
const top = Math.max(0, box
|
|
225
|
+
const top = Math.max(0, this.offset(box));
|
|
140
226
|
const bottom = top + box.clientHeight;
|
|
141
227
|
if (!this.measuring()) {
|
|
142
228
|
const size = this.line();
|
|
@@ -157,7 +243,7 @@ export class VirtualizeController {
|
|
|
157
243
|
return 0;
|
|
158
244
|
}
|
|
159
245
|
const length = this.measuring() ? this.heights.total(total) : total * this.line();
|
|
160
|
-
return Math.max(0, length - Math.max(0, box
|
|
246
|
+
return Math.max(0, length - Math.max(0, this.offset(box)) - box.clientHeight);
|
|
161
247
|
}
|
|
162
248
|
endInSight(length = Math.max(0, this.options.count())) {
|
|
163
249
|
if (this.options.count() <= 0 ||
|
|
@@ -188,9 +274,13 @@ export class VirtualizeController {
|
|
|
188
274
|
const box = this.options.container();
|
|
189
275
|
if (box) {
|
|
190
276
|
box.scrollTop += this.owed;
|
|
277
|
+
this.lastTop = box.scrollTop;
|
|
191
278
|
}
|
|
192
279
|
this.owed = 0;
|
|
193
280
|
}
|
|
281
|
+
this.settle();
|
|
282
|
+
}
|
|
283
|
+
settle() {
|
|
194
284
|
if (!this.measuring()) {
|
|
195
285
|
this.sampleRows();
|
|
196
286
|
return;
|
|
@@ -200,7 +290,10 @@ export class VirtualizeController {
|
|
|
200
290
|
return;
|
|
201
291
|
}
|
|
202
292
|
const total = Math.max(0, this.options.count());
|
|
203
|
-
const
|
|
293
|
+
const box = this.options.container();
|
|
294
|
+
const top = box ? this.offset(box) : 0;
|
|
295
|
+
const anchor = this.target ?? this.heights.indexAt(top, total);
|
|
296
|
+
const was = this.heights.before(anchor, total);
|
|
204
297
|
let news = false;
|
|
205
298
|
for (const { element, index } of rows) {
|
|
206
299
|
if (this.heights.record(index, element.getBoundingClientRect().height)) {
|
|
@@ -211,10 +304,15 @@ export class VirtualizeController {
|
|
|
211
304
|
return;
|
|
212
305
|
}
|
|
213
306
|
this.settling = 0;
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
307
|
+
const moved = this.heights.before(anchor, total) - was;
|
|
308
|
+
if (box && top > 0 && moved !== 0 && (this.options.anchor?.() ?? true)) {
|
|
309
|
+
if (this.scrolling()) {
|
|
310
|
+
this.drift -= moved;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
box.scrollTop += moved;
|
|
314
|
+
this.lastTop = box.scrollTop;
|
|
315
|
+
}
|
|
218
316
|
}
|
|
219
317
|
this.measure();
|
|
220
318
|
}
|
|
@@ -269,17 +367,21 @@ export class VirtualizeController {
|
|
|
269
367
|
}
|
|
270
368
|
else {
|
|
271
369
|
box.scrollTop = next;
|
|
370
|
+
this.lastTop = box.scrollTop;
|
|
371
|
+
this.target = index;
|
|
272
372
|
}
|
|
273
373
|
}
|
|
274
374
|
offsetOf(index) {
|
|
275
375
|
const total = Math.max(0, this.options.count());
|
|
276
376
|
return this.measuring()
|
|
277
|
-
? this.heights.before(index, total)
|
|
377
|
+
? this.heights.before(index, total) + this.drift
|
|
278
378
|
: Math.max(0, Math.min(index, total)) * this.line();
|
|
279
379
|
}
|
|
280
380
|
forget() {
|
|
281
381
|
this.heights.forget();
|
|
282
382
|
this.sample = undefined;
|
|
383
|
+
this.uneven = false;
|
|
384
|
+
this.square();
|
|
283
385
|
}
|
|
284
386
|
report() {
|
|
285
387
|
if (this.warned) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReorderDetail } from './details.js';
|
|
2
|
+
/**
|
|
3
|
+
* A row or an item is about to move to a new place, and the move can be
|
|
4
|
+
* refused.
|
|
5
|
+
*
|
|
6
|
+
* Sent once, when a drag lets go or a key drops the item, with the whole order
|
|
7
|
+
* the move would leave. Call `preventDefault()` to keep the item where it is: a
|
|
8
|
+
* pinned row, or a place the item may not go. Nothing has moved yet, and
|
|
9
|
+
* `helix-reorder` follows where nobody refused.
|
|
10
|
+
*/
|
|
11
|
+
export declare class HelixBeforeReorderEvent extends CustomEvent<ReorderDetail> {
|
|
12
|
+
static readonly eventName = "helix-before-reorder";
|
|
13
|
+
constructor(detail: ReorderDetail);
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class HelixBeforeReorderEvent extends CustomEvent {
|
|
2
|
+
static { this.eventName = 'helix-before-reorder'; }
|
|
3
|
+
constructor(detail) {
|
|
4
|
+
super(HelixBeforeReorderEvent.eventName, {
|
|
5
|
+
bubbles: true,
|
|
6
|
+
cancelable: true,
|
|
7
|
+
composed: true,
|
|
8
|
+
detail,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
package/dist/events/details.d.ts
CHANGED
|
@@ -261,6 +261,34 @@ export interface ChangeDetail {
|
|
|
261
261
|
/** The value after the change. */
|
|
262
262
|
value: string;
|
|
263
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Detail carried by `helix-before-reorder`, `helix-reorder`, and
|
|
266
|
+
* `helix-reordered`: one row, item, or column moved to a new place.
|
|
267
|
+
*
|
|
268
|
+
* `from` and `to` count from 0 in the old order and in `keys`. Where your
|
|
269
|
+
* array holds every key in the same order, `rows.splice(to, 0,
|
|
270
|
+
* ...rows.splice(from, 1))` makes the same move.
|
|
271
|
+
*
|
|
272
|
+
* **`kind` is a field because one element sends both.** A data table moves its
|
|
273
|
+
* rows and its columns, and both are `helix-reorder` from the same host.
|
|
274
|
+
*/
|
|
275
|
+
export interface ReorderDetail extends ChangeDetail {
|
|
276
|
+
/** Where the key was before the move, counting from 0 in the old order. */
|
|
277
|
+
from: number;
|
|
278
|
+
/** The key of what moved: a row's key, an item's value, or a column's field. */
|
|
279
|
+
key: string;
|
|
280
|
+
/** Every key in the new order. */
|
|
281
|
+
keys: string[];
|
|
282
|
+
/** What moved: a column of a data table, an item of a list, or a row of a data table. */
|
|
283
|
+
kind: 'column' | 'item' | 'row';
|
|
284
|
+
/** Where the key is after the move, counting from 0 in `keys`. */
|
|
285
|
+
to: number;
|
|
286
|
+
/**
|
|
287
|
+
* The new order as one string: fields separated by spaces for columns, which
|
|
288
|
+
* is what `order` takes, and keys separated by commas for rows and items.
|
|
289
|
+
*/
|
|
290
|
+
value: string;
|
|
291
|
+
}
|
|
264
292
|
/** Detail carried by `helix-activate`: the value after the move, and the one before it. */
|
|
265
293
|
export interface ActivateDetail extends ChangeDetail {
|
|
266
294
|
/** The value that was current before the move, where the set knows it. */
|
package/dist/events/events.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ import { HelixBeforePanelResizeEvent } from './before-panel-resize.js';
|
|
|
43
43
|
import { HelixBeforePinEvent } from './before-pin.js';
|
|
44
44
|
import { HelixBeforeReconnectEvent } from './before-reconnect.js';
|
|
45
45
|
import { HelixBeforeRelabelEvent } from './before-relabel.js';
|
|
46
|
+
import { HelixBeforeReorderEvent } from './before-reorder.js';
|
|
46
47
|
import { HelixBeforeResizeEvent } from './before-resize.js';
|
|
47
48
|
import { HelixBeforeSplitEvent } from './before-split.js';
|
|
48
49
|
import { HelixBeforeToggleEvent } from './before-toggle.js';
|
|
@@ -115,9 +116,9 @@ import { HelixToggleEvent } from './toggle.js';
|
|
|
115
116
|
import { HelixTourAskEvent } from './tour-ask.js';
|
|
116
117
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
117
118
|
import { HelixTypingEvent } from './typing.js';
|
|
118
|
-
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
119
|
+
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
119
120
|
export { helixEventNames } from './names.js';
|
|
120
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
121
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
121
122
|
/**
|
|
122
123
|
* Every event class, and the one place a new one is registered: a class in a
|
|
123
124
|
* module of its own, imported above, and named here and in `names.ts`.
|
|
@@ -146,6 +147,7 @@ declare const registry: {
|
|
|
146
147
|
readonly HelixBeforePinEvent: typeof HelixBeforePinEvent;
|
|
147
148
|
readonly HelixBeforeReconnectEvent: typeof HelixBeforeReconnectEvent;
|
|
148
149
|
readonly HelixBeforeRelabelEvent: typeof HelixBeforeRelabelEvent;
|
|
150
|
+
readonly HelixBeforeReorderEvent: typeof HelixBeforeReorderEvent;
|
|
149
151
|
readonly HelixBeforeResizeEvent: typeof HelixBeforeResizeEvent;
|
|
150
152
|
readonly HelixBeforeSplitEvent: typeof HelixBeforeSplitEvent;
|
|
151
153
|
readonly HelixBeforeToggleEvent: typeof HelixBeforeToggleEvent;
|
package/dist/events/events.js
CHANGED
|
@@ -13,6 +13,7 @@ import { HelixBeforePanelResizeEvent } from './before-panel-resize.js';
|
|
|
13
13
|
import { HelixBeforePinEvent } from './before-pin.js';
|
|
14
14
|
import { HelixBeforeReconnectEvent } from './before-reconnect.js';
|
|
15
15
|
import { HelixBeforeRelabelEvent } from './before-relabel.js';
|
|
16
|
+
import { HelixBeforeReorderEvent } from './before-reorder.js';
|
|
16
17
|
import { HelixBeforeResizeEvent } from './before-resize.js';
|
|
17
18
|
import { HelixBeforeSplitEvent } from './before-split.js';
|
|
18
19
|
import { HelixBeforeToggleEvent } from './before-toggle.js';
|
|
@@ -86,7 +87,7 @@ import { HelixTourAskEvent } from './tour-ask.js';
|
|
|
86
87
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
87
88
|
import { HelixTypingEvent } from './typing.js';
|
|
88
89
|
export { helixEventNames } from './names.js';
|
|
89
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
90
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
90
91
|
const registry = {
|
|
91
92
|
HelixActionEvent,
|
|
92
93
|
HelixActivateEvent,
|
|
@@ -103,6 +104,7 @@ const registry = {
|
|
|
103
104
|
HelixBeforePinEvent,
|
|
104
105
|
HelixBeforeReconnectEvent,
|
|
105
106
|
HelixBeforeRelabelEvent,
|
|
107
|
+
HelixBeforeReorderEvent,
|
|
106
108
|
HelixBeforeResizeEvent,
|
|
107
109
|
HelixBeforeSplitEvent,
|
|
108
110
|
HelixBeforeToggleEvent,
|
package/dist/events/names.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const helixEventNames = new Set(('action activate aura-fallback band before-activate before-change before-close ' +
|
|
2
2
|
'before-collapse before-edit before-move before-open before-panel-resize before-pin ' +
|
|
3
|
-
'before-reconnect before-relabel before-resize before-split before-toggle ' +
|
|
3
|
+
'before-reconnect before-relabel before-reorder before-resize before-split before-toggle ' +
|
|
4
4
|
'canvas-edit canvas-pan canvas-view canvas-zoom caret clear collapse complete ' +
|
|
5
5
|
'connect console copy copy-error create dismiss edit end expand facet filter ' +
|
|
6
6
|
'filtered graph-filter graph-layout graph-pan graph-part-change graph-ready ' +
|
package/dist/events/reorder.d.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReorderDetail } from './details.js';
|
|
2
2
|
/**
|
|
3
|
-
* Fired when
|
|
3
|
+
* Fired when you ask for a row, an item, or a column to move to a new place.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* then have to keep in step.
|
|
5
|
+
* **For rows and items, you move them.** Helix moves no element it does not
|
|
6
|
+
* own, so a list or a data table sends this after `helix-before-reorder`, and
|
|
7
|
+
* you move your data to the order in `keys`. Calling `preventDefault()` says
|
|
8
|
+
* the move did not happen, and the element tells a screen reader it was
|
|
9
|
+
* canceled.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* **For Data Table's columns, the table moves them.** Calling
|
|
12
|
+
* `preventDefault()` leaves the columns where they were, so you can store the
|
|
13
|
+
* order in a URL or a preference and decide it yourself, the way a server-side
|
|
14
|
+
* sort takes `helix-sort`. `value` is the whole order as fields separated by
|
|
15
|
+
* spaces, which is what `order` takes.
|
|
16
|
+
*
|
|
17
|
+
* `kind` says which of the three moved, since a data table sends this for its
|
|
18
|
+
* rows and for its columns. `helix-sort` orders rows by a column, and this
|
|
19
|
+
* moves one row or column by hand.
|
|
14
20
|
*/
|
|
15
|
-
export declare class HelixReorderEvent extends CustomEvent<
|
|
21
|
+
export declare class HelixReorderEvent extends CustomEvent<ReorderDetail> {
|
|
16
22
|
static readonly eventName = "helix-reorder";
|
|
17
|
-
constructor(detail:
|
|
23
|
+
constructor(detail: ReorderDetail);
|
|
18
24
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReorderDetail } from './details.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Data Table's columns are in a different order.
|
|
4
4
|
*
|
|
5
5
|
* The notification after `helix-reorder`, sent once the order has moved, with
|
|
6
6
|
* every field in the new one. Not cancelable, and past tense for the reason
|
|
7
7
|
* `helix-sorted` is.
|
|
8
8
|
*/
|
|
9
|
-
export declare class HelixReorderedEvent extends CustomEvent<
|
|
9
|
+
export declare class HelixReorderedEvent extends CustomEvent<ReorderDetail> {
|
|
10
10
|
static readonly eventName = "helix-reordered";
|
|
11
|
-
constructor(detail:
|
|
11
|
+
constructor(detail: ReorderDetail);
|
|
12
12
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LitElement, unsafeCSS } from 'lit';
|
|
2
|
+
import { auditReactProps } from '@fusion.dev/helix-core/audits/react';
|
|
2
3
|
import { measuring, reportRender } from '../utils/report-render/report-render.js';
|
|
3
4
|
import { noteVersion, reportUsage } from '../utils/report-usage/report-usage.js';
|
|
4
|
-
import { applyReactProperties,
|
|
5
|
+
import { applyReactProperties, bindReactHandler, reactPropsOf } from './react-bridge.js';
|
|
5
6
|
const BOX_SIZING = '*,::before,::after{box-sizing:border-box}';
|
|
6
7
|
const HIDDEN = ":host([hidden]:not([hidden='until-found'])){display:none}";
|
|
7
8
|
const SCROLLER = '[data-scroller]{overflow:auto}';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { auditReactProps as audit } from './react-audit.js';
|
|
2
|
+
/**
|
|
3
|
+
* The React prop audit in a production build: nothing.
|
|
4
|
+
*
|
|
5
|
+
* `#react-audit` resolves here unless the bundler or runtime asks for the
|
|
6
|
+
* `development` condition, so a production build carries none of the audit's
|
|
7
|
+
* code, its sentences or the list of every event name it checks against. The
|
|
8
|
+
* signature is the audit's, so a call site reads the same in both builds. See
|
|
9
|
+
* `react-audit.ts`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const auditReactProps: typeof audit;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const auditReactProps = () => { };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Says so when a handler prop is attached to nothing.
|
|
3
|
+
*
|
|
4
|
+
* **TypeScript will not catch any of this, and that is not our tooling's
|
|
5
|
+
* fault.** A JSX attribute whose name is not a valid identifier is exempt from
|
|
6
|
+
* checking on an intrinsic element, and every one of ours carries a hyphen. So
|
|
7
|
+
* `onhelix-opne` type-checks, `on:helix-open` type-checks, and a made-up
|
|
8
|
+
* `totally-invented` prop type-checks, all against fully generated types that
|
|
9
|
+
* do reject a wrong *value* on a normal attribute. Measured with `tsc`.
|
|
10
|
+
*
|
|
11
|
+
* That leaves runtime as the only place a typo can be caught, and React's props
|
|
12
|
+
* bag as the only place to look, which the bridge already reads. Once per
|
|
13
|
+
* element, because a warning that repeats on every keystroke is one a consumer
|
|
14
|
+
* silences.
|
|
15
|
+
*
|
|
16
|
+
* `on:helix-open` gets its own message because it is not a mistake so much as
|
|
17
|
+
* the wrong dialect. It is what the Solid types offer, correctly, and React
|
|
18
|
+
* binds it as an event named `:helix-open`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const auditReactProps: (host: EventTarget, props: Record<string, unknown>) => void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { eventsForTag } from '../events/element-events.js';
|
|
2
|
+
import { helixEventNames } from '../events/names.js';
|
|
3
|
+
import { reportRuntime } from '../utils/report-runtime/report-runtime.js';
|
|
4
|
+
const audited = new WeakSet();
|
|
5
|
+
const REMOVED = new Set(['onActiveChange', 'onCheckedChange', 'onOpenChange', 'onValueChange']);
|
|
6
|
+
export const auditReactProps = (host, props) => {
|
|
7
|
+
if (audited.has(host)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
audited.add(host);
|
|
11
|
+
const tag = host instanceof Element ? `<${host.localName}>` : 'A Helix element';
|
|
12
|
+
const element = host instanceof Element ? host.localName : undefined;
|
|
13
|
+
for (const key of Object.keys(props)) {
|
|
14
|
+
if (key.startsWith('on:')) {
|
|
15
|
+
reportRuntime({
|
|
16
|
+
kind: 'solid-handler-syntax',
|
|
17
|
+
message: `${tag} was given \`${key}\`, which is Solid's syntax. React binds the name after \`on\` ` +
|
|
18
|
+
`verbatim, so this listens for an event called \`${key.slice(2)}\`. Write \`on${key.slice(3)}\`.`,
|
|
19
|
+
tag: element,
|
|
20
|
+
});
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (REMOVED.has(key)) {
|
|
24
|
+
reportRuntime({
|
|
25
|
+
kind: 'removed-callback',
|
|
26
|
+
message: `${tag} was given \`${key}\`, which was removed. It never worked from JSX, because React ` +
|
|
27
|
+
`binds any \`on\` prop as an event of that name. Listen for the element's change event instead.`,
|
|
28
|
+
tag: element,
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!key.startsWith('on') || !key.includes('-')) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const name = key.slice(2);
|
|
36
|
+
if (!helixEventNames.has(name)) {
|
|
37
|
+
reportRuntime({
|
|
38
|
+
kind: 'unknown-event',
|
|
39
|
+
message: `${tag} was given \`${key}\`, and nothing dispatches \`${name}\`. TypeScript cannot ` +
|
|
40
|
+
`check a hyphenated JSX prop, so this is the only place it shows up.`,
|
|
41
|
+
tag: element,
|
|
42
|
+
});
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const mine = host instanceof Element ? eventsForTag(host.localName) : undefined;
|
|
46
|
+
if (mine && !mine.has(name)) {
|
|
47
|
+
reportRuntime({
|
|
48
|
+
kind: 'misplaced-handler',
|
|
49
|
+
message: `${tag} was given \`${key}\`, but it dispatches ${[...mine].map((one) => `\`${one}\``).join(', ')}. ` +
|
|
50
|
+
`\`${name}\` is sent by a different element, and React only wires an \`on\` prop on the ` +
|
|
51
|
+
'element that dispatches, so this handler will never run. Put it on that element.',
|
|
52
|
+
tag: element,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
import type { LitElement } from 'lit';
|
|
2
2
|
/** The props React is holding for a node, if React is holding any. */
|
|
3
3
|
export declare const reactPropsOf: (node: EventTarget) => Record<string, unknown> | undefined;
|
|
4
|
-
/**
|
|
5
|
-
* Says so when a handler prop is attached to nothing.
|
|
6
|
-
*
|
|
7
|
-
* **TypeScript will not catch any of this, and that is not our tooling's
|
|
8
|
-
* fault.** A JSX attribute whose name is not a valid identifier is exempt from
|
|
9
|
-
* checking on an intrinsic element, and every one of ours carries a hyphen. So
|
|
10
|
-
* `onhelix-opne` type-checks, `on:helix-open` type-checks, and a made-up
|
|
11
|
-
* `totally-invented` prop type-checks, all against fully generated types that
|
|
12
|
-
* do reject a wrong *value* on a normal attribute. Measured with `tsc`.
|
|
13
|
-
*
|
|
14
|
-
* That leaves runtime as the only place a typo can be caught, and React's props
|
|
15
|
-
* bag as the only place to look, which the binding above already reads. Once per
|
|
16
|
-
* element, because a warning that repeats on every keystroke is one a consumer
|
|
17
|
-
* silences.
|
|
18
|
-
*
|
|
19
|
-
* `on:helix-open` gets its own message because it is not a mistake so much as
|
|
20
|
-
* the wrong dialect. It is what the Solid types offer, correctly, and React
|
|
21
|
-
* binds it as an event named `:helix-open`.
|
|
22
|
-
*/
|
|
23
|
-
export declare const auditReactProps: (host: EventTarget, props: Record<string, unknown>) => void;
|
|
24
4
|
/**
|
|
25
5
|
* The prop React would be holding for this event, if it is holding one.
|
|
26
6
|
*
|
|
@@ -83,8 +63,8 @@ export declare const reactNativeProp: (type: string) => string;
|
|
|
83
63
|
*
|
|
84
64
|
* Called by the host as it dispatches, which is the first moment it knows the
|
|
85
65
|
* event's name. A host React does not render holds no props, and nothing is
|
|
86
|
-
* bound.
|
|
87
|
-
* warns.
|
|
66
|
+
* bound. In a development build the props are audited on the way, so a
|
|
67
|
+
* handler attached to nothing warns; see `react-audit.ts`.
|
|
88
68
|
*/
|
|
89
69
|
export declare const bindReactHandler: (host: EventTarget, event: Event) => void;
|
|
90
70
|
/**
|