@pzerelles/headlessui-svelte 2.0.0-next.1 → 2.1.2-next.2
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/button/Button.svelte +61 -0
- package/dist/button/Button.svelte.d.ts +47 -0
- package/dist/button/index.d.ts +1 -0
- package/dist/button/index.js +1 -0
- package/dist/checkbox/Checkbox.svelte +93 -61
- package/dist/checkbox/Checkbox.svelte.d.ts +45 -29
- package/dist/close-button/CloseButton.svelte +11 -0
- package/dist/close-button/CloseButton.svelte.d.ts +48 -0
- package/dist/close-button/index.d.ts +1 -0
- package/dist/close-button/index.js +1 -0
- package/dist/combobox/Combobox.svelte +6 -0
- package/dist/combobox/Combobox.svelte.d.ts +50 -0
- package/dist/data-interactive/DataInteractive.svelte +41 -0
- package/dist/data-interactive/DataInteractive.svelte.d.ts +39 -0
- package/dist/data-interactive/index.d.ts +1 -0
- package/dist/data-interactive/index.js +1 -0
- package/dist/description/Description.svelte +16 -41
- package/dist/description/Description.svelte.d.ts +15 -23
- package/dist/description/context.svelte.d.ts +17 -0
- package/dist/description/context.svelte.js +51 -0
- package/dist/dialog/Dialog.svelte +51 -0
- package/dist/dialog/Dialog.svelte.d.ts +60 -0
- package/dist/dialog/DialogBackdrop.svelte +39 -0
- package/dist/dialog/DialogBackdrop.svelte.d.ts +38 -0
- package/dist/dialog/DialogPanel.svelte +46 -0
- package/dist/dialog/DialogPanel.svelte.d.ts +40 -0
- package/dist/dialog/DialogTitle.svelte +29 -0
- package/dist/dialog/DialogTitle.svelte.d.ts +34 -0
- package/dist/dialog/InternalDialog.svelte +233 -0
- package/dist/dialog/InternalDialog.svelte.d.ts +42 -0
- package/dist/dialog/context.svelte.d.ts +15 -0
- package/dist/dialog/context.svelte.js +16 -0
- package/dist/dialog/index.d.ts +4 -0
- package/dist/dialog/index.js +4 -0
- package/dist/field/Field.svelte +14 -16
- package/dist/field/Field.svelte.d.ts +21 -17
- package/dist/fieldset/Fieldset.svelte +19 -17
- package/dist/fieldset/Fieldset.svelte.d.ts +21 -17
- package/dist/focus-trap/FocusTrap.svelte +332 -0
- package/dist/focus-trap/FocusTrap.svelte.d.ts +58 -0
- package/dist/hooks/document-overflow/adjust-scrollbar-padding.d.ts +2 -0
- package/dist/hooks/document-overflow/adjust-scrollbar-padding.js +18 -0
- package/dist/hooks/document-overflow/handle-ios-locking.d.ts +6 -0
- package/dist/hooks/document-overflow/handle-ios-locking.js +134 -0
- package/dist/hooks/document-overflow/overflow-store.d.ts +19 -0
- package/dist/hooks/document-overflow/overflow-store.js +76 -0
- package/dist/hooks/document-overflow/prevent-scroll.d.ts +2 -0
- package/dist/hooks/document-overflow/prevent-scroll.js +7 -0
- package/dist/hooks/document-overflow/use-document-overflow.svelte.d.ts +7 -0
- package/dist/hooks/document-overflow/use-document-overflow.svelte.js +27 -0
- package/dist/hooks/use-active-press.svelte.d.ts +14 -0
- package/dist/{actions/activePress.svelte.js → hooks/use-active-press.svelte.js} +33 -39
- package/dist/hooks/use-by-comparator.d.ts +2 -0
- package/dist/hooks/use-by-comparator.js +15 -0
- package/dist/hooks/use-controllable.svelte.d.ts +6 -0
- package/dist/hooks/use-controllable.svelte.js +34 -0
- package/dist/hooks/use-did-element-move.svelte.d.ts +6 -0
- package/dist/hooks/use-did-element-move.svelte.js +27 -0
- package/dist/hooks/use-disabled.d.ts +3 -0
- package/dist/hooks/use-disabled.js +9 -0
- package/dist/hooks/use-element-size.svelte.d.ts +7 -0
- package/dist/hooks/use-element-size.svelte.js +36 -0
- package/dist/hooks/use-escape.svelte.d.ts +5 -0
- package/dist/hooks/use-escape.svelte.js +26 -0
- package/dist/hooks/use-event-listener.svelte.d.ts +6 -0
- package/dist/hooks/use-event-listener.svelte.js +12 -0
- package/dist/hooks/use-flags.svelte.d.ts +8 -0
- package/dist/hooks/use-flags.svelte.js +18 -0
- package/dist/hooks/use-focus-ring.svelte.d.ts +10 -0
- package/dist/hooks/use-focus-ring.svelte.js +24 -0
- package/dist/hooks/use-hover.svelte.d.ts +26 -0
- package/dist/hooks/use-hover.svelte.js +124 -0
- package/dist/hooks/use-id.d.ts +1 -0
- package/dist/hooks/use-id.js +1 -0
- package/dist/hooks/use-inert-others.svelte.d.ts +32 -0
- package/dist/hooks/use-inert-others.svelte.js +114 -0
- package/dist/hooks/use-is-mounted.svelte.d.ts +3 -0
- package/dist/hooks/use-is-mounted.svelte.js +14 -0
- package/dist/hooks/use-is-top-layer.svelte.d.ts +29 -0
- package/dist/hooks/use-is-top-layer.svelte.js +82 -0
- package/dist/hooks/use-is-touch-device.svelte.d.ts +3 -0
- package/dist/hooks/use-is-touch-device.svelte.js +20 -0
- package/dist/hooks/use-on-disappear.svelte.d.ts +12 -0
- package/dist/hooks/use-on-disappear.svelte.js +38 -0
- package/dist/hooks/use-outside-click.svelte.d.ts +10 -0
- package/dist/hooks/use-outside-click.svelte.js +150 -0
- package/dist/hooks/use-reducer.d.ts +4 -0
- package/dist/hooks/use-reducer.js +11 -0
- package/dist/hooks/use-resolve-button-type.svelte.d.ts +10 -0
- package/dist/hooks/use-resolve-button-type.svelte.js +19 -0
- package/dist/hooks/use-root-containers.svelte.d.ts +9 -0
- package/dist/hooks/use-root-containers.svelte.js +50 -0
- package/dist/hooks/use-scroll-lock.svelte.d.ts +5 -0
- package/dist/hooks/use-scroll-lock.svelte.js +24 -0
- package/dist/hooks/use-sync-refs.d.ts +7 -0
- package/dist/hooks/use-sync-refs.js +22 -0
- package/dist/hooks/use-tab-direction.svelte.d.ts +7 -0
- package/dist/hooks/use-tab-direction.svelte.js +25 -0
- package/dist/hooks/use-text-value.svelte.d.ts +3 -0
- package/dist/hooks/use-text-value.svelte.js +20 -0
- package/dist/hooks/use-tracked-pointer.d.ts +4 -0
- package/dist/hooks/use-tracked-pointer.js +26 -0
- package/dist/hooks/use-transition.svelte.d.ts +20 -0
- package/dist/hooks/use-transition.svelte.js +253 -0
- package/dist/hooks/use-tree-walker.svelte.d.ts +8 -0
- package/dist/hooks/use-tree-walker.svelte.js +19 -0
- package/dist/hooks/use-watch.svelte.d.ts +4 -0
- package/dist/hooks/use-watch.svelte.js +16 -0
- package/dist/hooks/use-window-event.svelte.d.ts +6 -0
- package/dist/hooks/use-window-event.svelte.js +12 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/input/Input.svelte +59 -0
- package/dist/input/Input.svelte.d.ts +52 -0
- package/dist/input/index.d.ts +1 -0
- package/dist/input/index.js +1 -0
- package/dist/internal/FocusSentinel.svelte +45 -0
- package/dist/internal/FocusSentinel.svelte.d.ts +20 -0
- package/dist/internal/ForcePortalRoot.svelte +6 -0
- package/dist/internal/ForcePortalRoot.svelte.d.ts +22 -0
- package/dist/internal/FormFields.svelte +2 -4
- package/dist/internal/FormFields.svelte.d.ts +9 -7
- package/dist/internal/FormResolver.svelte +11 -16
- package/dist/internal/FormResolver.svelte.d.ts +6 -4
- package/dist/internal/Hidden.svelte +5 -9
- package/dist/internal/Hidden.svelte.d.ts +35 -19
- package/dist/internal/HoistFormFields.svelte.d.ts +5 -2
- package/dist/internal/MainTreeProvider.svelte +45 -0
- package/dist/internal/MainTreeProvider.svelte.d.ts +31 -0
- package/dist/internal/Portal.svelte.d.ts +5 -2
- package/dist/internal/close-provider.d.ts +7 -0
- package/dist/internal/close-provider.js +7 -0
- package/dist/internal/floating.svelte.d.ts +62 -0
- package/dist/internal/floating.svelte.js +488 -0
- package/dist/internal/frozen.svelte.d.ts +6 -0
- package/dist/internal/frozen.svelte.js +18 -0
- package/dist/internal/id.d.ts +8 -0
- package/dist/internal/id.js +11 -0
- package/dist/internal/open-closed.d.ts +14 -0
- package/dist/internal/open-closed.js +17 -0
- package/dist/internal/portal-force-root.svelte.d.ts +6 -0
- package/dist/internal/portal-force-root.svelte.js +11 -0
- package/dist/label/Label.svelte +17 -45
- package/dist/label/Label.svelte.d.ts +19 -23
- package/dist/label/context.svelte.d.ts +17 -0
- package/dist/label/context.svelte.js +56 -0
- package/dist/legend/Legend.svelte +4 -3
- package/dist/legend/Legend.svelte.d.ts +33 -16
- package/dist/listbox/Listbox.svelte +448 -0
- package/dist/listbox/Listbox.svelte.d.ts +126 -0
- package/dist/listbox/ListboxButton.svelte +139 -0
- package/dist/listbox/ListboxButton.svelte.d.ts +52 -0
- package/dist/listbox/ListboxOption.svelte +136 -0
- package/dist/listbox/ListboxOption.svelte.d.ts +50 -0
- package/dist/listbox/ListboxOptions.svelte +269 -0
- package/dist/listbox/ListboxOptions.svelte.d.ts +55 -0
- package/dist/listbox/ListboxSelectedOption.svelte +35 -0
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +40 -0
- package/dist/listbox/index.d.ts +5 -0
- package/dist/listbox/index.js +5 -0
- package/dist/menu/Menu.svelte +235 -0
- package/dist/menu/Menu.svelte.d.ts +42 -0
- package/dist/menu/MenuButton.svelte +127 -0
- package/dist/menu/MenuButton.svelte.d.ts +52 -0
- package/dist/menu/MenuHeading.svelte +19 -0
- package/dist/menu/MenuHeading.svelte.d.ts +39 -0
- package/dist/menu/MenuItem.svelte +114 -0
- package/dist/menu/MenuItem.svelte.d.ts +49 -0
- package/dist/menu/MenuItems.svelte +244 -0
- package/dist/menu/MenuItems.svelte.d.ts +55 -0
- package/dist/menu/MenuSection.svelte +14 -0
- package/dist/menu/MenuSection.svelte.d.ts +35 -0
- package/dist/menu/MenuSeparator.svelte +9 -0
- package/dist/menu/MenuSeparator.svelte.d.ts +35 -0
- package/dist/menu/context.svelte.d.ts +47 -0
- package/dist/menu/context.svelte.js +21 -0
- package/dist/menu/index.d.ts +7 -0
- package/dist/menu/index.js +7 -0
- package/dist/portal/InternalPortal.svelte +97 -0
- package/dist/portal/InternalPortal.svelte.d.ts +43 -0
- package/dist/portal/Portal.svelte +7 -0
- package/dist/portal/Portal.svelte.d.ts +23 -0
- package/dist/portal/PortalGroup.svelte +14 -0
- package/dist/portal/PortalGroup.svelte.d.ts +40 -0
- package/dist/switch/Switch.svelte +143 -0
- package/dist/switch/Switch.svelte.d.ts +61 -0
- package/dist/switch/SwitchGroup.svelte +37 -0
- package/dist/switch/SwitchGroup.svelte.d.ts +34 -0
- package/dist/switch/index.d.ts +2 -0
- package/dist/switch/index.js +2 -0
- package/dist/tabs/Tab.svelte +156 -0
- package/dist/tabs/Tab.svelte.d.ts +48 -0
- package/dist/tabs/TabGroup.svelte +241 -0
- package/dist/tabs/TabGroup.svelte.d.ts +67 -0
- package/dist/tabs/TabList.svelte +16 -0
- package/dist/tabs/TabList.svelte.d.ts +35 -0
- package/dist/tabs/TabPanel.svelte +61 -0
- package/dist/tabs/TabPanel.svelte.d.ts +47 -0
- package/dist/tabs/TabPanels.svelte +12 -0
- package/dist/tabs/TabPanels.svelte.d.ts +34 -0
- package/dist/tabs/index.d.ts +5 -0
- package/dist/tabs/index.js +5 -0
- package/dist/test-utils/accessability-assertions.d.ts +271 -0
- package/dist/test-utils/accessability-assertions.js +1572 -0
- package/dist/test-utils/fake-pointer.d.ts +24 -0
- package/dist/test-utils/fake-pointer.js +48 -0
- package/dist/test-utils/interactions.d.ts +61 -0
- package/dist/test-utils/interactions.js +453 -0
- package/dist/test-utils/suppress-console-logs.d.ts +7 -0
- package/dist/test-utils/suppress-console-logs.js +17 -0
- package/dist/transition/InternalTransitionChild.svelte +178 -0
- package/dist/transition/InternalTransitionChild.svelte.d.ts +55 -0
- package/dist/transition/Transition.svelte +89 -0
- package/dist/transition/Transition.svelte.d.ts +42 -0
- package/dist/transition/TransitionChild.svelte +16 -0
- package/dist/transition/TransitionChild.svelte.d.ts +44 -0
- package/dist/transition/context.svelte.d.ts +64 -0
- package/dist/transition/context.svelte.js +120 -0
- package/dist/transition/index.d.ts +2 -0
- package/dist/transition/index.js +2 -0
- package/dist/utils/ElementOrComponent.svelte +26 -0
- package/dist/utils/ElementOrComponent.svelte.d.ts +56 -0
- package/dist/utils/Generic.svelte +44 -0
- package/dist/utils/Generic.svelte.d.ts +35 -0
- package/dist/utils/StableCollection.svelte +43 -0
- package/dist/utils/StableCollection.svelte.d.ts +22 -0
- package/dist/utils/active-element-history.d.ts +1 -0
- package/dist/utils/active-element-history.js +35 -0
- package/dist/utils/alternative-types.d.ts +21 -0
- package/dist/utils/alternative-types.js +1 -0
- package/dist/utils/calculate-active-index.d.ts +25 -0
- package/dist/utils/calculate-active-index.js +74 -0
- package/dist/utils/class-names.d.ts +1 -0
- package/dist/utils/class-names.js +10 -0
- package/dist/utils/default-map.d.ts +5 -0
- package/dist/utils/default-map.js +15 -0
- package/dist/utils/disposables.d.ts +14 -12
- package/dist/utils/disposables.js +13 -10
- package/dist/utils/dom.d.ts +0 -2
- package/dist/utils/dom.js +2 -4
- package/dist/utils/env.d.ts +17 -0
- package/dist/utils/env.js +39 -0
- package/dist/utils/focus-management.d.ts +45 -0
- package/dist/utils/focus-management.js +242 -0
- package/dist/utils/focusVisible.svelte.d.ts +3 -3
- package/dist/utils/focusVisible.svelte.js +52 -41
- package/dist/utils/get-text-value.d.ts +1 -0
- package/dist/utils/get-text-value.js +71 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/match.d.ts +1 -0
- package/dist/utils/match.js +13 -0
- package/dist/utils/on-document-ready.d.ts +1 -0
- package/dist/utils/on-document-ready.js +12 -0
- package/dist/utils/once.d.ts +1 -0
- package/dist/utils/once.js +9 -0
- package/dist/utils/owner.d.ts +1 -0
- package/dist/utils/owner.js +8 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/utils/platform.js +17 -0
- package/dist/utils/ref.svelte.d.ts +4 -0
- package/dist/utils/ref.svelte.js +4 -0
- package/dist/utils/render.d.ts +34 -0
- package/dist/utils/render.js +119 -0
- package/dist/utils/state.d.ts +7 -1
- package/dist/utils/state.js +10 -6
- package/dist/utils/store.d.ts +11 -0
- package/dist/utils/store.js +20 -0
- package/dist/utils/types.d.ts +24 -0
- package/dist/utils/types.js +1 -0
- package/package.json +33 -25
- package/dist/actions/activePress.svelte.d.ts +0 -8
- package/dist/actions/focusRing.svelte.d.ts +0 -9
- package/dist/actions/focusRing.svelte.js +0 -34
- package/dist/utils/disabled.d.ts +0 -3
- package/dist/utils/disabled.js +0 -2
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { disposables } from "./disposables.js";
|
|
2
|
+
import { match } from "./match.js";
|
|
3
|
+
import { getOwnerDocument } from "./owner.js";
|
|
4
|
+
// Credit:
|
|
5
|
+
// - https://stackoverflow.com/a/30753870
|
|
6
|
+
export let focusableSelector = [
|
|
7
|
+
"[contentEditable=true]",
|
|
8
|
+
"[tabindex]",
|
|
9
|
+
"a[href]",
|
|
10
|
+
"area[href]",
|
|
11
|
+
"button:not([disabled])",
|
|
12
|
+
"iframe",
|
|
13
|
+
"input:not([disabled])",
|
|
14
|
+
"select:not([disabled])",
|
|
15
|
+
"textarea:not([disabled])",
|
|
16
|
+
]
|
|
17
|
+
.map(process.env.NODE_ENV === "test"
|
|
18
|
+
? // TODO: Remove this once JSDOM fixes the issue where an element that is
|
|
19
|
+
// "hidden" can be the document.activeElement, because this is not possible
|
|
20
|
+
// in real browsers.
|
|
21
|
+
(selector) => `${selector}:not([tabindex='-1']):not([style*='display: none'])`
|
|
22
|
+
: (selector) => `${selector}:not([tabindex='-1'])`)
|
|
23
|
+
.join(",");
|
|
24
|
+
let autoFocusableSelector = [
|
|
25
|
+
// In a perfect world this was just `autofocus`, but React doesn't pass `autofocus` to the DOM...
|
|
26
|
+
"[data-autofocus]",
|
|
27
|
+
]
|
|
28
|
+
.map(process.env.NODE_ENV === "test"
|
|
29
|
+
? // TODO: Remove this once JSDOM fixes the issue where an element that is
|
|
30
|
+
// "hidden" can be the document.activeElement, because this is not possible
|
|
31
|
+
// in real browsers.
|
|
32
|
+
(selector) => `${selector}:not([tabindex='-1']):not([style*='display: none'])`
|
|
33
|
+
: (selector) => `${selector}:not([tabindex='-1'])`)
|
|
34
|
+
.join(",");
|
|
35
|
+
export var Focus;
|
|
36
|
+
(function (Focus) {
|
|
37
|
+
/** Focus the first non-disabled element */
|
|
38
|
+
Focus[Focus["First"] = 1] = "First";
|
|
39
|
+
/** Focus the previous non-disabled element */
|
|
40
|
+
Focus[Focus["Previous"] = 2] = "Previous";
|
|
41
|
+
/** Focus the next non-disabled element */
|
|
42
|
+
Focus[Focus["Next"] = 4] = "Next";
|
|
43
|
+
/** Focus the last non-disabled element */
|
|
44
|
+
Focus[Focus["Last"] = 8] = "Last";
|
|
45
|
+
/** Wrap tab around */
|
|
46
|
+
Focus[Focus["WrapAround"] = 16] = "WrapAround";
|
|
47
|
+
/** Prevent scrolling the focusable elements into view */
|
|
48
|
+
Focus[Focus["NoScroll"] = 32] = "NoScroll";
|
|
49
|
+
/** Focus the first focusable element with the `data-autofocus` attribute. */
|
|
50
|
+
Focus[Focus["AutoFocus"] = 64] = "AutoFocus";
|
|
51
|
+
})(Focus || (Focus = {}));
|
|
52
|
+
export var FocusResult;
|
|
53
|
+
(function (FocusResult) {
|
|
54
|
+
/** Something went wrong while trying to focus. */
|
|
55
|
+
FocusResult[FocusResult["Error"] = 0] = "Error";
|
|
56
|
+
/** When `Focus.WrapAround` is enabled, going from position `N` to `N+1` where `N` is the last index in the array, then we overflow. */
|
|
57
|
+
FocusResult[FocusResult["Overflow"] = 1] = "Overflow";
|
|
58
|
+
/** Focus was successful. */
|
|
59
|
+
FocusResult[FocusResult["Success"] = 2] = "Success";
|
|
60
|
+
/** When `Focus.WrapAround` is enabled, going from position `N` to `N-1` where `N` is the first index in the array, then we underflow. */
|
|
61
|
+
FocusResult[FocusResult["Underflow"] = 3] = "Underflow";
|
|
62
|
+
})(FocusResult || (FocusResult = {}));
|
|
63
|
+
var Direction;
|
|
64
|
+
(function (Direction) {
|
|
65
|
+
Direction[Direction["Previous"] = -1] = "Previous";
|
|
66
|
+
Direction[Direction["Next"] = 1] = "Next";
|
|
67
|
+
})(Direction || (Direction = {}));
|
|
68
|
+
export function getFocusableElements(container = document.body) {
|
|
69
|
+
if (container == null)
|
|
70
|
+
return [];
|
|
71
|
+
return Array.from(container.querySelectorAll(focusableSelector)).sort(
|
|
72
|
+
// We want to move `tabIndex={0}` to the end of the list, this is what the browser does as well.
|
|
73
|
+
(a, z) => Math.sign((a.tabIndex || Number.MAX_SAFE_INTEGER) - (z.tabIndex || Number.MAX_SAFE_INTEGER)));
|
|
74
|
+
}
|
|
75
|
+
export function getAutoFocusableElements(container = document.body) {
|
|
76
|
+
if (container == null)
|
|
77
|
+
return [];
|
|
78
|
+
return Array.from(container.querySelectorAll(autoFocusableSelector)).sort(
|
|
79
|
+
// We want to move `tabIndex={0}` to the end of the list, this is what the browser does as well.
|
|
80
|
+
(a, z) => Math.sign((a.tabIndex || Number.MAX_SAFE_INTEGER) - (z.tabIndex || Number.MAX_SAFE_INTEGER)));
|
|
81
|
+
}
|
|
82
|
+
export var FocusableMode;
|
|
83
|
+
(function (FocusableMode) {
|
|
84
|
+
/** The element itself must be focusable. */
|
|
85
|
+
FocusableMode[FocusableMode["Strict"] = 0] = "Strict";
|
|
86
|
+
/** The element should be inside of a focusable element. */
|
|
87
|
+
FocusableMode[FocusableMode["Loose"] = 1] = "Loose";
|
|
88
|
+
})(FocusableMode || (FocusableMode = {}));
|
|
89
|
+
export function isFocusableElement(element, mode = FocusableMode.Strict) {
|
|
90
|
+
if (element === getOwnerDocument(element)?.body)
|
|
91
|
+
return false;
|
|
92
|
+
return match(mode, {
|
|
93
|
+
[FocusableMode.Strict]() {
|
|
94
|
+
return element.matches(focusableSelector);
|
|
95
|
+
},
|
|
96
|
+
[FocusableMode.Loose]() {
|
|
97
|
+
let next = element;
|
|
98
|
+
while (next !== null) {
|
|
99
|
+
if (next.matches(focusableSelector))
|
|
100
|
+
return true;
|
|
101
|
+
next = next.parentElement;
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
export function restoreFocusIfNecessary(element) {
|
|
108
|
+
let ownerDocument = getOwnerDocument(element);
|
|
109
|
+
disposables().nextFrame(() => {
|
|
110
|
+
if (ownerDocument && !isFocusableElement(ownerDocument.activeElement, FocusableMode.Strict)) {
|
|
111
|
+
focusElement(element);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// The method of triggering an action, this is used to determine how we should
|
|
116
|
+
// restore focus after an action has been performed.
|
|
117
|
+
var ActivationMethod;
|
|
118
|
+
(function (ActivationMethod) {
|
|
119
|
+
/* If the action was triggered by a keyboard event. */
|
|
120
|
+
ActivationMethod[ActivationMethod["Keyboard"] = 0] = "Keyboard";
|
|
121
|
+
/* If the action was triggered by a mouse / pointer / ... event.*/
|
|
122
|
+
ActivationMethod[ActivationMethod["Mouse"] = 1] = "Mouse";
|
|
123
|
+
})(ActivationMethod || (ActivationMethod = {}));
|
|
124
|
+
// We want to be able to set and remove the `data-headlessui-mouse` attribute on the `html` element.
|
|
125
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
126
|
+
document.addEventListener("keydown", (event) => {
|
|
127
|
+
if (event.metaKey || event.altKey || event.ctrlKey) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
document.documentElement.dataset.headlessuiFocusVisible = "";
|
|
131
|
+
}, true);
|
|
132
|
+
document.addEventListener("click", (event) => {
|
|
133
|
+
// Event originated from an actual mouse click
|
|
134
|
+
if (event.detail === ActivationMethod.Mouse) {
|
|
135
|
+
delete document.documentElement.dataset.headlessuiFocusVisible;
|
|
136
|
+
}
|
|
137
|
+
// Event originated from a keyboard event that triggered the `click` event
|
|
138
|
+
else if (event.detail === ActivationMethod.Keyboard) {
|
|
139
|
+
document.documentElement.dataset.headlessuiFocusVisible = "";
|
|
140
|
+
}
|
|
141
|
+
}, true);
|
|
142
|
+
}
|
|
143
|
+
export function focusElement(element) {
|
|
144
|
+
element?.focus({ preventScroll: true });
|
|
145
|
+
}
|
|
146
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
|
|
147
|
+
let selectableSelector = ["textarea", "input"].join(",");
|
|
148
|
+
function isSelectableElement(element) {
|
|
149
|
+
return element?.matches?.(selectableSelector) ?? false;
|
|
150
|
+
}
|
|
151
|
+
export function sortByDomNode(nodes, resolveKey = (i) => i) {
|
|
152
|
+
return nodes.slice().sort((aItem, zItem) => {
|
|
153
|
+
let a = resolveKey(aItem);
|
|
154
|
+
let z = resolveKey(zItem);
|
|
155
|
+
if (a === null || z === null)
|
|
156
|
+
return 0;
|
|
157
|
+
let position = a.compareDocumentPosition(z);
|
|
158
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING)
|
|
159
|
+
return -1;
|
|
160
|
+
if (position & Node.DOCUMENT_POSITION_PRECEDING)
|
|
161
|
+
return 1;
|
|
162
|
+
return 0;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export function focusFrom(current, focus) {
|
|
166
|
+
return focusIn(getFocusableElements(), focus, { relativeTo: current });
|
|
167
|
+
}
|
|
168
|
+
export function focusIn(container, focus, { sorted = true, relativeTo = null, skipElements = [], } = {}) {
|
|
169
|
+
let ownerDocument = Array.isArray(container)
|
|
170
|
+
? container.length > 0
|
|
171
|
+
? container[0].ownerDocument
|
|
172
|
+
: document
|
|
173
|
+
: container.ownerDocument;
|
|
174
|
+
let elements = Array.isArray(container)
|
|
175
|
+
? sorted
|
|
176
|
+
? sortByDomNode(container)
|
|
177
|
+
: container
|
|
178
|
+
: focus & Focus.AutoFocus
|
|
179
|
+
? getAutoFocusableElements(container)
|
|
180
|
+
: getFocusableElements(container);
|
|
181
|
+
if (skipElements.length > 0 && elements.length > 1) {
|
|
182
|
+
elements = elements.filter((element) => !skipElements.some((skipElement) => skipElement != null && "current" in skipElement
|
|
183
|
+
? skipElement?.current === element // Handle MutableRefObject
|
|
184
|
+
: skipElement === element // Handle HTMLElement directly
|
|
185
|
+
));
|
|
186
|
+
}
|
|
187
|
+
relativeTo = relativeTo ?? ownerDocument.activeElement;
|
|
188
|
+
let direction = (() => {
|
|
189
|
+
if (focus & (Focus.First | Focus.Next))
|
|
190
|
+
return Direction.Next;
|
|
191
|
+
if (focus & (Focus.Previous | Focus.Last))
|
|
192
|
+
return Direction.Previous;
|
|
193
|
+
throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last");
|
|
194
|
+
})();
|
|
195
|
+
let startIndex = (() => {
|
|
196
|
+
if (focus & Focus.First)
|
|
197
|
+
return 0;
|
|
198
|
+
if (focus & Focus.Previous)
|
|
199
|
+
return Math.max(0, elements.indexOf(relativeTo)) - 1;
|
|
200
|
+
if (focus & Focus.Next)
|
|
201
|
+
return Math.max(0, elements.indexOf(relativeTo)) + 1;
|
|
202
|
+
if (focus & Focus.Last)
|
|
203
|
+
return elements.length - 1;
|
|
204
|
+
throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last");
|
|
205
|
+
})();
|
|
206
|
+
let focusOptions = focus & Focus.NoScroll ? { preventScroll: true } : {};
|
|
207
|
+
let offset = 0;
|
|
208
|
+
let total = elements.length;
|
|
209
|
+
let next = undefined;
|
|
210
|
+
do {
|
|
211
|
+
// Guard against infinite loops
|
|
212
|
+
if (offset >= total || offset + total <= 0)
|
|
213
|
+
return FocusResult.Error;
|
|
214
|
+
let nextIdx = startIndex + offset;
|
|
215
|
+
if (focus & Focus.WrapAround) {
|
|
216
|
+
nextIdx = (nextIdx + total) % total;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
if (nextIdx < 0)
|
|
220
|
+
return FocusResult.Underflow;
|
|
221
|
+
if (nextIdx >= total)
|
|
222
|
+
return FocusResult.Overflow;
|
|
223
|
+
}
|
|
224
|
+
next = elements[nextIdx];
|
|
225
|
+
// Try the focus the next element, might not work if it is "hidden" to the user.
|
|
226
|
+
next?.focus(focusOptions);
|
|
227
|
+
// Try the next one in line
|
|
228
|
+
offset += direction;
|
|
229
|
+
} while (next !== ownerDocument.activeElement);
|
|
230
|
+
// By default if you <Tab> to a text input or a textarea, the browser will
|
|
231
|
+
// select all the text once the focus is inside these DOM Nodes. However,
|
|
232
|
+
// since we are manually moving focus this behavior is not happening. This
|
|
233
|
+
// code will make sure that the text gets selected as-if you did it manually.
|
|
234
|
+
// Note: We only do this when going forward / backward. Not for the
|
|
235
|
+
// Focus.First or Focus.Last actions. This is similar to the `autoFocus`
|
|
236
|
+
// behavior on an input where the input will get focus but won't be
|
|
237
|
+
// selected.
|
|
238
|
+
if (focus & (Focus.Next | Focus.Previous) && isSelectableElement(next)) {
|
|
239
|
+
next.select();
|
|
240
|
+
}
|
|
241
|
+
return FocusResult.Success;
|
|
242
|
+
}
|
|
@@ -4,7 +4,7 @@ export interface FocusVisibleProps {
|
|
|
4
4
|
/** Whether the element is a text input. */
|
|
5
5
|
isTextInput?: boolean;
|
|
6
6
|
/** Whether the element will be auto focused. */
|
|
7
|
-
|
|
7
|
+
autofocus?: boolean;
|
|
8
8
|
}
|
|
9
9
|
export interface FocusVisibleResult {
|
|
10
10
|
/** Whether keyboard focus is visible globally. */
|
|
@@ -13,7 +13,7 @@ export interface FocusVisibleResult {
|
|
|
13
13
|
interface GlobalListenerData {
|
|
14
14
|
focus: () => void;
|
|
15
15
|
}
|
|
16
|
-
export declare
|
|
16
|
+
export declare const hasSetupGlobalListeners: Map<Window, GlobalListenerData>;
|
|
17
17
|
/**
|
|
18
18
|
* EXPERIMENTAL
|
|
19
19
|
* Adds a window (i.e. iframe) to the list of windows that are being tracked for focus visible.
|
|
@@ -31,7 +31,7 @@ export declare let hasSetupGlobalListeners: Map<Window, GlobalListenerData>;
|
|
|
31
31
|
* @param element @default document.body - The element provided will be used to get the window to add.
|
|
32
32
|
* @returns A function to remove the event listeners and cleanup the state.
|
|
33
33
|
*/
|
|
34
|
-
export declare function addWindowFocusTracking(element?: HTMLElement
|
|
34
|
+
export declare function addWindowFocusTracking(element?: HTMLElement): () => void;
|
|
35
35
|
/**
|
|
36
36
|
* If true, keyboard focus is visible.
|
|
37
37
|
*/
|
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
// Original licensing for the following can be found in the
|
|
14
14
|
// NOTICE file in the root directory of this source tree.
|
|
15
15
|
// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
|
|
16
|
-
import {
|
|
16
|
+
import { getOwnerWindow } from "./dom.js";
|
|
17
17
|
import { isVirtualClick } from "./isVirtualEvent.js";
|
|
18
|
+
import { getOwnerDocument } from "./owner.js";
|
|
18
19
|
import { isMac } from "./platform.js";
|
|
19
20
|
let currentModality = null;
|
|
20
|
-
|
|
21
|
-
export
|
|
21
|
+
const changeHandlers = new Set();
|
|
22
|
+
export const hasSetupGlobalListeners = new Map(); // We use a map here to support setting event listeners across multiple document objects.
|
|
22
23
|
let hasEventBeforeFocus = false;
|
|
23
24
|
let hasBlurredWindowRecently = false;
|
|
24
25
|
// Only Tab or Esc keys will make focus visible on text input elements
|
|
@@ -27,7 +28,7 @@ const FOCUS_VISIBLE_INPUT_KEYS = {
|
|
|
27
28
|
Escape: true,
|
|
28
29
|
};
|
|
29
30
|
function triggerChangeHandlers(modality, e) {
|
|
30
|
-
for (
|
|
31
|
+
for (const handler of changeHandlers) {
|
|
31
32
|
handler(modality, e);
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -98,27 +99,31 @@ function setupGlobalFocusEvents(element) {
|
|
|
98
99
|
// However, we need to detect other cases when a focus event occurs without
|
|
99
100
|
// a preceding user event (e.g. screen reader focus). Overriding the focus
|
|
100
101
|
// method on HTMLElement.prototype is a bit hacky, but works.
|
|
101
|
-
|
|
102
|
-
windowObject.HTMLElement.prototype.focus = function () {
|
|
102
|
+
const focus = windowObject.HTMLElement.prototype.focus;
|
|
103
|
+
windowObject.HTMLElement.prototype.focus = function (...args) {
|
|
103
104
|
hasEventBeforeFocus = true;
|
|
104
|
-
focus.apply(this,
|
|
105
|
+
focus.apply(this, args);
|
|
105
106
|
};
|
|
106
|
-
documentObject
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if (documentObject) {
|
|
108
|
+
documentObject.addEventListener("keydown", handleKeyboardEvent, true);
|
|
109
|
+
documentObject.addEventListener("keyup", handleKeyboardEvent, true);
|
|
110
|
+
documentObject.addEventListener("click", handleClickEvent, true);
|
|
111
|
+
}
|
|
109
112
|
// Register focus events on the window so they are sure to happen
|
|
110
113
|
// before React's event listeners (registered on the document).
|
|
111
114
|
windowObject.addEventListener("focus", handleFocusEvent, true);
|
|
112
115
|
windowObject.addEventListener("blur", handleWindowBlur, false);
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
if (documentObject) {
|
|
117
|
+
if (typeof PointerEvent !== "undefined") {
|
|
118
|
+
documentObject.addEventListener("pointerdown", handlePointerEvent, true);
|
|
119
|
+
documentObject.addEventListener("pointermove", handlePointerEvent, true);
|
|
120
|
+
documentObject.addEventListener("pointerup", handlePointerEvent, true);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
documentObject.addEventListener("mousedown", handlePointerEvent, true);
|
|
124
|
+
documentObject.addEventListener("mousemove", handlePointerEvent, true);
|
|
125
|
+
documentObject.addEventListener("mouseup", handlePointerEvent, true);
|
|
126
|
+
}
|
|
122
127
|
}
|
|
123
128
|
// Add unmount handler
|
|
124
129
|
windowObject.addEventListener("beforeunload", () => {
|
|
@@ -129,27 +134,31 @@ function setupGlobalFocusEvents(element) {
|
|
|
129
134
|
const tearDownWindowFocusTracking = (element, loadListener) => {
|
|
130
135
|
const windowObject = getOwnerWindow(element);
|
|
131
136
|
const documentObject = getOwnerDocument(element);
|
|
132
|
-
if (loadListener) {
|
|
137
|
+
if (loadListener && documentObject) {
|
|
133
138
|
documentObject.removeEventListener("DOMContentLoaded", loadListener);
|
|
134
139
|
}
|
|
135
140
|
if (!hasSetupGlobalListeners.has(windowObject)) {
|
|
136
141
|
return;
|
|
137
142
|
}
|
|
138
143
|
windowObject.HTMLElement.prototype.focus = hasSetupGlobalListeners.get(windowObject).focus;
|
|
139
|
-
documentObject
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
if (documentObject) {
|
|
145
|
+
documentObject.removeEventListener("keydown", handleKeyboardEvent, true);
|
|
146
|
+
documentObject.removeEventListener("keyup", handleKeyboardEvent, true);
|
|
147
|
+
documentObject.removeEventListener("click", handleClickEvent, true);
|
|
148
|
+
}
|
|
142
149
|
windowObject.removeEventListener("focus", handleFocusEvent, true);
|
|
143
150
|
windowObject.removeEventListener("blur", handleWindowBlur, false);
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
if (documentObject) {
|
|
152
|
+
if (typeof PointerEvent !== "undefined") {
|
|
153
|
+
documentObject.removeEventListener("pointerdown", handlePointerEvent, true);
|
|
154
|
+
documentObject.removeEventListener("pointermove", handlePointerEvent, true);
|
|
155
|
+
documentObject.removeEventListener("pointerup", handlePointerEvent, true);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
documentObject.removeEventListener("mousedown", handlePointerEvent, true);
|
|
159
|
+
documentObject.removeEventListener("mousemove", handlePointerEvent, true);
|
|
160
|
+
documentObject.removeEventListener("mouseup", handlePointerEvent, true);
|
|
161
|
+
}
|
|
153
162
|
}
|
|
154
163
|
hasSetupGlobalListeners.delete(windowObject);
|
|
155
164
|
};
|
|
@@ -173,14 +182,16 @@ const tearDownWindowFocusTracking = (element, loadListener) => {
|
|
|
173
182
|
export function addWindowFocusTracking(element) {
|
|
174
183
|
const documentObject = getOwnerDocument(element);
|
|
175
184
|
let loadListener;
|
|
176
|
-
if (documentObject
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
loadListener = () => {
|
|
185
|
+
if (documentObject) {
|
|
186
|
+
if (documentObject.readyState !== "loading") {
|
|
181
187
|
setupGlobalFocusEvents(element);
|
|
182
|
-
}
|
|
183
|
-
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
loadListener = () => {
|
|
191
|
+
setupGlobalFocusEvents(element);
|
|
192
|
+
};
|
|
193
|
+
documentObject.addEventListener("DOMContentLoaded", loadListener);
|
|
194
|
+
}
|
|
184
195
|
}
|
|
185
196
|
return () => tearDownWindowFocusTracking(element, loadListener);
|
|
186
197
|
}
|
|
@@ -246,8 +257,8 @@ function isKeyboardFocusEvent(isTextInput, modality, e) {
|
|
|
246
257
|
* Manages focus visible state for the page, and subscribes individual components for updates.
|
|
247
258
|
*/
|
|
248
259
|
/*export function useFocusVisible(props: FocusVisibleProps = {}): FocusVisibleResult {
|
|
249
|
-
let { isTextInput,
|
|
250
|
-
let [isFocusVisibleState, setFocusVisible] = useState(
|
|
260
|
+
let { isTextInput, autofocus } = props
|
|
261
|
+
let [isFocusVisibleState, setFocusVisible] = useState(autofocus || isFocusVisible())
|
|
251
262
|
useFocusVisibleListener(
|
|
252
263
|
(isFocusVisible) => {
|
|
253
264
|
setFocusVisible(isFocusVisible)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getTextValue(element: HTMLElement): string;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
let emojiRegex = /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;
|
|
2
|
+
function getTextContents(element) {
|
|
3
|
+
// Using innerText instead of textContent because:
|
|
4
|
+
//
|
|
5
|
+
// > textContent gets the content of all elements, including <script> and <style> elements. In
|
|
6
|
+
// > contrast, innerText only shows "human-readable" elements.
|
|
7
|
+
// >
|
|
8
|
+
// > — https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext
|
|
9
|
+
let currentInnerText = element.innerText ?? "";
|
|
10
|
+
// Remove all the elements that shouldn't be there.
|
|
11
|
+
//
|
|
12
|
+
// [hidden] — The user doesn't see it
|
|
13
|
+
// [aria-hidden] — The screen reader doesn't see it
|
|
14
|
+
// [role="img"] — Even if it is text, it is used as an image
|
|
15
|
+
//
|
|
16
|
+
// This is probably the slowest part, but if you want complete control over the text value, then
|
|
17
|
+
// it is better to set an `aria-label` instead.
|
|
18
|
+
let copy = element.cloneNode(true);
|
|
19
|
+
if (!(copy instanceof HTMLElement)) {
|
|
20
|
+
return currentInnerText;
|
|
21
|
+
}
|
|
22
|
+
let dropped = false;
|
|
23
|
+
// Drop the elements that shouldn't be there.
|
|
24
|
+
for (let child of copy.querySelectorAll('[hidden],[aria-hidden],[role="img"]')) {
|
|
25
|
+
child.remove();
|
|
26
|
+
dropped = true;
|
|
27
|
+
}
|
|
28
|
+
// Now that the elements are removed, we can get the innerText such that we can strip the emojis.
|
|
29
|
+
let value = dropped ? copy.innerText ?? "" : currentInnerText;
|
|
30
|
+
// Check if it contains some emojis or not, if so, we need to remove them
|
|
31
|
+
// because ideally we work with simple text values.
|
|
32
|
+
//
|
|
33
|
+
// Ideally we can use the much simpler RegEx: /\p{Extended_Pictographic}/u
|
|
34
|
+
// but we can't rely on this yet, so we use the more complex one.
|
|
35
|
+
if (emojiRegex.test(value)) {
|
|
36
|
+
value = value.replace(emojiRegex, "");
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
export function getTextValue(element) {
|
|
41
|
+
// Try to use the `aria-label` first
|
|
42
|
+
let label = element.getAttribute("aria-label");
|
|
43
|
+
if (typeof label === "string")
|
|
44
|
+
return label.trim();
|
|
45
|
+
// Try to use the `aria-labelledby` second
|
|
46
|
+
let labelledby = element.getAttribute("aria-labelledby");
|
|
47
|
+
if (labelledby) {
|
|
48
|
+
// aria-labelledby can be a space-separated list of IDs, so we need to split them up and
|
|
49
|
+
// combine them into a single string.
|
|
50
|
+
let labels = labelledby
|
|
51
|
+
.split(" ")
|
|
52
|
+
.map((labelledby) => {
|
|
53
|
+
let labelEl = document.getElementById(labelledby);
|
|
54
|
+
if (labelEl) {
|
|
55
|
+
let label = labelEl.getAttribute("aria-label");
|
|
56
|
+
// Try to use the `aria-label` first (of the referenced element)
|
|
57
|
+
if (typeof label === "string")
|
|
58
|
+
return label.trim();
|
|
59
|
+
// This time, the `aria-labelledby` isn't used anymore (in Safari), so we just have to
|
|
60
|
+
// look at the contents itself.
|
|
61
|
+
return getTextContents(labelEl).trim();
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
})
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
if (labels.length > 0)
|
|
67
|
+
return labels.join(", ");
|
|
68
|
+
}
|
|
69
|
+
// Try to use the text contents of the element itself
|
|
70
|
+
return getTextContents(element).trim();
|
|
71
|
+
}
|
package/dist/utils/id.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const alphaid: (size?: number
|
|
1
|
+
export declare const alphaid: (size?: number) => string;
|
|
2
2
|
export declare const htmlid: (size?: number) => string;
|
|
3
3
|
export declare const getIdContext: () => string | undefined;
|
|
4
4
|
export declare const createIdContext: (id: string) => string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function match<TValue extends string | number = string, TReturnValue = unknown>(value: TValue, lookup: Record<TValue, TReturnValue | ((...args: any[]) => TReturnValue)>, ...args: any[]): TReturnValue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
export function match(value, lookup, ...args) {
|
|
3
|
+
if (value in lookup) {
|
|
4
|
+
const returnValue = lookup[value];
|
|
5
|
+
return typeof returnValue === "function" ? returnValue(...args) : returnValue;
|
|
6
|
+
}
|
|
7
|
+
const error = new Error(`Tried to handle "${value}" but there is no handler defined. Only defined handlers are: ${Object.keys(lookup)
|
|
8
|
+
.map((key) => `"${key}"`)
|
|
9
|
+
.join(", ")}.`);
|
|
10
|
+
if (Error.captureStackTrace)
|
|
11
|
+
Error.captureStackTrace(error, match);
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function onDocumentReady(cb: () => void): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function onDocumentReady(cb) {
|
|
2
|
+
function check() {
|
|
3
|
+
if (document.readyState === "loading")
|
|
4
|
+
return;
|
|
5
|
+
cb();
|
|
6
|
+
document.removeEventListener("DOMContentLoaded", check);
|
|
7
|
+
}
|
|
8
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
9
|
+
document.addEventListener("DOMContentLoaded", check);
|
|
10
|
+
check();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function once<T>(cb: (...args: T[]) => void): (...args: T[]) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getOwnerDocument<T extends Element>(element: T | null | undefined): Document | null;
|
package/dist/utils/platform.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export declare function testUserAgent(re: RegExp): any;
|
|
|
2
2
|
export declare function testPlatform(re: RegExp): boolean;
|
|
3
3
|
export declare const isMac: () => boolean;
|
|
4
4
|
export declare const isAndroid: () => boolean;
|
|
5
|
+
export declare function isIOS(): any;
|
|
6
|
+
export declare function isMobile(): any;
|
package/dist/utils/platform.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
export function testUserAgent(re) {
|
|
2
3
|
if (typeof window === "undefined" || window.navigator == null) {
|
|
3
4
|
return false;
|
|
@@ -27,3 +28,19 @@ export const isMac = cached(function () {
|
|
|
27
28
|
export const isAndroid = cached(function () {
|
|
28
29
|
return testUserAgent(/Android/i);
|
|
29
30
|
});
|
|
31
|
+
export function isIOS() {
|
|
32
|
+
// TODO: This is not a great way to detect iOS, but it's the best I can do for now.
|
|
33
|
+
// - `window.platform` is deprecated
|
|
34
|
+
// - `window.userAgentData.platform` is still experimental (https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/platform)
|
|
35
|
+
// - `window.userAgent` also doesn't contain the required information
|
|
36
|
+
return (
|
|
37
|
+
// Check if it is an iPhone
|
|
38
|
+
testUserAgent(/iPhone/i) ||
|
|
39
|
+
// Check if it is an iPad. iPad reports itself as "MacIntel", but we can check if it is a touch
|
|
40
|
+
// screen. Let's hope that Apple doesn't release a touch screen Mac (or maybe this would then
|
|
41
|
+
// work as expected 🤔).
|
|
42
|
+
(isMac() && typeof window !== "undefined" && window.navigator != null && window.navigator.maxTouchPoints > 0));
|
|
43
|
+
}
|
|
44
|
+
export function isMobile() {
|
|
45
|
+
return isIOS() || isAndroid();
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Props } from "./types.js";
|
|
2
|
+
export declare enum RenderFeatures {
|
|
3
|
+
/** No features at all */
|
|
4
|
+
None = 0,
|
|
5
|
+
/**
|
|
6
|
+
* When used, this will allow us to use one of the render strategies.
|
|
7
|
+
*
|
|
8
|
+
* **The render strategies are:**
|
|
9
|
+
* - **Unmount** _(Will unmount the component.)_
|
|
10
|
+
* - **Hidden** _(Will hide the component using the [hidden] attribute.)_
|
|
11
|
+
*/
|
|
12
|
+
RenderStrategy = 1,
|
|
13
|
+
/**
|
|
14
|
+
* When used, this will allow the user of our component to be in control. This can be used when
|
|
15
|
+
* you want to transition based on some state.
|
|
16
|
+
*/
|
|
17
|
+
Static = 2
|
|
18
|
+
}
|
|
19
|
+
export declare enum RenderStrategy {
|
|
20
|
+
Unmount = 0,
|
|
21
|
+
Hidden = 1
|
|
22
|
+
}
|
|
23
|
+
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
|
|
24
|
+
type PropsForFeature<TPassedInFeatures extends RenderFeatures, TForFeature extends RenderFeatures, TProps> = TPassedInFeatures extends TForFeature ? TProps : {};
|
|
25
|
+
export type PropsForFeatures<T extends RenderFeatures> = Expand<UnionToIntersection<PropsForFeature<T, RenderFeatures.Static, {
|
|
26
|
+
static?: boolean;
|
|
27
|
+
}> | PropsForFeature<T, RenderFeatures.RenderStrategy, {
|
|
28
|
+
unmount?: boolean;
|
|
29
|
+
}>>>;
|
|
30
|
+
export declare function mergeProps<T extends Props<any, any>[]>(...listOfProps: T): Props<any, any>;
|
|
31
|
+
export declare function mergePropsAdvanced(...listOfProps: Props<any, any>[]): Props<any, any>;
|
|
32
|
+
export declare function compact<T extends Record<any, any>>(object: T): {} & T;
|
|
33
|
+
export declare function omit<T extends Record<any, any>>(object: T, keysToOmit?: string[]): T;
|
|
34
|
+
export {};
|