@altano/use-element-observer 3.0.0 → 4.0.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 CHANGED
@@ -1,44 +1,53 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
 
3
+ //#region src/types.d.ts
3
4
  type ReactElementWithRef = React.ReactElement<{
4
- ref: React.Ref<Element>;
5
+ ref: React.Ref<Element>;
5
6
  }>;
6
7
 
8
+ //#endregion
9
+ //#region src/useElementObserver.d.ts
7
10
  interface Context {
8
- mountedElements: Set<Element>;
11
+ mountedElements: Set<Element>;
9
12
  }
10
13
  declare const ElementObserverContext: React.Context<Context | null>;
11
14
  type Options = ChildOptions & {
12
- selector: string;
15
+ selector: string;
13
16
  };
14
17
  type ChildOptions = {
15
- useWrapperDiv: false;
16
- tree: ReactElementWithRef;
18
+ useWrapperDiv: false;
19
+ tree: ReactElementWithRef;
17
20
  } | {
18
- useWrapperDiv: true;
19
- tree: React.ReactNode;
21
+ useWrapperDiv: true;
22
+ tree: React.ReactNode;
20
23
  } | {
21
- useWrapperDiv?: undefined;
22
- tree: React.ReactNode;
24
+ useWrapperDiv?: undefined;
25
+ tree: React.ReactNode;
23
26
  };
24
27
  /**
25
- * Allows observing mount/unmount of elements that match a given selector in the
26
- * given React tree. Tree must be static: only the mounting of the tree itself
27
- * is monitored. If the tree's DOM is dynamically changed those mounts and
28
- * unmounts will not be detected.
29
- *
30
- * @param tree The React tree to observe.
31
- * @param onMount The callback that will be passed any elements in the tree that
32
- * match the given selector, as they mount.
33
- * @param onUnmount The callback that will be passed any elements in the tree
34
- * that match the given selector, as they unmount.
35
- * @param selector The css selector used to select which elements are observed.
36
- * @param useWrapperDiv If `true`, a 'div' will wrap the observed children. If
37
- * `false`, `children` must be a single child element that can take a ref (which
38
- * will be overwritten).
39
- * @returns A tuple of: (1) set of elements and (2) the observed tree to be
40
- * rendered.
41
- */
42
- declare function useElementObserver({ tree, selector, useWrapperDiv, }: Options): [Set<Element>, React.ReactElement];
28
+ * Allows observing mount/unmount of elements that match a given selector in the
29
+ * given React tree. Tree must be static: only the mounting of the tree itself
30
+ * is monitored. If the tree's DOM is dynamically changed those mounts and
31
+ * unmounts will not be detected.
32
+ *
33
+ * @param tree The React tree to observe.
34
+ * @param onMount The callback that will be passed any elements in the tree that
35
+ * match the given selector, as they mount.
36
+ * @param onUnmount The callback that will be passed any elements in the tree
37
+ * that match the given selector, as they unmount.
38
+ * @param selector The css selector used to select which elements are observed.
39
+ * @param useWrapperDiv If `true`, a 'div' will wrap the observed children. If
40
+ * `false`, `children` must be a single child element that can take a ref (which
41
+ * will be overwritten).
42
+ * @returns A tuple of: (1) set of elements and (2) the observed tree to be
43
+ * rendered.
44
+ */
45
+ declare function useElementObserver({
46
+ tree,
47
+ selector,
48
+ useWrapperDiv
49
+ }: Options): [Set<Element>, React.ReactElement];
43
50
 
44
- export { type ChildOptions, ElementObserverContext, type Options, type ReactElementWithRef, useElementObserver };
51
+ //#endregion
52
+ export { ChildOptions, ElementObserverContext, Options, ReactElementWithRef, useElementObserver };
53
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,85 +1,100 @@
1
- // src/useElementObserver.tsx
2
- import React3 from "react";
1
+ import React, { useCallback, useContext, useEffect, useRef } from "react";
3
2
  import { useSet } from "@uidotdev/usehooks";
3
+ import { jsx } from "react/jsx-runtime";
4
4
 
