Skip to content

Commit

Permalink
Allow for custom renderers
Browse files Browse the repository at this point in the history
  • Loading branch information
jameskerr committed Apr 17, 2024
1 parent b0ec88d commit 61318f6
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 27 deletions.
6 changes: 3 additions & 3 deletions modules/react-arborist/src/components/default-cursor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { CSSProperties } from "react";
import { CursorProps } from "../types/renderers.js";
import { CursorRendererProps } from "../types/renderers.js";

const placeholderStyle = {
display: "flex",
Expand All @@ -21,11 +21,11 @@ const circleStyle = {
borderRadius: "50%",
};

export const DefaultCursor = React.memo(function DefaultCursor({
export const DefaultCursorRenderer = React.memo(function DefaultCursorRenderer({
top,
left,
indent,
}: CursorProps) {
}: CursorRendererProps) {
const style: CSSProperties = {
position: "absolute",
pointerEvents: "none",
Expand Down
36 changes: 16 additions & 20 deletions modules/react-arborist/src/components/tree-view.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import React, {
HTMLAttributes,
ReactElement,
forwardRef,
useContext,
useRef,
} from "react";
import React, { forwardRef, useContext, useRef } from "react";
import { TreeController } from "../controllers/tree-controller.js";
import { TreeViewProps } from "../types/tree-view-props.js";
import { FixedSizeList } from "react-window";
import { NodeController } from "../controllers/node-controller.js";
import { createRowAttributes } from "../row/attributes.js";
import { DefaultCursor } from "./default-cursor.js";
import { DefaultCursorRenderer } from "./default-cursor.js";
import { useCursorProps } from "../cursor/use-cursor-props.js";
import { useCursorContainerStyle } from "../cursor/use-cursor-container-style.js";
import { useListInnerStyle } from "../list/use-list-inner-style.js";
Expand All @@ -20,6 +14,7 @@ import { useDefaultProps } from "../props/use-default-props.js";
import { useRowFocus } from "../focus/use-row-focus.js";
import { createTreeViewAttributes } from "../tree-view/attributes.js";
import { useTreeDrop } from "../dnd/use-tree-drop.js";
import { NodeRendererProps, RowRendererProps } from "../types/renderers.js";

export function TreeView<T>(props: Partial<TreeViewProps<T>>) {
const filledProps = useDefaultProps(props);
Expand Down Expand Up @@ -115,7 +110,7 @@ function CursorContainer() {
if (!props) return null;
return (
<div style={style}>
<DefaultCursor {...props} />
<DefaultCursorRenderer {...props} />
</div>
);
}
Expand All @@ -126,6 +121,7 @@ function RowContainer<T>(props: { style: React.CSSProperties; index: number }) {
const attrs = createRowAttributes(tree, node, props.style);
const ref = useRef<any>();
const dropProps = useNodeDrop(node, ref);
const RowRenderer = tree.props.renderRow;
useRowFocus(node, ref);

return (
Expand All @@ -135,12 +131,7 @@ function RowContainer<T>(props: { style: React.CSSProperties; index: number }) {
);
}

export function RowRenderer<T>(props: {
node: NodeController<T>;
attrs: HTMLAttributes<any>;
children: ReactElement;
innerRef: any;
}) {
export function DefaultRowRenderer<T>(props: RowRendererProps<T>) {
return (
<div
{...props.attrs}
Expand All @@ -157,14 +148,19 @@ function NodeContainer<T>(props: { node: NodeController<T> }) {
const indent = node.tree.indent * node.level;
const style = { paddingInlineStart: indent + 10 };
const dragProps = useNodeDrag(node);
const NodeRenderer = node.tree.props.renderNode;

return <NodeRenderer attrs={{ style, ...dragProps }} node={node} />;
return (
<NodeRenderer
attrs={{ style, ...dragProps }}
node={node}
style={style}
tree={node.tree}
/>
);
}

function NodeRenderer<T>(props: {
attrs: HTMLAttributes<any>;
node: NodeController<T>;
}) {
export function DefaultNodeRenderer<T>(props: NodeRendererProps<T>) {
const { node, attrs } = props;

function onSubmit(e: any) {
Expand Down
10 changes: 10 additions & 0 deletions modules/react-arborist/src/props/use-default-props.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import * as defaultCommands from "../commands/default-commands.js";
import { DefaultCursorRenderer } from "../components/default-cursor.js";
import {
DefaultNodeRenderer,
DefaultRowRenderer,
} from "../components/tree-view.js";
import { useCursor } from "../cursor/use-cursor.js";
import { useDnd } from "../dnd/use-dnd.js";
import { useEdit } from "../edit/use-edit.js";
Expand Down Expand Up @@ -39,6 +44,11 @@ export function useDefaultProps<T>(
overscanCount: props.overscanCount ?? 1,
direction: "ltr",

/* Renderers */
renderRow: props.renderRow ?? DefaultRowRenderer,
renderNode: props.renderNode ?? DefaultNodeRenderer,
renderCursor: props.renderCursor ?? DefaultCursorRenderer,

/* Callbacks */
onScroll: props.onScroll ?? (() => {}),

Expand Down
12 changes: 9 additions & 3 deletions modules/react-arborist/src/types/renderers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { CSSProperties, HTMLAttributes, ReactElement } from "react";
import {
CSSProperties,
HTMLAttributes,
MutableRefObject,
ReactElement,
} from "react";
import { TreeController } from "../controllers/tree-controller.js";
import { NodeController } from "../controllers/node-controller.js";
import { XY } from "../dnd/types.js";

export type NodeRendererProps<T> = {
attrs: HTMLAttributes<any>;
style: CSSProperties;
node: NodeController<T>;
tree: TreeController<T>;
Expand All @@ -13,7 +19,7 @@ export type NodeRendererProps<T> = {

export type RowRendererProps<T> = {
node: NodeController<T>;
innerRef: (el: HTMLDivElement | null) => void;
innerRef: MutableRefObject<any>;
attrs: HTMLAttributes<any>;
children: ReactElement;
};
Expand All @@ -26,7 +32,7 @@ export type DragPreviewProps = {
isDragging: boolean;
};

export type CursorProps = {
export type CursorRendererProps = {
top: number;
left: number;
indent: number;
Expand Down
2 changes: 1 addition & 1 deletion modules/react-arborist/src/types/tree-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface TreeProps<T> {
children?: ElementType<renderers.NodeRendererProps<T>>;
renderRow?: ElementType<renderers.RowRendererProps<T>>;
renderDragPreview?: ElementType<renderers.DragPreviewProps>;
renderCursor?: ElementType<renderers.CursorProps>;
renderCursor?: ElementType<renderers.CursorRendererProps>;
renderContainer?: ElementType<{}>;

/* Sizes */
Expand Down
9 changes: 9 additions & 0 deletions modules/react-arborist/src/types/tree-view-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import { VisiblePartialController } from "../visible/types.js";
import { ShortcutAttrs } from "../shortcuts/types.js";
import { CommandObject } from "../commands/types.js";
import { ListOnScrollProps } from "react-window";
import {
CursorRendererProps,
NodeRendererProps,
RowRendererProps,
} from "./renderers.js";

export type TreeViewProps<T> = {
/* Partial Controllers */
Expand Down Expand Up @@ -46,4 +51,8 @@ export type TreeViewProps<T> = {
/* Configurations */
openByDefault: boolean;
disableDrop?: string | boolean | DisableDropCheck<T>;

renderRow: (props: RowRendererProps<T>) => any;
renderNode: (props: NodeRendererProps<T>) => any;
renderCursor: (props: CursorRendererProps) => any;
};

0 comments on commit 61318f6

Please sign in to comment.