@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
package/src/js/tooltip.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
2
  import {on} from '@oscarpalmer/toretto/event';
3
+ import {findAncestor} from '@oscarpalmer/toretto/find';
3
4
  import {attributable} from './attributable';
4
- import {activate, deactivate, Floatable} from './floatable';
5
+ import {Floatable} from './floatable';
5
6
 
6
7
  type Attributes = {
7
8
  ariaDescribedby: string | null;
@@ -14,40 +15,80 @@ type Content = {
14
15
  };
15
16
 
16
17
  class Tooltip {
17
- abortController = new AbortController();
18
18
  attributes: Attributes;
19
+
19
20
  floatable: Floatable;
20
21
 
22
+ timer: number | undefined;
23
+
21
24
  constructor(anchor: HTMLElement, content: Content) {
22
25
  this.attributes = content.attributes;
23
- this.floatable = new Floatable(anchor, content.element);
24
26
 
25
- initialize(this);
27
+ this.floatable = new Floatable({
28
+ anchor,
29
+ content: content.element,
30
+ defaultPosition: 'vertical',
31
+ interactive: false,
32
+ preferAbove: true,
33
+ positionAttribute: ATTRIBUTE_POSITION,
34
+ });
35
+
36
+ anchor.insertAdjacentElement('afterend', content.element);
37
+
38
+ TOOLTIPS_ALL.set(content.element, this);
26
39
  }
27
40
 
28
41
  destroy(): void {
29
- deactivate(this.floatable, active);
30
- reset(this.floatable.anchor, this.attributes);
42
+ const {attributes, floatable} = this;
31
43
 
32
- this.abortController.abort();
33
- this.floatable.content.remove();
34
- this.floatable.destroy();
44
+ TOOLTIPS_ACTIVE.delete(this);
45
+ TOOLTIPS_ALL.delete(floatable.options.anchor);
46
+ TOOLTIPS_ALL.delete(floatable.options.content);
47
+
48
+ reset(floatable.options.anchor, attributes);
49
+
50
+ floatable.options.content.remove();
51
+ floatable.destroy();
35
52
 
36
- this.abortController = undefined as never;
37
53
  this.attributes = undefined as never;
38
54
  this.floatable = undefined as never;
39
55
  }
40
56
  }
41
57
 
42
58
  function addTooltip(anchor: HTMLElement): void {
43
- if (tooltips.has(anchor)) {
59
+ if (TOOLTIPS_ALL.has(anchor)) {
44
60
  return;
45
61
  }
46
62
 
47
63
  const content = getContent(anchor);
48
64
 
49
65
  if (content != null) {
50
- tooltips.set(anchor, new Tooltip(anchor, content));
66
+ TOOLTIPS_ALL.set(anchor, new Tooltip(anchor, content));
67
+ }
68
+ }
69
+
70
+ function closeTooltips(next: Tooltip | undefined): void {
71
+ const tooltips = [...TOOLTIPS_ACTIVE];
72
+
73
+ for (const active of tooltips) {
74
+ if (active === next) {
75
+ continue;
76
+ }
77
+
78
+ if (active.timer != null) {
79
+ clearTimeout(active.timer);
80
+ }
81
+
82
+ active.floatable.options.content.removeAttribute(
83
+ 'oui-tooltip-content-active',
84
+ );
85
+
86
+ requestAnimationFrame(() => {
87
+ active.timer = setTimeout(() => {
88
+ TOOLTIPS_ACTIVE.delete(active);
89
+ active.floatable.toggle(false);
90
+ }, delay) as never;
91
+ });
51
92
  }
52
93
  }
53
94
 
@@ -112,7 +153,7 @@ function getContent(anchor: HTMLElement): Content | undefined {
112
153
  }
113
154
 
114
155
  function getElements(attribute: string | null): HTMLElement[] {
115
- const ids = attribute?.split(/\s+/) ?? [];
156
+ const ids = attribute?.split(EXPRESSION_WHITESPACE) ?? [];
116
157
  const elements: HTMLElement[] = [];
117
158
 
118
159
  for (const id of ids) {
@@ -137,57 +178,92 @@ function getElements(attribute: string | null): HTMLElement[] {
137
178
  function getWrapper(anchor: HTMLElement): HTMLElement {
138
179
  const wrapper = document.createElement('div');
139
180
 
140
- wrapper.setAttribute(`${selector}-content`, '');
181
+ wrapper.setAttribute(ATTRIBUTE_CONTENT, '');
141
182
 
142
- wrapper.className = anchor.getAttribute(`${selector}-class`) ?? '';
183
+ wrapper.className = anchor.getAttribute(ATTRIBUTE_CLASS) ?? '';
143
184
  wrapper.hidden = true;
144
- wrapper.id = `${selector}-${++index}`;
185
+ wrapper.id = `${SELECTOR}-${++index}`;
145
186
  wrapper.role = 'tooltip';
146
187
  wrapper.tabIndex = -1;
147
188
 
148
189
  return wrapper;
149
190
  }
150
191
 
151
- function initialize(tooltip: Tooltip): void {
152
- const {abortController, floatable} = tooltip;
153
- const {anchor, content} = floatable;
154
-
155
- anchor.insertAdjacentElement('afterend', content);
156
-
157
- const elements = [anchor, content];
158
-
159
- for (const element of elements) {
160
- for (const event of activateEvents) {
161
- on(
162
- element,
163
- event,
164
- () => {
165
- activate(floatable, active, undefined, 250);
166
- },
167
- {
168
- signal: abortController.signal,
169
- },
170
- );
192
+ function onActivate(event: Event): void {
193
+ onToggle(event, true);
194
+ }
195
+
196
+ function onClick(event: Event): void {
197
+ if (findAncestor(event.target as HTMLElement, SELECTOR_CONTENT) != null) {
198
+ event.stopPropagation();
199
+ }
200
+ }
201
+
202
+ function onDeactivate(event: Event): void {
203
+ onToggle(event, false);
204
+ }
205
+
206
+ function onToggle(event: Event, activate: boolean): void {
207
+ if (toggle != null) {
208
+ cancelAnimationFrame(toggle);
209
+ }
210
+
211
+ toggle = requestAnimationFrame(() => {
212
+ toggle = undefined;
213
+
214
+ const element = findAncestor(
215
+ event.target as HTMLElement,
216
+ SELECTOR_FULL,
217
+ ) as HTMLElement;
218
+
219
+ const tooltip = TOOLTIPS_ALL.get(element);
220
+
221
+ if (TOOLTIPS_ACTIVE.size > 0) {
222
+ closeTooltips(tooltip);
171
223
  }
172
224
 
173
- for (const event of deactivateEvents) {
174
- on(
175
- element,
176
- event,
177
- () => {
178
- deactivate(floatable, active, undefined, 250);
179
- },
180
- {
181
- signal: abortController.signal,
182
- },
183
- );
225
+ if (
226
+ tooltip == null ||
227
+ tooltip.floatable.options.content.hasAttribute(
228
+ 'oui-tooltip-content-active',
229
+ ) === activate
230
+ ) {
231
+ return;
184
232
  }
185
- }
233
+
234
+ if (activate) {
235
+ if (tooltip.timer != null) {
236
+ clearTimeout(tooltip.timer);
237
+ }
238
+
239
+ TOOLTIPS_ACTIVE.add(tooltip);
240
+ tooltip.floatable.toggle(true);
241
+
242
+ requestAnimationFrame(() => {
243
+ tooltip.floatable.options.content.setAttribute(
244
+ 'oui-tooltip-content-active',
245
+ '',
246
+ );
247
+ });
248
+
249
+ return;
250
+ }
251
+
252
+ tooltip.floatable.options.content.removeAttribute(
253
+ 'oui-tooltip-content-active',
254
+ );
255
+
256
+ tooltip.timer ??= setTimeout(() => {
257
+ TOOLTIPS_ACTIVE.delete(tooltip);
258
+ tooltip.floatable.toggle(false);
259
+ }, delay) as never;
260
+ });
186
261
  }
187
262
 
188
263
  function removeTooltip(element: HTMLElement): void {
189
- tooltips.get(element)?.destroy();
190
- tooltips.delete(element);
264
+ if (!element.hasAttribute(ATTRIBUTE_CONTENT)) {
265
+ TOOLTIPS_ALL.get(element)?.destroy();
266
+ }
191
267
  }
192
268
 
193
269
  function reset(anchor: HTMLElement, attributes: Attributes): void {
@@ -198,28 +274,46 @@ function reset(anchor: HTMLElement, attributes: Attributes): void {
198
274
  }
199
275
  }
200
276
 
277
+ function setDelay(value: number): void {
278
+ delay = typeof value === 'number' && value >= 0 ? value : delay;
279
+ }
280
+
201
281
  //
202
282
 
203
- const active = new Set<Floatable>();
283
+ const SELECTOR = 'oui-tooltip';
284
+
285
+ const ATTRIBUTE_CLASS = `${SELECTOR}-class`;
286
+
287
+ const ATTRIBUTE_CONTENT = `${SELECTOR}-content`;
288
+
289
+ const ATTRIBUTE_POSITION = `${SELECTOR}-position`;
290
+
291
+ const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
292
+
293
+ const SELECTOR_FULL = `[${SELECTOR}], [${ATTRIBUTE_CONTENT}]`;
204
294
 
205
- const activateEvents = ['focus', 'mouseenter', 'touchstart'];
295
+ const EXPRESSION_WHITESPACE = /\s+/;
206
296
 
207
- const deactivateEvents = ['blur', 'mouseleave'];
297
+ const TOOLTIPS_ACTIVE: Set<Tooltip> = new Set();
208
298
 
209
- const selector = 'oui-tooltip';
299
+ const TOOLTIPS_ALL: WeakMap<HTMLElement, Tooltip> = new WeakMap();
210
300
 
211
- const tooltips = new WeakMap<HTMLElement, Tooltip>();
301
+ let delay = 250;
212
302
 
213
303
  let index = 0;
214
304
 
305
+ let toggle: DOMHighResTimeStamp | undefined;
306
+
215
307
  //
216
308
 
217
- attributable(selector, addTooltip, removeTooltip);
309
+ attributable(SELECTOR, addTooltip, removeTooltip);
218
310
 
219
- on(document, 'keydown', event => {
220
- if (event.key === 'Escape') {
221
- for (const floatable of active) {
222
- deactivate(floatable, active);
223
- }
224
- }
225
- });
311
+ on(document, 'click', onClick, {capture: true});
312
+ on(document, 'focusin', onActivate);
313
+ on(document, 'focusout', onDeactivate);
314
+ on(document, 'mousemove', onActivate);
315
+ on(document, 'touchstart', onActivate);
316
+
317
+ //
318
+
319
+ export {setDelay};
@@ -1,12 +1,24 @@
1
1
  export declare class Floatable {
2
- anchor: HTMLElement;
3
- content: HTMLElement;
4
- activate: number | undefined;
2
+ readonly options: Options;
5
3
  active: boolean;
6
- deactivate: number | undefined;
4
+ disabled: boolean;
7
5
  frame: DOMHighResTimeStamp | undefined;
8
- constructor(anchor: HTMLElement, content: HTMLElement);
6
+ ignoreFocus: boolean;
7
+ constructor(options: Options);
9
8
  destroy(): void;
9
+ disable(): void;
10
+ enable(): void;
11
+ toggle(active: boolean, ignoreFocus?: boolean): void;
10
12
  }
11
- export declare function activate(floatable: Floatable, active: Set<Floatable>, order?: Floatable[], time?: number): void;
12
- export declare function deactivate(floatable: Floatable, active: Set<Floatable>, order?: Floatable[], time?: number): void;
13
+ type Options = {
14
+ anchor: HTMLElement;
15
+ content: HTMLElement;
16
+ defaultPosition: Position;
17
+ interactive: boolean;
18
+ positionAttribute: string;
19
+ preferAbove: boolean;
20
+ onAfter?: (active: boolean) => void;
21
+ };
22
+ type Position = 'above' | 'above-end' | 'above-start' | 'below' | 'below-end' | 'below-start' | 'end' | 'end-bottom' | 'end-top' | 'horizontal' | 'horizontal-bottom' | 'horizontal-top' | 'start' | 'start-bottom' | 'start-top' | 'vertical' | 'vertical-end' | 'vertical-start';
23
+ export declare function deactivate(floatable: Floatable): void;
24
+ export {};
@@ -1,11 +1,24 @@
1
1
  export declare class FocusTrap {
2
+ disabled: boolean;
3
+ connected: boolean;
2
4
  element: HTMLElement;
3
- active: boolean;
4
- constructor(element: HTMLElement);
5
+ embedded: boolean;
6
+ get contain(): boolean;
7
+ get noescape(): boolean;
8
+ constructor(element: HTMLElement, options?: Options);
9
+ connect(): void;
5
10
  destroy(): void;
6
11
  disable(): void;
12
+ disconnect(): void;
7
13
  enable(): void;
14
+ focus(last: boolean): void;
8
15
  }
9
- export declare function createFocusTrap(element: HTMLElement): FocusTrap;
10
- export declare const focusTraps: WeakMap<HTMLElement, FocusTrap>;
11
- export declare const selector = "oui-focus-trap";
16
+ type Options = {
17
+ noescape: boolean;
18
+ };
19
+ export declare function createFocusTrap(element: HTMLElement, options?: Options): FocusTrap;
20
+ export declare const FOCUS_TRAP_SELECTOR = "oui-focus-trap";
21
+ export declare const FOCUS_TRAP_CONTAIN = "oui-focus-trap-contain";
22
+ export declare const FOCUS_TRAP_NOESCAPE = "oui-focus-trap-noescape";
23
+ export declare const FOCUSTRAPS_ALL: WeakMap<HTMLElement, FocusTrap>;
24
+ export {};
package/types/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './focus-trap/standalone';
2
2
  export * from './popover';
3
+ export * from './splitter';
3
4
  export * from './tooltip';
@@ -7,6 +7,8 @@ export declare class OuiPopoverElement extends HTMLElement {
7
7
  #private;
8
8
  constructor();
9
9
  close(): void;
10
+ connectedCallback(): void;
11
+ disconnectedCallback(): void;
10
12
  hidePopover(): void;
11
13
  open(): void;
12
14
  showPopover(): void;
@@ -1,11 +1,23 @@
1
1
  declare global {
2
2
  interface HTMLElementTagNameMap {
3
- 'oui-splitter': OuiSplitterElement;
3
+ [SELECTOR]: OuiSplitterElement;
4
4
  }
5
5
  }
6
6
  export declare class OuiSplitterElement extends HTMLElement {
7
7
  #private;
8
+ static readonly observedAttributes: string[];
9
+ get max(): number;
10
+ set max(value: number);
11
+ get min(): number;
12
+ set min(value: number);
13
+ get size(): number;
14
+ set size(value: number);
15
+ get type(): string;
16
+ set type(value: string);
8
17
  constructor();
9
18
  connectedCallback(): void;
10
19
  disconnectedCallback(): void;
20
+ attributeChangedCallback(name: string): void;
11
21
  }
22
+ declare const SELECTOR = "oui-splitter";
23
+ export {};
@@ -1 +1,2 @@
1
- export {};
1
+ declare function setDelay(value: number): void;
2
+ export { setDelay };
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- function attributable(attribute, add, remove) {
4
- const observer = new MutationObserver((entries) => {
5
- const { length } = entries;
6
- for (let index = 0; index < length; index += 1) {
7
- const entry = entries[index];
8
- if (entry.type === "attributes" && entry.target instanceof HTMLElement) {
9
- if (entry.target.hasAttribute(attribute)) {
10
- handleAdded(attribute, [entry.target], add);
11
- } else {
12
- handleRemoved([entry.target], remove);
13
- }
14
- } else if (entry.type === "childList") {
15
- handleAdded(attribute, entry.addedNodes, add);
16
- handleRemoved(entry.removedNodes, remove);
17
- }
18
- }
19
- });
20
- observer.observe(document, {
21
- attributeFilter: [attribute],
22
- attributes: true,
23
- childList: true,
24
- subtree: true
25
- });
26
- requestAnimationFrame(() => {
27
- handleAdded(attribute, document.querySelectorAll(`[${attribute}]`), add);
28
- });
29
- }
30
- function handleAdded(attribute, nodes, add) {
31
- const elements = [...nodes].filter(
32
- (node) => node instanceof HTMLElement
33
- );
34
- const { length } = elements;
35
- for (let index = 0; index < length; index += 1) {
36
- const element = elements[index];
37
- if (element.hasAttribute(attribute)) {
38
- add(element);
39
- }
40
- }
41
- }
42
- function handleRemoved(nodes, remove) {
43
- const elements = [...nodes].filter(
44
- (node) => node instanceof HTMLElement
45
- );
46
- const { length } = elements;
47
- for (let index = 0; index < length; index += 1) {
48
- remove(elements[index]);
49
- }
50
- }
51
- exports.attributable = attributable;
@@ -1,134 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- class Floatable {
4
- constructor(anchor, content) {
5
- this.anchor = anchor;
6
- this.content = content;
7
- setStyles(content);
8
- }
9
- activate;
10
- active = false;
11
- deactivate;
12
- frame;
13
- destroy() {
14
- this.activate = void 0;
15
- this.deactivate = void 0;
16
- this.frame = void 0;
17
- this.anchor = void 0;
18
- this.content = void 0;
19
- }
20
- }
21
- function activate(floatable, active, order, time) {
22
- stop(floatable);
23
- if (floatable.active) {
24
- return;
25
- }
26
- if (time == null || time === 0) {
27
- onActivate(floatable, active, order);
28
- } else {
29
- floatable.activate = +setTimeout(() => {
30
- onActivate(floatable, active, order);
31
- }, time);
32
- }
33
- }
34
- function deactivate(floatable, active, order, time) {
35
- stop(floatable);
36
- if (!floatable.active) {
37
- return;
38
- }
39
- if (time == null || time === 0) {
40
- onDeactivate(floatable, active, order);
41
- } else {
42
- floatable.deactivate = +setTimeout(() => {
43
- onDeactivate(floatable, active, order);
44
- }, time);
45
- }
46
- }
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;
74
- }
75
- top = anchor.bottom + margin;
76
- if (top + content.height + margin <= window.innerHeight) {
77
- return top;
78
- }
79
- return anchor.top + (anchor.height - content.height) / 2;
80
- }
81
- function onActivate(floatable, active, order) {
82
- floatable.active = true;
83
- active.add(floatable);
84
- if (order != null) {
85
- order.push(floatable);
86
- }
87
- document.body.append(floatable.content);
88
- floatable.content.hidden = false;
89
- update(floatable);
90
- }
91
- function onDeactivate(floatable, active, order) {
92
- floatable.active = false;
93
- active.delete(floatable);
94
- const index = order?.indexOf(floatable) ?? -1;
95
- if (index > -1) {
96
- order?.splice(index, 1);
97
- }
98
- floatable.content.hidden = true;
99
- floatable.anchor.insertAdjacentElement("afterend", floatable.content);
100
- }
101
- function update(floatable) {
102
- function run() {
103
- const anchor = floatable.anchor.getBoundingClientRect();
104
- 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`}`;
108
- floatable.frame = requestAnimationFrame(run);
109
- }
110
- floatable.frame = requestAnimationFrame(run);
111
- }
112
- function setStyles(content) {
113
- content.style.position = "fixed";
114
- content.style.inset = "0 auto auto 0";
115
- content.style.zIndex = "10";
116
- }
117
- function stop(floatable) {
118
- if (floatable.frame != null) {
119
- cancelAnimationFrame(floatable.frame);
120
- }
121
- if (floatable.activate != null) {
122
- clearTimeout(floatable.activate);
123
- }
124
- if (floatable.deactivate != null) {
125
- clearTimeout(floatable.deactivate);
126
- }
127
- floatable.activate = void 0;
128
- floatable.deactivate = void 0;
129
- floatable.frame = void 0;
130
- }
131
- const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) / 2;
132
- exports.Floatable = Floatable;
133
- exports.activate = activate;
134
- exports.deactivate = deactivate;