5
- // src/Observer.tsx
6
- import React2, { useCallback, useContext } from "react";
7
-
8
- // src/useMountRef.tsx
9
- import { useEffect, useRef } from "react";
10
- function useMountRef({
11
- onMount,
12
- onUnmount
13
- }) {
14
- const newRef = useRef(null);
15
- useEffect(() => {
16
- const ref = newRef.current;
17
- if (ref == null) {
18
- return () => {
19
- };
20
- }
21
- onMount(ref);
22
- return () => onUnmount(ref);
23
- }, [newRef, onMount, onUnmount]);
24
- return newRef;
5
+ //#region src/useMountRef.tsx
6
+ function useMountRef({ onMount, onUnmount }) {
7
+ const newRef = useRef(null);
8
+ useEffect(() => {
9
+ const ref = newRef.current;
10
+ if (ref == null) return () => {};
11
+ onMount(ref);
12
+ return () => onUnmount(ref);
13
+ }, [
14
+ newRef,
15
+ onMount,
16
+ onUnmount
17
+ ]);
18
+ return newRef;
25
19
  }
26
20
 
27
- // src/Observer.tsx
28
- import { jsx } from "react/jsx-runtime";
29
- function ObserveChildWithWrapperDiv({
30
- children,
31
- onMount,
32
- onUnmount
33
- }) {
34
- const ref = useMountRef({ onMount, onUnmount });
35
- return /* @__PURE__ */ jsx("div", { style: { display: "inherit" }, ref, children });
21
+ //#endregion
22
+ //#region src/Observer.tsx
23
+ function ObserveChildWithWrapperDiv({ children, onMount, onUnmount }) {
24
+ const ref = useMountRef({
25
+ onMount,
26
+ onUnmount
27
+ });
28
+ return /* @__PURE__ */ jsx("div", {
29
+ style: { display: "inherit" },
30
+ ref,
31
+ children
32
+ });
36
33
  }
37
- function ObserveChild({
38
- children,
39
- onMount,
40
- onUnmount
41
- }) {
42
- const newRef = useMountRef({ onMount, onUnmount });
43
- return React2.cloneElement(children, { ref: newRef });
34
+ function ObserveChild({ children, onMount, onUnmount }) {
35
+ const newRef = useMountRef({
36
+ onMount,
37
+ onUnmount
38
+ });
39
+ return React.cloneElement(children, { ref: newRef });
44
40
  }
45
- function Observer({
46
- children,
47
- selector,
48
- useWrapperDiv
49
- }) {
50
- const context = useContext(ElementObserverContext);
51
- if (context == null) {
52
- throw new Error("Observer context was null");
53
- }
54
- const { mountedElements } = context;
55
- const onMount = useCallback(
56
- (ref) => {
57
- Array.from(ref.querySelectorAll(selector)).forEach(
58
- (e) => mountedElements.add(e)
59
- );
60
- },
61
- [selector, mountedElements]
62
- );
63
- const onUnmount = useCallback(
64
- () => mountedElements.clear(),
65
- [mountedElements]
66
- );
67
- return useWrapperDiv ? /* @__PURE__ */ jsx(ObserveChildWithWrapperDiv, { onMount, onUnmount, children }) : /* @__PURE__ */ jsx(ObserveChild, { onMount, onUnmount, children });
41
+ function Observer({ children, selector, useWrapperDiv }) {
42
+ const context = useContext(ElementObserverContext);
43
+ if (context == null) throw new Error("Observer context was null");
44
+ const { mountedElements } = context;
45
+ const onMount = useCallback((ref) => {
46
+ Array.from(ref.querySelectorAll(selector)).forEach((e) => mountedElements.add(e));
47
+ }, [selector, mountedElements]);
48
+ const onUnmount = useCallback(() => mountedElements.clear(), [mountedElements]);
49
+ return useWrapperDiv ? /* @__PURE__ */ jsx(ObserveChildWithWrapperDiv, {
50
+ onMount,
51
+ onUnmount,
52
+ children
53
+ }) : /* @__PURE__ */ jsx(ObserveChild, {
54
+ onMount,
55
+ onUnmount,
56
+ children
57
+ });
68
58
  }
69
59
 
70
- // src/useElementObserver.tsx
71
- import { jsx as jsx2 } from "react/jsx-runtime";
72
- var ElementObserverContext = React3.createContext(null);
73
- function useElementObserver({
74
- tree,
75
- selector,
76
- useWrapperDiv
77
- }) {
78
- const mountedElements = useSet();
79
- const observedTree = /* @__PURE__ */ jsx2(ElementObserverContext.Provider, { value: { mountedElements }, children: useWrapperDiv == null || useWrapperDiv === true ? /* @__PURE__ */ jsx2(Observer, { selector, useWrapperDiv: true, children: tree }) : /* @__PURE__ */ jsx2(Observer, { selector, useWrapperDiv: false, children: tree }) });
80
- return [mountedElements, observedTree];
60
+ //#endregion
61
+ //#region src/useElementObserver.tsx
62
+ const ElementObserverContext = React.createContext(null);
63
+ /**
64
+ * Allows observing mount/unmount of elements that match a given selector in the
65
+ * given React tree. Tree must be static: only the mounting of the tree itself
66
+ * is monitored. If the tree's DOM is dynamically changed those mounts and
67
+ * unmounts will not be detected.
68
+ *
69
+ * @param tree The React tree to observe.
70
+ * @param onMount The callback that will be passed any elements in the tree that
71
+ * match the given selector, as they mount.
72
+ * @param onUnmount The callback that will be passed any elements in the tree
73
+ * that match the given selector, as they unmount.
74
+ * @param selector The css selector used to select which elements are observed.
75
+ * @param useWrapperDiv If `true`, a 'div' will wrap the observed children. If
76
+ * `false`, `children` must be a single child element that can take a ref (which
77
+ * will be overwritten).
78
+ * @returns A tuple of: (1) set of elements and (2) the observed tree to be
79
+ * rendered.
80
+ */
81
+ function useElementObserver({ tree, selector, useWrapperDiv }) {
82
+ const mountedElements = useSet();
83
+ const observedTree = /* @__PURE__ */ jsx(ElementObserverContext.Provider, {
84
+ value: { mountedElements },
85
+ children: useWrapperDiv == null || useWrapperDiv === true ? /* @__PURE__ */ jsx(Observer, {
86
+ selector,
87
+ useWrapperDiv: true,
88
+ children: tree
89
+ }) : /* @__PURE__ */ jsx(Observer, {
90
+ selector,
91
+ useWrapperDiv: false,
92
+ children: tree
93
+ })
94
+ });
95
+ return [mountedElements, observedTree];
81
96
  }
82
- export {
83
- ElementObserverContext,
84
- useElementObserver
85
- };
97
+
98
+ //#endregion
99
+ export { ElementObserverContext, useElementObserver };
100
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@altano/use-element-observer",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "Intersection-Observer-based Scroll Spy React Hook",
5
5
  "homepage": "https://github.com/altano/npm-packages/tree/main/packages/use-element-observer",
6
6
  "repository": {
@@ -30,18 +30,19 @@
30
30
  "@testing-library/react": "^16.2.0",
31
31
  "@types/react": "^19.0.12",
32
32
  "@types/react-dom": "^19.0.4",
33
- "@vitest/coverage-v8": "^3.1.1",
33
+ "@vitest/coverage-v8": "^3.1.4",
34
34
  "depcheck": "^1.4.7",
35
35
  "eslint": "^9.23.0",
36
36
  "jsdom": "^26.0.0",
37
37
  "prettier": "^3.5.3",
38
38
  "react": "^19.1.0",
39
+ "tsdown": "^0.12.3",
39
40
  "typescript": "^5.8.2",
40
- "vite": "^6.2.4",
41
- "vitest": "^3.1.1",
42
- "@altano/build-config": "0.0.0",
43
- "@altano/tsconfig": "0.0.0",
44
- "@altano/testing": "0.0.0"
41
+ "vite": "^6.2.6",
42
+ "vitest": "^3.1.4",
43
+ "@altano/build-config": "0.0.1",
44
+ "@altano/testing": "0.0.1",
45
+ "@altano/tsconfig": "0.0.1"
45
46
  },
46
47
  "peerDependencies": {
47
48
  "react": "19.x.x"
@@ -50,8 +51,8 @@
50
51
  "access": "public"
51
52
  },
52
53
  "scripts": {
53
- "build": "tsup --config build-config/tsup.config.browser.ts",
54
- "check:exports": "attw --pack . --ignore-rules=cjs-resolves-to-esm",
54
+ "build": "tsdown --config ../build-config/tsdown.config.browser.ts",
55
+ "check:exports": "attw --pack . --profile esm-only --quiet",
55
56
  "check:types:src": "tsc --noEmit",
56
57
  "check:types:test": "tsc --noEmit --project ./tests/tsconfig.json",
57
58
  "check:unused-dependencies": "depcheck",