@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.
@@ -67,9 +67,6 @@
67
67
  :where(.oui-button-tiny) {
68
68
  --oui-foreground-percentage: 12.5%;
69
69
  font-size: 0.75em;
70
- font-weight: bold;
71
- letter-spacing: 0.1em;
72
- text-transform: uppercase;
73
70
  }
74
71
  :where(.oui-button:focus-visible) {
75
72
  --oui-outline-percentage: 75%;
@@ -5,5 +5,8 @@
5
5
  background-color: var(--oui-absolute);
6
6
  border-radius: 0.5rem;
7
7
  }
8
+ :where([oui-popover-content]):focus {
9
+ outline: none;
10
+ }
8
11
 
9
12
 
@@ -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
+
@@ -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 (content.width + 2 * margin >= window.innerWidth) {
49
- return {
50
- left: margin,
51
- right: margin
52
- };
53
- }
54
- const left = anchor.left + (anchor.width - content.width) / 2;
55
- const right = window.innerWidth - margin;
56
- if (left < margin) {
57
- return {
58
- left: margin
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
- top = anchor.bottom + margin;
76
- if (top + content.height + margin <= window.innerHeight) {
77
- return top;
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 { left, right } = getX(anchor, content);
106
- const top = getY(anchor, content);
107
- floatable.content.style.inset = `${top}px ${right == null ? "auto" : `${right}px`} auto ${left == null ? "auto" : `${left}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) / 4;
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;
@@ -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 (content.width + 2 * margin >= window.innerWidth) {
47
- return {
48
- left: margin,
49
- right: margin
50
- };
51
- }
52
- const left = anchor.left + (anchor.width - content.width) / 2;
53
- const right = window.innerWidth - margin;
54
- if (left < margin) {
55
- return {
56
- left: margin
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
- top = anchor.bottom + margin;
74
- if (top + content.height + margin <= window.innerHeight) {
75
- return top;
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 { left, right } = getX(anchor, content);
104
- const top = getY(anchor, content);
105
- floatable.content.style.inset = `${top}px ${right == null ? "auto" : `${right}px`} auto ${left == null ? "auto" : `${left}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) / 4;
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,
@@ -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(toggle2, content);
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.focus();
104
+ focus(order[index2].content);
99
105
  }
100
106
  function focus(content) {
101
107
  let target = focusable.getFocusable(content)[0];
@@ -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(toggle2, content);
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.focus();
102
+ focus(order[index2].content);
97
103
  }
98
104
  function focus(content) {
99
105
  let target = getFocusable(content)[0];