@tamagui/react-native-use-responder-events 1.0.1-beta.194

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 (48) hide show
  1. package/dist/cjs/PressResponder.js +373 -0
  2. package/dist/cjs/PressResponder.js.map +7 -0
  3. package/dist/cjs/ResponderSystem.js +365 -0
  4. package/dist/cjs/ResponderSystem.js.map +7 -0
  5. package/dist/cjs/ResponderTouchHistoryStore.js +184 -0
  6. package/dist/cjs/ResponderTouchHistoryStore.js.map +7 -0
  7. package/dist/cjs/createResponderEvent.js +152 -0
  8. package/dist/cjs/createResponderEvent.js.map +7 -0
  9. package/dist/cjs/index.js +19 -0
  10. package/dist/cjs/index.js.map +7 -0
  11. package/dist/cjs/types.js +98 -0
  12. package/dist/cjs/types.js.map +7 -0
  13. package/dist/cjs/useResponderEvents.js +76 -0
  14. package/dist/cjs/useResponderEvents.js.map +7 -0
  15. package/dist/cjs/utils.js +169 -0
  16. package/dist/cjs/utils.js.map +7 -0
  17. package/dist/esm/PressResponder.js +349 -0
  18. package/dist/esm/PressResponder.js.map +7 -0
  19. package/dist/esm/ResponderSystem.js +338 -0
  20. package/dist/esm/ResponderSystem.js.map +7 -0
  21. package/dist/esm/ResponderTouchHistoryStore.js +160 -0
  22. package/dist/esm/ResponderTouchHistoryStore.js.map +7 -0
  23. package/dist/esm/createResponderEvent.js +130 -0
  24. package/dist/esm/createResponderEvent.js.map +7 -0
  25. package/dist/esm/index.js +2 -0
  26. package/dist/esm/index.js.map +7 -0
  27. package/dist/esm/types.js +55 -0
  28. package/dist/esm/types.js.map +7 -0
  29. package/dist/esm/useResponderEvents.js +45 -0
  30. package/dist/esm/useResponderEvents.js.map +7 -0
  31. package/dist/esm/utils.js +137 -0
  32. package/dist/esm/utils.js.map +7 -0
  33. package/package.json +30 -0
  34. package/src/ResponderSystem.ts +531 -0
  35. package/src/ResponderTouchHistoryStore.ts +213 -0
  36. package/src/createResponderEvent.ts +187 -0
  37. package/src/index.ts +1 -0
  38. package/src/types.ts +78 -0
  39. package/src/useResponderEvents.ts +72 -0
  40. package/src/utils.ts +192 -0
  41. package/types/PressResponder.d.ts +92 -0
  42. package/types/ResponderSystem.d.ts +47 -0
  43. package/types/ResponderTouchHistoryStore.d.ts +37 -0
  44. package/types/createResponderEvent.d.ts +36 -0
  45. package/types/index.d.ts +2 -0
  46. package/types/types.d.ts +52 -0
  47. package/types/useResponderEvents.d.ts +9 -0
  48. package/types/utils.d.ts +38 -0
