@oscarpalmer/oui 0.18.0 → 0.20.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/dist/css/a11y.css +0 -1
- package/dist/css/badge.css +10 -10
- package/dist/css/button.css +9 -9
- package/dist/css/color.css +99 -99
- package/dist/css/content.css +1 -1
- package/dist/css/flex.css +39 -39
- package/dist/css/form.css +29 -57
- package/dist/css/message.css +6 -6
- package/dist/css/popover.css +22 -0
- package/dist/css/reset.css +11 -10
- package/dist/css/table.css +5 -5
- package/dist/css/tooltip.css +61 -1
- package/dist/js/attributable.d.mts +4 -0
- package/dist/js/{attributable.js → attributable.mjs} +8 -1
- package/dist/js/floatable.d.mts +26 -0
- package/dist/js/{floatable.js → floatable.mjs} +73 -50
- package/dist/js/focus-trap/embedded.d.mts +26 -0
- package/dist/js/focus-trap/{embedded.js → embedded.mjs} +10 -8
- package/dist/js/focus-trap/standalone.d.mts +1 -0
- package/dist/js/focus-trap/{standalone.js → standalone.mjs} +5 -2
- package/dist/js/index.d.mts +4 -0
- package/dist/js/index.mjs +5 -0
- package/dist/js/popover.d.mts +20 -0
- package/dist/js/{popover.js → popover.mjs} +11 -9
- package/dist/js/splitter.d.mts +25 -0
- package/dist/js/{splitter.js → splitter.mjs} +60 -58
- package/dist/js/tooltip.d.mts +4 -0
- package/dist/js/{tooltip.js → tooltip.mjs} +21 -19
- package/package.json +65 -70
- package/src/css/a11y.scss +1 -1
- package/src/css/badge.scss +23 -19
- package/src/css/button.scss +9 -9
- package/src/css/color.scss +99 -99
- package/src/css/content.scss +6 -8
- package/src/css/flex.scss +21 -20
- package/src/css/form.scss +37 -60
- package/src/css/message.scss +8 -12
- package/src/css/mixins.scss +41 -13
- package/src/css/popover.scss +7 -2
- package/src/css/reset.scss +18 -18
- package/src/css/splitter.scss +15 -13
- package/src/css/table.scss +12 -12
- package/src/css/tooltip.scss +79 -4
- package/src/js/attributable.ts +14 -11
- package/src/js/floatable.ts +134 -74
- package/src/js/focus-trap/embedded.ts +7 -31
- package/src/js/popover.ts +3 -3
- package/src/js/splitter.ts +10 -43
- package/src/js/tooltip.ts +8 -20
- package/dist/css/value.css +0 -1
- package/dist/js/attributable.full.js +0 -48
- package/dist/js/floatable.full.js +0 -413
- package/dist/js/focus-trap/embedded.full.js +0 -351
- package/dist/js/focus-trap/standalone.full.js +0 -402
- package/dist/js/index.js +0 -5
- package/dist/js/oui.full.js +0 -1596
- package/dist/js/popover.full.js +0 -822
- package/dist/js/splitter.full.js +0 -605
- package/dist/js/tooltip.full.js +0 -679
- package/types/attributable.d.ts +0 -1
- package/types/floatable.d.ts +0 -24
- package/types/focus-trap/embedded.d.ts +0 -24
- package/types/focus-trap/standalone.d.ts +0 -1
- package/types/index.d.ts +0 -4
- package/types/popover.d.ts +0 -17
- package/types/splitter.d.ts +0 -23
- package/types/tooltip.d.ts +0 -2
package/src/css/table.scss
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
background-color: var(--oui-absolute);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
:where(
|
|
9
|
+
:where(&_wrapper) {
|
|
10
10
|
max-height: 32em;
|
|
11
11
|
overflow: auto;
|
|
12
|
+
overscroll-behavior: contain;
|
|
12
13
|
border: 1px solid var(--oui-gray-3);
|
|
13
|
-
border-radius: .25em;
|
|
14
|
+
border-radius: 0.25em;
|
|
14
15
|
position: relative;
|
|
15
|
-
overscroll-behavior-y: none;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
:where(& caption) {
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
align-content: center;
|
|
21
21
|
background-color: var(--oui-gray-1);
|
|
22
22
|
border: solid var(--oui-gray-3);
|
|
23
|
-
border-width: 0 0 1px
|
|
24
|
-
font-size: .875rem;
|
|
23
|
+
border-width: 0 0 1px;
|
|
24
|
+
font-size: 0.875rem;
|
|
25
25
|
text-align: left;
|
|
26
|
-
text-indent: .5rem;
|
|
26
|
+
text-indent: 0.5rem;
|
|
27
27
|
position: sticky;
|
|
28
28
|
top: 0;
|
|
29
29
|
z-index: 2;
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
height: 4px;
|
|
51
51
|
background-image: linear-gradient(
|
|
52
52
|
to var(--oui-shadow-direction),
|
|
53
|
-
|
|
53
|
+
rgb(0 0 0 / 10%),
|
|
54
54
|
transparent
|
|
55
55
|
);
|
|
56
56
|
position: absolute;
|
|
@@ -58,13 +58,13 @@
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
:where(& th, & td) {
|
|
61
|
-
padding: .5em .625rem;
|
|
61
|
+
padding: 0.5em 0.625rem;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
:where(& thead th) {
|
|
65
|
-
font-size: .75rem;
|
|
65
|
+
font-size: 0.75rem;
|
|
66
66
|
font-weight: bold;
|
|
67
|
-
letter-spacing: .1em;
|
|
67
|
+
letter-spacing: 0.1em;
|
|
68
68
|
text-align: left;
|
|
69
69
|
text-transform: uppercase;
|
|
70
70
|
top: 0;
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
--oui-shadow-direction: bottom;
|
|
74
74
|
|
|
75
75
|
border-top: 1px solid var(--oui-gray-3);
|
|
76
|
-
inset: 100
|
|
76
|
+
inset: 100%;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
--oui-shadow-direction: top;
|
|
89
89
|
|
|
90
90
|
border-bottom: 1px solid var(--oui-gray-3);
|
|
91
|
-
inset: -4px
|
|
91
|
+
inset: -4px;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
package/src/css/tooltip.scss
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
@use 'mixins.scss' as mixins;
|
|
2
2
|
|
|
3
|
-
:where(
|
|
3
|
+
:where(
|
|
4
|
+
[oui-tooltip]:is(
|
|
5
|
+
abbr,
|
|
6
|
+
b,
|
|
7
|
+
cite,
|
|
8
|
+
dfn,
|
|
9
|
+
code,
|
|
10
|
+
em,
|
|
11
|
+
i,
|
|
12
|
+
kbd,
|
|
13
|
+
mark,
|
|
14
|
+
q,
|
|
15
|
+
samp,
|
|
16
|
+
small,
|
|
17
|
+
span,
|
|
18
|
+
strong,
|
|
19
|
+
sub,
|
|
20
|
+
sup,
|
|
21
|
+
time,
|
|
22
|
+
var
|
|
23
|
+
)
|
|
24
|
+
) {
|
|
4
25
|
text-decoration: underline dotted;
|
|
5
26
|
text-decoration-skip-ink: auto;
|
|
6
27
|
text-underline-offset: 0.25em;
|
|
@@ -8,7 +29,7 @@
|
|
|
8
29
|
}
|
|
9
30
|
|
|
10
31
|
:where([oui-tooltip-content]) {
|
|
11
|
-
@include mixins.
|
|
32
|
+
@include mixins.floatable;
|
|
12
33
|
|
|
13
34
|
max-width: 48ch;
|
|
14
35
|
padding: 0.75em 1em;
|
|
@@ -16,11 +37,65 @@
|
|
|
16
37
|
background-color: var(--oui-absolute);
|
|
17
38
|
border-radius: 0.25rem;
|
|
18
39
|
font-size: 0.875rem;
|
|
19
|
-
transition: opacity .125s ease-in-out;
|
|
40
|
+
transition: opacity 0.125s ease-in-out;
|
|
20
41
|
transition-delay: 0s;
|
|
42
|
+
|
|
43
|
+
&::after {
|
|
44
|
+
content: '';
|
|
45
|
+
opacity: 0;
|
|
46
|
+
position: absolute;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&[position^='above'],
|
|
50
|
+
&[position^='below'],
|
|
51
|
+
&[position^='bottom'],
|
|
52
|
+
&[position^='top'] {
|
|
53
|
+
&::after {
|
|
54
|
+
width: 100%;
|
|
55
|
+
height: 0.5rem;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&[position^='above'],
|
|
60
|
+
&[position^='top'] {
|
|
61
|
+
&::after {
|
|
62
|
+
inset: 100% 0 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&[position^='below'],
|
|
67
|
+
&[position^='bottom'] {
|
|
68
|
+
&::after {
|
|
69
|
+
inset: -5rem 0 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&[position^='end'],
|
|
74
|
+
&[position^='left'],
|
|
75
|
+
&[position^='right'],
|
|
76
|
+
&[position^='start'] {
|
|
77
|
+
&::after {
|
|
78
|
+
width: 0.5rem;
|
|
79
|
+
height: 100%;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
&[position^='end'],
|
|
84
|
+
&[position^='right'] {
|
|
85
|
+
&::after {
|
|
86
|
+
inset: 0 0 0 -0.5rem;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&[position^='left'],
|
|
91
|
+
&[position^='start'] {
|
|
92
|
+
&::after {
|
|
93
|
+
inset: 0 0 0 100%;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
21
96
|
}
|
|
22
97
|
|
|
23
98
|
:where([oui-tooltip-content][oui-tooltip-content-active]) {
|
|
24
99
|
opacity: 1;
|
|
25
|
-
transition-delay: .25s;
|
|
100
|
+
transition-delay: 0.25s;
|
|
26
101
|
}
|
package/src/js/attributable.ts
CHANGED
|
@@ -39,9 +39,7 @@ function handleAdded(
|
|
|
39
39
|
nodes: Node[] | NodeList,
|
|
40
40
|
add: (element: HTMLElement) => void,
|
|
41
41
|
): void {
|
|
42
|
-
const elements = [...nodes].filter(
|
|
43
|
-
node => node instanceof HTMLElement,
|
|
44
|
-
) as HTMLElement[];
|
|
42
|
+
const elements = [...nodes].filter(node => node instanceof HTMLElement) as HTMLElement[];
|
|
45
43
|
|
|
46
44
|
const {length} = elements;
|
|
47
45
|
|
|
@@ -51,20 +49,25 @@ function handleAdded(
|
|
|
51
49
|
if (element.hasAttribute(attribute)) {
|
|
52
50
|
add(element);
|
|
53
51
|
}
|
|
52
|
+
|
|
53
|
+
if (element.hasChildNodes()) {
|
|
54
|
+
handleAdded(attribute, element.childNodes, add);
|
|
55
|
+
}
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
function handleRemoved(
|
|
58
|
-
|
|
59
|
-
remove: (element: HTMLElement) => void,
|
|
60
|
-
): void {
|
|
61
|
-
const elements = [...nodes].filter(
|
|
62
|
-
node => node instanceof HTMLElement,
|
|
63
|
-
) as HTMLElement[];
|
|
59
|
+
function handleRemoved(nodes: Node[] | NodeList, remove: (element: HTMLElement) => void): void {
|
|
60
|
+
const elements = [...nodes].filter(node => node instanceof HTMLElement) as HTMLElement[];
|
|
64
61
|
|
|
65
62
|
const {length} = elements;
|
|
66
63
|
|
|
67
64
|
for (let index = 0; index < length; index += 1) {
|
|
68
|
-
|
|
65
|
+
const element = elements[index];
|
|
66
|
+
|
|
67
|
+
remove(element);
|
|
68
|
+
|
|
69
|
+
if (element.hasChildNodes()) {
|
|
70
|
+
handleRemoved(element.childNodes, remove);
|
|
71
|
+
}
|
|
69
72
|
}
|
|
70
73
|
}
|
package/src/js/floatable.ts
CHANGED
|
@@ -91,7 +91,6 @@ export class Floatable {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
type FloatableWindow = Window & {
|
|
94
|
-
// biome-ignore lint/style/useNamingConvention: Non-standard name to avoid conflicts
|
|
95
94
|
_oscarpalmer_oui_floatable: State;
|
|
96
95
|
};
|
|
97
96
|
|
|
@@ -151,9 +150,7 @@ function closeAbove(element: HTMLElement): void {
|
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
const index = state.order.findIndex(
|
|
154
|
-
floatable =>
|
|
155
|
-
floatable.options.anchor === element ||
|
|
156
|
-
floatable.options.content === element,
|
|
153
|
+
floatable => floatable.options.anchor === element || floatable.options.content === element,
|
|
157
154
|
);
|
|
158
155
|
|
|
159
156
|
if (index === -1 || index === state.order.length - 1) {
|
|
@@ -190,95 +187,162 @@ export function deactivate(floatable: Floatable): void {
|
|
|
190
187
|
|
|
191
188
|
floatable.options.content.hidden = true;
|
|
192
189
|
|
|
193
|
-
floatable.options.anchor.insertAdjacentElement(
|
|
194
|
-
INSERT_AFTEREND,
|
|
195
|
-
floatable.options.content,
|
|
196
|
-
);
|
|
190
|
+
floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
|
|
197
191
|
|
|
198
192
|
floatable.options.onAfter?.(false);
|
|
199
193
|
}
|
|
200
194
|
|
|
195
|
+
function getAttribute(
|
|
196
|
+
position: Position,
|
|
197
|
+
anchor: DOMRect,
|
|
198
|
+
top: number,
|
|
199
|
+
left: number,
|
|
200
|
+
): Position | undefined {
|
|
201
|
+
switch (position) {
|
|
202
|
+
case 'horizontal':
|
|
203
|
+
case 'horizontal-bottom':
|
|
204
|
+
case 'horizontal-top':
|
|
205
|
+
return position.replace('horizontal', left >= anchor.right ? 'right' : 'left') as Position;
|
|
206
|
+
|
|
207
|
+
case 'vertical':
|
|
208
|
+
case 'vertical-end':
|
|
209
|
+
case 'vertical-start':
|
|
210
|
+
return position.replace('vertical', top >= anchor.bottom ? 'bottom' : 'top') as Position;
|
|
211
|
+
|
|
212
|
+
default:
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function getMargin(): number {
|
|
218
|
+
try {
|
|
219
|
+
const fontsize = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
220
|
+
|
|
221
|
+
if (Number.isNaN(fontsize)) {
|
|
222
|
+
return 5;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const margin = fontsize / 2;
|
|
226
|
+
|
|
227
|
+
return margin < 5 ? 5 : margin;
|
|
228
|
+
} catch {
|
|
229
|
+
return 5;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
201
233
|
function getState(): State {
|
|
202
234
|
return (window as unknown as FloatableWindow)._oscarpalmer_oui_floatable;
|
|
203
235
|
}
|
|
204
236
|
|
|
205
|
-
function getX(anchor: DOMRect, content: DOMRect, position: Position): number {
|
|
206
|
-
if (position
|
|
207
|
-
const
|
|
237
|
+
function getX(anchor: DOMRect, content: DOMRect, position: Position, margin: number): number {
|
|
238
|
+
if (position === 'above' || position === 'below' || position === 'vertical') {
|
|
239
|
+
const center = anchor.left + anchor.width / 2;
|
|
240
|
+
const width = content.width / 2;
|
|
208
241
|
|
|
209
|
-
|
|
210
|
-
|
|
242
|
+
if (center + width + margin >= document.body.clientWidth) {
|
|
243
|
+
return document.body.clientWidth - content.width - margin / 2;
|
|
244
|
+
}
|
|
211
245
|
|
|
212
|
-
|
|
213
|
-
|
|
246
|
+
if (center - width - margin <= 0) {
|
|
247
|
+
return margin / 2;
|
|
248
|
+
}
|
|
214
249
|
|
|
215
|
-
return
|
|
216
|
-
? window.innerWidth - content.width
|
|
217
|
-
: start;
|
|
250
|
+
return center - width;
|
|
218
251
|
}
|
|
219
252
|
|
|
220
|
-
if (position.startsWith(
|
|
253
|
+
if (position.startsWith('end')) {
|
|
221
254
|
return anchor.right;
|
|
222
255
|
}
|
|
223
256
|
|
|
224
|
-
if (position.startsWith(
|
|
257
|
+
if (position.startsWith('start')) {
|
|
225
258
|
return anchor.left - content.width;
|
|
226
259
|
}
|
|
227
260
|
|
|
228
|
-
if (position.
|
|
229
|
-
|
|
230
|
-
|
|
261
|
+
if (position.endsWith('end')) {
|
|
262
|
+
return anchor.right - content.width - margin <= 0 ? margin / 2 : anchor.right - content.width;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (position.endsWith('start')) {
|
|
266
|
+
if (anchor.left + content.width + margin >= document.body.clientWidth) {
|
|
267
|
+
return document.body.clientWidth - content.width - margin / 2;
|
|
231
268
|
}
|
|
232
269
|
|
|
233
|
-
return anchor.left -
|
|
270
|
+
return anchor.left - margin <= 0 ? margin / 2 : anchor.left;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (!position.startsWith('horizontal')) {
|
|
274
|
+
return 0;
|
|
234
275
|
}
|
|
235
276
|
|
|
236
|
-
|
|
277
|
+
if (anchor.right + content.width + margin >= document.body.clientWidth) {
|
|
278
|
+
return anchor.left - content.width;
|
|
279
|
+
}
|
|
237
280
|
|
|
238
|
-
return
|
|
281
|
+
return anchor.right;
|
|
239
282
|
}
|
|
240
283
|
|
|
241
284
|
function getY(
|
|
242
285
|
anchor: DOMRect,
|
|
243
286
|
content: DOMRect,
|
|
244
287
|
position: Position,
|
|
288
|
+
margin: number,
|
|
245
289
|
preferAbove: boolean,
|
|
246
290
|
): number {
|
|
247
|
-
if (position
|
|
291
|
+
if (position === 'end' || position === 'start' || position === 'horizontal') {
|
|
292
|
+
const center = anchor.top + anchor.height / 2;
|
|
293
|
+
const height = content.height / 2;
|
|
294
|
+
|
|
295
|
+
if (center + height + margin >= document.body.clientHeight) {
|
|
296
|
+
return document.body.clientHeight - content.height - margin / 2;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (center - height - margin <= 0) {
|
|
300
|
+
return margin / 2;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return center - height;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (position.startsWith('above')) {
|
|
248
307
|
return anchor.top - content.height;
|
|
249
308
|
}
|
|
250
309
|
|
|
251
|
-
if (position.startsWith(
|
|
310
|
+
if (position.startsWith('below')) {
|
|
252
311
|
return anchor.bottom;
|
|
253
312
|
}
|
|
254
313
|
|
|
255
|
-
if (position.endsWith(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
314
|
+
if (position.endsWith('bottom')) {
|
|
315
|
+
return anchor.bottom - content.height - margin <= 0
|
|
316
|
+
? margin / 2
|
|
317
|
+
: anchor.bottom - content.height;
|
|
259
318
|
}
|
|
260
319
|
|
|
261
|
-
if (position.endsWith(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
? window.innerHeight - content.height
|
|
266
|
-
: top;
|
|
320
|
+
if (position.endsWith('top')) {
|
|
321
|
+
return anchor.top + content.height + margin >= document.body.clientHeight
|
|
322
|
+
? document.body.clientHeight - content.height - margin
|
|
323
|
+
: anchor.top;
|
|
267
324
|
}
|
|
268
325
|
|
|
269
|
-
if (position.startsWith(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
326
|
+
if (!position.startsWith('vertical')) {
|
|
327
|
+
return 0;
|
|
328
|
+
}
|
|
273
329
|
|
|
274
|
-
|
|
330
|
+
if (preferAbove) {
|
|
331
|
+
if (
|
|
332
|
+
anchor.top - content.height - margin <= 0 &&
|
|
333
|
+
anchor.bottom + content.height + margin <= document.body.clientHeight
|
|
334
|
+
) {
|
|
275
335
|
return anchor.bottom;
|
|
276
336
|
}
|
|
277
337
|
|
|
278
338
|
return anchor.top - content.height;
|
|
279
339
|
}
|
|
280
340
|
|
|
281
|
-
|
|
341
|
+
if (anchor.bottom + content.height + margin >= document.body.clientHeight) {
|
|
342
|
+
return anchor.top - content.height;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return anchor.bottom;
|
|
282
346
|
}
|
|
283
347
|
|
|
284
348
|
function initialize(floatable: Floatable): void {
|
|
@@ -308,7 +372,7 @@ function isDisabled(element: HTMLElement): boolean {
|
|
|
308
372
|
}
|
|
309
373
|
|
|
310
374
|
function onClick(event: PointerEvent): void {
|
|
311
|
-
const related = findAncestor(event
|
|
375
|
+
const related = findAncestor(event, SELECTOR_ALL);
|
|
312
376
|
|
|
313
377
|
if (!(related instanceof HTMLElement)) {
|
|
314
378
|
closeAll();
|
|
@@ -332,7 +396,7 @@ function onKeyDown(event: KeyboardEvent): void {
|
|
|
332
396
|
|
|
333
397
|
closeNonInteractive(state);
|
|
334
398
|
|
|
335
|
-
const related = findAncestor(event
|
|
399
|
+
const related = findAncestor(event, SELECTOR_CONTENT);
|
|
336
400
|
|
|
337
401
|
if (!(related instanceof HTMLElement)) {
|
|
338
402
|
return;
|
|
@@ -347,6 +411,22 @@ function onKeyDown(event: KeyboardEvent): void {
|
|
|
347
411
|
}
|
|
348
412
|
}
|
|
349
413
|
|
|
414
|
+
function setAttribute(
|
|
415
|
+
position: Position,
|
|
416
|
+
anchor: DOMRect,
|
|
417
|
+
floater: HTMLElement,
|
|
418
|
+
top: number,
|
|
419
|
+
left: number,
|
|
420
|
+
): void {
|
|
421
|
+
let actual: Position | undefined;
|
|
422
|
+
|
|
423
|
+
if (/^(horizontal|vertical)/.test(position)) {
|
|
424
|
+
actual = getAttribute(position, anchor, top, left);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
floater.setAttribute('position', actual ?? position);
|
|
428
|
+
}
|
|
429
|
+
|
|
350
430
|
function stop(floatable: Floatable): void {
|
|
351
431
|
if (floatable.frame != null) {
|
|
352
432
|
cancelAnimationFrame(floatable.frame);
|
|
@@ -386,6 +466,8 @@ function updatePosition(floatable: Floatable): void {
|
|
|
386
466
|
position = floatable.options.defaultPosition;
|
|
387
467
|
}
|
|
388
468
|
|
|
469
|
+
const margin = getMargin();
|
|
470
|
+
|
|
389
471
|
let previousAnchor: DOMRect;
|
|
390
472
|
let previousContent: DOMRect;
|
|
391
473
|
|
|
@@ -399,12 +481,8 @@ function updatePosition(floatable: Floatable): void {
|
|
|
399
481
|
if (calculated) {
|
|
400
482
|
if (previousAnchor != null && previousContent != null) {
|
|
401
483
|
if (
|
|
402
|
-
PROPERTIES.every(
|
|
403
|
-
|
|
404
|
-
) &&
|
|
405
|
-
PROPERTIES.every(
|
|
406
|
-
property => content[property] === previousContent[property],
|
|
407
|
-
)
|
|
484
|
+
PROPERTIES.every(property => anchor[property] === previousAnchor[property]) &&
|
|
485
|
+
PROPERTIES.every(property => content[property] === previousContent[property])
|
|
408
486
|
) {
|
|
409
487
|
floatable.frame = requestAnimationFrame(run);
|
|
410
488
|
|
|
@@ -422,8 +500,10 @@ function updatePosition(floatable: Floatable): void {
|
|
|
422
500
|
previousAnchor = anchor;
|
|
423
501
|
previousContent = content;
|
|
424
502
|
|
|
425
|
-
const left = getX(anchor, content, position);
|
|
426
|
-
const top = getY(anchor, content, position, floatable.options.preferAbove);
|
|
503
|
+
const left = getX(anchor, content, position, margin);
|
|
504
|
+
const top = getY(anchor, content, position, margin, floatable.options.preferAbove);
|
|
505
|
+
|
|
506
|
+
setAttribute(position, anchor, floatable.options.content, top, left);
|
|
427
507
|
|
|
428
508
|
if (top + content.height > window.innerHeight) {
|
|
429
509
|
floatable.options.content.style.height = `${window.innerHeight - top}px`;
|
|
@@ -460,26 +540,6 @@ const ATTRIBUTE_CONTENT = 'oui-floatable-content';
|
|
|
460
540
|
|
|
461
541
|
const INSERT_AFTEREND = 'afterend';
|
|
462
542
|
|
|
463
|
-
const POSITION_ABOVE = 'above';
|
|
464
|
-
|
|
465
|
-
const POSITION_BELOW = 'below';
|
|
466
|
-
|
|
467
|
-
const POSITION_BOTTOM = 'bottom';
|
|
468
|
-
|
|
469
|
-
const POSITION_END = 'end';
|
|
470
|
-
|
|
471
|
-
const POSITION_HORIZONTAL = 'horizontal';
|
|
472
|
-
|
|
473
|
-
const POSITION_START = 'start';
|
|
474
|
-
|
|
475
|
-
const POSITION_SUFFIX_END = '-end';
|
|
476
|
-
|
|
477
|
-
const POSITION_SUFFIX_START = '-start';
|
|
478
|
-
|
|
479
|
-
const POSITION_TOP = 'top';
|
|
480
|
-
|
|
481
|
-
const POSITION_VERTICAL = 'vertical';
|
|
482
|
-
|
|
483
543
|
const POSITIONS: Set<Position> = new Set([
|
|
484
544
|
'above',
|
|
485
545
|
'above-end',
|
|
@@ -70,10 +70,7 @@ type Options = {
|
|
|
70
70
|
|
|
71
71
|
//
|
|
72
72
|
|
|
73
|
-
export function createFocusTrap(
|
|
74
|
-
element: HTMLElement,
|
|
75
|
-
options?: Options,
|
|
76
|
-
): FocusTrap {
|
|
73
|
+
export function createFocusTrap(element: HTMLElement, options?: Options): FocusTrap {
|
|
77
74
|
let focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
78
75
|
|
|
79
76
|
if (focusTrap == null) {
|
|
@@ -86,10 +83,7 @@ export function createFocusTrap(
|
|
|
86
83
|
}
|
|
87
84
|
|
|
88
85
|
function onEscape(event: KeyboardEvent): void {
|
|
89
|
-
let element = findAncestor(
|
|
90
|
-
event.target as HTMLElement,
|
|
91
|
-
ATTRIBUTE_SELECTOR,
|
|
92
|
-
) as HTMLElement;
|
|
86
|
+
let element = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
|
|
93
87
|
|
|
94
88
|
let focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
95
89
|
|
|
@@ -118,12 +112,7 @@ function onEscape(event: KeyboardEvent): void {
|
|
|
118
112
|
}
|
|
119
113
|
|
|
120
114
|
function onFocusIn(event: Event): void {
|
|
121
|
-
const focusTrap = FOCUSTRAPS_ALL.get(
|
|
122
|
-
findAncestor(
|
|
123
|
-
event.target as HTMLElement,
|
|
124
|
-
ATTRIBUTE_SELECTOR,
|
|
125
|
-
) as HTMLElement,
|
|
126
|
-
);
|
|
115
|
+
const focusTrap = FOCUSTRAPS_ALL.get(findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement);
|
|
127
116
|
|
|
128
117
|
lastTarget = focusTrap == null ? undefined : (event.target as HTMLElement);
|
|
129
118
|
}
|
|
@@ -144,15 +133,8 @@ function onKeydown(event: KeyboardEvent): void {
|
|
|
144
133
|
}
|
|
145
134
|
|
|
146
135
|
function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
147
|
-
const lastFocusTrap = findAncestor(
|
|
148
|
-
|
|
149
|
-
ATTRIBUTE_SELECTOR,
|
|
150
|
-
) as HTMLElement;
|
|
151
|
-
|
|
152
|
-
const nextFocusTrap = findAncestor(
|
|
153
|
-
event.target as HTMLElement,
|
|
154
|
-
ATTRIBUTE_SELECTOR,
|
|
155
|
-
) as HTMLElement;
|
|
136
|
+
const lastFocusTrap = findAncestor(lastTarget as HTMLElement, ATTRIBUTE_SELECTOR) as HTMLElement;
|
|
137
|
+
const nextFocusTrap = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
|
|
156
138
|
|
|
157
139
|
if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
|
|
158
140
|
if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
|
|
@@ -174,10 +156,7 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
|
|
|
174
156
|
}
|
|
175
157
|
|
|
176
158
|
function onTab(event: KeyboardEvent): void {
|
|
177
|
-
const element = findAncestor(
|
|
178
|
-
event.target as HTMLElement,
|
|
179
|
-
ATTRIBUTE_SELECTOR,
|
|
180
|
-
) as HTMLElement;
|
|
159
|
+
const element = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
|
|
181
160
|
|
|
182
161
|
const focusTrap = FOCUSTRAPS_ALL.get(element);
|
|
183
162
|
|
|
@@ -228,10 +207,7 @@ function tabToElement(
|
|
|
228
207
|
const next = clamp(index + modifier, 0, length - 1, true);
|
|
229
208
|
|
|
230
209
|
if (focusTrap.disabled) {
|
|
231
|
-
if (
|
|
232
|
-
(index === length - 1 && next === 0) ||
|
|
233
|
-
(index === 0 && next === length - 1)
|
|
234
|
-
) {
|
|
210
|
+
if ((index === length - 1 && next === 0) || (index === 0 && next === length - 1)) {
|
|
235
211
|
lastTarget = undefined;
|
|
236
212
|
|
|
237
213
|
focusTrap.enable();
|
package/src/js/popover.ts
CHANGED
|
@@ -84,7 +84,7 @@ export class OuiPopoverElement extends HTMLElement {
|
|
|
84
84
|
this.#focusTrap.disconnect();
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
hidePopover(): void {
|
|
87
|
+
override hidePopover(): void {
|
|
88
88
|
if (this.#floatable.active && this.isConnected) {
|
|
89
89
|
this.#floatable.toggle(false);
|
|
90
90
|
}
|
|
@@ -94,7 +94,7 @@ export class OuiPopoverElement extends HTMLElement {
|
|
|
94
94
|
this.showPopover();
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
showPopover(): void {
|
|
97
|
+
override showPopover(): void {
|
|
98
98
|
if (!this.#floatable.active && this.isConnected) {
|
|
99
99
|
this.#floatable.toggle(true);
|
|
100
100
|
}
|
|
@@ -104,7 +104,7 @@ export class OuiPopoverElement extends HTMLElement {
|
|
|
104
104
|
this.togglePopover();
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
togglePopover(options?: boolean): boolean {
|
|
107
|
+
override togglePopover(options?: boolean): boolean {
|
|
108
108
|
if (typeof options === 'boolean') {
|
|
109
109
|
if (options === true) {
|
|
110
110
|
this.showPopover();
|