reshaped 3.9.1-canary.2 → 3.10.0-canary.4

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 (119) hide show
  1. package/dist/bundle.css +1 -1
  2. package/dist/bundle.d.ts +2 -2
  3. package/dist/bundle.js +2 -2
  4. package/dist/components/Accordion/AccordionControlled.js +1 -1
  5. package/dist/components/Accordion/AccordionTrigger.js +1 -1
  6. package/dist/components/ActionBar/ActionBar.js +2 -1
  7. package/dist/components/Avatar/Avatar.js +2 -1
  8. package/dist/components/Badge/Badge.js +6 -5
  9. package/dist/components/Badge/Badge.module.css +1 -1
  10. package/dist/components/Badge/BadgeContainer.js +1 -1
  11. package/dist/components/Breadcrumbs/Breadcrumbs.js +1 -1
  12. package/dist/components/Button/Button.js +2 -1
  13. package/dist/components/Button/ButtonGroup.js +1 -1
  14. package/dist/components/Calendar/CalendarDate.js +1 -1
  15. package/dist/components/Card/Card.js +1 -1
  16. package/dist/components/Carousel/Carousel.js +3 -2
  17. package/dist/components/Carousel/CarouselControl.js +1 -1
  18. package/dist/components/Checkbox/Checkbox.js +2 -1
  19. package/dist/components/Container/Container.js +1 -1
  20. package/dist/components/Dismissible/Dismissible.js +1 -1
  21. package/dist/components/Divider/Divider.js +2 -1
  22. package/dist/components/DropdownMenu/DropdownMenu.js +1 -1
  23. package/dist/components/FileUpload/FileUpload.js +1 -1
  24. package/dist/components/Flyout/Flyout.types.d.ts +1 -1
  25. package/dist/components/Flyout/FlyoutContent.js +3 -12
  26. package/dist/components/Flyout/FlyoutControlled.js +2 -1
  27. package/dist/components/Grid/Grid.js +2 -1
  28. package/dist/components/Hidden/Hidden.js +2 -1
  29. package/dist/components/HiddenInput/HiddenInput.js +1 -1
  30. package/dist/components/Hotkey/Hotkey.js +1 -1
  31. package/dist/components/Icon/Icon.js +1 -1
  32. package/dist/components/Image/Image.js +1 -1
  33. package/dist/components/Link/Link.js +1 -1
  34. package/dist/components/Loader/Loader.js +2 -1
  35. package/dist/components/MenuItem/MenuItem.js +2 -1
  36. package/dist/components/Modal/Modal.js +3 -2
  37. package/dist/components/Overlay/Overlay.js +2 -2
  38. package/dist/components/Popover/Popover.js +1 -1
  39. package/dist/components/Progress/Progress.js +1 -1
  40. package/dist/components/ProgressIndicator/ProgressIndicator.js +1 -1
  41. package/dist/components/Radio/Radio.js +2 -1
  42. package/dist/components/Reshaped/Reshaped.js +1 -1
  43. package/dist/components/Resizable/Resizable.js +1 -1
  44. package/dist/components/Resizable/ResizableHandle.js +1 -1
  45. package/dist/components/Scrim/Scrim.js +1 -1
  46. package/dist/components/ScrollArea/ScrollArea.js +2 -2
  47. package/dist/components/Select/SelectNative.js +1 -1
  48. package/dist/components/Select/SelectRoot.js +2 -1
  49. package/dist/components/Skeleton/Skeleton.js +1 -1
  50. package/dist/components/Slider/Slider.utilities.d.ts +7 -0
  51. package/dist/components/Slider/Slider.utilities.js +11 -0
  52. package/dist/components/Slider/SliderControlled.js +15 -6
  53. package/dist/components/Slider/SliderThumb.js +1 -1
  54. package/dist/components/Switch/Switch.js +2 -1
  55. package/dist/components/Table/Table.js +2 -1
  56. package/dist/components/Tabs/TabsItem.js +2 -2
  57. package/dist/components/Tabs/TabsList.js +1 -1
  58. package/dist/components/Tabs/TabsPanel.js +2 -2
  59. package/dist/components/Text/Text.js +2 -1
  60. package/dist/components/TextArea/TextArea.js +2 -1
  61. package/dist/components/TextField/TextField.js +2 -1
  62. package/dist/components/Theme/Theme.js +1 -1
  63. package/dist/components/Timeline/Timeline.js +1 -1
  64. package/dist/components/Toast/ToastContainer.js +3 -2
  65. package/dist/components/Toast/ToastRegion.js +2 -2
  66. package/dist/components/View/View.js +2 -1
  67. package/dist/components/_private/Aligner/Aligner.js +1 -1
  68. package/dist/components/_private/Expandable/Expandable.js +1 -1
  69. package/dist/core/Actionable/Actionable.js +1 -1
  70. package/dist/hooks/_private/useDrag.js +1 -1
  71. package/dist/hooks/_private/useFadeSide.js +1 -1
  72. package/dist/hooks/_private/useSingletonKeyboardMode.js +1 -1
  73. package/dist/hooks/useKeyboardArrowNavigation.js +1 -1
  74. package/dist/hooks/useScrollLock.js +3 -3
  75. package/dist/index.d.ts +2 -2
  76. package/dist/index.js +2 -2
  77. package/dist/utilities/helpers.d.ts +0 -1
  78. package/dist/utilities/helpers.js +0 -14
  79. package/dist/utilities/props.d.ts +0 -4
  80. package/dist/utilities/props.js +0 -18
  81. package/package.json +4 -4
  82. package/dist/utilities/Chain.d.ts +0 -20
  83. package/dist/utilities/Chain.js +0 -60
  84. package/dist/utilities/a11y/TrapFocus.d.ts +0 -28
  85. package/dist/utilities/a11y/TrapFocus.js +0 -162
  86. package/dist/utilities/a11y/TrapScreenReader.d.ts +0 -15
  87. package/dist/utilities/a11y/TrapScreenReader.js +0 -42
  88. package/dist/utilities/a11y/focus.d.ts +0 -38
  89. package/dist/utilities/a11y/focus.js +0 -101
  90. package/dist/utilities/a11y/index.d.ts +0 -4
  91. package/dist/utilities/a11y/index.js +0 -3
  92. package/dist/utilities/a11y/keyboardMode.d.ts +0 -3
  93. package/dist/utilities/a11y/keyboardMode.js +0 -10
  94. package/dist/utilities/a11y/types.d.ts +0 -24
  95. package/dist/utilities/a11y/types.js +0 -1
  96. package/dist/utilities/css.d.ts +0 -7
  97. package/dist/utilities/css.js +0 -18
  98. package/dist/utilities/dom/event.d.ts +0 -7
  99. package/dist/utilities/dom/event.js +0 -11
  100. package/dist/utilities/dom/find.d.ts +0 -10
  101. package/dist/utilities/dom/find.js +0 -37
  102. package/dist/utilities/dom/index.d.ts +0 -3
  103. package/dist/utilities/dom/index.js +0 -3
  104. package/dist/utilities/dom/shadowDom.d.ts +0 -1
  105. package/dist/utilities/dom/shadowDom.js +0 -4
  106. package/dist/utilities/platform.d.ts +0 -1
  107. package/dist/utilities/platform.js +0 -16
  108. package/dist/utilities/scroll/disable.d.ts +0 -7
  109. package/dist/utilities/scroll/disable.js +0 -15
  110. package/dist/utilities/scroll/helpers.d.ts +0 -1
  111. package/dist/utilities/scroll/helpers.js +0 -17
  112. package/dist/utilities/scroll/index.d.ts +0 -2
  113. package/dist/utilities/scroll/index.js +0 -2
  114. package/dist/utilities/scroll/lock.d.ts +0 -5
  115. package/dist/utilities/scroll/lock.js +0 -32
  116. package/dist/utilities/scroll/lockSafari.d.ts +0 -2
  117. package/dist/utilities/scroll/lockSafari.js +0 -20
  118. package/dist/utilities/scroll/lockStandard.d.ts +0 -4
  119. package/dist/utilities/scroll/lockStandard.js +0 -15
