@headless-tree/react 0.0.0-20250915162508 → 0.0.0-20250918201417

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/CHANGELOG.md CHANGED
@@ -1,19 +1,25 @@
1
1
  # @headless-tree/react
2
2
 
3
- ## 0.0.0-20250915162508
3
+ ## 0.0.0-20250918201417
4
+
5
+ ### Minor Changes
6
+
7
+ - cbeaba6: all state updates (like setSelectedItems) will not propagate while the component is unmounted. This happened before for `tree.setState()` calls directly, but not individual state atoms like `setSelectedItems`. When calling `createTree()` directly (instead of `useTree()`), `tree.setMounted(true)` needs to be called once after mount. No changes are necessary when using the React-based `useTree()` integration. (#158)
4
8
 
5
9
  ### Patch Changes
6
10
 
7
11
  - 72e714b: all NPM deployments will now publish with provenance
8
12
  - 7a7424f: fixed incorrect exports definition in package.json for require/cjs imports (#161)
9
13
  - Updated dependencies [72e714b]
14
+ - Updated dependencies [6693986]
10
15
  - Updated dependencies [7a7424f]
16
+ - Updated dependencies [cbeaba6]
11
17
  - Updated dependencies [215ab4b]
12
18
  - Updated dependencies [51b0dea]
13
19
  - Updated dependencies [cf845d7]
14
20
  - Updated dependencies [597faad]
15
21
  - Updated dependencies [b0ee382]
16
- - @headless-tree/core@0.0.0-20250915162508
22
+ - @headless-tree/core@0.0.0-20250918201417
17
23
 
18
24
  ## 1.4.0
19
25
 
package/dist/index.js CHANGED
@@ -123,39 +123,24 @@ var AssistiveTreeDescription = (_a) => {
123
123
  // src/use-tree.tsx
124
124
  var import_react2 = require("react");
125
125
  var import_core2 = require("@headless-tree/core");
126
- var useApplyAfterMount = () => {
127
- const isMounted = (0, import_react2.useRef)(false);
128
- const callbacks = (0, import_react2.useRef)([]);
129
- (0, import_react2.useEffect)(() => {
130
- isMounted.current = true;
131
- callbacks.current.forEach((callback) => callback());
132
- }, []);
133
- const apply = (callback) => {
134
- if (isMounted.current) {
135
- callback();
136
- } else {
137
- callbacks.current.push(callback);
138
- }
139
- };
140
- return apply;
141
- };
142
126
  var useTree = (config) => {
143
- const apply = useApplyAfterMount();
144
127
  const [tree] = (0, import_react2.useState)(() => ({ current: (0, import_core2.createTree)(config) }));
145
128
  const [state, setState] = (0, import_react2.useState)(
146
129
  () => tree.current.getState()
147
130
  );
148
131
  (0, import_react2.useEffect)(() => {
132
+ tree.current.setMounted(true);
149
133
  tree.current.rebuildTree();
134
+ return () => {
135
+ tree.current.setMounted(false);
136
+ };
150
137
  }, [tree]);
151
138
  tree.current.setConfig((prev) => __spreadProps(__spreadValues(__spreadValues({}, prev), config), {
152
139
  state: __spreadValues(__spreadValues({}, state), config.state),
153
140
  setState: (state2) => {
154
- apply(() => {
155
- var _a;
156
- setState(state2);
157
- (_a = config.setState) == null ? void 0 : _a.call(config, state2);
158
- });
141
+ var _a;
142
+ setState(state2);
143
+ (_a = config.setState) == null ? void 0 : _a.call(config, state2);
159
144
  }
160
145
  }));
161
146
  return tree.current;
package/dist/index.mjs CHANGED
@@ -63,41 +63,26 @@ var AssistiveTreeDescription = (_a) => {
63
63
  };
64
64
 
65
65
  // src/use-tree.tsx
66
- import { useEffect, useRef, useState } from "react";
66
+ import { useEffect, useState } from "react";
67
67
  import { createTree } from "@headless-tree/core";
68
- var useApplyAfterMount = () => {
69
- const isMounted = useRef(false);
70
- const callbacks = useRef([]);
71
- useEffect(() => {
72
- isMounted.current = true;
73
- callbacks.current.forEach((callback) => callback());
74
- }, []);
75
- const apply = (callback) => {
76
- if (isMounted.current) {
77
- callback();
78
- } else {
79
- callbacks.current.push(callback);
80
- }
81
- };
82
- return apply;
83
- };
84
68
  var useTree = (config) => {
85
- const apply = useApplyAfterMount();
86
69
  const [tree] = useState(() => ({ current: createTree(config) }));
87
70
  const [state, setState] = useState(
88
71
  () => tree.current.getState()
89
72
  );
90
73
  useEffect(() => {
74
+ tree.current.setMounted(true);
91
75
  tree.current.rebuildTree();
76
+ return () => {
77
+ tree.current.setMounted(false);
78
+ };
92
79
  }, [tree]);
93
80
  tree.current.setConfig((prev) => __spreadProps(__spreadValues(__spreadValues({}, prev), config), {
94
81
  state: __spreadValues(__spreadValues({}, state), config.state),
95
82
  setState: (state2) => {
96
- apply(() => {
97
- var _a;
98
- setState(state2);
99
- (_a = config.setState) == null ? void 0 : _a.call(config, state2);
100
- });
83
+ var _a;
84
+ setState(state2);
85
+ (_a = config.setState) == null ? void 0 : _a.call(config, state2);
101
86
  }
102
87
  }));
103
88
  return tree.current;
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "checkbox",
14
14
  "hook"
15
15
  ],
16
- "version": "0.0.0-20250915162508",
16
+ "version": "0.0.0-20250918201417",
17
17
  "main": "dist/index.d.ts",
18
18
  "module": "dist/index.mjs",
19
19
  "types": "dist/index.d.mts",
@@ -68,7 +68,7 @@
68
68
  "typescript": "^5.7.2"
69
69
  },
70
70
  "peerDependencies": {
71
- "@headless-tree/core": "0.0.0-20250915162508",
71
+ "@headless-tree/core": "0.0.0-20250918201417",
72
72
  "react": "*",
73
73
  "react-dom": "*"
74
74
  }
package/src/use-tree.tsx CHANGED
@@ -1,42 +1,20 @@
1
- import { useEffect, useRef, useState } from "react";
1
+ import { useEffect, useState } from "react";
2
2
  import { TreeConfig, TreeState, createTree } from "@headless-tree/core";
3
3
 
4
- /* A bug with NextJS was reported in the past where very quick state updates (i.e. data
5
- * loader returning withing milliseconds) will cause the state update to occur before
6
- * mount, resulting in a console warning. This alleviates this.
7
- * We should monitor if this remains a problem in the future, maybe we can eventually
8
- * remove this workaround...
9
- */
10
- const useApplyAfterMount = () => {
11
- const isMounted = useRef(false);
12
- const callbacks = useRef<(() => void)[]>([]);
13
-
14
- useEffect(() => {
15
- isMounted.current = true;
16
- callbacks.current.forEach((callback) => callback());
17
- }, []);
18
-
19
- const apply = (callback: () => void) => {
20
- if (isMounted.current) {
21
- callback();
22
- } else {
23
- callbacks.current.push(callback);
24
- }
25
- };
26
-
27
- return apply;
28
- };
29
-
30
4
  export const useTree = <T,>(config: TreeConfig<T>) => {
31
- const apply = useApplyAfterMount();
32
5
  const [tree] = useState(() => ({ current: createTree(config) }));
33
6
  const [state, setState] = useState<Partial<TreeState<T>>>(() =>
34
7
  tree.current.getState(),
35
8
  );
36
9
 
37
10
  useEffect(() => {
11
+ (tree.current as any).setMounted(true);
38
12
  tree.current.rebuildTree();
39
- }, [tree]); // runs only once after mount
13
+ return () => {
14
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15
+ (tree.current as any).setMounted(false);
16
+ };
17
+ }, [tree]);
40
18
 
41
19
  tree.current.setConfig((prev) => ({
42
20
  ...prev,
@@ -46,10 +24,8 @@ export const useTree = <T,>(config: TreeConfig<T>) => {
46
24
  ...config.state,
47
25
  },
48
26
  setState: (state) => {
49
- apply(() => {
50
- setState(state);
51
- config.setState?.(state);
52
- });
27
+ setState(state);
28
+ config.setState?.(state);
53
29
  },
54
30
  }));
55
31