@oscarpalmer/oui 0.15.0 → 0.17.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/button.css +0 -3
- package/dist/css/popover.css +3 -0
- package/dist/css/splitter.css +78 -0
- package/dist/js/floatable.cjs +77 -35
- package/dist/js/floatable.js +77 -35
- package/dist/js/popover.cjs +8 -2
- package/dist/js/popover.js +8 -2
- package/dist/js/splitter.cjs +272 -0
- package/dist/js/splitter.js +272 -0
- package/dist/js/tooltip.cjs +7 -1
- package/dist/js/tooltip.js +7 -1
- package/package.json +22 -2
- package/src/css/button.scss +0 -3
- package/src/css/popover.scss +4 -0
- package/src/css/splitter.scss +87 -0
- package/src/js/floatable.ts +124 -37
- package/src/js/popover.ts +9 -2
- package/src/js/splitter.ts +407 -0
- package/src/js/tooltip.ts +8 -1
- package/types/floatable.d.cts +5 -1
- package/types/floatable.d.ts +6 -1
- package/types/splitter.d.cts +10 -0
- package/types/splitter.d.ts +11 -0
package/dist/css/button.css
CHANGED
package/dist/css/popover.css
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
:where(oui-splitter) {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-flow: row nowrap;
|
|
5
|
+
flex: 1;
|
|
6
|
+
}
|
|
7
|
+
:where(oui-splitter > :first-child) {
|
|
8
|
+
flex: var(--oui-splitter-size, 0.5);
|
|
9
|
+
}
|
|
10
|
+
:where(oui-splitter > :last-child) {
|
|
11
|
+
flex: calc(1 - var(--oui-splitter-size, 0.5));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:where([oui-splitter-separator]) {
|
|
15
|
+
width: 0.25rem;
|
|
16
|
+
background-color: rgba(0, 0, 0, 0.1);
|
|
17
|
+
border-radius: 0.25rem;
|
|
18
|
+
position: relative;
|
|
19
|
+
transition: background 0.125s ease-in-out;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:where([oui-splitter-separator]:has([oui-splitter-handle]:focus)),
|
|
23
|
+
:where([oui-splitter-separator]:has([oui-splitter-handle]:hover)),
|
|
24
|
+
:where([oui-splitter-separator][oui-splitter-active]) {
|
|
25
|
+
background-color: color-mix(in oklab, var(--oui-blue-6), transparent 82.5%);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
:where([oui-splitter-handle]) {
|
|
29
|
+
width: 2rem;
|
|
30
|
+
height: 4rem;
|
|
31
|
+
padding: 0.875rem;
|
|
32
|
+
position: absolute;
|
|
33
|
+
inset: 50% auto auto 50%;
|
|
34
|
+
transform: translate3d(-50%, -50%, 0);
|
|
35
|
+
cursor: ew-resize;
|
|
36
|
+
}
|
|
37
|
+
:where([oui-splitter-handle]):focus {
|
|
38
|
+
outline: none;
|
|
39
|
+
}
|
|
40
|
+
:where([oui-splitter-handle])::after {
|
|
41
|
+
content: "";
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
display: block;
|
|
45
|
+
background-color: rgba(0, 0, 0, 0.25);
|
|
46
|
+
outline: 0.25rem solid transparent;
|
|
47
|
+
outline-offset: 0.25rem;
|
|
48
|
+
border-radius: 0.25rem;
|
|
49
|
+
transition: background 0.125s ease-in-out, outline 0.125s ease-in-out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([oui-splitter-handle]:focus)::after,
|
|
53
|
+
:where([oui-splitter-handle]:hover)::after,
|
|
54
|
+
:where([oui-splitter-handle][oui-splitter-active])::after {
|
|
55
|
+
background-color: color-mix(in oklab, var(--oui-blue-6), transparent 50%);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
:where([oui-splitter-handle]:focus-visible)::after {
|
|
59
|
+
outline-color: color-mix(in oklab, var(--oui-blue-6), transparent 50%);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:where(oui-splitter[type=horizontal i],
|
|
63
|
+
oui-splitter[oui-splitter-horizontal]) {
|
|
64
|
+
flex-flow: column nowrap;
|
|
65
|
+
}
|
|
66
|
+
:where(oui-splitter[type=horizontal i] [oui-splitter-separator],
|
|
67
|
+
oui-splitter[oui-splitter-horizontal] [oui-splitter-separator]) {
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 0.25rem;
|
|
70
|
+
}
|
|
71
|
+
:where(oui-splitter[type=horizontal i] [oui-splitter-handle],
|
|
72
|
+
oui-splitter[oui-splitter-horizontal] [oui-splitter-handle]) {
|
|
73
|
+
width: 4rem;
|
|
74
|
+
height: 2rem;
|
|
75
|
+
cursor: ns-resize;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
package/dist/js/floatable.cjs
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
class Floatable {
|
|
4
|
-
constructor(anchor, content) {
|
|
4
|
+
constructor(anchor, content, attribute, position, preferAbove) {
|
|
5
5
|
this.anchor = anchor;
|
|
6
6
|
this.content = content;
|
|
7
|
+
this.attribute = attribute;
|
|
8
|
+
this.position = position;
|
|
9
|
+
this.preferAbove = preferAbove;
|
|
7
10
|
setStyles(content);
|
|
8
11
|
}
|
|
9
12
|
activate;
|
|
@@ -44,37 +47,52 @@ function deactivate(floatable, active, order, time) {
|
|
|
44
47
|
}, time);
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
function getX(anchor, content) {
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (left + content.width > right) {
|
|
62
|
-
return {
|
|
63
|
-
right: margin
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
left
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
function getY(anchor, content) {
|
|
71
|
-
let top = anchor.top - content.height - margin;
|
|
72
|
-
if (top - margin >= 0) {
|
|
73
|
-
return top;
|
|
50
|
+
function getX(anchor, content, position) {
|
|
51
|
+
if (position.endsWith("-end")) {
|
|
52
|
+
const end = anchor.right - content.width;
|
|
53
|
+
return end - margin < 0 ? margin : end;
|
|
54
|
+
}
|
|
55
|
+
if (position.endsWith("-start")) {
|
|
56
|
+
const start = anchor.left;
|
|
57
|
+
return start + content.width + margin > window.innerWidth ? window.innerWidth - content.width - margin : start;
|
|
58
|
+
}
|
|
59
|
+
if (position.startsWith("end")) {
|
|
60
|
+
return anchor.right + margin;
|
|
61
|
+
}
|
|
62
|
+
if (position.startsWith("start")) {
|
|
63
|
+
return anchor.left - content.width - margin;
|
|
74
64
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
if (position.startsWith("horizontal")) {
|
|
66
|
+
if (anchor.right + content.width + margin <= window.innerWidth) {
|
|
67
|
+
return anchor.right + margin;
|
|
68
|
+
}
|
|
69
|
+
return anchor.left - content.width - margin;
|
|
70
|
+
}
|
|
71
|
+
return anchor.left + (anchor.width - content.width) / 2;
|
|
72
|
+
}
|
|
73
|
+
function getY(anchor, content, position, preferAbove) {
|
|
74
|
+
if (position.startsWith("above")) {
|
|
75
|
+
return anchor.top - content.height - margin;
|
|
76
|
+
}
|
|
77
|
+
if (position.startsWith("below")) {
|
|
78
|
+
return anchor.bottom + margin;
|
|
79
|
+
}
|
|
80
|
+
if (position.endsWith("bottom")) {
|
|
81
|
+
const bottom = anchor.bottom - content.height;
|
|
82
|
+
return bottom + margin < 0 ? margin : bottom;
|
|
83
|
+
}
|
|
84
|
+
if (position.endsWith("top")) {
|
|
85
|
+
const top = anchor.top;
|
|
86
|
+
return top + content.height + margin > window.innerHeight ? window.innerHeight - content.height - margin : top;
|
|
87
|
+
}
|
|
88
|
+
if (position.startsWith("vertical")) {
|
|
89
|
+
if (preferAbove && anchor.top - content.height - margin >= 0) {
|
|
90
|
+
return anchor.top - content.height - margin;
|
|
91
|
+
}
|
|
92
|
+
if (anchor.bottom + content.height + margin <= document.body.clientHeight) {
|
|
93
|
+
return anchor.bottom + margin;
|
|
94
|
+
}
|
|
95
|
+
return anchor.top - content.height - margin;
|
|
78
96
|
}
|
|
79
97
|
return anchor.top + (anchor.height - content.height) / 2;
|
|
80
98
|
}
|
|
@@ -99,12 +117,16 @@ function onDeactivate(floatable, active, order) {
|
|
|
99
117
|
floatable.anchor.insertAdjacentElement("afterend", floatable.content);
|
|
100
118
|
}
|
|
101
119
|
function update(floatable) {
|
|
120
|
+
let position = floatable.anchor.getAttribute(floatable.attribute)?.trim() ?? floatable.position;
|
|
121
|
+
if (!positions.has(position)) {
|
|
122
|
+
position = floatable.position;
|
|
123
|
+
}
|
|
102
124
|
function run() {
|
|
103
125
|
const anchor = floatable.anchor.getBoundingClientRect();
|
|
104
126
|
const content = floatable.content.getBoundingClientRect();
|
|
105
|
-
const
|
|
106
|
-
const top = getY(anchor, content);
|
|
107
|
-
floatable.content.style.inset = `${top}px
|
|
127
|
+
const left = getX(anchor, content, position);
|
|
128
|
+
const top = getY(anchor, content, position, floatable.preferAbove);
|
|
129
|
+
floatable.content.style.inset = `${top}px auto auto ${left}px`;
|
|
108
130
|
floatable.frame = requestAnimationFrame(run);
|
|
109
131
|
}
|
|
110
132
|
floatable.frame = requestAnimationFrame(run);
|
|
@@ -128,7 +150,27 @@ function stop(floatable) {
|
|
|
128
150
|
floatable.deactivate = void 0;
|
|
129
151
|
floatable.frame = void 0;
|
|
130
152
|
}
|
|
131
|
-
const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) /
|
|
153
|
+
const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) / 2;
|
|
154
|
+
const positions = /* @__PURE__ */ new Set([
|
|
155
|
+
"above",
|
|
156
|
+
"above-end",
|
|
157
|
+
"above-start",
|
|
158
|
+
"below",
|
|
159
|
+
"below-end",
|
|
160
|
+
"below-start",
|
|
161
|
+
"end",
|
|
162
|
+
"end-bottom",
|
|
163
|
+
"end-top",
|
|
164
|
+
"horizontal",
|
|
165
|
+
"horizontal-bottom",
|
|
166
|
+
"horizontal-top",
|
|
167
|
+
"start",
|
|
168
|
+
"start-bottom",
|
|
169
|
+
"start-top",
|
|
170
|
+
"vertical",
|
|
171
|
+
"vertical-end",
|
|
172
|
+
"vertical-start"
|
|
173
|
+
]);
|
|
132
174
|
exports.Floatable = Floatable;
|
|
133
175
|
exports.activate = activate;
|
|
134
176
|
exports.deactivate = deactivate;
|
package/dist/js/floatable.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
class Floatable {
|
|
2
|
-
constructor(anchor, content) {
|
|
2
|
+
constructor(anchor, content, attribute, position, preferAbove) {
|
|
3
3
|
this.anchor = anchor;
|
|
4
4
|
this.content = content;
|
|
5
|
+
this.attribute = attribute;
|
|
6
|
+
this.position = position;
|
|
7
|
+
this.preferAbove = preferAbove;
|
|
5
8
|
setStyles(content);
|
|
6
9
|
}
|
|
7
10
|
activate;
|
|
@@ -42,37 +45,52 @@ function deactivate(floatable, active, order, time) {
|
|
|
42
45
|
}, time);
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
|
-
function getX(anchor, content) {
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (left + content.width > right) {
|
|
60
|
-
return {
|
|
61
|
-
right: margin
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
left
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function getY(anchor, content) {
|
|
69
|
-
let top = anchor.top - content.height - margin;
|
|
70
|
-
if (top - margin >= 0) {
|
|
71
|
-
return top;
|
|
48
|
+
function getX(anchor, content, position) {
|
|
49
|
+
if (position.endsWith("-end")) {
|
|
50
|
+
const end = anchor.right - content.width;
|
|
51
|
+
return end - margin < 0 ? margin : end;
|
|
52
|
+
}
|
|
53
|
+
if (position.endsWith("-start")) {
|
|
54
|
+
const start = anchor.left;
|
|
55
|
+
return start + content.width + margin > window.innerWidth ? window.innerWidth - content.width - margin : start;
|
|
56
|
+
}
|
|
57
|
+
if (position.startsWith("end")) {
|
|
58
|
+
return anchor.right + margin;
|
|
59
|
+
}
|
|
60
|
+
if (position.startsWith("start")) {
|
|
61
|
+
return anchor.left - content.width - margin;
|
|
72
62
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
if (position.startsWith("horizontal")) {
|
|
64
|
+
if (anchor.right + content.width + margin <= window.innerWidth) {
|
|
65
|
+
return anchor.right + margin;
|
|
66
|
+
}
|
|
67
|
+
return anchor.left - content.width - margin;
|
|
68
|
+
}
|
|
69
|
+
return anchor.left + (anchor.width - content.width) / 2;
|
|
70
|
+
}
|
|
71
|
+
function getY(anchor, content, position, preferAbove) {
|
|
72
|
+
if (position.startsWith("above")) {
|
|
73
|
+
return anchor.top - content.height - margin;
|
|
74
|
+
}
|
|
75
|
+
if (position.startsWith("below")) {
|
|
76
|
+
return anchor.bottom + margin;
|
|
77
|
+
}
|
|
78
|
+
if (position.endsWith("bottom")) {
|
|
79
|
+
const bottom = anchor.bottom - content.height;
|
|
80
|
+
return bottom + margin < 0 ? margin : bottom;
|
|
81
|
+
}
|
|
82
|
+
if (position.endsWith("top")) {
|
|
83
|
+
const top = anchor.top;
|
|
84
|
+
return top + content.height + margin > window.innerHeight ? window.innerHeight - content.height - margin : top;
|
|
85
|
+
}
|
|
86
|
+
if (position.startsWith("vertical")) {
|
|
87
|
+
if (preferAbove && anchor.top - content.height - margin >= 0) {
|
|
88
|
+
return anchor.top - content.height - margin;
|
|
89
|
+
}
|
|
90
|
+
if (anchor.bottom + content.height + margin <= document.body.clientHeight) {
|
|
91
|
+
return anchor.bottom + margin;
|
|
92
|
+
}
|
|
93
|
+
return anchor.top - content.height - margin;
|
|
76
94
|
}
|
|
77
95
|
return anchor.top + (anchor.height - content.height) / 2;
|
|
78
96
|
}
|
|
@@ -97,12 +115,16 @@ function onDeactivate(floatable, active, order) {
|
|
|
97
115
|
floatable.anchor.insertAdjacentElement("afterend", floatable.content);
|
|
98
116
|
}
|
|
99
117
|
function update(floatable) {
|
|
118
|
+
let position = floatable.anchor.getAttribute(floatable.attribute)?.trim() ?? floatable.position;
|
|
119
|
+
if (!positions.has(position)) {
|
|
120
|
+
position = floatable.position;
|
|
121
|
+
}
|
|
100
122
|
function run() {
|
|
101
123
|
const anchor = floatable.anchor.getBoundingClientRect();
|
|
102
124
|
const content = floatable.content.getBoundingClientRect();
|
|
103
|
-
const
|
|
104
|
-
const top = getY(anchor, content);
|
|
105
|
-
floatable.content.style.inset = `${top}px
|
|
125
|
+
const left = getX(anchor, content, position);
|
|
126
|
+
const top = getY(anchor, content, position, floatable.preferAbove);
|
|
127
|
+
floatable.content.style.inset = `${top}px auto auto ${left}px`;
|
|
106
128
|
floatable.frame = requestAnimationFrame(run);
|
|
107
129
|
}
|
|
108
130
|
floatable.frame = requestAnimationFrame(run);
|
|
@@ -126,7 +148,27 @@ function stop(floatable) {
|
|
|
126
148
|
floatable.deactivate = void 0;
|
|
127
149
|
floatable.frame = void 0;
|
|
128
150
|
}
|
|
129
|
-
const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) /
|
|
151
|
+
const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) / 2;
|
|
152
|
+
const positions = /* @__PURE__ */ new Set([
|
|
153
|
+
"above",
|
|
154
|
+
"above-end",
|
|
155
|
+
"above-start",
|
|
156
|
+
"below",
|
|
157
|
+
"below-end",
|
|
158
|
+
"below-start",
|
|
159
|
+
"end",
|
|
160
|
+
"end-bottom",
|
|
161
|
+
"end-top",
|
|
162
|
+
"horizontal",
|
|
163
|
+
"horizontal-bottom",
|
|
164
|
+
"horizontal-top",
|
|
165
|
+
"start",
|
|
166
|
+
"start-bottom",
|
|
167
|
+
"start-top",
|
|
168
|
+
"vertical",
|
|
169
|
+
"vertical-end",
|
|
170
|
+
"vertical-start"
|
|
171
|
+
]);
|
|
130
172
|
export {
|
|
131
173
|
Floatable,
|
|
132
174
|
activate,
|
package/dist/js/popover.cjs
CHANGED
|
@@ -34,7 +34,13 @@ class OuiPopoverElement extends HTMLElement {
|
|
|
34
34
|
}
|
|
35
35
|
toggle2.setAttribute("aria-controls", content.id);
|
|
36
36
|
toggle2.setAttribute("aria-haspopup", "dialog");
|
|
37
|
-
this.#floatable = new floatable.Floatable(
|
|
37
|
+
this.#floatable = new floatable.Floatable(
|
|
38
|
+
toggle2,
|
|
39
|
+
content,
|
|
40
|
+
"position",
|
|
41
|
+
"below-start",
|
|
42
|
+
false
|
|
43
|
+
);
|
|
38
44
|
this.#focusTrap = focusTrap_embedded.createFocusTrap(content);
|
|
39
45
|
mapped.set(toggle2, this.#floatable);
|
|
40
46
|
mapped.set(content, this.#floatable);
|
|
@@ -95,7 +101,7 @@ function closeAbove(element) {
|
|
|
95
101
|
floatable.deactivate(floatable$1, active, order);
|
|
96
102
|
}
|
|
97
103
|
}
|
|
98
|
-
order[index2].content
|
|
104
|
+
focus(order[index2].content);
|
|
99
105
|
}
|
|
100
106
|
function focus(content) {
|
|
101
107
|
let target = focusable.getFocusable(content)[0];
|
package/dist/js/popover.js
CHANGED
|
@@ -32,7 +32,13 @@ class OuiPopoverElement extends HTMLElement {
|
|
|
32
32
|
}
|
|
33
33
|
toggle2.setAttribute("aria-controls", content.id);
|
|
34
34
|
toggle2.setAttribute("aria-haspopup", "dialog");
|
|
35
|
-
this.#floatable = new Floatable(
|
|
35
|
+
this.#floatable = new Floatable(
|
|
36
|
+
toggle2,
|
|
37
|
+
content,
|
|
38
|
+
"position",
|
|
39
|
+
"below-start",
|
|
40
|
+
false
|
|
41
|
+
);
|
|
36
42
|
this.#focusTrap = createFocusTrap(content);
|
|
37
43
|
mapped.set(toggle2, this.#floatable);
|
|
38
44
|
mapped.set(content, this.#floatable);
|
|
@@ -93,7 +99,7 @@ function closeAbove(element) {
|
|
|
93
99
|
deactivate(floatable, active, order);
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
|
-
order[index2].content
|
|
102
|
+
focus(order[index2].content);
|
|
97
103
|
}
|
|
98
104
|
function focus(content) {
|
|
99
105
|
let target = getFocusable(content)[0];
|