@@ -1,162 +0,0 @@
1
- var _a;
2
- import * as keys from "../../constants/keys.js";
3
- import Chain from "../Chain.js";
4
- import { getShadowRoot } from "../dom/index.js";
5
- import { getActiveElement, getFocusableElements, focusElement, getFocusData } from "./focus.js";
6
- import { checkKeyboardMode } from "./keyboardMode.js";
7
- import TrapScreenReader from "./TrapScreenReader.js";
8
- class TrapFocus {
9
- static chain = new Chain();
10
- #chainId;
11
- #root = null;
12
- #trigger = null;
13
- #options = {};
14
- trapped;
15
- #screenReaderTrap = null;
16
- #mutationObserver = null;
17
- constructor() { }
18
- /**
19
- * Handle keyboard navigation while focus is trapped
20
- */
21
- #handleKeyDown = (event) => {
22
- if (event.defaultPrevented)
23
- return;
24
- if (_a.chain.tailId !== this.#chainId)
25
- return;
26
- if (!this.#root)
27
- return;
28
- const { mode, onRelease, pseudoFocus, includeTrigger } = this.#options;
29
- let navigationMode = "tabs";
30
- if (mode === "action-menu" || mode === "selection-menu" || mode === "action-bar") {
31
- navigationMode = "arrows";
32
- }
33
- const key = event.key;
34
- const isTab = key === keys.TAB;
35
- const isPrevTab = isTab && event.shiftKey;
36
- const isNextTab = isTab && !event.shiftKey;
37
- const isArrow = [keys.LEFT, keys.RIGHT, keys.UP, keys.DOWN].includes(key);
38
- const isPrevArrow = navigationMode === "arrows" && key === (mode === "action-bar" ? keys.LEFT : keys.UP);
39
- const isNextArrow = navigationMode === "arrows" && key === (mode === "action-bar" ? keys.RIGHT : keys.DOWN);
40
- const isPrev = (isPrevTab && navigationMode === "tabs") || isPrevArrow;
41
- const isNext = (isNextTab && navigationMode === "tabs") || isNextArrow;
42
- const isFocusedOnTrigger = getActiveElement(this.#root) === this.#trigger;
43
- const focusData = getFocusData({
44
- root: this.#root,
45
- target: isPrev ? "prev" : "next",
46
- options: {
47
- additionalElement: includeTrigger ? this.#trigger : undefined,
48
- circular: true,
49
- },
50
- });
51
- // Release the trap when tab is used in navigation modes that support arrows
52
- const hasNavigatedOutside = (isTab && navigationMode === "arrows") ||
53
- (mode === "content-menu" && isTab && focusData.overflow);
54
- if (hasNavigatedOutside) {
55
- // Prevent shift + tab event to avoid focus moving after the trap release
56
- if (isPrevTab && !isFocusedOnTrigger)
57
- event.preventDefault();
58
- this.release();
59
- onRelease?.();
60
- return;
61
- }
62
- if (!isPrev && !isNext) {
63
- // Avoid page from scrolling with arrow keys while focus it trapped
64
- if (isArrow && (mode === "action-bar" || mode === "action-menu"))
65
- event.preventDefault();
66
- return;
67
- }
68
- event.preventDefault();
69
- if (!focusData.el)
70
- return;
71
- focusElement(focusData.el, { pseudoFocus });
72
- };
73
- #addListeners = () => {
74
- const shadowRoot = getShadowRoot(this.#root);
75
- const el = shadowRoot ?? document;
76
- el.addEventListener("keydown", this.#handleKeyDown);
77
- };
78
- #removeListeners = () => {
79
- const shadowRoot = getShadowRoot(this.#root);
80
- const el = shadowRoot ?? document;
81
- el.removeEventListener("keydown", this.#handleKeyDown);
82
- };
83
- #isLast = () => {
84
- const tailItem = _a.chain.tailId && _a.chain.get(_a.chain.tailId);
85
- return tailItem && tailItem.data.#root === this.#root;
86
- };
87
- /**
88
- * Trap the focus, add observer and keyboard event listeners
89
- * and create a chain item
90
- */
91
- trap = (root, options = {}) => {
92
- const { mode = "dialog", includeTrigger, initialFocusEl } = options;
93
- this.#root = root;
94
- this.#screenReaderTrap = new TrapScreenReader(root);
95
- const trigger = getActiveElement(this.#root);
96
- const focusable = getFocusableElements(this.#root, {
97
- additionalElement: includeTrigger ? trigger : undefined,
98
- });
99
- const pseudoFocus = mode === "selection-menu";
100
- this.#options = { ...options, pseudoFocus };
101
- this.#trigger = trigger;
102
- this.#mutationObserver = new MutationObserver(() => {
103
- if (!this.#root)
104
- return;
105
- if (!this.#isLast())
106
- return;
107
- const currentActiveElement = getActiveElement(this.#root);
108
- // Focus stayed inside the wrapper, no need to refocus
109
- if (this.#root.contains(currentActiveElement))
110
- return;
111
- const focusable = getFocusableElements(this.#root, {
112
- additionalElement: includeTrigger ? trigger : undefined,
113
- });
114
- if (!focusable.length)
115
- return;
116
- focusElement(focusable[0], { pseudoFocus });
117
- });
118
- this.#removeListeners();
119
- this.#mutationObserver.observe(this.#root, { childList: true, subtree: true });
120
- // Don't trap in case there is nothing to focus inside
121
- if (!focusable.length && !initialFocusEl)
122
- return;
123
- this.#addListeners();
124
- if (mode === "dialog")
125
- this.#screenReaderTrap.trap();
126
- const currentActiveElement = getActiveElement(this.#root);
127
- const isLastInChain = this.#isLast();
128
- // Don't add back to the chain if we're traversing back
129
- if (!isLastInChain) {
130
- this.#chainId = _a.chain.add(this);
131
- // If the focus was moved manually (e.g. with autoFocus) - keep it there
132
- if (!this.#root.contains(currentActiveElement)) {
133
- focusElement(initialFocusEl || focusable[0], { pseudoFocus });
134
- }
135
- }
136
- this.trapped = true;
137
- };
138
- /**
139
- * Disabled the trap focus for the element,
140
- * cleanup all observers/handlers and trap for the previous element in the chain
141
- */
142
- release = (releaseOptions = {}) => {
143
- const { withoutFocusReturn } = releaseOptions;
144
- if (!this.trapped || !this.#chainId || !this.#root)
145
- return;
146
- this.trapped = false;
147
- if (this.#trigger && !withoutFocusReturn) {
148
- this.#trigger.focus({ preventScroll: !checkKeyboardMode() });
149
- }
150
- _a.chain.removePreviousTill(this.#chainId, (item) => document.body.contains(item.data.#trigger));
151
- this.#mutationObserver?.disconnect();
152
- this.#removeListeners();
153
- this.#screenReaderTrap?.release();
154
- const previousItem = _a.chain.tailId && _a.chain.get(_a.chain.tailId);
155
- if (previousItem && previousItem.data.#root) {
156
- const trapInstance = new _a();
157
- trapInstance.trap(previousItem.data.#root, previousItem.data.#options);
158
- }
159
- };
160
- }
161
- _a = TrapFocus;
162
- export default TrapFocus;
@@ -1,15 +0,0 @@
1
- declare class TrapScreenReader {
2
- root: HTMLElement;
3
- /**
4
- * Elements ignored by screen reader when trap is active
5
- */
6
- private hiddenElements;
7
- constructor(root: HTMLElement);
8
- /**
9
- * Apply aria-hidden to all elements except the passed
10
- */
11
- hideSiblingsFromScreenReader: (el: HTMLElement) => void;
12
- release: () => void;
13
- trap: () => void;
14
- }
15
- export default TrapScreenReader;
@@ -1,42 +0,0 @@
1
- class TrapScreenReader {
2
- root;
3
- /**
4
- * Elements ignored by screen reader when trap is active
5
- */
6
- hiddenElements = [];
7
- constructor(root) {
8
- this.root = root;
9
- }
10
- /**
11
- * Apply aria-hidden to all elements except the passed
12
- */
13
- hideSiblingsFromScreenReader = (el) => {
14
- let sibling = el.parentNode && el.parentNode.firstChild;
15
- while (sibling) {
16
- const notCurrent = sibling !== el;
17
- const isValid = sibling.nodeType === 1 && !sibling.hasAttribute("aria-hidden");
18
- if (notCurrent && isValid) {
19
- sibling.setAttribute("aria-hidden", "true");
20
- this.hiddenElements.push(sibling);
21
- }
22
- sibling = sibling.nextSibling;
23
- }
24
- };
25
- release = () => {
26
- this.hiddenElements.forEach((el) => {
27
- el.removeAttribute("aria-hidden");
28
- });
29
- this.hiddenElements = [];
30
- };
31
- trap = () => {
32
- let currentEl = this.root;
33
- this.release();
34
- // Stop at the body level for regular pages
35
- // And stop at shadow root
36
- while (currentEl !== document.body && currentEl.parentElement) {
37
- this.hideSiblingsFromScreenReader(currentEl);
38
- currentEl = currentEl.parentElement;
39
- }
40
- };
41
- }
42
- export default TrapScreenReader;
@@ -1,38 +0,0 @@
1
- import type { FocusableElement, FocusableOptions } from "./types";
2
- export declare const focusableSelector = "a,button,input:not([type=\"hidden\"]),textarea,select,details,[tabindex],[contenteditable]";
3
- export declare const getActiveElement: (originEl?: HTMLElement | null) => HTMLButtonElement;
4
- export declare const focusElement: (el: FocusableElement, options?: {
5
- pseudoFocus?: boolean;
6
- }) => void;
7
- export declare const getFocusableElements: (rootEl: HTMLElement, options?: FocusableOptions) => FocusableElement[];
8
- export declare const getFocusData: (args: {
9
- root: HTMLElement;
10
- target: "next" | "prev" | "first" | "last";
11
- options?: FocusableOptions & {
12
- circular?: boolean;
13
- };
14
- }) => {
15
- overflow: boolean;
16
- el: FocusableElement;
17
- focusableElements: FocusableElement[];
18
- };
19
- export declare const focusNextElement: (root: HTMLElement, options?: {
20
- circular?: boolean;
21
- }) => {
22
- el: FocusableElement;
23
- focusableElements: FocusableElement[];
24
- };
25
- export declare const focusPreviousElement: (root: HTMLElement, options?: {
26
- circular?: boolean;
27
- }) => {
28
- el: FocusableElement;
29
- focusableElements: FocusableElement[];
30
- };
31
- export declare const focusFirstElement: (root: HTMLElement) => {
32
- el: FocusableElement;
33
- focusableElements: FocusableElement[];
34
- };
35
- export declare const focusLastElement: (root: HTMLElement) => {
36
- el: FocusableElement;
37
- focusableElements: FocusableElement[];
38
- };
@@ -1,101 +0,0 @@
1
- import { getShadowRoot } from "../dom/index.js";
2
- const pseudoFocusAttribute = "data-rs-focus";
3
- export const focusableSelector = 'a,button,input:not([type="hidden"]),textarea,select,details,[tabindex],[contenteditable]';
4
- export const getActiveElement = (originEl) => {
5
- const shadowRoot = originEl ? getShadowRoot(originEl) : null;
6
- const rootEl = shadowRoot ?? document;
7
- const pseudoFocusedEl = rootEl.querySelector(`[${pseudoFocusAttribute}]`);
8
- return (pseudoFocusedEl || rootEl.activeElement);
9
- };
10
- export const focusElement = (el, options) => {
11
- const shadowRoot = getShadowRoot(el);
12
- const rootEl = shadowRoot ?? document;
13
- rootEl.querySelector(`[${pseudoFocusAttribute}]`)?.removeAttribute(pseudoFocusAttribute);
14
- if (options?.pseudoFocus) {
15
- el.setAttribute(pseudoFocusAttribute, "true");
16
- }
17
- else {
18
- el.focus();
19
- }
20
- };
21
- export const getFocusableElements = (rootEl, options) => {
22
- const focusableElements = Array.from(rootEl.querySelectorAll(focusableSelector));
23
- const filteredElements = focusableElements.filter((el) => {
24
- if (el.hasAttribute("disabled"))
25
- return false;
26
- if (el.clientHeight === 0)
27
- return false;
28
- // Using getAttribute here since browser sets el.tabIndex to -1 by default
29
- if (!options?.includeNegativeTabIndex && el.getAttribute("tabindex") === "-1")
30
- return false;
31
- if (el.type === "radio") {
32
- let sameNameRadioEls;
33
- if (el.form) {
34
- const formInputs = el.form.elements.namedItem(el.name);
35
- // Synthetic error handling for narrowing down types
36
- // Radio element can't find itself in the form, so we don't need to include it in the array
37
- if (!formInputs)
38
- return false;
39
- const multipleElementsFound = "length" in formInputs;
40
- if (!multipleElementsFound) {
41
- // Single element found is always an input radio since we're inside the condition
42
- sameNameRadioEls = [formInputs];
43
- }
44
- else {
45
- sameNameRadioEls = Array.from(formInputs).filter((el) => "type" in el && el.type === "radio");
46
- }
47
- }
48
- else {
49
- sameNameRadioEls = Array.from(rootEl.querySelectorAll(`[type="radio"][name="${el.name}"]`));
50
- }
51
- if (sameNameRadioEls?.length) {
52
- const checkedEl = Array.from(sameNameRadioEls).find((el) => el.checked);
53
- if (checkedEl && el !== checkedEl)
54
- return false;
55
- if (!checkedEl && el !== sameNameRadioEls[0])
56
- return false;
57
- }
58
- }
59
- return true;
60
- });
61
- if (options?.additionalElement && filteredElements.length) {
62
- filteredElements.unshift(options.additionalElement);
63
- }
64
- return filteredElements;
65
- };
66
- export const getFocusData = (args) => {
67
- const { root, target, options } = args;
68
- const focusable = getFocusableElements(root, {
69
- additionalElement: options?.additionalElement,
70
- includeNegativeTabIndex: options?.includeNegativeTabIndex,
71
- });
72
- const focusableLimit = focusable.length - 1;
73
- const currentElement = getActiveElement(root);
74
- const currentIndex = focusable.indexOf(currentElement);
75
- const positions = {
76
- next: currentIndex + 1,
77
- prev: currentIndex - 1,
78
- first: 0,
79
- last: focusableLimit,
80
- };
81
- let nextIndex = positions[target];
82
- const isOverflow = nextIndex > focusableLimit || nextIndex < 0;
83
- if (isOverflow) {
84
- if (options?.circular) {
85
- nextIndex = target === "prev" ? positions.last : positions.first;
86
- }
87
- else {
88
- nextIndex = target === "prev" ? positions.first : positions.last;
89
- }
90
- }
91
- return { overflow: isOverflow, el: focusable[nextIndex], focusableElements: focusable };
92
- };
93
- const focusTargetElement = (root, target, options) => {
94
- const data = getFocusData({ root, target, options });
95
- focusElement(data.el);
96
- return { el: data.el, focusableElements: data.focusableElements };
97
- };
98
- export const focusNextElement = (root, options) => focusTargetElement(root, "next", { ...options, includeNegativeTabIndex: true });
99
- export const focusPreviousElement = (root, options) => focusTargetElement(root, "prev", { ...options, includeNegativeTabIndex: true });
100
- export const focusFirstElement = (root) => focusTargetElement(root, "first", { includeNegativeTabIndex: true });
101
- export const focusLastElement = (root) => focusTargetElement(root, "last", { includeNegativeTabIndex: true });
@@ -1,4 +0,0 @@
1
- export { focusableSelector, getActiveElement, getFocusableElements, focusNextElement, focusPreviousElement, focusFirstElement, focusLastElement, } from "./focus";
2
- export { activateKeyboardMode, deactivateKeyboardMode, checkKeyboardMode } from "./keyboardMode";
3
- export { default as TrapFocus } from "./TrapFocus";
4
- export type { TrapMode, FocusableElement } from "./types";
@@ -1,3 +0,0 @@
1
- export { focusableSelector, getActiveElement, getFocusableElements, focusNextElement, focusPreviousElement, focusFirstElement, focusLastElement, } from "./focus.js";
2
- export { activateKeyboardMode, deactivateKeyboardMode, checkKeyboardMode } from "./keyboardMode.js";
3
- export { default as TrapFocus } from "./TrapFocus.js";
@@ -1,3 +0,0 @@
1
- export declare const activateKeyboardMode: () => void;
2
- export declare const deactivateKeyboardMode: () => void;
3
- export declare const checkKeyboardMode: () => boolean;
@@ -1,10 +0,0 @@
1
- const keyboardModeAttribute = "data-rs-keyboard";
2
- export const activateKeyboardMode = () => {
3
- document.documentElement.setAttribute(keyboardModeAttribute, "true");
4
- };
5
- export const deactivateKeyboardMode = () => {
6
- document.documentElement.removeAttribute(keyboardModeAttribute);
7
- };
8
- export const checkKeyboardMode = () => {
9
- return document.documentElement.hasAttribute(keyboardModeAttribute);
10
- };
@@ -1,24 +0,0 @@
1
- /**
2
- * dialog: Completely trap the focus inside for tab navigation until content is closed
3
- * example: Modal
4
- *
5
- * action-menu: Trap the arrow navigation, while tab moves the focus to
6
- * the next element on the page after the trigger
7
- * example: Dropdown Menu
8
- *
9
- * action-bar: Same as action-menu but with horizontal keyboard arrow navigation
10
- *
11
- * content-menu: Include dropdown content into the tab navigation flow and move the focus to
12
- * the next element on the page after the trigger after navigation through the trapped content
13
- * example: Header navigation dropdowns
14
- *
15
- * selection-menu: Keep the focus on the trigger and enable arrow key navigation with pseudo focusing with data-attributes
16
- * without moving the focus away from the trigger
17
- * example: Autocomplete
18
- */
19
- export type TrapMode = "dialog" | "action-menu" | "action-bar" | "content-menu" | "selection-menu";
20
- export type FocusableElement = HTMLButtonElement | HTMLInputElement;
21
- export type FocusableOptions = {
22
- additionalElement?: FocusableElement | null;
23
- includeNegativeTabIndex?: boolean;
24
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,7 +0,0 @@
1
- type Styles = Record<string, string>;
2
- export declare class StyleCache {
3
- cache: Map<HTMLElement, Record<string, string>>;
4
- set: (el: HTMLElement, styles: Styles) => void;
5
- reset: () => void;
6
- }
7
- export {};
@@ -1,18 +0,0 @@
1
- export class StyleCache {
2
- cache = new Map();
3
- set = (el, styles) => {
4
- const originalStyles = {};
5
- const cachedStyles = this.cache.get(el);
6
- Object.keys(styles).forEach((key) => {
7
- originalStyles[key] = el.style.getPropertyValue(key);
8
- });
9
- this.cache.set(el, { ...originalStyles, ...cachedStyles });
10
- Object.assign(el.style, styles);
11
- };
12
- reset = () => {
13
- for (const [el, styles] of this.cache.entries()) {
14
- Object.assign(el.style, styles);
15
- }
16
- this.cache.clear();
17
- };
18
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Workaround for changing a hidden input value with triggerring
3
- * React input onChange and form onChange handlers
4
- *
5
- * Based on https://stackoverflow.com/a/60378508
6
- */
7
- export declare const triggerChangeEvent: (el: HTMLInputElement, value: string) => void;
@@ -1,11 +0,0 @@
1
- /**
2
- * Workaround for changing a hidden input value with triggerring
3
- * React input onChange and form onChange handlers
4
- *
5
- * Based on https://stackoverflow.com/a/60378508
6
- */
7
- export const triggerChangeEvent = (el, value) => {
8
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
9
- nativeInputValueSetter.call(el, value);
10
- el.dispatchEvent(new Event("change", { bubbles: true }));
11
- };
@@ -1,10 +0,0 @@
1
- export declare const findParent: (element: HTMLElement, condition: (el: HTMLElement) => boolean) => HTMLElement | null;
2
- export declare const findClosestPositionContainer: (args: {
3
- el: HTMLElement | null;
4
- iteration?: number;
5
- }) => HTMLElement;
6
- export declare const findClosestScrollableContainer: (args: {
7
- el: HTMLElement;
8
- iteration?: number;
9
- overflowOnly?: boolean;
10
- }) => HTMLElement;
@@ -1,37 +0,0 @@
1
- import { getShadowRoot } from "./shadowDom.js";
2
- export const findParent = (element, condition) => {
3
- let currentElement = element.parentElement;
4
- while (currentElement) {
5
- if (condition(currentElement))
6
- return currentElement;
7
- currentElement = currentElement.parentElement;
8
- }
9
- return null;
10
- };
11
- export const findClosestPositionContainer = (args) => {
12
- const { el, iteration = 0 } = args;
13
- const style = el && window.getComputedStyle(el);
14
- const position = style?.position;
15
- const isFixed = position === "fixed" || position === "sticky";
16
- if (iteration === 0) {
17
- const shadowRoot = getShadowRoot(el);
18
- if (shadowRoot?.firstElementChild)
19
- return shadowRoot.firstElementChild;
20
- }
21
- if (el === document.body || !el)
22
- return document.body;
23
- if (isFixed)
24
- return el;
25
- return findClosestPositionContainer({ el: el.parentElement, iteration: iteration + 1 });
26
- };
27
- export const findClosestScrollableContainer = (args) => {
28
- const { el, iteration = 0 } = args;
29
- const style = el && window.getComputedStyle(el);
30
- const overflowY = style?.overflowY;
31
- const isScrollable = overflowY?.includes("scroll") || overflowY?.includes("auto");
32
- if (!el.parentElement)
33
- return el;
34
- if (isScrollable && el.scrollHeight > el.clientHeight)
35
- return el;
36
- return findClosestScrollableContainer({ el: el.parentElement, iteration: iteration + 1 });
37
- };
@@ -1,3 +0,0 @@
1
- export { getShadowRoot } from "./shadowDom";
2
- export { findParent, findClosestScrollableContainer, findClosestPositionContainer } from "./find";
3
- export { triggerChangeEvent } from "./event";
@@ -1,3 +0,0 @@
1
- export { getShadowRoot } from "./shadowDom.js";
2
- export { findParent, findClosestScrollableContainer, findClosestPositionContainer } from "./find.js";
3
- export { triggerChangeEvent } from "./event.js";
@@ -1 +0,0 @@
1
- export declare const getShadowRoot: (el: HTMLElement | null) => ShadowRoot | null;
@@ -1,4 +0,0 @@
1
- export const getShadowRoot = (el) => {
2
- const rootNode = el?.getRootNode();
3
- return rootNode instanceof ShadowRoot ? rootNode : null;
4
- };
@@ -1 +0,0 @@
1
- export declare const isIOS: () => boolean;
@@ -1,16 +0,0 @@
1
- const testPlatform = (re) => {
2
- // Using experimentral and deprecated features here since that's the only way to detect platform consistently
3
- const platform =
4
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
- // @ts-ignore
6
- window.navigator.userAgentData?.platform || window.navigator.platform;
7
- return typeof window !== "undefined" ? re.test(platform) : false;
8
- };
9
- const isIPhone = () => testPlatform(/^iPhone/i);
10
- const isMac = () => testPlatform(/^Mac/i);
11
- const isIPad = () => {
12
- return (testPlatform(/^iPad/i) ||
13
- // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
14
- (isMac() && navigator.maxTouchPoints > 1));
15
- };
16
- export const isIOS = () => isIPhone() || isIPad();
@@ -1,7 +0,0 @@
1
- export declare const preventDefault: (e: Event) => void;
2
- /**
3
- * Prevent scrolling events for the cases when dragging elements
4
- * without locking the page with overflow
5
- */
6
- export declare const disableScroll: () => void;
7
- export declare const enableScroll: () => void;
@@ -1,15 +0,0 @@
1
- export const preventDefault = (e) => e.preventDefault();
2
- /**
3
- * Prevent scrolling events for the cases when dragging elements
4
- * without locking the page with overflow
5
- */
6
- export const disableScroll = () => {
7
- window.addEventListener("wheel", preventDefault, { passive: false });
8
- window.addEventListener("touchmove", preventDefault, { passive: false });
9
- document.body.style.userSelect = "none";
10
- };
11
- export const enableScroll = () => {
12
- window.removeEventListener("wheel", preventDefault);
13
- window.removeEventListener("touchmove", preventDefault);
14
- document.body.style.userSelect = "";
15
- };
@@ -1 +0,0 @@
1
- export declare const getScrollbarWidth: () => number;
@@ -1,17 +0,0 @@
1
- export const getScrollbarWidth = (() => {
2
- let scrollbarWidth;
3
- return () => {
4
- if (scrollbarWidth)
5
- return scrollbarWidth;
6
- const scrollDiv = document.createElement("div");
7
- scrollDiv.style.position = "absolute";
8
- scrollDiv.style.top = "-9999px";
9
- scrollDiv.style.width = "50px";
10
- scrollDiv.style.height = "50px";
11
- scrollDiv.style.overflow = "scroll";
12
- document.body.appendChild(scrollDiv);
13
- scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
14
- document.body.removeChild(scrollDiv);
15
- return scrollbarWidth;
16
- };
17
- })();
@@ -1,2 +0,0 @@
1
- export { disableScroll, enableScroll } from "./disable";
2
- export { lockScroll } from "./lock";
@@ -1,2 +0,0 @@
1
- export { disableScroll, enableScroll } from "./disable.js";
2
- export { lockScroll } from "./lock.js";
@@ -1,5 +0,0 @@
1
- export declare const lockScroll: (args: {
2
- containerEl?: HTMLElement | null;
3
- originEl?: HTMLElement | null;
4
- cb?: () => void;
5
- }) => ((cb?: () => void) => void) | undefined;
@@ -1,32 +0,0 @@
1
- import { findClosestScrollableContainer } from "../dom/index.js";
2
- import { isIOS } from "../platform.js";
3
- import lockSafariScroll from "./lockSafari.js";
4
- import lockStandardScroll from "./lockStandard.js";
5
- let bodyLockedCount = 0;
6
- export const lockScroll = (args) => {
7
- const isIOSLock = isIOS();
8
- let reset = () => { };
9
- let container = document.body;
10
- if (args.originEl)
11
- container = findClosestScrollableContainer({ el: args.originEl });
12
- if (args.containerEl)
13
- container = args.containerEl;
14
- const lockedBodyScroll = container === document.body;
15
- if (lockedBodyScroll)
16
- bodyLockedCount += 1;
17
- if (lockedBodyScroll && bodyLockedCount > 1)
18
- return;
19
- if (isIOSLock && lockedBodyScroll) {
20
- reset = lockSafariScroll();
21
- }
22
- else {
23
- reset = lockStandardScroll({ container });
24
- }
25
- args.cb?.();
26
- return (cb) => {
27
- if (lockedBodyScroll)
28
- bodyLockedCount -= 1;
29
- reset();
30
- cb?.();
31
- };
32
- };
@@ -1,2 +0,0 @@
1
- declare const lockSafariScroll: () => () => void;
2
- export default lockSafariScroll;