diff --git a/README.md b/README.md
index 00f9bc8..5eaaf12 100755
--- a/README.md
+++ b/README.md
@@ -251,15 +251,16 @@ paired with the [`useVirtualize()`](#usevirtualize) hook.
---
-### useNodeProps()
+### useNode()
-A hook that creates and memoizes node-specific props from a set of input props.
+A plugin that creates and memoizes node-specific props.
#### Arguments
-| Name | Type | Required? | Description |
-| ------ | -------------------------- | --------- | -------------------------------------------- |
-| config | [`NodeProps`](#node-props) | Yes | Options to generate node-specific props from |
+| Name | Type | Required? | Description |
+| -------- | ----------------------------------------------------- | --------- | -------------------------------------------- |
+| fileTree | `FileTree` | Yes | A file tree |
+| config | `Pick, "node" \| "index" \| "style">` | Yes | Options to generate node-specific props from |
---
diff --git a/src/index.ts b/src/index.ts
index 160f8f5..8096f6f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -15,8 +15,8 @@ export type {
FileTreeFactory,
GetNodes,
} from "./file-tree";
-export { Node } from "./node";
-export type { NodeProps } from "./node";
+export { Node, useNode } from "./node";
+export type { NodeProps, UseNodeConfig } from "./node";
export { SubjectMap, SubjectSet } from "./observable-data";
export * as pathFx from "./path-fx";
export { subject } from "./tree/subject";
diff --git a/src/node.tsx b/src/node.tsx
index 814d11b..8df2d37 100644
--- a/src/node.tsx
+++ b/src/node.tsx
@@ -13,33 +13,29 @@ import { retryWithBackoff } from "./utils";
* @param props - Node props
*/
export function Node(props: NodeProps) {
- const nodeProps = useNodeProps(props);
-
const elementProps = useNodePlugins(props.node.id, [
...(props.plugins ?? empty),
- {
- didChange: noopSubject,
- getProps() {
- return nodeProps;
- },
- },
+ useNode(props.tree, props),
]);
return React.createElement(props.as ?? "div", elementProps, props.children);
}
/**
- * A hook that creates and memoizes node-specific props from a set of input props.
+ * A plugin that creates and memoizes node-specific props.
*
+ * @param fileTree - A file tree
* @param config - Props to generate exploration node-specific props from
*/
-export function useNodeProps(config: Omit, "as">) {
- const { node, tree, index, style } = config;
+export function useNode(
+ fileTree: FileTree,
+ config: UseNodeConfig
+) {
+ const { node, index, style } = config;
const type = isDir(node) ? "dir" : isFile(node) ? "file" : "prompt";
const expanded = isDir(node) ? node.expanded : undefined;
const { id, depth } = node;
-
- return React.useMemo>(() => {
+ const props = React.useMemo>(() => {
return {
role: "button",
style,
@@ -63,18 +59,25 @@ export function useNodeProps(config: Omit, "as">) {
if (isDir(node)) {
if (expanded) {
- tree.collapse(node);
+ fileTree.collapse(node);
} else {
- retryWithBackoff(() => tree.expand(node), {
+ retryWithBackoff(() => fileTree.expand(node), {
shouldRetry() {
- return node.expanded && !tree.isExpanded(node);
+ return node.expanded && !fileTree.isExpanded(node);
},
}).catch(() => {});
}
}
},
};
- }, [index, depth, expanded, style, type, node, tree, id]);
+ }, [index, depth, expanded, style, type, node, fileTree, id]);
+
+ return {
+ didChange: noopSubject,
+ getProps() {
+ return props;
+ },
+ };
}
const empty: [] = [];
@@ -112,3 +115,8 @@ export interface NodeProps {
*/
children: React.ReactNode;
}
+
+export type UseNodeConfig = Pick<
+ NodeProps,
+ "node" | "index" | "style"
+>;
diff --git a/src/use-virtualize.ts b/src/use-virtualize.ts
index 2ff2fed..941872b 100644
--- a/src/use-virtualize.ts
+++ b/src/use-virtualize.ts
@@ -163,12 +163,12 @@ const createStyle = trieMemoize(
[Map, Map],
(height: number, top: number): React.CSSProperties => ({
position: "absolute",
- width: "100%",
- height,
contain: "strict",
userSelect: "none",
- top,
+ width: "100%",
left: 0,
+ height,
+ top,
})
);