@fusion.dev/helix-headless 0.147.0 → 0.148.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 +4512 -790
- package/dist/accordion/item/accordion-item.d.ts +5 -2
- package/dist/accordion/item/accordion-item.js +11 -7
- package/dist/accordion/root/accordion-root.js +4 -6
- package/dist/announcement/root/announcement-root.d.ts +56 -5
- package/dist/announcement/root/announcement-root.js +124 -21
- package/dist/area-chart/root/area-chart-root.js +3 -4
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.js +8 -22
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +2 -2
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +13 -3
- package/dist/chat/root/chat-root.js +2 -6
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +18 -10
- package/dist/checkbox-group/select-all.d.ts +11 -0
- package/dist/checkbox-group/select-all.js +5 -0
- package/dist/code-block/root/code-block-root.d.ts +8 -6
- package/dist/code-block/root/code-block-root.js +4 -3
- package/dist/color-picker/root/color-picker-root.js +6 -12
- package/dist/color-picker/wheel.d.ts +11 -0
- package/dist/color-picker/wheel.js +9 -0
- package/dist/combobox/root/combobox-root.d.ts +70 -11
- package/dist/combobox/root/combobox-root.js +68 -18
- package/dist/command/root/command-root.d.ts +4 -3
- package/dist/data-table/root/data-table-root.js +17 -44
- package/dist/description-list/item/description-list-item.d.ts +4 -0
- package/dist/description-list/item/description-list-item.js +7 -1
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/drilldown/item/drilldown-item.js +3 -4
- package/dist/element-events.generated.js +1 -0
- package/dist/empty/root/empty-root.d.ts +17 -3
- package/dist/empty/root/empty-root.js +29 -5
- package/dist/file-input/root/file-input-root.js +3 -4
- package/dist/file-input/status.js +2 -1
- package/dist/filter-input/chip/filter-chip.js +2 -3
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +2 -1
- package/dist/format-date/options.js +9 -38
- package/dist/format-date/root/format-date-root.d.ts +35 -3
- package/dist/format-date/root/format-date-root.js +24 -32
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/heatmap-root.d.ts +12 -0
- package/dist/heatmap/root/heatmap-root.js +26 -11
- package/dist/image/root/image-root.d.ts +11 -0
- package/dist/kbd/root/kbd-root.js +1 -2
- package/dist/legend/root/legend-root.js +4 -17
- package/dist/list/root/list-root.js +8 -22
- package/dist/listbox/root/listbox-root.d.ts +119 -24
- package/dist/listbox/root/listbox-root.js +130 -132
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/root/megamenu-root.js +4 -11
- package/dist/menu/root/menu-root.d.ts +2 -2
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +41 -5
- package/dist/notifications/root/notifications-root.js +27 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +5 -1
- package/dist/object-inspector/root/object-inspector-root.js +21 -11
- package/dist/pagination/size/pagination-size.d.ts +1 -0
- package/dist/pagination/size/pagination-size.js +1 -1
- package/dist/pin-input/code.d.ts +23 -0
- package/dist/pin-input/code.js +25 -0
- package/dist/pin-input/root/pin-input-root.js +9 -23
- package/dist/qr-code/root/qr-code-root.d.ts +14 -3
- package/dist/qr-code/root/qr-code-root.js +19 -5
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +2 -6
- package/dist/scatter-chart/root/scatter-chart-root.js +6 -19
- package/dist/select/root/select-root.d.ts +56 -8
- package/dist/select/root/select-root.js +33 -9
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +26 -1
- package/dist/speed-dial/item/speed-dial-item.js +41 -3
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +80 -1
- package/dist/speed-dial/root/speed-dial-root.js +114 -5
- package/dist/splitter/root/splitter-root.d.ts +7 -3
- package/dist/splitter/root/splitter-root.js +16 -3
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +81 -24
- package/dist/table/row/table-row.d.ts +13 -1
- package/dist/table/row/table-row.js +20 -6
- package/dist/tag/group/tag-group.js +6 -15
- package/dist/time-picker/root/time-picker-root.d.ts +1 -0
- package/dist/time-picker/root/time-picker-root.js +3 -0
- package/dist/toast/item/toast-item.d.ts +6 -3
- package/dist/toast/item/toast-item.js +1 -0
- package/dist/toast/root/toast-root.d.ts +13 -1
- package/dist/toast/root/toast-root.js +20 -14
- package/dist/toggle/group/toggle-group.js +3 -5
- package/dist/toolbar/root/toolbar-root.d.ts +31 -0
- package/dist/toolbar/root/toolbar-root.js +39 -8
- package/dist/tooltip/root/tooltip-root.js +1 -2
- package/dist/video/root/video-root.d.ts +11 -0
- package/dist/video/root/video-root.js +15 -1
- package/dist/virtual-list/root/virtual-list-root.js +6 -18
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2005 -266
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +338 -62
- package/dist/kbd/keys.d.ts +0 -29
- package/dist/kbd/keys.js +0 -52
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a card lands on a board that snaps: the arithmetic of a ruling, kept
|
|
3
|
+
* apart from the board that applies it.
|
|
4
|
+
*
|
|
5
|
+
* Every value is in the document's own units, and a step of nothing, zero or
|
|
6
|
+
* less is no snapping at all, so a board without `snap` moves exactly as it
|
|
7
|
+
* did before there was one.
|
|
8
|
+
*/
|
|
9
|
+
/** A box on the board, in the document's own units. */
|
|
10
|
+
export interface SnapBox {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A value at the nearest multiple of `step`, or the value as it is where there
|
|
18
|
+
* is no step. A drag lets go wherever the hand is, and lands on the line
|
|
19
|
+
* nearest it.
|
|
20
|
+
*/
|
|
21
|
+
export declare const snapTo: (value: number, step: number | undefined) => number;
|
|
22
|
+
/**
|
|
23
|
+
* The next multiple of `step` from `value`, the way a key points: `way` is `1`
|
|
24
|
+
* or `-1`.
|
|
25
|
+
*
|
|
26
|
+
* **On to the next line, and never back onto the same one.** A card sitting
|
|
27
|
+
* between two lines goes to the line ahead of it, and one on a line goes a
|
|
28
|
+
* whole step, so every press moves the card and every press lands on a line.
|
|
29
|
+
*/
|
|
30
|
+
export declare const stepTo: (value: number, way: number, step: number) => number;
|
|
31
|
+
/**
|
|
32
|
+
* A box resized from a corner, with the edges that corner moves snapped, and
|
|
33
|
+
* held to a least size.
|
|
34
|
+
*
|
|
35
|
+
* Only the moving edges: the corner opposite the one in hand stays where it
|
|
36
|
+
* was, as it does without a ruling. Where the line nearest is inside the least
|
|
37
|
+
* size, the box stays at the least size rather than turning inside out.
|
|
38
|
+
*/
|
|
39
|
+
export declare const snapBox: (box: SnapBox, start: SnapBox, corner: string, step: number | undefined, least: {
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
}) => SnapBox;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const snaps = (step) => step !== undefined && Number.isFinite(step) && step > 0;
|
|
2
|
+
export const snapTo = (value, step) => snaps(step) ? Math.round(value / step) * step : value;
|
|
3
|
+
export const stepTo = (value, way, step) => {
|
|
4
|
+
if (way === 0) {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
const at = value / step;
|
|
8
|
+
const near = Math.round(at);
|
|
9
|
+
const on = Math.abs(at - near) < 1e-9 ? near : at;
|
|
10
|
+
return (way > 0 ? Math.floor(on) + 1 : Math.ceil(on) - 1) * step;
|
|
11
|
+
};
|
|
12
|
+
export const snapBox = (box, start, corner, step, least) => {
|
|
13
|
+
if (!snaps(step)) {
|
|
14
|
+
return box;
|
|
15
|
+
}
|
|
16
|
+
const left = corner.endsWith('left');
|
|
17
|
+
const top = corner.startsWith('top');
|
|
18
|
+
const right = start.x + start.width;
|
|
19
|
+
const bottom = start.y + start.height;
|
|
20
|
+
const width = left
|
|
21
|
+
? Math.max(least.width, right - snapTo(box.x, step))
|
|
22
|
+
: Math.max(least.width, snapTo(box.x + box.width, step) - start.x);
|
|
23
|
+
const height = top
|
|
24
|
+
? Math.max(least.height, bottom - snapTo(box.y, step))
|
|
25
|
+
: Math.max(least.height, snapTo(box.y + box.height, step) - start.y);
|
|
26
|
+
return {
|
|
27
|
+
height,
|
|
28
|
+
width,
|
|
29
|
+
x: left ? right - width : start.x,
|
|
30
|
+
y: top ? bottom - height : start.y,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary Shows one slide of several, with controls to move between them.
|
|
@@ -727,9 +727,10 @@ export declare class HelixHeadlessCarousel extends HelixElement {
|
|
|
727
727
|
* that changes an assignment is this component calling `assign`, so a slide
|
|
728
728
|
* appended by a consumer would reach no slot, render nowhere and be counted by
|
|
729
729
|
* nothing. A default slot needs no watcher, taking whatever is there; a manual
|
|
730
|
-
* one does. `Chat` watches for the same reason
|
|
730
|
+
* one does. `Chat` watches for the same reason, through the same core
|
|
731
|
+
* controller.
|
|
731
732
|
*/
|
|
732
|
-
|
|
733
|
+
protected readonly childWatch: ChildrenController;
|
|
733
734
|
connectedCallback(): void;
|
|
734
735
|
disconnectedCallback(): void;
|
|
735
736
|
/** Pauses without forgetting that the reader wanted it running. */
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { capturePointer, customElement, fillTemplate, HelixActivateEvent, HelixElement, HelixSelectEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ChildrenController, capturePointer, customElement, fillTemplate, HelixActivateEvent, HelixElement, HelixSelectEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft, caretRight, play, stop } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -185,7 +185,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
185
185
|
};
|
|
186
186
|
this.scrollFrame = 0;
|
|
187
187
|
this.stopped = false;
|
|
188
|
-
this.
|
|
188
|
+
this.childWatch = new ChildrenController(this);
|
|
189
189
|
this.pause = () => {
|
|
190
190
|
if (!this.stopped) {
|
|
191
191
|
this.rotating = false;
|
|
@@ -388,8 +388,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
388
388
|
super.connectedCallback();
|
|
389
389
|
this.addEventListener('focusin', this.pause);
|
|
390
390
|
this.addEventListener('pointerenter', this.pause);
|
|
391
|
-
this.watcher = new MutationObserver(() => this.requestUpdate());
|
|
392
|
-
this.watcher.observe(this, { childList: true });
|
|
393
391
|
this.watchPane();
|
|
394
392
|
if (this.hasUpdated) {
|
|
395
393
|
this.runTimer();
|
|
@@ -403,8 +401,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
403
401
|
}
|
|
404
402
|
this.removeEventListener('focusin', this.pause);
|
|
405
403
|
this.removeEventListener('pointerenter', this.pause);
|
|
406
|
-
this.watcher?.disconnect();
|
|
407
|
-
this.watcher = undefined;
|
|
408
404
|
this.sizes?.disconnect();
|
|
409
405
|
this.sizes = undefined;
|
|
410
406
|
this.watched = undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { type HelixHeadlessChatMessage } from '../message/chat-message.js';
|
|
4
4
|
/** One turn handed over as data, which is what `turns` holds. */
|
|
@@ -253,8 +253,18 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
|
253
253
|
* a turn is told again only when they change.
|
|
254
254
|
*/
|
|
255
255
|
private words;
|
|
256
|
-
/**
|
|
257
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Watches for turns arriving, since a manual slot hears nothing about them.
|
|
258
|
+
*
|
|
259
|
+
* **A turn that arrives after first paint reaches nothing on its own.**
|
|
260
|
+
* Slots are assigned by hand here, so appending a child assigns it to
|
|
261
|
+
* nothing, fires no `slotchange`, and schedules no render: the transcript
|
|
262
|
+
* went on showing "Nothing to show" over six children it already had, and
|
|
263
|
+
* the one thing a conversation does is grow. Measured with
|
|
264
|
+
* `assignedElements()` at zero against `children` at nine. Children only,
|
|
265
|
+
* never a turn's own text, which a streaming turn rewrites every frame.
|
|
266
|
+
*/
|
|
267
|
+
protected readonly childWatch: ChildrenController;
|
|
258
268
|
/** Watches the turns' own `state`, which is when one of them settles. */
|
|
259
269
|
private settling;
|
|
260
270
|
/** Watches the turns and the log for size, which scrolling does not report. */
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessChat_1;
|
|
8
|
-
import { customElement, fillTemplate, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, wordsConverter, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { ChildrenController, customElement, fillTemplate, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, wordsConverter, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { keyed } from 'lit/directives/keyed.js';
|
|
@@ -56,7 +56,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
56
56
|
this.announcement = '';
|
|
57
57
|
this.said = 0;
|
|
58
58
|
this.words = TURN_WORDS;
|
|
59
|
-
this.
|
|
59
|
+
this.childWatch = new ChildrenController(this, () => this.handleSlotChange());
|
|
60
60
|
this.settling = undefined;
|
|
61
61
|
this.grower = undefined;
|
|
62
62
|
this.watched = [];
|
|
@@ -349,8 +349,6 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
349
349
|
}
|
|
350
350
|
connectedCallback() {
|
|
351
351
|
super.connectedCallback();
|
|
352
|
-
this.watcher = new MutationObserver(this.handleSlotChange);
|
|
353
|
-
this.watcher.observe(this, { childList: true });
|
|
354
352
|
this.settling = new MutationObserver(this.handleSettle);
|
|
355
353
|
this.settling.observe(this, { attributeFilter: ['state'], subtree: true });
|
|
356
354
|
this.opening = true;
|
|
@@ -363,8 +361,6 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
363
361
|
}
|
|
364
362
|
disconnectedCallback() {
|
|
365
363
|
super.disconnectedCallback();
|
|
366
|
-
this.watcher?.disconnect();
|
|
367
|
-
this.watcher = undefined;
|
|
368
364
|
this.settling?.disconnect();
|
|
369
365
|
this.settling = undefined;
|
|
370
366
|
this.grower?.disconnect();
|
|
@@ -96,8 +96,21 @@ export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGro
|
|
|
96
96
|
*/
|
|
97
97
|
get values(): string[];
|
|
98
98
|
set values(next: string[]);
|
|
99
|
+
/**
|
|
100
|
+
* Writes the set the boxes are given at the next update: by value, or, for
|
|
101
|
+
* a set a press decided, by box.
|
|
102
|
+
*/
|
|
103
|
+
private choose;
|
|
99
104
|
/** The values last written, which the boxes are given at the next update. */
|
|
100
105
|
private declared;
|
|
106
|
+
/**
|
|
107
|
+
* The boxes to check at the next update, where a press on a box or on the
|
|
108
|
+
* select-all box decided the set.
|
|
109
|
+
*
|
|
110
|
+
* **By box, since boxes can share a value.** Boxes written with no `value`
|
|
111
|
+
* all submit `on`, and pushed by value, a press on one checked every one.
|
|
112
|
+
*/
|
|
113
|
+
private checking;
|
|
101
114
|
/**
|
|
102
115
|
* Whether `declared` has yet to reach the boxes.
|
|
103
116
|
*
|
|
@@ -5,19 +5,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessCheckboxGroup_1;
|
|
8
|
-
import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField,
|
|
8
|
+
import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
11
|
import { html } from 'lit/static-html.js';
|
|
12
12
|
import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
|
|
13
13
|
import '../../checkbox/index.js';
|
|
14
|
-
import { selectAllState } from '../select-all.js';
|
|
14
|
+
import { selectAllPress, selectAllState } from '../select-all.js';
|
|
15
15
|
let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(...arguments);
|
|
18
18
|
this.selectAll = false;
|
|
19
19
|
this.selectAllLabel = 'Select all';
|
|
20
20
|
this.declared = [];
|
|
21
|
+
this.checking = undefined;
|
|
21
22
|
this.pending = false;
|
|
22
23
|
this.watched = new Set();
|
|
23
24
|
this.member = {
|
|
@@ -41,14 +42,13 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
const wanted = event.detail.checked;
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
.map((box) => box.value);
|
|
45
|
+
const checking = this.boxes.filter((box) => (box === changed ? wanted : box.checked));
|
|
46
|
+
const next = checking.map((box) => box.value);
|
|
47
47
|
if (!this.dispatchEvent(new HelixBeforeChangeEvent({ value: next.join(',') }))) {
|
|
48
48
|
event.preventDefault();
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
this.
|
|
51
|
+
this.choose(next, checking);
|
|
52
52
|
this.announceInput();
|
|
53
53
|
this.announceChange();
|
|
54
54
|
};
|
|
@@ -60,12 +60,14 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
60
60
|
this.handleSelectAll = (event) => {
|
|
61
61
|
event.preventDefault();
|
|
62
62
|
event.stopPropagation();
|
|
63
|
-
const boxes = this.
|
|
64
|
-
const
|
|
63
|
+
const boxes = this.boxes;
|
|
64
|
+
const pressed = selectAllPress(this.setBoxes());
|
|
65
|
+
const checking = boxes.filter((_, at) => pressed[at]);
|
|
66
|
+
const next = checking.map((box) => box.value);
|
|
65
67
|
if (!this.dispatchEvent(new HelixBeforeChangeEvent({ value: next.join(',') }))) {
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
68
|
-
this.
|
|
70
|
+
this.choose(next, checking);
|
|
69
71
|
this.announceInput();
|
|
70
72
|
this.announceChange();
|
|
71
73
|
};
|
|
@@ -86,8 +88,12 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
86
88
|
: boxes.filter((box) => box.checked).map((box) => box.value);
|
|
87
89
|
}
|
|
88
90
|
set values(next) {
|
|
91
|
+
this.choose(next);
|
|
92
|
+
}
|
|
93
|
+
choose(next, boxes) {
|
|
89
94
|
const previous = this.value;
|
|
90
95
|
this.declared = [...next];
|
|
96
|
+
this.checking = boxes ? new Set(boxes) : undefined;
|
|
91
97
|
this.pending = true;
|
|
92
98
|
this.requestUpdate('value', previous);
|
|
93
99
|
}
|
|
@@ -125,8 +131,10 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
125
131
|
}
|
|
126
132
|
this.pending = false;
|
|
127
133
|
const wanted = new Set(this.declared);
|
|
134
|
+
const checking = this.checking;
|
|
135
|
+
this.checking = undefined;
|
|
128
136
|
for (const box of boxes) {
|
|
129
|
-
box.checked = wanted.has(box.value);
|
|
137
|
+
box.checked = checking ? checking.has(box) : wanted.has(box.value);
|
|
130
138
|
}
|
|
131
139
|
}
|
|
132
140
|
connectedCallback() {
|
|
@@ -19,3 +19,14 @@ export declare const selectAllState: (boxes: readonly SetBox[]) => {
|
|
|
19
19
|
checked: boolean;
|
|
20
20
|
indeterminate: boolean;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* What a press on the select-all box does to each box, in the set's order:
|
|
24
|
+
* every enabled box checked, or every one cleared once all of them are, with a
|
|
25
|
+
* disabled box keeping its state. A set with no enabled box stays as it is.
|
|
26
|
+
*
|
|
27
|
+
* **By box and not by value**, so boxes that share a value, such as boxes
|
|
28
|
+
* written with none, which all submit `on`, are each moved on their own: by
|
|
29
|
+
* value, one checked box made every box with its value count as checked, and
|
|
30
|
+
* the press cleared the set where it should have filled it.
|
|
31
|
+
*/
|
|
32
|
+
export declare const selectAllPress: (boxes: readonly SetBox[]) => boolean[];
|
|
@@ -5,3 +5,8 @@ export const selectAllState = (boxes) => {
|
|
|
5
5
|
const checked = counted.length > 0 && ticked === counted.length;
|
|
6
6
|
return { checked, indeterminate: ticked > 0 && !checked };
|
|
7
7
|
};
|
|
8
|
+
export const selectAllPress = (boxes) => {
|
|
9
|
+
const enabled = boxes.filter((box) => !box.disabled);
|
|
10
|
+
const every = enabled.length > 0 && enabled.every((box) => box.checked);
|
|
11
|
+
return boxes.map((box) => (box.disabled ? box.checked : !every));
|
|
12
|
+
};
|
|
@@ -78,7 +78,7 @@ import '../../copy-button/index.js';
|
|
|
78
78
|
* @csspart gutter - The line numbers beside the code, shown when `line-numbers` is set.
|
|
79
79
|
* @csspart header - The bar that holds the name and the copy button, shown when there is a name.
|
|
80
80
|
* @csspart hunk - In a diff, a `@@` line saying where the lines under it are.
|
|
81
|
-
* @csspart label - The
|
|
81
|
+
* @csspart label - The block's name: its `label`, or its `language` where it has no label.
|
|
82
82
|
* @csspart marker - In a diff, the `+`, `-`, or space that starts a line.
|
|
83
83
|
* @csspart new - In a split diff, the new version's `<pre>`.
|
|
84
84
|
* @csspart number - In a diff, a line number.
|
|
@@ -151,18 +151,20 @@ export declare class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
151
151
|
*/
|
|
152
152
|
highlight?: (code: string, language: string) => string;
|
|
153
153
|
/**
|
|
154
|
-
* The block's name, usually a file name
|
|
154
|
+
* The block's name, usually a file name, drawn in the header.
|
|
155
155
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
156
|
+
* Absent, the block is named by `language` where there is one. In a diff,
|
|
157
|
+
* each file is named from the patch, and this names a patch that carries no
|
|
158
|
+
* name of its own.
|
|
158
159
|
*/
|
|
159
160
|
label: string;
|
|
160
161
|
/**
|
|
161
162
|
* The language the code is written in, such as `ts` or `css`, handed to
|
|
162
163
|
* `highlight` as its second argument.
|
|
163
164
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
165
|
+
* A block with no `label` is named by it, in the header and on the copy
|
|
166
|
+
* button, as a docs site names a snippet by its language. Absent hands
|
|
167
|
+
* `highlight` an empty string and names nothing.
|
|
166
168
|
*/
|
|
167
169
|
language: string;
|
|
168
170
|
/**
|
|
@@ -109,10 +109,11 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
109
109
|
const gutter = this.lineNumbers
|
|
110
110
|
? html `<span part="gutter" aria-hidden="true">${lines === 0 ? nothing : gutterNumbers(lines)}</span>`
|
|
111
111
|
: nothing;
|
|
112
|
-
|
|
112
|
+
const name = this.label || this.language;
|
|
113
|
+
return html `${this.renderHeader(name)}
|
|
113
114
|
<div part="frame">
|
|
114
115
|
<pre id="block" part="block">${gutter}${code}</pre>
|
|
115
|
-
${
|
|
116
|
+
${name ? nothing : this.renderCopy()}
|
|
116
117
|
</div>${this.renderExpand()}`;
|
|
117
118
|
}
|
|
118
119
|
renderExpand() {
|
|
@@ -140,7 +141,7 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
140
141
|
renderCopy(value, name) {
|
|
141
142
|
return this.noCopy ? nothing : this.renderCopyButton(value, name);
|
|
142
143
|
}
|
|
143
|
-
renderCopyButton(value = this.text, name = this.label) {
|
|
144
|
+
renderCopyButton(value = this.text, name = this.label || this.language) {
|
|
144
145
|
return html `<${this.tag('copy-button')}
|
|
145
146
|
part="copy"
|
|
146
147
|
exportparts="button: copy-button, text: copy-text, mark: copy-mark, live: copy-live, spinner: copy-spinner, tooltip: copy-tooltip,
|
|
@@ -4,14 +4,14 @@ 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 { CopyController, capturePointer, clamp, colorName, customElement, drawIcon, fillTemplate, formatColor, formatNumber, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, hueName, isRtl, KeyboardNavigationController, localeOf, MixinControllerValue, MixinPickerFeedback, parseColor, rovingStop, splitValues, toCss, wordsConverter, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CopyController, capturePointer, clamp, colorName, customElement, drawIcon, fillTemplate, focusItemOf, formatColor, formatNumber, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, hueName, isRtl, KeyboardNavigationController, localeOf, MixinControllerValue, MixinPickerFeedback, parseColor, rovingStop, splitValues, toCss, wordsConverter, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { eyedropper } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { live } from 'lit/directives/live.js';
|
|
12
12
|
import { html } from 'lit/static-html.js';
|
|
13
13
|
import { channelFields, writeChannel } from '../channels.js';
|
|
14
|
-
import { hueAt } from '../wheel.js';
|
|
14
|
+
import { areaAt, hueAt } from '../wheel.js';
|
|
15
15
|
import '../../button/index.js';
|
|
16
16
|
import '../../button-group/index.js';
|
|
17
17
|
import '../../slider/index.js';
|
|
@@ -99,15 +99,12 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinPicke
|
|
|
99
99
|
items: () => [
|
|
100
100
|
...(this.renderRoot?.querySelectorAll('[part="swatches"] [part="swatch"]') ??
|
|
101
101
|
[]),
|
|
102
|
-
].map((swatch, index) => ({
|
|
103
|
-
|
|
104
|
-
disabled: false,
|
|
105
|
-
focusItem: () => {
|
|
102
|
+
].map((swatch, index) => focusItemOf(swatch, {
|
|
103
|
+
focus: () => {
|
|
106
104
|
this.swatchAt = index;
|
|
107
105
|
swatch.focus();
|
|
108
106
|
},
|
|
109
|
-
|
|
110
|
-
selected: false,
|
|
107
|
+
owns: (node) => node === swatch,
|
|
111
108
|
})),
|
|
112
109
|
origin: 'focus',
|
|
113
110
|
selects: () => false,
|
|
@@ -165,10 +162,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinPicke
|
|
|
165
162
|
if (box.width === 0 || box.height === 0) {
|
|
166
163
|
return;
|
|
167
164
|
}
|
|
168
|
-
|
|
169
|
-
const across = isRtl(grid) ? 1 - fromLeft : fromLeft;
|
|
170
|
-
const down = Math.min(1, Math.max(0, (event.clientY - box.top) / box.height));
|
|
171
|
-
this.move({ brightness: Math.round((1 - down) * 100), saturation: Math.round(across * 100) });
|
|
165
|
+
this.move(areaAt(event.clientX, event.clientY, box, isRtl(grid)));
|
|
172
166
|
};
|
|
173
167
|
this.handleWheelPointer = (event) => {
|
|
174
168
|
const wheel = event.currentTarget;
|
|
@@ -15,3 +15,14 @@ export interface WheelBox {
|
|
|
15
15
|
* whatever the writing direction, since a circle has no line of text.
|
|
16
16
|
*/
|
|
17
17
|
export declare const hueAt: (x: number, y: number, box: WheelBox) => number;
|
|
18
|
+
/**
|
|
19
|
+
* The saturation and brightness at a point in the color square, 0 to 100:
|
|
20
|
+
* brightness falls downward, and saturation runs along the line, the way the
|
|
21
|
+
* two ramps under the square do, being native ranges. On a right-to-left page
|
|
22
|
+
* (`rtl`) it grows toward the left. A point outside the square is held to its
|
|
23
|
+
* edge.
|
|
24
|
+
*/
|
|
25
|
+
export declare const areaAt: (x: number, y: number, box: WheelBox, rtl: boolean) => {
|
|
26
|
+
brightness: number;
|
|
27
|
+
saturation: number;
|
|
28
|
+
};
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import { clamp } from '@fusion.dev/helix-core';
|
|
1
2
|
export const hueAt = (x, y, box) => {
|
|
2
3
|
const across = x - (box.left + box.width / 2);
|
|
3
4
|
const down = y - (box.top + box.height / 2);
|
|
4
5
|
const degrees = Math.round((Math.atan2(across, -down) * 180) / Math.PI);
|
|
5
6
|
return (degrees + 360) % 360;
|
|
6
7
|
};
|
|
8
|
+
export const areaAt = (x, y, box, rtl) => {
|
|
9
|
+
const fromLeft = clamp((x - box.left) / box.width, 0, 1);
|
|
10
|
+
const down = clamp((y - box.top) / box.height, 0, 1);
|
|
11
|
+
return {
|
|
12
|
+
brightness: Math.round((1 - down) * 100),
|
|
13
|
+
saturation: Math.round((rtl ? 1 - fromLeft : fromLeft) * 100),
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -17,13 +17,33 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
|
|
|
17
17
|
* reopened combobox starts from the whole list.
|
|
18
18
|
*
|
|
19
19
|
* Focus stays in the text field. The arrow keys move through the list with the
|
|
20
|
-
* listbox's public `navigate` method.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* listbox's public `navigate` method. As typing narrows the list, a screen
|
|
21
|
+
* reader hears how many options are left, such as "3 results". Emptying the
|
|
22
|
+
* field and leaving it clears a single choice.
|
|
23
|
+
*
|
|
24
|
+
* **Keyboard.**
|
|
25
|
+
*
|
|
26
|
+
* | Key | What it does |
|
|
27
|
+
* |---|---|
|
|
28
|
+
* | Down, Up | On a closed field, opens the list on the chosen option, or the first or the last. In the open list, moves the highlight, round from the last option to the first. |
|
|
29
|
+
* | Page Down, Page Up | In the open list, moves the highlight by as many options as the list shows at once. |
|
|
30
|
+
* | Enter | Chooses the highlighted option. With nothing left in the list, creates what was typed with `creatable`, or takes it with `allows-custom-value`. On a closed field, submits the form. |
|
|
31
|
+
* | Escape | Closes the list and puts the chosen words back. On a closed field, a second Escape clears a single choice. |
|
|
32
|
+
* | Tab | Closes the list and moves on. |
|
|
33
|
+
* | Backspace | With `multiple`, on an empty field, removes the last tag. |
|
|
34
|
+
* | Space, Home, End, letters | Edit the text. |
|
|
35
|
+
*
|
|
36
|
+
* **ARIA.** The input is the `combobox`, named by the label, with
|
|
37
|
+
* `aria-expanded`, `aria-controls` naming the list, `aria-autocomplete`
|
|
38
|
+
* (`both` with `suggest`, `list` otherwise) and `aria-activedescendant` on
|
|
39
|
+
* the highlighted option. The list is the listbox `Listbox` describes.
|
|
40
|
+
*
|
|
41
|
+
* On Apple devices, where VoiceOver does not read the option the field points
|
|
42
|
+
* to, the field says it in a live region as the highlight moves, says how many
|
|
43
|
+
* options there are as the list opens, and says a choice once it is made, as
|
|
44
|
+
* React Aria's combobox does there.
|
|
45
|
+
*
|
|
46
|
+
* Set `autocomplete` to let a browser's autofill choose an option.
|
|
27
47
|
*
|
|
28
48
|
* With `multiple`, each chosen option is a tag in the field with its own remove
|
|
29
49
|
* control. The panel stays open and the filter clears after each choice, so the
|
|
@@ -83,6 +103,7 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
|
|
|
83
103
|
* @csspart listbox-loading - Shown while the options are loading.
|
|
84
104
|
* @csspart listbox-search - The region holding the field that narrows the list.
|
|
85
105
|
* @csspart listbox-search-field - The filter field inside that region.
|
|
106
|
+
* @csspart live - The region VoiceOver hears the highlight, the count and a choice from on Apple devices, drawn once there is one to say. Visually hidden in the styled tier.
|
|
86
107
|
* @csspart rest - The count of choices held beyond `max-tags`. A `<button>` with `expandable`, a `<span>` without it.
|
|
87
108
|
* @csspart surface - The floating panel.
|
|
88
109
|
* @csspart tag - One chosen option.
|
|
@@ -94,13 +115,22 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
|
|
|
94
115
|
* @csspart tag-start - The category before the label.
|
|
95
116
|
* @csspart tags - The row of chosen options, when `multiple` is set.
|
|
96
117
|
*
|
|
118
|
+
* @cssstate blank - While nothing is chosen.
|
|
97
119
|
* @cssstate error - While `load-error` is set.
|
|
98
120
|
* @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
|
|
121
|
+
* @cssstate loading - While `loading` is set.
|
|
99
122
|
* @cssstate no-results - What was typed hid every option of a list that has some.
|
|
100
123
|
* @cssstate open - While the list is open.
|
|
101
124
|
*/
|
|
102
125
|
export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
103
126
|
protected readonly aria: AriaForwardController;
|
|
127
|
+
/** The region VoiceOver hears the highlight, the count and a choice from. */
|
|
128
|
+
private readonly status;
|
|
129
|
+
/**
|
|
130
|
+
* The option, or the create row, the region last said: `null` for none,
|
|
131
|
+
* and `undefined` until it has spoken since the list opened.
|
|
132
|
+
*/
|
|
133
|
+
private told;
|
|
104
134
|
/**
|
|
105
135
|
* Whether text that names no option is taken as the value, as React Aria's
|
|
106
136
|
* `allowsCustomValue`.
|
|
@@ -113,12 +143,19 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
|
113
143
|
*/
|
|
114
144
|
allowsCustomValue: boolean;
|
|
115
145
|
/**
|
|
116
|
-
* What the browser may autofill
|
|
146
|
+
* What the browser may autofill, as a platform token such as `country`.
|
|
117
147
|
*
|
|
118
148
|
* **Defaults to `off`, which is not the platform's default and is the
|
|
119
149
|
* point.** The field filters a list rather than collecting a value, so a
|
|
120
150
|
* browser offering to fill it with a saved address is competing for the same
|
|
121
151
|
* keystrokes as the listbox. A consumer who wants autofill can still ask.
|
|
152
|
+
*
|
|
153
|
+
* Set, a combobox whose answer is one of its options keeps a hidden native
|
|
154
|
+
* `<select>` with the same options for the browser to fill, as React Aria's
|
|
155
|
+
* combobox and Select do, and the option the browser picks, by its value or
|
|
156
|
+
* its words, becomes the value. The text field itself stays `off`, so the
|
|
157
|
+
* browser fills the answer and not the filter. With `allows-custom-value`
|
|
158
|
+
* the token goes on the text field, whose words are the answer.
|
|
122
159
|
*/
|
|
123
160
|
autocomplete: string;
|
|
124
161
|
/**
|
|
@@ -155,10 +192,11 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
|
155
192
|
listLabel: string;
|
|
156
193
|
/**
|
|
157
194
|
* What the list says when its options could not be loaded, such as after a
|
|
158
|
-
* request to a server fails. Empty
|
|
159
|
-
*
|
|
195
|
+
* request to a server fails. Empty, null or no attribute is no error, so
|
|
196
|
+
* removing the attribute clears it. Passed to the list, which shows it
|
|
197
|
+
* under any options there are and tells screen readers.
|
|
160
198
|
*/
|
|
161
|
-
loadError: string;
|
|
199
|
+
loadError: string | null;
|
|
162
200
|
/**
|
|
163
201
|
* Whether the options are still loading.
|
|
164
202
|
*
|
|
@@ -236,6 +274,11 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
|
236
274
|
* two.
|
|
237
275
|
*/
|
|
238
276
|
resultsLabel: string;
|
|
277
|
+
/**
|
|
278
|
+
* What VoiceOver hears for a chosen option, as the highlight reaches it and
|
|
279
|
+
* once it is chosen, on Apple devices. `{name}` is the option's words.
|
|
280
|
+
*/
|
|
281
|
+
selectedLabel: string;
|
|
239
282
|
/**
|
|
240
283
|
* Whether the field completes the word as the user types.
|
|
241
284
|
*
|
|
@@ -459,6 +502,20 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
|
459
502
|
* is missing.
|
|
460
503
|
*/
|
|
461
504
|
private linkActive;
|
|
505
|
+
/**
|
|
506
|
+
* Says the highlight, and the count as the list opens, where VoiceOver
|
|
507
|
+
* would not.
|
|
508
|
+
*
|
|
509
|
+
* **VoiceOver does not read the option `aria-activedescendant` points to**
|
|
510
|
+
* while focus is in a text field, so on Apple devices the arrows moved
|
|
511
|
+
* through the list in silence. React Aria says the option there, with
|
|
512
|
+
* "selected" where it is chosen, and how many there are as the list opens.
|
|
513
|
+
* Only when the highlight moves to another option, so an update that leaves
|
|
514
|
+
* it where it was says nothing.
|
|
515
|
+
*/
|
|
516
|
+
private tell;
|
|
517
|
+
/** How many options there are, said as the list opens, until an option is said with it. */
|
|
518
|
+
private counted;
|
|
462
519
|
/**
|
|
463
520
|
* Takes what the list announced and stops it there.
|
|
464
521
|
*
|
|
@@ -565,6 +622,8 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
|
565
622
|
*/
|
|
566
623
|
private renderCreate;
|
|
567
624
|
protected render(): TemplateResult;
|
|
625
|
+
/** Whether a browser's autofill fills the hidden select, rather than the text field. */
|
|
626
|
+
private get fills();
|
|
568
627
|
}
|
|
569
628
|
declare global {
|
|
570
629
|
interface HTMLElementTagNameMap {
|