@lucasols/dnd-kit-utilities 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +119 -11
- package/dist/index.js +229 -7
- package/dist/index.js.map +1 -0
- package/package.json +18 -16
- package/dist/adjustment.d.ts +0 -2
- package/dist/coordinates/getEventCoordinates.d.ts +0 -5
- package/dist/coordinates/index.d.ts +0 -2
- package/dist/coordinates/types.d.ts +0 -4
- package/dist/css.d.ts +0 -25
- package/dist/dnd-kit-utilities.cjs.development.js +0 -361
- package/dist/dnd-kit-utilities.cjs.development.js.map +0 -1
- package/dist/dnd-kit-utilities.cjs.production.min.js +0 -2
- package/dist/dnd-kit-utilities.cjs.production.min.js.map +0 -1
- package/dist/dnd-kit-utilities.esm.js +0 -333
- package/dist/dnd-kit-utilities.esm.js.map +0 -1
- package/dist/event/hasViewportRelativeCoordinates.d.ts +0 -1
- package/dist/event/index.d.ts +0 -3
- package/dist/event/isKeyboardEvent.d.ts +0 -1
- package/dist/event/isTouchEvent.d.ts +0 -1
- package/dist/execution-context/canUseDOM.d.ts +0 -1
- package/dist/execution-context/getOwnerDocument.d.ts +0 -1
- package/dist/execution-context/getWindow.d.ts +0 -1
- package/dist/execution-context/index.d.ts +0 -3
- package/dist/focus/findFirstFocusableNode.d.ts +0 -1
- package/dist/focus/index.d.ts +0 -1
- package/dist/hooks/index.d.ts +0 -9
- package/dist/hooks/useCombinedRefs.d.ts +0 -1
- package/dist/hooks/useEvent.d.ts +0 -1
- package/dist/hooks/useInterval.d.ts +0 -1
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +0 -6
- package/dist/hooks/useLatestValue.d.ts +0 -2
- package/dist/hooks/useLazyMemo.d.ts +0 -1
- package/dist/hooks/useNodeRef.d.ts +0 -2
- package/dist/hooks/usePrevious.d.ts +0 -1
- package/dist/hooks/useUniqueId.d.ts +0 -1
- package/dist/type-guards/index.d.ts +0 -5
- package/dist/type-guards/isDocument.d.ts +0 -1
- package/dist/type-guards/isHTMLElement.d.ts +0 -1
- package/dist/type-guards/isNode.d.ts +0 -1
- package/dist/type-guards/isSVGElement.d.ts +0 -1
- package/dist/type-guards/isWindow.d.ts +0 -1
- package/dist/types.d.ts +0 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { DependencyList, useLayoutEffect } from "react";
|
|
2
|
+
//#region src/hooks/useCombinedRefs.d.ts
|
|
3
|
+
export declare function useCombinedRefs<T>(...refs: ((node: T) => void)[]): (node: T) => void;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/hooks/useEvent.d.ts
|
|
6
|
+
export declare function useEvent<T extends Function>(handler: T | undefined): (...args: any) => any;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/hooks/useIsomorphicLayoutEffect.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* A hook that resolves to useEffect on the server and useLayoutEffect on the client
|
|
11
|
+
* @param callback {function} Callback function that is invoked when the dependencies of the hook change
|
|
12
|
+
*/
|
|
13
|
+
export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/hooks/useInterval.d.ts
|
|
16
|
+
export declare function useInterval(): readonly [(listener: Function, duration: number) => void, () => void];
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/hooks/useLatestValue.d.ts
|
|
19
|
+
export declare function useLatestValue<T extends any>(value: T, dependencies?: DependencyList): import("react").RefObject<T>;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/hooks/useLazyMemo.d.ts
|
|
22
|
+
export declare function useLazyMemo<T>(callback: (prevValue: T | undefined) => T, dependencies: any[]): T;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/hooks/useNodeRef.d.ts
|
|
25
|
+
export declare function useNodeRef(onChange?: (newElement: HTMLElement | null, previousElement: HTMLElement | null) => void): readonly [import("react").RefObject<HTMLElement | null>, (element: HTMLElement | null) => void];
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/hooks/usePrevious.d.ts
|
|
28
|
+
export declare function usePrevious<T>(value: T): T | undefined;
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/hooks/useUniqueId.d.ts
|
|
31
|
+
export declare function useUniqueId(prefix: string, value?: string): string;
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/adjustment.d.ts
|
|
34
|
+
export declare const add: <T extends Record<U, number>, U extends string>(object: T, ...adjustments: Partial<T>[]) => T;
|
|
35
|
+
export declare const subtract: <T extends Record<U, number>, U extends string>(object: T, ...adjustments: Partial<T>[]) => T;
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/coordinates/types.d.ts
|
|
38
|
+
type Coordinates = {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/coordinates/getEventCoordinates.d.ts
|
|
44
|
+
/**
|
|
45
|
+
* Returns the normalized x and y coordinates for mouse and touch events.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getEventCoordinates(event: Event): Coordinates | null;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/css.d.ts
|
|
50
|
+
type Transform = {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
scaleX: number;
|
|
54
|
+
scaleY: number;
|
|
55
|
+
};
|
|
56
|
+
interface Transition {
|
|
57
|
+
property: string;
|
|
58
|
+
easing: string;
|
|
59
|
+
duration: number;
|
|
60
|
+
}
|
|
61
|
+
export declare const CSS: Readonly<{
|
|
62
|
+
Translate: {
|
|
63
|
+
toString(transform: Transform | null): string | undefined;
|
|
64
|
+
};
|
|
65
|
+
Scale: {
|
|
66
|
+
toString(transform: Transform | null): string | undefined;
|
|
67
|
+
};
|
|
68
|
+
Transform: {
|
|
69
|
+
toString(transform: Transform | null): string | undefined;
|
|
70
|
+
};
|
|
71
|
+
Transition: {
|
|
72
|
+
toString({ property, duration, easing }: Transition): string;
|
|
73
|
+
};
|
|
74
|
+
}>;
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/event/hasViewportRelativeCoordinates.d.ts
|
|
77
|
+
export declare function hasViewportRelativeCoordinates(event: Event): event is Event & Pick<PointerEvent, 'clientX' | 'clientY'>;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/event/isKeyboardEvent.d.ts
|
|
80
|
+
export declare function isKeyboardEvent(event: Event | undefined | null): event is KeyboardEvent;
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/event/isTouchEvent.d.ts
|
|
83
|
+
export declare function isTouchEvent(event: Event | undefined | null): event is TouchEvent;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/execution-context/canUseDOM.d.ts
|
|
86
|
+
export declare const canUseDOM: boolean;
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/execution-context/getOwnerDocument.d.ts
|
|
89
|
+
export declare function getOwnerDocument(target: Event['target']): Document;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/execution-context/getWindow.d.ts
|
|
92
|
+
export declare function getWindow(target: Event['target']): typeof window;
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/focus/findFirstFocusableNode.d.ts
|
|
95
|
+
export declare function findFirstFocusableNode(element: HTMLElement): HTMLElement | null;
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/type-guards/isDocument.d.ts
|
|
98
|
+
export declare function isDocument(node: Node): node is Document;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/type-guards/isHTMLElement.d.ts
|
|
101
|
+
export declare function isHTMLElement(node: Node | Window): node is HTMLElement;
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/type-guards/isNode.d.ts
|
|
104
|
+
export declare function isNode(node: Object): node is Node;
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/type-guards/isSVGElement.d.ts
|
|
107
|
+
export declare function isSVGElement(node: Node): node is SVGElement;
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/type-guards/isWindow.d.ts
|
|
110
|
+
export declare function isWindow(element: Object): element is typeof window;
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/types.d.ts
|
|
113
|
+
type Arguments<T> = T extends ((...args: infer U) => any) ? U : never;
|
|
114
|
+
type DeepRequired<T> = { [K in keyof T]-?: Required<T[K]>; };
|
|
115
|
+
type FirstArgument<T> = T extends ((firstArg: infer U, ...args: Array<any>) => any) ? U : never;
|
|
116
|
+
type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
|
117
|
+
//#endregion
|
|
118
|
+
export type { Arguments, Coordinates, DeepRequired, FirstArgument, Transform, Transition, Without };
|
|
119
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,230 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
1
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
2
|
+
//#region src/hooks/useCombinedRefs.ts
|
|
3
|
+
function useCombinedRefs(...refs) {
|
|
4
|
+
return useMemo(() => (node) => {
|
|
5
|
+
refs.forEach((ref) => ref(node));
|
|
6
|
+
}, refs);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/execution-context/canUseDOM.ts
|
|
10
|
+
const canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/type-guards/isWindow.ts
|
|
13
|
+
function isWindow(element) {
|
|
14
|
+
const elementString = Object.prototype.toString.call(element);
|
|
15
|
+
return elementString === "[object Window]" || elementString === "[object global]";
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/type-guards/isNode.ts
|
|
19
|
+
function isNode(node) {
|
|
20
|
+
return "nodeType" in node;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/execution-context/getWindow.ts
|
|
24
|
+
function getWindow(target) {
|
|
25
|
+
if (!target) return window;
|
|
26
|
+
if (isWindow(target)) return target;
|
|
27
|
+
if (!isNode(target)) return window;
|
|
28
|
+
return target.ownerDocument?.defaultView ?? window;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/type-guards/isDocument.ts
|
|
32
|
+
function isDocument(node) {
|
|
33
|
+
const { Document } = getWindow(node);
|
|
34
|
+
return node instanceof Document;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/type-guards/isHTMLElement.ts
|
|
38
|
+
function isHTMLElement(node) {
|
|
39
|
+
if (isWindow(node)) return false;
|
|
40
|
+
return node instanceof getWindow(node).HTMLElement;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/type-guards/isSVGElement.ts
|
|
44
|
+
function isSVGElement(node) {
|
|
45
|
+
return node instanceof getWindow(node).SVGElement;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/execution-context/getOwnerDocument.ts
|
|
49
|
+
function getOwnerDocument(target) {
|
|
50
|
+
if (!target) return document;
|
|
51
|
+
if (isWindow(target)) return target.document;
|
|
52
|
+
if (!isNode(target)) return document;
|
|
53
|
+
if (isDocument(target)) return target;
|
|
54
|
+
if (isHTMLElement(target) || isSVGElement(target)) return target.ownerDocument;
|
|
55
|
+
return document;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/hooks/useIsomorphicLayoutEffect.ts
|
|
59
|
+
/**
|
|
60
|
+
* A hook that resolves to useEffect on the server and useLayoutEffect on the client
|
|
61
|
+
* @param callback {function} Callback function that is invoked when the dependencies of the hook change
|
|
62
|
+
*/
|
|
63
|
+
const useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/hooks/useEvent.ts
|
|
66
|
+
function useEvent(handler) {
|
|
67
|
+
const handlerRef = useRef(handler);
|
|
68
|
+
useIsomorphicLayoutEffect(() => {
|
|
69
|
+
handlerRef.current = handler;
|
|
70
|
+
});
|
|
71
|
+
return useCallback(function(...args) {
|
|
72
|
+
return handlerRef.current?.(...args);
|
|
73
|
+
}, []);
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/hooks/useInterval.ts
|
|
77
|
+
function useInterval() {
|
|
78
|
+
const intervalRef = useRef(null);
|
|
79
|
+
return [useCallback((listener, duration) => {
|
|
80
|
+
intervalRef.current = setInterval(listener, duration);
|
|
81
|
+
}, []), useCallback(() => {
|
|
82
|
+
if (intervalRef.current !== null) {
|
|
83
|
+
clearInterval(intervalRef.current);
|
|
84
|
+
intervalRef.current = null;
|
|
85
|
+
}
|
|
86
|
+
}, [])];
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/hooks/useLatestValue.ts
|
|
90
|
+
function useLatestValue(value, dependencies = [value]) {
|
|
91
|
+
const valueRef = useRef(value);
|
|
92
|
+
useIsomorphicLayoutEffect(() => {
|
|
93
|
+
if (valueRef.current !== value) valueRef.current = value;
|
|
94
|
+
}, dependencies);
|
|
95
|
+
return valueRef;
|
|
8
96
|
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/hooks/useLazyMemo.ts
|
|
99
|
+
function useLazyMemo(callback, dependencies) {
|
|
100
|
+
const valueRef = useRef(void 0);
|
|
101
|
+
return useMemo(() => {
|
|
102
|
+
const newValue = callback(valueRef.current);
|
|
103
|
+
valueRef.current = newValue;
|
|
104
|
+
return newValue;
|
|
105
|
+
}, [...dependencies]);
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/hooks/useNodeRef.ts
|
|
109
|
+
function useNodeRef(onChange) {
|
|
110
|
+
const onChangeHandler = useEvent(onChange);
|
|
111
|
+
const node = useRef(null);
|
|
112
|
+
return [node, useCallback((element) => {
|
|
113
|
+
if (element !== node.current) onChangeHandler?.(element, node.current);
|
|
114
|
+
node.current = element;
|
|
115
|
+
}, [])];
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/hooks/usePrevious.ts
|
|
119
|
+
function usePrevious(value) {
|
|
120
|
+
const ref = useRef(void 0);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
ref.current = value;
|
|
123
|
+
}, [value]);
|
|
124
|
+
return ref.current;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/hooks/useUniqueId.ts
|
|
128
|
+
let ids = {};
|
|
129
|
+
function useUniqueId(prefix, value) {
|
|
130
|
+
return useMemo(() => {
|
|
131
|
+
if (value) return value;
|
|
132
|
+
const id = ids[prefix] == null ? 0 : ids[prefix] + 1;
|
|
133
|
+
ids[prefix] = id;
|
|
134
|
+
return `${prefix}-${id}`;
|
|
135
|
+
}, [prefix, value]);
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/adjustment.ts
|
|
139
|
+
function createAdjustmentFn(modifier) {
|
|
140
|
+
return (object, ...adjustments) => {
|
|
141
|
+
return adjustments.reduce((accumulator, adjustment) => {
|
|
142
|
+
const entries = Object.entries(adjustment);
|
|
143
|
+
for (const [key, valueAdjustment] of entries) {
|
|
144
|
+
const value = accumulator[key];
|
|
145
|
+
if (value != null) accumulator[key] = value + modifier * valueAdjustment;
|
|
146
|
+
}
|
|
147
|
+
return accumulator;
|
|
148
|
+
}, { ...object });
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const add = createAdjustmentFn(1);
|
|
152
|
+
const subtract = createAdjustmentFn(-1);
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/event/hasViewportRelativeCoordinates.ts
|
|
155
|
+
function hasViewportRelativeCoordinates(event) {
|
|
156
|
+
return "clientX" in event && "clientY" in event;
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/event/isKeyboardEvent.ts
|
|
160
|
+
function isKeyboardEvent(event) {
|
|
161
|
+
if (!event) return false;
|
|
162
|
+
const { KeyboardEvent } = getWindow(event.target);
|
|
163
|
+
return KeyboardEvent && event instanceof KeyboardEvent;
|
|
164
|
+
}
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/event/isTouchEvent.ts
|
|
167
|
+
function isTouchEvent(event) {
|
|
168
|
+
if (!event) return false;
|
|
169
|
+
const { TouchEvent } = getWindow(event.target);
|
|
170
|
+
return TouchEvent && event instanceof TouchEvent;
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/coordinates/getEventCoordinates.ts
|
|
174
|
+
/**
|
|
175
|
+
* Returns the normalized x and y coordinates for mouse and touch events.
|
|
176
|
+
*/
|
|
177
|
+
function getEventCoordinates(event) {
|
|
178
|
+
if (isTouchEvent(event)) {
|
|
179
|
+
if (event.touches && event.touches.length) {
|
|
180
|
+
const { clientX: x, clientY: y } = event.touches[0];
|
|
181
|
+
return {
|
|
182
|
+
x,
|
|
183
|
+
y
|
|
184
|
+
};
|
|
185
|
+
} else if (event.changedTouches && event.changedTouches.length) {
|
|
186
|
+
const { clientX: x, clientY: y } = event.changedTouches[0];
|
|
187
|
+
return {
|
|
188
|
+
x,
|
|
189
|
+
y
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (hasViewportRelativeCoordinates(event)) return {
|
|
194
|
+
x: event.clientX,
|
|
195
|
+
y: event.clientY
|
|
196
|
+
};
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/css.ts
|
|
201
|
+
const CSS = Object.freeze({
|
|
202
|
+
Translate: { toString(transform) {
|
|
203
|
+
if (!transform) return;
|
|
204
|
+
const { x, y } = transform;
|
|
205
|
+
return `translate3d(${x ? Math.round(x) : 0}px, ${y ? Math.round(y) : 0}px, 0)`;
|
|
206
|
+
} },
|
|
207
|
+
Scale: { toString(transform) {
|
|
208
|
+
if (!transform) return;
|
|
209
|
+
const { scaleX, scaleY } = transform;
|
|
210
|
+
return `scaleX(${scaleX}) scaleY(${scaleY})`;
|
|
211
|
+
} },
|
|
212
|
+
Transform: { toString(transform) {
|
|
213
|
+
if (!transform) return;
|
|
214
|
+
return [CSS.Translate.toString(transform), CSS.Scale.toString(transform)].join(" ");
|
|
215
|
+
} },
|
|
216
|
+
Transition: { toString({ property, duration, easing }) {
|
|
217
|
+
return `${property} ${duration}ms ${easing}`;
|
|
218
|
+
} }
|
|
219
|
+
});
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/focus/findFirstFocusableNode.ts
|
|
222
|
+
const SELECTOR = "a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";
|
|
223
|
+
function findFirstFocusableNode(element) {
|
|
224
|
+
if (element.matches(SELECTOR)) return element;
|
|
225
|
+
return element.querySelector(SELECTOR);
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
export { CSS, add, canUseDOM, findFirstFocusableNode, getEventCoordinates, getOwnerDocument, getWindow, hasViewportRelativeCoordinates, isDocument, isHTMLElement, isKeyboardEvent, isNode, isSVGElement, isTouchEvent, isWindow, subtract, useCombinedRefs, useEvent, useInterval, useIsomorphicLayoutEffect, useLatestValue, useLazyMemo, useNodeRef, usePrevious, useUniqueId };
|
|
229
|
+
|
|
230
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/hooks/useCombinedRefs.ts","../src/execution-context/canUseDOM.ts","../src/type-guards/isWindow.ts","../src/type-guards/isNode.ts","../src/execution-context/getWindow.ts","../src/type-guards/isDocument.ts","../src/type-guards/isHTMLElement.ts","../src/type-guards/isSVGElement.ts","../src/execution-context/getOwnerDocument.ts","../src/hooks/useIsomorphicLayoutEffect.ts","../src/hooks/useEvent.ts","../src/hooks/useInterval.ts","../src/hooks/useLatestValue.ts","../src/hooks/useLazyMemo.ts","../src/hooks/useNodeRef.ts","../src/hooks/usePrevious.ts","../src/hooks/useUniqueId.ts","../src/adjustment.ts","../src/event/hasViewportRelativeCoordinates.ts","../src/event/isKeyboardEvent.ts","../src/event/isTouchEvent.ts","../src/coordinates/getEventCoordinates.ts","../src/css.ts","../src/focus/findFirstFocusableNode.ts"],"sourcesContent":["import {useMemo} from 'react';\n\nexport function useCombinedRefs<T>(\n ...refs: ((node: T) => void)[]\n): (node: T) => void {\n return useMemo(\n () => (node: T) => {\n refs.forEach((ref) => ref(node));\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n","// https://github.com/facebook/react/blob/master/packages/shared/ExecutionEnvironment.js\nexport const canUseDOM =\n typeof window !== 'undefined' &&\n typeof window.document !== 'undefined' &&\n typeof window.document.createElement !== 'undefined';\n","export function isWindow(element: Object): element is typeof window {\n const elementString = Object.prototype.toString.call(element);\n return (\n elementString === '[object Window]' ||\n // In Electron context the Window object serializes to [object global]\n elementString === '[object global]'\n );\n}\n","export function isNode(node: Object): node is Node {\n return 'nodeType' in node;\n}\n","import {isWindow} from '../type-guards/isWindow';\nimport {isNode} from '../type-guards/isNode';\n\nexport function getWindow(target: Event['target']): typeof window {\n if (!target) {\n return window;\n }\n\n if (isWindow(target)) {\n return target;\n }\n\n if (!isNode(target)) {\n return window;\n }\n\n return target.ownerDocument?.defaultView ?? window;\n}\n","import {getWindow} from '../execution-context/getWindow';\n\nexport function isDocument(node: Node): node is Document {\n const {Document} = getWindow(node);\n\n return node instanceof Document;\n}\n","import {getWindow} from '../execution-context/getWindow';\n\nimport {isWindow} from './isWindow';\n\nexport function isHTMLElement(node: Node | Window): node is HTMLElement {\n if (isWindow(node)) {\n return false;\n }\n\n return node instanceof getWindow(node).HTMLElement;\n}\n","import {getWindow} from '../execution-context/getWindow';\n\nexport function isSVGElement(node: Node): node is SVGElement {\n return node instanceof getWindow(node).SVGElement;\n}\n","import {\n isWindow,\n isHTMLElement,\n isDocument,\n isNode,\n isSVGElement,\n} from '../type-guards';\n\nexport function getOwnerDocument(target: Event['target']): Document {\n if (!target) {\n return document;\n }\n\n if (isWindow(target)) {\n return target.document;\n }\n\n if (!isNode(target)) {\n return document;\n }\n\n if (isDocument(target)) {\n return target;\n }\n\n if (isHTMLElement(target) || isSVGElement(target)) {\n return target.ownerDocument;\n }\n\n return document;\n}\n","import {useEffect, useLayoutEffect} from 'react';\n\nimport {canUseDOM} from '../execution-context';\n\n/**\n * A hook that resolves to useEffect on the server and useLayoutEffect on the client\n * @param callback {function} Callback function that is invoked when the dependencies of the hook change\n */\nexport const useIsomorphicLayoutEffect = canUseDOM\n ? useLayoutEffect\n : useEffect;\n","import {useCallback, useRef} from 'react';\n\nimport {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect';\n\nexport function useEvent<T extends Function>(handler: T | undefined) {\n const handlerRef = useRef<T | undefined>(handler);\n\n useIsomorphicLayoutEffect(() => {\n handlerRef.current = handler;\n });\n\n return useCallback(function (...args: any) {\n return handlerRef.current?.(...args);\n }, []);\n}\n","import {useCallback, useRef} from 'react';\n\nexport function useInterval() {\n const intervalRef = useRef<number | null>(null);\n\n const set = useCallback((listener: Function, duration: number) => {\n intervalRef.current = setInterval(listener, duration);\n }, []);\n\n const clear = useCallback(() => {\n if (intervalRef.current !== null) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n }, []);\n\n return [set, clear] as const;\n}\n","import {useRef} from 'react';\nimport type {DependencyList} from 'react';\n\nimport {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect';\n\nexport function useLatestValue<T extends any>(\n value: T,\n dependencies: DependencyList = [value]\n) {\n const valueRef = useRef<T>(value);\n\n useIsomorphicLayoutEffect(() => {\n if (valueRef.current !== value) {\n valueRef.current = value;\n }\n }, dependencies);\n\n return valueRef;\n}\n","import {useMemo, useRef} from 'react';\n\nexport function useLazyMemo<T>(\n callback: (prevValue: T | undefined) => T,\n dependencies: any[]\n) {\n const valueRef = useRef<T | undefined>(undefined);\n\n return useMemo(\n () => {\n const newValue = callback(valueRef.current);\n valueRef.current = newValue;\n\n return newValue;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [...dependencies]\n );\n}\n","import {useRef, useCallback} from 'react';\n\nimport {useEvent} from './useEvent';\n\nexport function useNodeRef(\n onChange?: (\n newElement: HTMLElement | null,\n previousElement: HTMLElement | null\n ) => void\n) {\n const onChangeHandler = useEvent(onChange);\n const node = useRef<HTMLElement | null>(null);\n const setNodeRef = useCallback(\n (element: HTMLElement | null) => {\n if (element !== node.current) {\n onChangeHandler?.(element, node.current);\n }\n\n node.current = element;\n },\n //eslint-disable-next-line\n []\n );\n\n return [node, setNodeRef] as const;\n}\n","import {useRef, useEffect} from 'react';\n\nexport function usePrevious<T>(value: T) {\n const ref = useRef<T | undefined>(undefined);\n\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref.current;\n}\n","import {useMemo} from 'react';\n\nlet ids: Record<string, number> = {};\n\nexport function useUniqueId(prefix: string, value?: string) {\n return useMemo(() => {\n if (value) {\n return value;\n }\n\n const id = ids[prefix] == null ? 0 : ids[prefix] + 1;\n ids[prefix] = id;\n\n return `${prefix}-${id}`;\n }, [prefix, value]);\n}\n","function createAdjustmentFn(modifier: number) {\n return <T extends Record<U, number>, U extends string>(\n object: T,\n ...adjustments: Partial<T>[]\n ): T => {\n return adjustments.reduce<T>(\n (accumulator, adjustment) => {\n const entries = Object.entries(adjustment) as [U, number][];\n\n for (const [key, valueAdjustment] of entries) {\n const value = accumulator[key];\n\n if (value != null) {\n accumulator[key] = (value + modifier * valueAdjustment) as T[U];\n }\n }\n\n return accumulator;\n },\n {\n ...object,\n }\n );\n };\n}\n\nexport const add = createAdjustmentFn(1);\nexport const subtract = createAdjustmentFn(-1);\n","export function hasViewportRelativeCoordinates(\n event: Event\n): event is Event & Pick<PointerEvent, 'clientX' | 'clientY'> {\n return 'clientX' in event && 'clientY' in event;\n}\n","import {getWindow} from '../execution-context';\n\nexport function isKeyboardEvent(\n event: Event | undefined | null\n): event is KeyboardEvent {\n if (!event) {\n return false;\n }\n\n const {KeyboardEvent} = getWindow(event.target);\n\n return KeyboardEvent && event instanceof KeyboardEvent;\n}\n","import {getWindow} from '../execution-context';\n\nexport function isTouchEvent(\n event: Event | undefined | null\n): event is TouchEvent {\n if (!event) {\n return false;\n }\n\n const {TouchEvent} = getWindow(event.target);\n\n return TouchEvent && event instanceof TouchEvent;\n}\n","import type {Coordinates} from './types';\nimport {isTouchEvent, hasViewportRelativeCoordinates} from '../event';\n\n/**\n * Returns the normalized x and y coordinates for mouse and touch events.\n */\nexport function getEventCoordinates(event: Event): Coordinates | null {\n if (isTouchEvent(event)) {\n if (event.touches && event.touches.length) {\n const {clientX: x, clientY: y} = event.touches[0];\n\n return {\n x,\n y,\n };\n } else if (event.changedTouches && event.changedTouches.length) {\n const {clientX: x, clientY: y} = event.changedTouches[0];\n\n return {\n x,\n y,\n };\n }\n }\n\n if (hasViewportRelativeCoordinates(event)) {\n return {\n x: event.clientX,\n y: event.clientY,\n };\n }\n\n return null;\n}\n","export type Transform = {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n};\n\nexport interface Transition {\n property: string;\n easing: string;\n duration: number;\n}\n\nexport const CSS = Object.freeze({\n Translate: {\n toString(transform: Transform | null) {\n if (!transform) {\n return;\n }\n\n const {x, y} = transform;\n\n return `translate3d(${x ? Math.round(x) : 0}px, ${\n y ? Math.round(y) : 0\n }px, 0)`;\n },\n },\n Scale: {\n toString(transform: Transform | null) {\n if (!transform) {\n return;\n }\n\n const {scaleX, scaleY} = transform;\n\n return `scaleX(${scaleX}) scaleY(${scaleY})`;\n },\n },\n Transform: {\n toString(transform: Transform | null) {\n if (!transform) {\n return;\n }\n\n return [\n CSS.Translate.toString(transform),\n CSS.Scale.toString(transform),\n ].join(' ');\n },\n },\n Transition: {\n toString({property, duration, easing}: Transition) {\n return `${property} ${duration}ms ${easing}`;\n },\n },\n});\n","const SELECTOR =\n 'a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]';\n\nexport function findFirstFocusableNode(\n element: HTMLElement\n): HTMLElement | null {\n if (element.matches(SELECTOR)) {\n return element;\n }\n\n return element.querySelector(SELECTOR);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucasols/dnd-kit-utilities",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Internal utilities to bee shared between `@dnd-kit` packages",
|
|
5
5
|
"author": "Claudéric Demers",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,30 +9,32 @@
|
|
|
9
9
|
"url": "git+https://github.com/clauderic/dnd-kit.git",
|
|
10
10
|
"directory": "packages/utilities"
|
|
11
11
|
},
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"typings": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
18
22
|
},
|
|
19
|
-
"main": "dist/index.js",
|
|
20
|
-
"module": "dist/dnd-kit-utilities.esm.js",
|
|
21
|
-
"typings": "dist/index.d.ts",
|
|
22
23
|
"files": [
|
|
23
24
|
"README.md",
|
|
24
25
|
"CHANGELOG.md",
|
|
25
26
|
"LICENSE",
|
|
26
27
|
"dist"
|
|
27
28
|
],
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"tslib": "^2.0.0"
|
|
30
|
-
},
|
|
31
29
|
"peerDependencies": {
|
|
32
|
-
"react": "
|
|
30
|
+
"react": "^19.0.0"
|
|
33
31
|
},
|
|
34
32
|
"publishConfig": {
|
|
35
33
|
"access": "public"
|
|
36
34
|
},
|
|
37
|
-
"
|
|
38
|
-
|
|
35
|
+
"scripts": {
|
|
36
|
+
"start": "tsdown --config ../../tsdown.config.mts --watch",
|
|
37
|
+
"build": "tsdown --config ../../tsdown.config.mts",
|
|
38
|
+
"test": "vitest run --config ../../vitest.config.mts"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/dist/adjustment.d.ts
DELETED
package/dist/css.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export declare type Transform = {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
scaleX: number;
|
|
5
|
-
scaleY: number;
|
|
6
|
-
};
|
|
7
|
-
export interface Transition {
|
|
8
|
-
property: string;
|
|
9
|
-
easing: string;
|
|
10
|
-
duration: number;
|
|
11
|
-
}
|
|
12
|
-
export declare const CSS: Readonly<{
|
|
13
|
-
Translate: {
|
|
14
|
-
toString(transform: Transform | null): string | undefined;
|
|
15
|
-
};
|
|
16
|
-
Scale: {
|
|
17
|
-
toString(transform: Transform | null): string | undefined;
|
|
18
|
-
};
|
|
19
|
-
Transform: {
|
|
20
|
-
toString(transform: Transform | null): string | undefined;
|
|
21
|
-
};
|
|
22
|
-
Transition: {
|
|
23
|
-
toString({ property, duration, easing }: Transition): string;
|
|
24
|
-
};
|
|
25
|
-
}>;
|