@oscarpalmer/oui 0.16.0 → 0.18.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.
Files changed (62) hide show
  1. package/dist/css/badge.css +3 -3
  2. package/dist/css/content.css +9 -11
  3. package/dist/css/form.css +36 -22
  4. package/dist/css/message.css +4 -0
  5. package/dist/css/popover.css +3 -0
  6. package/dist/css/reset.css +176 -56
  7. package/dist/css/splitter.css +3 -3
  8. package/dist/css/tooltip.css +8 -0
  9. package/dist/js/attributable.full.js +48 -0
  10. package/dist/js/attributable.js +30 -45
  11. package/dist/js/floatable.full.js +413 -0
  12. package/dist/js/floatable.js +259 -132
  13. package/dist/js/focus-trap/embedded.full.js +351 -0
  14. package/dist/js/focus-trap/embedded.js +131 -131
  15. package/dist/js/focus-trap/standalone.full.js +402 -0
  16. package/dist/js/focus-trap/standalone.js +4 -4
  17. package/dist/js/index.js +4 -5
  18. package/dist/js/oui.full.js +1596 -0
  19. package/dist/js/popover.full.js +822 -0
  20. package/dist/js/popover.js +83 -156
  21. package/dist/js/splitter.full.js +605 -0
  22. package/dist/js/splitter.js +279 -200
  23. package/dist/js/tooltip.full.js +679 -0
  24. package/dist/js/tooltip.js +159 -144
  25. package/package.json +31 -59
  26. package/src/css/content.scss +1 -2
  27. package/src/css/form.scss +12 -4
  28. package/src/css/message.scss +3 -0
  29. package/src/css/mixins.scss +7 -0
  30. package/src/css/popover.scss +4 -0
  31. package/src/css/reset.scss +180 -54
  32. package/src/css/splitter.scss +3 -3
  33. package/src/css/tooltip.scss +8 -0
  34. package/src/js/floatable.ts +458 -124
  35. package/src/js/focus-trap/embedded.ts +149 -64
  36. package/src/js/focus-trap/standalone.ts +4 -4
  37. package/src/js/index.ts +1 -0
  38. package/src/js/popover.ts +51 -114
  39. package/src/js/splitter.ts +346 -109
  40. package/src/js/tooltip.ts +157 -63
  41. package/types/floatable.d.ts +19 -7
  42. package/types/focus-trap/embedded.d.ts +18 -5
  43. package/types/index.d.ts +1 -0
  44. package/types/popover.d.ts +2 -0
  45. package/types/splitter.d.ts +13 -1
  46. package/types/tooltip.d.ts +2 -1
  47. package/dist/js/attributable.cjs +0 -51
  48. package/dist/js/floatable.cjs +0 -134
  49. package/dist/js/focus-trap/embedded.cjs +0 -150
  50. package/dist/js/focus-trap/standalone.cjs +0 -8
  51. package/dist/js/index.cjs +0 -6
  52. package/dist/js/popover.cjs +0 -160
  53. package/dist/js/splitter.cjs +0 -211
  54. package/dist/js/tooltip.cjs +0 -160
  55. package/types/attributable.d.cts +0 -5
  56. package/types/floatable.d.cts +0 -16
  57. package/types/focus-trap/embedded.d.cts +0 -15
  58. package/types/focus-trap/standalone.d.cts +0 -3
  59. package/types/index.d.cts +0 -14
  60. package/types/popover.d.cts +0 -14
  61. package/types/splitter.d.cts +0 -10
  62. package/types/tooltip.d.cts +0 -3
@@ -1,160 +1,87 @@
1
+ import { Floatable } from "./floatable.js";
2
+ import { createFocusTrap } from "./focus-trap/embedded.js";
1
3
  import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
2
- import { on } from "@oscarpalmer/toretto/event";
3
- import { findAncestor } from "@oscarpalmer/toretto/find";
4
4
  import { getFocusable } from "@oscarpalmer/toretto/focusable";