package/src/utils.ts ADDED
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+
7
+ const keyName = '__reactResponderId'
8
+
9
+ export const canUseDOM = !!(
10
+ typeof window !== 'undefined' &&
11
+ window.document &&
12
+ window.document.createElement
13
+ )
14
+
15
+ export const getBoundingClientRect = (node: HTMLElement | null): void | DOMRect => {
16
+ if (!node) return
17
+ if (node.nodeType !== 1) return
18
+ if (node.getBoundingClientRect) {
19
+ return node.getBoundingClientRect()
20
+ }
21
+ }
22
+
23
+ function getEventPath(domEvent: any): Array<any> {
24
+ // The 'selectionchange' event always has the 'document' as the target.
25
+ // Use the anchor node as the initial target to reconstruct a path.
26
+ // (We actually only need the first "responder" node in practice.)
27
+ if (domEvent.type === 'selectionchange') {
28
+ const target = window.getSelection()?.anchorNode
29
+ return composedPathFallback(target)
30
+ } else {
31
+ const path =
32
+ domEvent.composedPath != null
33
+ ? domEvent.composedPath()
34
+ : composedPathFallback(domEvent.target)
35
+ return path
36
+ }
37
+ }
38
+
39
+ function composedPathFallback(target: any): Array<any> {
40
+ const path: any[] = []
41
+ while (target != null && target !== document.body) {
42
+ path.push(target)
43
+ target = target.parentNode
44
+ }
45
+ return path
46
+ }
47
+
48
+ /**
49
+ * Retrieve the responderId from a host node
50
+ */
51
+ function getResponderId(node: any): number | null {
52
+ if (node != null) {
53
+ return node[keyName]
54
+ }
55
+ return null
56
+ }
57
+
58
+ /**
59
+ * Store the responderId on a host node
60
+ */
61
+ export function setResponderId(node: any, id: number) {
62
+ if (node != null) {
63
+ node[keyName] = id
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Filter the event path to contain only the nodes attached to the responder system
69
+ */
70
+ export function getResponderPaths(domEvent: any): {
71
+ idPath: Array<number>
72
+ nodePath: Array<any>
73
+ } {
74
+ const idPath: any[] = []
75
+ const nodePath: any[] = []
76
+ const eventPath = getEventPath(domEvent)
77
+ for (let i = 0; i < eventPath.length; i++) {
78
+ const node = eventPath[i]
79
+ const id = getResponderId(node)
80
+ if (id != null) {
81
+ idPath.push(id)
82
+ nodePath.push(node)
83
+ }
84
+ }
85
+ return { idPath, nodePath }
86
+ }
87
+
88
+ /**
89
+ * Walk the paths and find the first common ancestor
90
+ */
91
+ export function getLowestCommonAncestor(pathA: Array<any>, pathB: Array<any>): any {
92
+ let pathALength = pathA.length
93
+ let pathBLength = pathB.length
94
+ if (
95
+ // If either path is empty
96
+ pathALength === 0 ||
97
+ pathBLength === 0 ||
98
+ // If the last elements aren't the same there can't be a common ancestor
99
+ // that is connected to the responder system
100
+ pathA[pathALength - 1] !== pathB[pathBLength - 1]
101
+ ) {
102
+ return null
103
+ }
104
+
105
+ let itemA = pathA[0]
106
+ let indexA = 0
107
+ let itemB = pathB[0]
108
+ let indexB = 0
109
+
110
+ // If A is deeper, skip indices that can't match.
111
+ if (pathALength - pathBLength > 0) {
112
+ indexA = pathALength - pathBLength
113
+ itemA = pathA[indexA]
114
+ pathALength = pathBLength
115
+ }
116
+
117
+ // If B is deeper, skip indices that can't match
118
+ if (pathBLength - pathALength > 0) {
119
+ indexB = pathBLength - pathALength
120
+ itemB = pathB[indexB]
121
+ pathBLength = pathALength
122
+ }
123
+
124
+ // Walk in lockstep until a match is found
125
+ let depth = pathALength
126
+ while (depth--) {
127
+ if (itemA === itemB) {
128
+ return itemA
129
+ }
130
+ itemA = pathA[indexA++]
131
+ itemB = pathB[indexB++]
132
+ }
133
+ return null
134
+ }
135
+
136
+ /**
137
+ * Determine whether any of the active touches are within the current responder.
138
+ * This cannot rely on W3C `targetTouches`, as neither IE11 nor Safari implement it.
139
+ */
140
+ export function hasTargetTouches(target: any, touches: any): boolean {
141
+ if (!touches || touches.length === 0) {
142
+ return false
143
+ }
144
+ for (let i = 0; i < touches.length; i++) {
145
+ const node = touches[i].target
146
+ if (node != null) {
147
+ if (target.contains(node)) {
148
+ return true
149
+ }
150
+ }
151
+ }
152
+ return false
153
+ }
154
+
155
+ /**
156
+ * Ignore 'selectionchange' events that don't correspond with a person's intent to
157
+ * select text.
158
+ */
159
+ export function hasValidSelection(domEvent: any): boolean {
160
+ if (domEvent.type === 'selectionchange') {
161
+ return isSelectionValid()
162
+ }
163
+ return domEvent.type === 'select'
164
+ }
165
+
166
+ /**
167
+ * Events are only valid if the primary button was used without specific modifier keys.
168
+ */
169
+ export function isPrimaryPointerDown(domEvent: any): boolean {
170
+ const { altKey, button, buttons, ctrlKey, type } = domEvent
171
+ const isTouch = type === 'touchstart' || type === 'touchmove'
172
+ const isPrimaryMouseDown = type === 'mousedown' && (button === 0 || buttons === 1)
173
+ const isPrimaryMouseMove = type === 'mousemove' && buttons === 1
174
+ const noModifiers = altKey === false && ctrlKey === false
175
+
176
+ if (isTouch || (isPrimaryMouseDown && noModifiers) || (isPrimaryMouseMove && noModifiers)) {
177
+ return true
178
+ }
179
+ return false
180
+ }
181
+
182
+ export function isSelectionValid(): boolean {
183
+ const selection = window.getSelection()
184
+ if (!selection) return false
185
+ const string = selection.toString()
186
+ const anchorNode = selection.anchorNode
187
+ const focusNode = selection.focusNode
188
+ const isTextNode =
189
+ (anchorNode && anchorNode.nodeType === window.Node.TEXT_NODE) ||
190
+ (focusNode && focusNode.nodeType === window.Node.TEXT_NODE)
191
+ return string.length >= 1 && string !== '\n' && !!isTextNode
192
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ /// <reference types="node" />
7
+ declare type ClickEvent = any;
8
+ declare type KeyboardEvent = any;
9
+ declare type ResponderEvent = any;
10
+ export declare type PressResponderConfig = {
11
+ cancelable?: boolean | null;
12
+ disabled?: boolean | null;
13
+ delayLongPress?: number | null;
14
+ delayPressStart?: number | null;
15
+ delayPressEnd?: number | null;
16
+ onLongPress?: ((event: ResponderEvent) => void) | null;
17
+ onPress?: ((event: ClickEvent) => void) | null;
18
+ onPressChange?: ((event: ResponderEvent) => void) | null;
19
+ onPressStart?: ((event: ResponderEvent) => void) | null;
20
+ onPressMove?: ((event: ResponderEvent) => void) | null;
21
+ onPressEnd?: ((event: ResponderEvent) => void) | null;
22
+ };
23
+ export declare type EventHandlers = {
24
+ onClick: (event: ClickEvent) => void;
25
+ onContextMenu: (event: ClickEvent) => void;
26
+ onKeyDown: (event: KeyboardEvent) => void;
27
+ onResponderGrant: (event: ResponderEvent) => void;
28
+ onResponderMove: (event: ResponderEvent) => void;
29
+ onResponderRelease: (event: ResponderEvent) => void;
30
+ onResponderTerminate: (event: ResponderEvent) => void;
31
+ onResponderTerminationRequest: (event: ResponderEvent) => boolean;
32
+ onStartShouldSetResponder: (event: ResponderEvent) => boolean;
33
+ };
34
+ declare enum States {
35
+ DELAY = 0,
36
+ ERROR = 1,
37
+ LONG_PRESS_DETECTED = 2,
38
+ NOT_RESPONDER = 3,
39
+ RESPONDER_ACTIVE_LONG_PRESS_START = 4,
40
+ RESPONDER_ACTIVE_PRESS_START = 5,
41
+ RESPONDER_INACTIVE_PRESS_START = 6,
42
+ RESPONDER_GRANT = 7,
43
+ RESPONDER_RELEASE = 8,
44
+ RESPONDER_TERMINATED = 9
45
+ }
46
+ declare type TouchState = States.NOT_RESPONDER | States.RESPONDER_INACTIVE_PRESS_START | States.RESPONDER_ACTIVE_PRESS_START | States.RESPONDER_ACTIVE_LONG_PRESS_START | States.ERROR;
47
+ declare type TouchSignal = States.DELAY | States.RESPONDER_GRANT | States.RESPONDER_RELEASE | States.RESPONDER_TERMINATED | States.LONG_PRESS_DETECTED;
48
+ declare type TimeoutID = NodeJS.Timer | null;
49
+ export declare class PressResponder {
50
+ _config: PressResponderConfig;
51
+ _eventHandlers?: EventHandlers | null;
52
+ _isPointerTouch?: boolean;
53
+ _longPressDelayTimeout?: TimeoutID;
54
+ _longPressDispatched?: boolean;
55
+ _pressDelayTimeout?: TimeoutID;
56
+ _pressOutDelayTimeout?: TimeoutID;
57
+ _selectionTerminated?: boolean;
58
+ _touchActivatePosition?: {
59
+ pageX: number;
60
+ pageY: number;
61
+ } | null;
62
+ _touchState: TouchState;
63
+ constructor(config: PressResponderConfig);
64
+ configure(config: PressResponderConfig): void;
65
+ /**
66
+ * Resets any pending timers. This should be called on unmount.
67
+ */
68
+ reset(): void;
69
+ /**
70
+ * Returns a set of props to spread into the interactive element.
71
+ */
72
+ getEventHandlers(): EventHandlers;
73
+ _createEventHandlers(): EventHandlers;
74
+ /**
75
+ * Receives a state machine signal, performs side effects of the transition
76
+ * and stores the new state. Validates the transition as well.
77
+ */
78
+ _receiveSignal(signal: TouchSignal, event: ResponderEvent): void;
79
+ /**
80
+ * Performs a transition between touchable states and identify any activations
81
+ * or deactivations (and callback invocations).
82
+ */
83
+ _performTransitionSideEffects(prevState: TouchState, nextState: TouchState, signal: TouchSignal, event: ResponderEvent): void;
84
+ _activate(event: ResponderEvent): void;
85
+ _deactivate(event: ResponderEvent): void;
86
+ _handleLongPress(event: ResponderEvent): void;
87
+ _cancelLongPressDelayTimeout(): void;
88
+ _cancelPressDelayTimeout(): void;
89
+ _cancelPressOutDelayTimeout(): void;
90
+ }
91
+ export {};
92
+ //# sourceMappingURL=PressResponder.d.ts.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import type { ResponderEvent } from './createResponderEvent';
7
+ declare type ResponderId = string;
8
+ export declare type ResponderConfig = {
9
+ onResponderEnd?: ((e: ResponderEvent) => void) | null;
10
+ onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null;
11
+ onResponderMove?: ((e: ResponderEvent) => void) | null;
12
+ onResponderRelease?: ((e: ResponderEvent) => void) | null;
13
+ onResponderReject?: ((e: ResponderEvent) => void) | null;
14
+ onResponderStart?: ((e: ResponderEvent) => void) | null;
15
+ onResponderTerminate?: ((e: ResponderEvent) => void) | null;
16
+ onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null;
17
+ onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null;
18
+ onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null;
19
+ onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null;
20
+ onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null;
21
+ onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null;
22
+ onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null;
23
+ onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null;
24
+ onSelectionChangeShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null;
25
+ };
26
+ export declare function attachListeners(): void;
27
+ /**
28
+ * Register a node with the ResponderSystem.
29
+ */
30
+ export declare function addNode(id: ResponderId, node: any, config: ResponderConfig): void;
31
+ /**
32
+ * Unregister a node with the ResponderSystem.
33
+ */
34
+ export declare function removeNode(id: ResponderId): void;
35
+ /**
36
+ * Allow the current responder to be terminated from within components to support
37
+ * more complex requirements, such as use with other React libraries for working
38
+ * with scroll views, input views, etc.
39
+ */
40
+ export declare function terminateResponder(): void;
41
+ /**
42
+ * Allow unit tests to inspect the current responder in the system.
43
+ * FOR TESTING ONLY.
44
+ */
45
+ export declare function getResponderNode(): any;
46
+ export {};
47
+ //# sourceMappingURL=ResponderSystem.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { TouchEvent } from './types';
8
+ declare type TouchRecord = {
9
+ currentPageX: number;
10
+ currentPageY: number;
11
+ currentTimeStamp: number;
12
+ previousPageX: number;
13
+ previousPageY: number;
14
+ previousTimeStamp: number;
15
+ startPageX: number;
16
+ startPageY: number;
17
+ startTimeStamp: number;
18
+ touchActive: boolean;
19
+ };
20
+ export declare type TouchHistory = {
21
+ indexOfSingleActiveTouch: number;
22
+ mostRecentTimeStamp: number;
23
+ numberActiveTouches: number;
24
+ touchBank: Array<TouchRecord>;
25
+ };
26
+ export declare class ResponderTouchHistoryStore {
27
+ _touchHistory: {
28
+ touchBank: never[];
29
+ numberActiveTouches: number;
30
+ indexOfSingleActiveTouch: number;
31
+ mostRecentTimeStamp: number;
32
+ };
33
+ recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void;
34
+ get touchHistory(): TouchHistory;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=ResponderTouchHistoryStore.d.ts.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import { ResponderTouchHistoryStore, TouchHistory } from './ResponderTouchHistoryStore';
7
+ export declare type ResponderEvent = {
8
+ bubbles: boolean;
9
+ cancelable: boolean;
10
+ currentTarget: any;
11
+ defaultPrevented: boolean | null;
12
+ dispatchConfig: {
13
+ registrationName?: string;
14
+ phasedRegistrationNames?: {
15
+ bubbled: string;
16
+ captured: string;
17
+ };
18
+ };
19
+ eventPhase: number | null;
20
+ isDefaultPrevented: () => boolean;
21
+ isPropagationStopped: () => boolean;
22
+ isTrusted: boolean | null;
23
+ preventDefault: () => void;
24
+ stopPropagation: () => void;
25
+ nativeEvent: TouchEvent;
26
+ persist: () => void;
27
+ target: any | null;
28
+ timeStamp: number;
29
+ touchHistory: TouchHistory;
30
+ };
31
+ /**
32
+ * Converts a native DOM event to a ResponderEvent.
33
+ * Mouse events are transformed into fake touch events.
34
+ */
35
+ export default function createResponderEvent(domEvent: any, responderTouchHistoryStore: ResponderTouchHistoryStore): ResponderEvent;
36
+ //# sourceMappingURL=createResponderEvent.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from './useResponderEvents';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ export declare type Touch = {
7
+ force: number;
8
+ identifier: number;
9
+ locationX: any;
10
+ locationY: any;
11
+ pageX: number;
12
+ pageY: number;
13
+ target: any;
14
+ timestamp: number;
15
+ };
16
+ export declare type TouchEvent = {
17
+ altKey: boolean;
18
+ ctrlKey: boolean;
19
+ metaKey: boolean;
20
+ shiftKey: boolean;
21
+ changedTouches: Array<Touch>;
22
+ force: number;
23
+ identifier: number;
24
+ locationX: any;
25
+ locationY: any;
26
+ pageX: number;
27
+ pageY: number;
28
+ target: any;
29
+ timestamp: number;
30
+ touches: Array<Touch>;
31
+ };
32
+ export declare const BLUR = "blur";
33
+ export declare const CONTEXT_MENU = "contextmenu";
34
+ export declare const FOCUS_OUT = "focusout";
35
+ export declare const MOUSE_DOWN = "mousedown";
36
+ export declare const MOUSE_MOVE = "mousemove";
37
+ export declare const MOUSE_UP = "mouseup";
38
+ export declare const MOUSE_CANCEL = "dragstart";
39
+ export declare const TOUCH_START = "touchstart";
40
+ export declare const TOUCH_MOVE = "touchmove";
41
+ export declare const TOUCH_END = "touchend";
42
+ export declare const TOUCH_CANCEL = "touchcancel";
43
+ export declare const SCROLL = "scroll";
44
+ export declare const SELECT = "select";
45
+ export declare const SELECTION_CHANGE = "selectionchange";
46
+ export declare function isStartish(eventType: unknown): boolean;
47
+ export declare function isMoveish(eventType: unknown): boolean;
48
+ export declare function isEndish(eventType: unknown): boolean;
49
+ export declare function isCancelish(eventType: unknown): boolean;
50
+ export declare function isScroll(eventType: unknown): boolean;
51
+ export declare function isSelectionChange(eventType: unknown): boolean;
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import * as ResponderSystem from './ResponderSystem';
7
+ export * from './utils';
8
+ export declare function useResponderEvents(hostRef: any, config?: ResponderSystem.ResponderConfig): void;
9
+ //# sourceMappingURL=useResponderEvents.d.ts.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ export declare const canUseDOM: boolean;
7
+ export declare const getBoundingClientRect: (node: HTMLElement | null) => void | DOMRect;
8
+ /**
9
+ * Store the responderId on a host node
10
+ */
11
+ export declare function setResponderId(node: any, id: number): void;
12
+ /**
13
+ * Filter the event path to contain only the nodes attached to the responder system
14
+ */
15
+ export declare function getResponderPaths(domEvent: any): {
16
+ idPath: Array<number>;
17
+ nodePath: Array<any>;
18
+ };
19
+ /**
20
+ * Walk the paths and find the first common ancestor
21
+ */
22
+ export declare function getLowestCommonAncestor(pathA: Array<any>, pathB: Array<any>): any;
23
+ /**
24
+ * Determine whether any of the active touches are within the current responder.
25
+ * This cannot rely on W3C `targetTouches`, as neither IE11 nor Safari implement it.
26
+ */
27
+ export declare function hasTargetTouches(target: any, touches: any): boolean;
28
+ /**
29
+ * Ignore 'selectionchange' events that don't correspond with a person's intent to
30
+ * select text.
31
+ */
32
+ export declare function hasValidSelection(domEvent: any): boolean;
33
+ /**
34
+ * Events are only valid if the primary button was used without specific modifier keys.
35
+ */
36
+ export declare function isPrimaryPointerDown(domEvent: any): boolean;
37
+ export declare function isSelectionValid(): boolean;
38
+ //# sourceMappingURL=utils.d.ts.map