@fusion.dev/helix-core 0.171.0 → 0.173.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 +103 -4
- package/dist/controllers/command-controller/command-controller.d.ts +37 -0
- package/dist/controllers/command-controller/command-controller.js +55 -1
- package/dist/controllers/floating-controller/floating-controller.d.ts +15 -1
- package/dist/controllers/floating-controller/floating-controller.js +13 -6
- package/dist/controllers/indicator-controller/indicator-controller.d.ts +8 -0
- package/dist/controllers/indicator-controller/indicator-controller.js +14 -1
- package/dist/controllers/popover-controller/popover-controller.d.ts +6 -0
- package/dist/controllers/popover-controller/popover-controller.js +3 -0
- package/dist/mixins/mixin-picker-feedback/mixin-picker-feedback.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/custom-elements.json
CHANGED
|
@@ -983,12 +983,83 @@
|
|
|
983
983
|
"readonly": true,
|
|
984
984
|
"default": "options"
|
|
985
985
|
},
|
|
986
|
+
{
|
|
987
|
+
"kind": "field",
|
|
988
|
+
"name": "invokers",
|
|
989
|
+
"privacy": "private",
|
|
990
|
+
"readonly": true,
|
|
991
|
+
"default": "new Set<Element>()",
|
|
992
|
+
"description": "The invokers this host tells whether it is open: each one that sent an\nopening command, unless it carried `aria-expanded` of its own before then."
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
"kind": "field",
|
|
996
|
+
"name": "theirs",
|
|
997
|
+
"privacy": "private",
|
|
998
|
+
"readonly": true,
|
|
999
|
+
"default": "new WeakSet<Element>()",
|
|
1000
|
+
"description": "Invokers that carried `aria-expanded` before a command, which stay the consumer's."
|
|
1001
|
+
},
|
|
986
1002
|
{
|
|
987
1003
|
"kind": "field",
|
|
988
1004
|
"name": "handle",
|
|
989
1005
|
"privacy": "private",
|
|
990
1006
|
"readonly": true
|
|
991
1007
|
},
|
|
1008
|
+
{
|
|
1009
|
+
"kind": "method",
|
|
1010
|
+
"name": "note",
|
|
1011
|
+
"privacy": "private",
|
|
1012
|
+
"return": {
|
|
1013
|
+
"type": {
|
|
1014
|
+
"text": "void"
|
|
1015
|
+
}
|
|
1016
|
+
},
|
|
1017
|
+
"parameters": [
|
|
1018
|
+
{
|
|
1019
|
+
"name": "source",
|
|
1020
|
+
"type": {
|
|
1021
|
+
"text": "Element | null"
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
],
|
|
1025
|
+
"description": "Takes the invoker on as one to tell, for a host that opens.\n\n**The platform says it for a native popover and not for this.** Chromium\nexposes a `popovertarget` button, or one with `command=\"toggle-popover\"`,\nas expanded or collapsed, and a custom command reaches a custom element\nwith nothing said. Measured before this: a `command=\"--toggle\"` button\nopened a Popover and its node had no expanded state. React Aria's trigger\nsays `aria-expanded` on every overlay it opens.\n\nFrom the first command on, so nothing is written onto markup a server\nsent until a reader presses. A plain invoker is also pointed at the host\nthrough `ariaControlsElements`, which writes no attribute."
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
"kind": "method",
|
|
1029
|
+
"name": "tell",
|
|
1030
|
+
"privacy": "private",
|
|
1031
|
+
"return": {
|
|
1032
|
+
"type": {
|
|
1033
|
+
"text": "void"
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
"description": "Writes the host's state on each invoker it tells, forgetting one that has left."
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
"kind": "method",
|
|
1040
|
+
"name": "write",
|
|
1041
|
+
"privacy": "private",
|
|
1042
|
+
"return": {
|
|
1043
|
+
"type": {
|
|
1044
|
+
"text": "void"
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
"parameters": [
|
|
1048
|
+
{
|
|
1049
|
+
"name": "invoker",
|
|
1050
|
+
"type": {
|
|
1051
|
+
"text": "Element"
|
|
1052
|
+
}
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
"name": "open",
|
|
1056
|
+
"type": {
|
|
1057
|
+
"text": "boolean"
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
],
|
|
1061
|
+
"description": "Says `open` on one invoker: a Helix control through its `expanded`\nproperty, which its own button carries and which puts nothing in the\nmarkup, and a plain element through `aria-expanded`."
|
|
1062
|
+
},
|
|
992
1063
|
{
|
|
993
1064
|
"kind": "method",
|
|
994
1065
|
"name": "hostConnected",
|
|
@@ -998,6 +1069,15 @@
|
|
|
998
1069
|
}
|
|
999
1070
|
}
|
|
1000
1071
|
},
|
|
1072
|
+
{
|
|
1073
|
+
"kind": "method",
|
|
1074
|
+
"name": "hostUpdated",
|
|
1075
|
+
"return": {
|
|
1076
|
+
"type": {
|
|
1077
|
+
"text": "void"
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
},
|
|
1001
1081
|
{
|
|
1002
1082
|
"kind": "method",
|
|
1003
1083
|
"name": "hostDisconnected",
|
|
@@ -2675,6 +2755,25 @@
|
|
|
2675
2755
|
}
|
|
2676
2756
|
}
|
|
2677
2757
|
},
|
|
2758
|
+
{
|
|
2759
|
+
"kind": "method",
|
|
2760
|
+
"name": "span",
|
|
2761
|
+
"privacy": "private",
|
|
2762
|
+
"return": {
|
|
2763
|
+
"type": {
|
|
2764
|
+
"text": "Pick<DOMRect, 'bottom' | 'height' | 'left' | 'right' | 'top' | 'width'>"
|
|
2765
|
+
}
|
|
2766
|
+
},
|
|
2767
|
+
"parameters": [
|
|
2768
|
+
{
|
|
2769
|
+
"name": "active",
|
|
2770
|
+
"type": {
|
|
2771
|
+
"text": "HTMLElement"
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
],
|
|
2775
|
+
"description": "The box from `active` through the element `through` names, or `active`'s own."
|
|
2776
|
+
},
|
|
2678
2777
|
{
|
|
2679
2778
|
"kind": "method",
|
|
2680
2779
|
"name": "stopWaiting",
|
|
@@ -3923,7 +4022,7 @@
|
|
|
3923
4022
|
},
|
|
3924
4023
|
"privacy": "private",
|
|
3925
4024
|
"readonly": true,
|
|
3926
|
-
"default": "new FloatingController(host, { anchor: options.anchor, ...(options.arrow === undefined ? {} : { arrow: options.arrow }), floating: options.surface, ...(options.offset === undefined ? {} : { offset: options.offset }), ...(options.onPlace === undefined ? {} : { onPlace: options.onPlace }), ...(options.placement === undefined ? {} : { placement: options.placement }), ...(options.within === undefined ? {} : { within: options.within }), })"
|
|
4025
|
+
"default": "new FloatingController(host, { anchor: options.anchor, ...(options.arrow === undefined ? {} : { arrow: options.arrow }), floating: options.surface, ...(options.offset === undefined ? {} : { offset: options.offset }), ...(options.crossOffset === undefined ? {} : { crossOffset: options.crossOffset }), ...(options.flip === undefined ? {} : { flip: options.flip }), ...(options.padding === undefined ? {} : { padding: options.padding }), ...(options.onPlace === undefined ? {} : { onPlace: options.onPlace }), ...(options.placement === undefined ? {} : { placement: options.placement }), ...(options.within === undefined ? {} : { within: options.within }), })"
|
|
3927
4026
|
},
|
|
3928
4027
|
{
|
|
3929
4028
|
"kind": "field",
|
|
@@ -21133,7 +21232,7 @@
|
|
|
21133
21232
|
"text": "TemplateResult | typeof nothing"
|
|
21134
21233
|
}
|
|
21135
21234
|
},
|
|
21136
|
-
"description": "The `feedback` line, or nothing while there is none."
|
|
21235
|
+
"description": "The `feedback` line, or nothing while there is none.\n\n`role=\"alert\"`, as a field's feedback line has, so the message is\nannounced when it appears and the label and hint are not read with it."
|
|
21137
21236
|
}
|
|
21138
21237
|
],
|
|
21139
21238
|
"attributes": [
|
|
@@ -33711,7 +33810,7 @@
|
|
|
33711
33810
|
"type": {
|
|
33712
33811
|
"text": "string"
|
|
33713
33812
|
},
|
|
33714
|
-
"default": "'0.
|
|
33813
|
+
"default": "'0.173.0'",
|
|
33715
33814
|
"description": "The version of the package this file ships in.\n\n**Written by `fusion/scripts/version.mjs`** wherever it writes the package's\n`package.json`, and stamped back into the repository beside it after a\nrelease, so the two never disagree; a spec beside this holds them to it.\nNothing else in the running code knows which release it is."
|
|
33716
33815
|
}
|
|
33717
33816
|
],
|
|
@@ -34271,6 +34370,6 @@
|
|
|
34271
34370
|
],
|
|
34272
34371
|
"helix": {
|
|
34273
34372
|
"package": "@fusion.dev/helix-core",
|
|
34274
|
-
"version": "0.
|
|
34373
|
+
"version": "0.173.0"
|
|
34275
34374
|
}
|
|
34276
34375
|
}
|
|
@@ -40,6 +40,12 @@ export declare class HelixFallbackCommandEvent extends Event {
|
|
|
40
40
|
export interface CommandOptions {
|
|
41
41
|
/** Each command the host implements, keyed by the name a trigger writes. */
|
|
42
42
|
commands: Record<string, (source: Element | null) => void>;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the host is open, for a host a command opens and closes. Given,
|
|
45
|
+
* each invoker that has sent `--show` or `--toggle` says so with
|
|
46
|
+
* `aria-expanded`.
|
|
47
|
+
*/
|
|
48
|
+
expanded?: () => boolean;
|
|
43
49
|
}
|
|
44
50
|
/**
|
|
45
51
|
* Lets a control elsewhere on the page operate this one, declaratively.
|
|
@@ -75,7 +81,38 @@ export declare class CommandController implements ReactiveController {
|
|
|
75
81
|
private readonly host;
|
|
76
82
|
private readonly options;
|
|
77
83
|
constructor(host: ReactiveControllerHost & HTMLElement, options: CommandOptions);
|
|
84
|
+
/**
|
|
85
|
+
* The invokers this host tells whether it is open: each one that sent an
|
|
86
|
+
* opening command, unless it carried `aria-expanded` of its own before then.
|
|
87
|
+
*/
|
|
88
|
+
private readonly invokers;
|
|
89
|
+
/** Invokers that carried `aria-expanded` before a command, which stay the consumer's. */
|
|
90
|
+
private readonly theirs;
|
|
78
91
|
private readonly handle;
|
|
92
|
+
/**
|
|
93
|
+
* Takes the invoker on as one to tell, for a host that opens.
|
|
94
|
+
*
|
|
95
|
+
* **The platform says it for a native popover and not for this.** Chromium
|
|
96
|
+
* exposes a `popovertarget` button, or one with `command="toggle-popover"`,
|
|
97
|
+
* as expanded or collapsed, and a custom command reaches a custom element
|
|
98
|
+
* with nothing said. Measured before this: a `command="--toggle"` button
|
|
99
|
+
* opened a Popover and its node had no expanded state. React Aria's trigger
|
|
100
|
+
* says `aria-expanded` on every overlay it opens.
|
|
101
|
+
*
|
|
102
|
+
* From the first command on, so nothing is written onto markup a server
|
|
103
|
+
* sent until a reader presses. A plain invoker is also pointed at the host
|
|
104
|
+
* through `ariaControlsElements`, which writes no attribute.
|
|
105
|
+
*/
|
|
106
|
+
private note;
|
|
107
|
+
/** Writes the host's state on each invoker it tells, forgetting one that has left. */
|
|
108
|
+
private tell;
|
|
109
|
+
/**
|
|
110
|
+
* Says `open` on one invoker: a Helix control through its `expanded`
|
|
111
|
+
* property, which its own button carries and which puts nothing in the
|
|
112
|
+
* markup, and a plain element through `aria-expanded`.
|
|
113
|
+
*/
|
|
114
|
+
private write;
|
|
79
115
|
hostConnected(): void;
|
|
116
|
+
hostUpdated(): void;
|
|
80
117
|
hostDisconnected(): void;
|
|
81
118
|
}
|
|
@@ -6,24 +6,78 @@ export class HelixFallbackCommandEvent extends Event {
|
|
|
6
6
|
this.source = source;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
const OPENING = new Set(['--show', '--toggle']);
|
|
9
10
|
export class CommandController {
|
|
10
11
|
constructor(host, options) {
|
|
12
|
+
this.invokers = new Set();
|
|
13
|
+
this.theirs = new WeakSet();
|
|
11
14
|
this.handle = (event) => {
|
|
12
15
|
const command = event.command;
|
|
13
16
|
const run = this.options.commands[command];
|
|
14
17
|
if (!run) {
|
|
15
18
|
return;
|
|
16
19
|
}
|
|
17
|
-
|
|
20
|
+
const source = event.source;
|
|
21
|
+
if (OPENING.has(command)) {
|
|
22
|
+
this.note(source);
|
|
23
|
+
}
|
|
24
|
+
run(source);
|
|
18
25
|
};
|
|
19
26
|
this.host = host;
|
|
20
27
|
this.options = options;
|
|
21
28
|
host.addController(this);
|
|
22
29
|
}
|
|
30
|
+
note(source) {
|
|
31
|
+
if (!this.options.expanded || !source || this.invokers.has(source) || this.theirs.has(source)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (source.hasAttribute('aria-expanded')) {
|
|
35
|
+
this.theirs.add(source);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.invokers.add(source);
|
|
39
|
+
if (!source.localName.includes('-') && 'ariaControlsElements' in source) {
|
|
40
|
+
;
|
|
41
|
+
source.ariaControlsElements = [
|
|
42
|
+
this.host,
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
this.tell();
|
|
46
|
+
}
|
|
47
|
+
tell() {
|
|
48
|
+
const expanded = this.options.expanded;
|
|
49
|
+
if (!expanded) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const open = expanded();
|
|
53
|
+
for (const invoker of this.invokers) {
|
|
54
|
+
if (invoker.isConnected) {
|
|
55
|
+
this.write(invoker, open);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.invokers.delete(invoker);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
write(invoker, open) {
|
|
63
|
+
if (invoker.localName.includes('-')) {
|
|
64
|
+
;
|
|
65
|
+
invoker.expanded = open;
|
|
66
|
+
}
|
|
67
|
+
else if (invoker.getAttribute('aria-expanded') !== String(open)) {
|
|
68
|
+
invoker.setAttribute('aria-expanded', String(open));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
23
71
|
hostConnected() {
|
|
24
72
|
this.host.addEventListener('command', this.handle);
|
|
25
73
|
}
|
|
74
|
+
hostUpdated() {
|
|
75
|
+
this.tell();
|
|
76
|
+
}
|
|
26
77
|
hostDisconnected() {
|
|
27
78
|
this.host.removeEventListener('command', this.handle);
|
|
79
|
+
for (const invoker of this.invokers) {
|
|
80
|
+
this.write(invoker, false);
|
|
81
|
+
}
|
|
28
82
|
}
|
|
29
83
|
}
|
|
@@ -25,6 +25,13 @@ export type Placement = 'bottom' | 'bottom-end' | 'bottom-start' | 'left' | 'lef
|
|
|
25
25
|
export interface FloatingOptions {
|
|
26
26
|
/** The element being pointed at. */
|
|
27
27
|
anchor: () => HTMLElement | null | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* How far to slide the floating element along the side it is placed on, in
|
|
30
|
+
* pixels: rightward on the top or the bottom, downward on the left or the
|
|
31
|
+
* right, and toward the end of the line where the placement names `-end`.
|
|
32
|
+
* Floating UI's `crossAxis` offset, React Aria's `crossOffset`.
|
|
33
|
+
*/
|
|
34
|
+
crossOffset?: number | (() => number);
|
|
28
35
|
/**
|
|
29
36
|
* An element to point at the anchor, positioned against whichever side the
|
|
30
37
|
* floating element landed on.
|
|
@@ -32,13 +39,20 @@ export interface FloatingOptions {
|
|
|
32
39
|
arrow?: () => HTMLElement | null | undefined;
|
|
33
40
|
/** The element being placed. */
|
|
34
41
|
floating: () => HTMLElement | null | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* How close to the window's edges the floating element may come, in
|
|
44
|
+
* pixels, when it slides or is capped to fit, and, where it is given, when
|
|
45
|
+
* it flips. Defaults to 8 for the first two and none for flipping. React
|
|
46
|
+
* Aria's `containerPadding`, Radix's `collisionPadding`.
|
|
47
|
+
*/
|
|
48
|
+
padding?: number | (() => number | undefined);
|
|
35
49
|
/**
|
|
36
50
|
* Whether to try another side when the preferred one does not fit.
|
|
37
51
|
*
|
|
38
52
|
* On by default. A menu that opens off the bottom of the window is one the
|
|
39
53
|
* reader cannot use.
|
|
40
54
|
*/
|
|
41
|
-
flip?: boolean;
|
|
55
|
+
flip?: boolean | (() => boolean);
|
|
42
56
|
/**
|
|
43
57
|
* Told the placement the element landed on, after every measurement, and
|
|
44
58
|
* how wide the window leaves it room to be.
|
|
@@ -37,17 +37,24 @@ export class FloatingController {
|
|
|
37
37
|
const preferred = typeof this.options.placement === 'function'
|
|
38
38
|
? this.options.placement()
|
|
39
39
|
: this.options.placement;
|
|
40
|
-
const
|
|
40
|
+
const cross = typeof this.options.crossOffset === 'function'
|
|
41
|
+
? this.options.crossOffset()
|
|
42
|
+
: (this.options.crossOffset ?? 0);
|
|
43
|
+
const asked = typeof this.options.padding === 'function' ? this.options.padding() : this.options.padding;
|
|
44
|
+
const margin = asked ?? 8;
|
|
45
|
+
const edge = asked === undefined ? {} : { padding: asked };
|
|
46
|
+
const middleware = [offset({ crossAxis: cross, mainAxis: gap ?? 0 })];
|
|
41
47
|
let room;
|
|
42
|
-
|
|
48
|
+
const flips = typeof this.options.flip === 'function' ? this.options.flip() : this.options.flip;
|
|
49
|
+
if (flips !== false) {
|
|
43
50
|
const side = (preferred ?? 'bottom-start').split('-')[0];
|
|
44
51
|
middleware.push(flip(side === 'left' || side === 'right'
|
|
45
|
-
? { crossAxis: 'alignment', fallbackAxisSideDirection: 'end' }
|
|
46
|
-
:
|
|
52
|
+
? { crossAxis: 'alignment', fallbackAxisSideDirection: 'end', ...edge }
|
|
53
|
+
: edge));
|
|
47
54
|
}
|
|
48
55
|
if (this.options.shift !== false) {
|
|
49
56
|
const inside = this.options.within?.();
|
|
50
|
-
middleware.push(shift({ padding:
|
|
57
|
+
middleware.push(shift({ padding: margin, ...(inside ? { boundary: inside } : {}) }));
|
|
51
58
|
}
|
|
52
59
|
if (this.options.resize !== false) {
|
|
53
60
|
middleware.push(size({
|
|
@@ -56,7 +63,7 @@ export class FloatingController {
|
|
|
56
63
|
elements.floating.style.setProperty('--floating-available-block-size', `${Math.round(availableHeight)}px`);
|
|
57
64
|
elements.floating.style.setProperty('--floating-anchor-inline-size', `${matchedInlineSize(rects.reference.width, availableWidth)}px`);
|
|
58
65
|
},
|
|
59
|
-
padding:
|
|
66
|
+
padding: margin,
|
|
60
67
|
}));
|
|
61
68
|
}
|
|
62
69
|
if (pointer) {
|
|
@@ -21,6 +21,12 @@ export interface IndicatorOptions {
|
|
|
21
21
|
* re-read costs nothing and needs no bookkeeping about who is watched.
|
|
22
22
|
*/
|
|
23
23
|
observe?: () => readonly Element[];
|
|
24
|
+
/**
|
|
25
|
+
* The last element marked, where the mark runs from `active` through several,
|
|
26
|
+
* as an outline marking every section on screen. The mark then covers both
|
|
27
|
+
* and everything between. Absent, or the same element, it covers `active`.
|
|
28
|
+
*/
|
|
29
|
+
through?: () => HTMLElement | null | undefined;
|
|
24
30
|
/**
|
|
25
31
|
* The box the mark is positioned against, which is its containing block.
|
|
26
32
|
*
|
|
@@ -96,6 +102,8 @@ export declare class IndicatorController implements ReactiveController {
|
|
|
96
102
|
*/
|
|
97
103
|
private waiting;
|
|
98
104
|
place(): void;
|
|
105
|
+
/** The box from `active` through the element `through` names, or `active`'s own. */
|
|
106
|
+
private span;
|
|
99
107
|
/** Takes the pending listener and its guard off, wherever they came from. */
|
|
100
108
|
private stopWaiting;
|
|
101
109
|
}
|
|
@@ -35,7 +35,7 @@ export class IndicatorController {
|
|
|
35
35
|
indicator.removeAttribute('data-placed');
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
-
const box =
|
|
38
|
+
const box = this.span(active);
|
|
39
39
|
const own = surface.getBoundingClientRect();
|
|
40
40
|
if (box.width === 0 && box.height === 0) {
|
|
41
41
|
return;
|
|
@@ -69,6 +69,19 @@ export class IndicatorController {
|
|
|
69
69
|
this.waiting = { on: indicator, settle };
|
|
70
70
|
this.settling = setTimeout(settle, 1000);
|
|
71
71
|
}
|
|
72
|
+
span(active) {
|
|
73
|
+
const first = active.getBoundingClientRect();
|
|
74
|
+
const end = this.options.through?.();
|
|
75
|
+
if (!end || end === active) {
|
|
76
|
+
return first;
|
|
77
|
+
}
|
|
78
|
+
const last = end.getBoundingClientRect();
|
|
79
|
+
const top = Math.min(first.top, last.top);
|
|
80
|
+
const bottom = Math.max(first.bottom, last.bottom);
|
|
81
|
+
const left = Math.min(first.left, last.left);
|
|
82
|
+
const right = Math.max(first.right, last.right);
|
|
83
|
+
return { bottom, height: bottom - top, left, right, top, width: right - left };
|
|
84
|
+
}
|
|
72
85
|
stopWaiting() {
|
|
73
86
|
clearTimeout(this.settling);
|
|
74
87
|
this.settling = undefined;
|
|
@@ -21,6 +21,12 @@ export interface PopoverOptions {
|
|
|
21
21
|
boundary?: () => Element | readonly (Element | null | undefined)[] | null | undefined;
|
|
22
22
|
/** Space between the anchor and the surface, in pixels. */
|
|
23
23
|
offset?: number | (() => number);
|
|
24
|
+
/** Whether the surface may move to the other side to fit. On by default. See `FloatingController`. */
|
|
25
|
+
flip?: boolean | (() => boolean);
|
|
26
|
+
/** How far to slide the surface along its side, in pixels. See `FloatingController`. */
|
|
27
|
+
crossOffset?: number | (() => number);
|
|
28
|
+
/** How close to the window's edges the surface may come, in pixels. See `FloatingController`. */
|
|
29
|
+
padding?: number | (() => number | undefined);
|
|
24
30
|
/**
|
|
25
31
|
* A box to keep the surface inside, instead of the viewport.
|
|
26
32
|
*
|
|
@@ -10,6 +10,9 @@ export class PopoverController {
|
|
|
10
10
|
...(options.arrow === undefined ? {} : { arrow: options.arrow }),
|
|
11
11
|
floating: options.surface,
|
|
12
12
|
...(options.offset === undefined ? {} : { offset: options.offset }),
|
|
13
|
+
...(options.crossOffset === undefined ? {} : { crossOffset: options.crossOffset }),
|
|
14
|
+
...(options.flip === undefined ? {} : { flip: options.flip }),
|
|
15
|
+
...(options.padding === undefined ? {} : { padding: options.padding }),
|
|
13
16
|
...(options.onPlace === undefined ? {} : { onPlace: options.onPlace }),
|
|
14
17
|
...(options.placement === undefined ? {} : { placement: options.placement }),
|
|
15
18
|
...(options.within === undefined ? {} : { within: options.within }),
|
|
@@ -57,7 +57,7 @@ export const MixinPickerFeedback = (Base) => {
|
|
|
57
57
|
renderPickerFeedback() {
|
|
58
58
|
return this.feedback === ''
|
|
59
59
|
? nothing
|
|
60
|
-
: html `<p part="feedback" id="feedback">${this.feedback}</p>`;
|
|
60
|
+
: html `<p part="feedback" id="feedback" role="alert">${this.feedback}</p>`;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
__decorate([
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.173.0';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.173.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@floating-ui/dom": "^1.8.0",
|
|
65
|
-
"@fusion.dev/helix-icons": "0.
|
|
65
|
+
"@fusion.dev/helix-icons": "0.173.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@fusion.dev/helix-cem": "0.
|
|
69
|
-
"@fusion.dev/helix-testing": "0.
|
|
68
|
+
"@fusion.dev/helix-cem": "0.173.0",
|
|
69
|
+
"@fusion.dev/helix-testing": "0.173.0",
|
|
70
70
|
"@lit-labs/ssr": "^4.1.0",
|
|
71
71
|
"lit": "^3.2.1"
|
|
72
72
|
},
|