5
- import { Floatable, deactivate, activate } from "./floatable.js";
6
- import { createFocusTrap } from "./focus-trap/embedded.js";
7
- const mapped = /* @__PURE__ */ new Map();
8
- let index = 0;
9
- class OuiPopoverElement extends HTMLElement {
10
- #floatable;
11
- #focusTrap;
12
- constructor() {
13
- super();
14
- const content = this.querySelector(":scope > [oui-popover-content]");
15
- const toggle2 = this.querySelector(":scope > [oui-popover-toggle]");
16
- if (!(content instanceof HTMLElement)) {
17
- throw new Error(
18
- "A oui-popover must have a direct child element with the [oui-popover-content]-attribute"
19
- );
20
- }
21
- if (!(toggle2 instanceof HTMLButtonElement)) {
22
- throw new Error(
23
- "A oui-popover must have a direct child element with the [oui-popover-toggle]-attribute and be a button"
24
- );
25
- }
26
- content.hidden = true;
27
- content.setAttribute("role", "dialog");
28
- content.setAttribute("oui-focus-trap", "");
29
- content.setAttribute("oui-focus-trap-noescape", "");
30
- if (isNullableOrWhitespace(content.id)) {
31
- content.setAttribute("id", `oui-popover-content-${++index}`);
32
- }
33
- toggle2.setAttribute("aria-controls", content.id);
34
- toggle2.setAttribute("aria-haspopup", "dialog");
35
- this.#floatable = new Floatable(toggle2, content);
36
- this.#focusTrap = createFocusTrap(content);
37
- mapped.set(toggle2, this.#floatable);
38
- mapped.set(content, this.#floatable);
39
- }
40
- close() {
41
- this.hidePopover();
42
- }
43
- hidePopover() {
44
- if (this.#floatable.active) {
45
- closeAbove(this.#floatable.content);
46
- deactivate(this.#floatable, active, order);
47
- this.#floatable.anchor.focus();
48
- }
49
- }
50
- open() {
51
- this.showPopover();
52
- }
53
- showPopover() {
54
- if (!this.#floatable.active) {
55
- toggle(this.#floatable.anchor);
56
- }
57
- }
58
- toggle() {
59
- this.togglePopover();
60
- }
61
- togglePopover(options) {
62
- if (typeof options === "boolean") {
63
- if (options === true) {
64
- this.showPopover();
65
- } else {
66
- this.hidePopover();
67
- }
68
- return options;
69
- }
70
- if (this.#floatable.active) {
71
- this.hidePopover();
72
- return false;
73
- }
74
- this.showPopover();
75
- return true;
76
- }
77
- }
78
- function closeAll() {
79
- for (const floatable of active) {
80
- deactivate(floatable, active, order);
81
- }
82
- }
83
- function closeAbove(element) {
84
- const index2 = order.findIndex(
85
- (floatable) => floatable.anchor === element || floatable.content === element
86
- );
87
- if (index2 === -1 || index2 === order.length - 1) {
88
- return;
89
- }
90
- while (index2 < order.length - 1) {
91
- const floatable = order.pop();
92
- if (floatable != null) {
93
- deactivate(floatable, active, order);
94
- }
95
- }
96
- focus(order[index2].content);
97
- }
5
+ var index = 0;
6
+ var OuiPopoverElement = class extends HTMLElement {
7
+ #floatable;
8
+ #focusTrap;
9
+ constructor() {
10
+ super();
11
+ const content = this.querySelector(SELECTOR_CONTENT);
12
+ const toggle = this.querySelector(SELECTOR_TOGGLE);
13
+ if (!(content instanceof HTMLElement)) throw new Error("A oui-popover must have a direct child element with the [oui-popover-content]-attribute");
14
+ if (!(toggle instanceof HTMLButtonElement)) throw new Error("A oui-popover must have a direct child element with the [oui-popover-toggle]-attribute and be a button");
15
+ content.hidden = true;
16
+ content.setAttribute("role", "dialog");
17
+ content.setAttribute("aria-modal", "true");
18
+ if (isNullableOrWhitespace(content.id)) content.setAttribute("id", `${ATTRIBUTE_ID_PREFIX}_${++index}`);
19
+ toggle.setAttribute("aria-controls", content.id);
20
+ toggle.setAttribute("aria-haspopup", "dialog");
21
+ this.#floatable = new Floatable({
22
+ content,
23
+ anchor: toggle,
24
+ defaultPosition: "below-start",
25
+ interactive: true,
26
+ positionAttribute: "position",
27
+ preferAbove: false,
28
+ onAfter: (active) => {
29
+ if (active) focus(content);
30
+ else if (!this.#floatable.ignoreFocus) toggle.focus();
31
+ }
32
+ });
33
+ this.#focusTrap = createFocusTrap(content, { noescape: true });
34
+ POPOVERS.set(toggle, this.#floatable);
35
+ POPOVERS.set(content, this.#floatable);
36
+ }
37
+ close() {
38
+ this.hidePopover();
39
+ }
40
+ connectedCallback() {
41
+ this.#floatable.enable();
42
+ this.#focusTrap.connect();
43
+ }
44
+ disconnectedCallback() {
45
+ this.#floatable.disable();
46
+ this.#focusTrap.disconnect();
47
+ }
48
+ hidePopover() {
49
+ if (this.#floatable.active && this.isConnected) this.#floatable.toggle(false);
50
+ }
51
+ open() {
52
+ this.showPopover();
53
+ }
54
+ showPopover() {
55
+ if (!this.#floatable.active && this.isConnected) this.#floatable.toggle(true);
56
+ }
57
+ toggle() {
58
+ this.togglePopover();
59
+ }
60
+ togglePopover(options) {
61
+ if (typeof options === "boolean") {
62
+ if (options === true) this.showPopover();
63
+ else this.hidePopover();
64
+ return options;
65
+ }
66
+ if (this.#floatable.active) {
67
+ this.hidePopover();
68
+ return false;
69
+ }
70
+ this.showPopover();
71
+ return true;
72
+ }
73
+ };
98
74
  function focus(content) {
99
- let target = getFocusable(content)[0];
100
- if (!(target instanceof HTMLElement)) {
101
- target = content;
102
- }
103
- requestAnimationFrame(() => {
104
- target.focus();
105
- });
106
- }
107
- function onClick(event) {
108
- const related = findAncestor(
109
- event.target,
110
- "[oui-popover-toggle], [oui-popover-content]"
111
- );
112
- if (!(related instanceof HTMLElement)) {
113
- closeAll();
114
- } else if (related.hasAttribute("oui-popover-content")) {
115
- closeAbove(related);
116
- } else {
117
- toggle(related);
118
- }
119
- }
120
- function onKeydown(event) {
121
- if (event.key !== "Escape" || order.length === 0) {
122
- return;
123
- }
124
- const related = findAncestor(event.target, "[oui-popover-content]");
125
- if (!(related instanceof HTMLElement)) {
126
- return;
127
- }
128
- closeAbove(related);
129
- const floatable = mapped.get(related);
130
- if (floatable != null) {
131
- deactivate(floatable, active, order);
132
- floatable.anchor.focus();
133
- }
75
+ let target = getFocusable(content)[0];
76
+ if (!(target instanceof HTMLElement)) target = content;
77
+ requestAnimationFrame(() => {
78
+ target.focus();
79
+ });
134
80
  }
135
- function toggle(anchor) {
136
- const content = findAncestor(anchor, "[oui-popover-content]");
137
- if (content instanceof HTMLElement) {
138
- closeAbove(content);
139
- } else {
140
- closeAll();
141
- }
142
- const floatable = mapped.get(anchor);
143
- if (floatable == null) {
144
- return;
145
- }
146
- if (floatable.active) {
147
- deactivate(floatable, active, order);
148
- } else {
149
- activate(floatable, active, order);
150
- focus(floatable.content);
151
- }
152
- }
153
- customElements.define("oui-popover", OuiPopoverElement);
154
- on(document, "click", onClick);
155
- on(document, "keydown", onKeydown);
156
- const active = /* @__PURE__ */ new Set();
157
- const order = [];
158
- export {
159
- OuiPopoverElement
160
- };
81
+ var ATTRIBUTE_ID_PREFIX = "oui_popover_content_";
82
+ var POPOVERS = /* @__PURE__ */ new Map();
83
+ var SELECTOR = "oui-popover";
84
+ var SELECTOR_CONTENT = `:scope > [${SELECTOR}-content]`;
85
+ var SELECTOR_TOGGLE = `:scope > [${SELECTOR}-toggle]`;
86
+ customElements.define(SELECTOR, OuiPopoverElement);
87
+ export { OuiPopoverElement };