@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.
Files changed (42) hide show
  1. package/dist/index.d.ts +119 -11
  2. package/dist/index.js +229 -7
  3. package/dist/index.js.map +1 -0
  4. package/package.json +18 -16
  5. package/dist/adjustment.d.ts +0 -2
  6. package/dist/coordinates/getEventCoordinates.d.ts +0 -5
  7. package/dist/coordinates/index.d.ts +0 -2
  8. package/dist/coordinates/types.d.ts +0 -4
  9. package/dist/css.d.ts +0 -25
  10. package/dist/dnd-kit-utilities.cjs.development.js +0 -361
  11. package/dist/dnd-kit-utilities.cjs.development.js.map +0 -1
  12. package/dist/dnd-kit-utilities.cjs.production.min.js +0 -2
  13. package/dist/dnd-kit-utilities.cjs.production.min.js.map +0 -1
  14. package/dist/dnd-kit-utilities.esm.js +0 -333
  15. package/dist/dnd-kit-utilities.esm.js.map +0 -1
  16. package/dist/event/hasViewportRelativeCoordinates.d.ts +0 -1
  17. package/dist/event/index.d.ts +0 -3
  18. package/dist/event/isKeyboardEvent.d.ts +0 -1
  19. package/dist/event/isTouchEvent.d.ts +0 -1
  20. package/dist/execution-context/canUseDOM.d.ts +0 -1
  21. package/dist/execution-context/getOwnerDocument.d.ts +0 -1
  22. package/dist/execution-context/getWindow.d.ts +0 -1
  23. package/dist/execution-context/index.d.ts +0 -3
  24. package/dist/focus/findFirstFocusableNode.d.ts +0 -1
  25. package/dist/focus/index.d.ts +0 -1
  26. package/dist/hooks/index.d.ts +0 -9
  27. package/dist/hooks/useCombinedRefs.d.ts +0 -1
  28. package/dist/hooks/useEvent.d.ts +0 -1
  29. package/dist/hooks/useInterval.d.ts +0 -1
  30. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +0 -6
  31. package/dist/hooks/useLatestValue.d.ts +0 -2
  32. package/dist/hooks/useLazyMemo.d.ts +0 -1
  33. package/dist/hooks/useNodeRef.d.ts +0 -2
  34. package/dist/hooks/usePrevious.d.ts +0 -1
  35. package/dist/hooks/useUniqueId.d.ts +0 -1
  36. package/dist/type-guards/index.d.ts +0 -5
  37. package/dist/type-guards/isDocument.d.ts +0 -1
  38. package/dist/type-guards/isHTMLElement.d.ts +0 -1
  39. package/dist/type-guards/isNode.d.ts +0 -1
  40. package/dist/type-guards/isSVGElement.d.ts +0 -1
  41. package/dist/type-guards/isWindow.d.ts +0 -1
  42. package/dist/types.d.ts +0 -6
package/dist/index.d.ts CHANGED
@@ -1,11 +1,119 @@
1
- export { useCombinedRefs, useEvent, useIsomorphicLayoutEffect, useInterval, useLatestValue, useLazyMemo, useNodeRef, usePrevious, useUniqueId, } from './hooks';
2
- export { add, subtract } from './adjustment';
3
- export type { Coordinates } from './coordinates';
4
- export { getEventCoordinates } from './coordinates';
5
- export { CSS } from './css';
6
- export type { Transform, Transition } from './css';
7
- export { hasViewportRelativeCoordinates, isKeyboardEvent, isTouchEvent, } from './event';
8
- export { canUseDOM, getOwnerDocument, getWindow } from './execution-context';
9
- export { findFirstFocusableNode } from './focus';
10
- export { isDocument, isHTMLElement, isNode, isSVGElement, isWindow, } from './type-guards';
11
- export type { Arguments, DeepRequired, FirstArgument, Without } from './types';
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
- 'use strict'
3
-
4
- if (process.env.NODE_ENV === 'production') {
5
- module.exports = require('./dnd-kit-utilities.cjs.production.min.js')
6
- } else {
7
- module.exports = require('./dnd-kit-utilities.cjs.development.js')
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.1.3",
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
- "scripts": {
13
- "start": "tsdx watch --tsconfig tsconfig.build.json --verbose --noClean",
14
- "build": "tsdx build --tsconfig tsconfig.build.json",
15
- "test": "tsdx test",
16
- "lint": "tsdx lint",
17
- "prepublish": "npm run build"
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": ">=16.8.0"
30
+ "react": "^19.0.0"
33
31
  },
34
32
  "publishConfig": {
35
33
  "access": "public"
36
34
  },
37
- "gitHead": "b8fa0a4b51deb61c010ec4d52879e9c0fa995928"
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
+ }
@@ -1,2 +0,0 @@
1
- export declare const add: <T extends Record<U, number>, U extends string>(object: T, ...adjustments: Partial<T>[]) => T;
2
- export declare const subtract: <T extends Record<U, number>, U extends string>(object: T, ...adjustments: Partial<T>[]) => T;
@@ -1,5 +0,0 @@
1
- import type { Coordinates } from './types';
2
- /**
3
- * Returns the normalized x and y coordinates for mouse and touch events.
4
- */
5
- export declare function getEventCoordinates(event: Event): Coordinates | null;
@@ -1,2 +0,0 @@
1
- export type { Coordinates } from './types';
2
- export { getEventCoordinates } from './getEventCoordinates';
@@ -1,4 +0,0 @@
1
- export declare type Coordinates = {
2
- x: number;
3
- y: number;
4
- };
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
- }>;