Skip to content

Support Material-UI tree #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/core/src/header/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ export const BackIconRenderer = () => <>⬅️</>;

const Header = props => {
const {
headerRef,
parents = [],
onClick,
title = "",
getStyles,
backIconRenderer: BackIcon = BackIconRenderer
} = props;
return (
<div css={getStyles("header", props)}>
<div ref={headerRef} css={getStyles("header", props)}>
{parents.length > 0 && (
<>
<span css={getStyles("headerBackIcon", props)} onClick={onClick}>
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/hooks/use_components_refs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useRef } from "react";

const useComponentsRefs = () => {
const containerRef = useRef();
const headerRef = useRef();
const inputRef = useRef();

const itemsHeight =
(containerRef?.current?.clientHeight || 0) -
(headerRef?.current?.clientHeight || 0) -
(inputRef?.current?.clientHeight || 0);

return { containerRef, headerRef, inputRef, itemsHeight };
};

export default useComponentsRefs;
4 changes: 3 additions & 1 deletion packages/core/src/hooks/use_leaves_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const useLeavesManager = ({ structure, parents, currentDepth }) => {
const [searchTerm, setSearchTerm] = useState("");
const [leaves, setLeaves] = useState([]);

const onInputChange = event => setSearchTerm(event.target.value || "");

useEffect(() => {
const leaves = structure
.filter(
Expand All @@ -22,7 +24,7 @@ const useLeavesManager = ({ structure, parents, currentDepth }) => {
setLeaves(removeDuplicateLeafs(leaves));
}, [searchTerm, parents, currentDepth]);

return { searchTerm, setSearchTerm, leaves };
return { searchTerm, setSearchTerm, onInputChange, leaves };
};

export default useLeavesManager;
7 changes: 4 additions & 3 deletions packages/core/src/input/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ export const InputIconRenderer = () => <>🔍</>;

const Input = props => {
const {
inputRef,
searchTerm,
setSearchTerm,
onInputChange,
getStyles,
inputIconRenderer: InputIcon = InputIconRenderer
} = props;
return (
<div css={getStyles("inputWrapper", props)}>
<div ref={inputRef} css={getStyles("inputWrapper", props)}>
<span css={getStyles("searchInput", props)}>
<InputIcon />
</span>
<input
css={getStyles("input", props)}
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
onChange={onInputChange}
/>
</div>
);
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/items/items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** @jsx jsx */
import { jsx } from "@emotion/core";
import React from "react";

const ItemsRenderer = props => {
const {
getStyles,
children
} = props;
return (
<div css={getStyles("items", props)}>
{children}
</div>
);
};

export default ItemsRenderer;
4 changes: 2 additions & 2 deletions packages/core/src/items/itemsStyle.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default () => ({
maxHeight: "203px",
export default ({ height }) => ({
maxHeight: height,
overflowY: "auto"
});
5 changes: 3 additions & 2 deletions packages/core/src/no_results/noResultsStyle.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export const css = () => ({
export const css = ({ height }) => ({
display: "flex",
flexDirection: "column",
alignItems: "center",
marginTop: "30px"
justifyContent: "center",
height: height
});

export const icon = () => ({
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/styles/styles.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import treeCss from "../treeStyle";
import containerCss from "../tree_container/treeContainerStyle";
import {
wrapperCss as headerWrapperCss,
backIconCss as headerBackIconCss
Expand All @@ -22,7 +22,7 @@ import {
} from "../no_results/noResultsStyle";

export const defaultStyles = {
tree: treeCss,
container: containerCss,
header: headerWrapperCss,
headerBackIcon: headerBackIconCss,
item: itemCss,
Expand Down
56 changes: 40 additions & 16 deletions packages/core/src/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,32 @@ import NoResultsDefault from "./no_results/no_results";

import useLeavesManager from "./hooks/use_leaves_manager";
import useItemCallbacks from "./hooks/use_item_callbacks";
import TreeContainerRenderer from "./tree_container/tree_container";
import ItemsRenderer from "./items/items";
import useContainerHeight from "./hooks/use_components_refs";

const DEFAULT_WIDTH = 230;
const DEFAULT_HEIGHT = 300;
const PIXEL_SUFFIX = "px";

const Tree = props => {
const {
structure = [],
title,
onSelect,
className,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liorheber Here is the removal of className.
Is it ok? Or should I change it back?

width,
height,
noResultsText = "No matching results",
styles,
headerRenderer: Header = HeaderDefault,
backIconRenderer,
inputRenderer: Input = InputDefault,
inputIconRenderer,
noResultsRenderer: NoResults = NoResultsDefault,
noResultsIconRenderer,
itemRenderer: Item = ItemDefault,
forwardIconRenderer
itemsRenderer: Items = ItemsRenderer,
forwardIconRenderer,
treeContainerRenderer: TreeContainer = TreeContainerRenderer
} = props;

const getStyles = (key, props = {}) => {
Expand All @@ -36,19 +45,32 @@ const Tree = props => {
return custom ? custom(base, props) : base;
};

const {
containerRef,
headerRef,
inputRef,
itemsHeight
} = useContainerHeight();

const { onClick, onBackClick, currentDepth, parents } = useItemCallbacks(
onSelect
);

const { searchTerm, setSearchTerm, leaves } = useLeavesManager({
const { searchTerm, onInputChange, leaves } = useLeavesManager({
structure,
parents,
currentDepth
});

return (
<div css={getStyles("tree", props)}>
<TreeContainer
containerRef={containerRef}
getStyles={getStyles}
width={(width || DEFAULT_WIDTH) + PIXEL_SUFFIX}
height={(height || DEFAULT_HEIGHT) + PIXEL_SUFFIX}
>
<Header
headerRef={headerRef}
parents={parents}
title={title}
onClick={onBackClick}
Expand All @@ -58,12 +80,13 @@ const Tree = props => {
{title}
</Header>
<Input
inputRef={inputRef}
getStyles={getStyles}
searchTerm={searchTerm}
setSearchTerm={setSearchTerm}
onInputChange={onInputChange}
inputIconRenderer={inputIconRenderer}
/>
<div css={getStyles("items", props)}>
<Items getStyles={getStyles} height={itemsHeight}>
{leaves &&
leaves.length > 0 &&
leaves.map(item => (
Expand All @@ -75,15 +98,16 @@ const Tree = props => {
forwardIconRenderer={forwardIconRenderer}
/>
))}
{leaves && leaves.length === 0 && (
<NoResults
text={noResultsText}
getStyles={getStyles}
noResultsIconRenderer={noResultsIconRenderer}
/>
)}
</div>
</div>
</Items>
{leaves && leaves.length === 0 && (
<NoResults
height={itemsHeight}
text={noResultsText}
getStyles={getStyles}
noResultsIconRenderer={noResultsIconRenderer}
/>
)}
</TreeContainer>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default () => ({
width: "230px",
height: "280px",
export default ({ width, height }) => ({
width: width,
height: height,
backgroundColor: "#F8F9FA",
boxShadow: "0 6px 10px 0 rgba(27, 32, 70, 0.09)",
border: "1px solid #E1E4EB",
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/tree_container/tree_container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/** @jsx jsx */
import { jsx } from "@emotion/core";
import React from "react";

const TreeContainerRenderer = props => {
const { containerRef, getStyles, children } = props;
return (
<div ref={containerRef} css={getStyles("container", props)}>
{children}
</div>
);
};

export default TreeContainerRenderer;
87 changes: 79 additions & 8 deletions packages/docs/stories/core.stories.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
import React from "react";
import Tree from "@kenshooui/react-tree";
import MaterialTree from "@kenshooui/material-tree";
import makeStyles from "@material-ui/core/styles/makeStyles";

const useStyles = makeStyles({
wrapper: {
padding: 40,
display: "flex",
justifyContent: "start",
alignItems: "start"
},
item: {
display: "flex",
alignItems: "center",
marginRight: 25,
flexDirection: "column"
},
title: {
fontSize: 16,
color: "#747070",
marginBottom: 16,
fontWeight: "bold"
}
});

export default {
title: "Tree",
Expand Down Expand Up @@ -29,14 +52,62 @@ const structure = [
["Keywords", "one level"]
];

export const Basic = () => (
<Tree
structure={structure}
title={"Choose an item"}
onSelect={item => alert(item)}
/>
);
export const Basic = () => {
const classes = useStyles();
return (
<div className={classes.wrapper}>
<div className={classes.item}>
<div className={classes.title}>Default Dimensions</div>
<Tree
structure={structure}
title={"Choose an item"}
onSelect={item => alert(item)}
/>
</div>
<div className={classes.item}>
<div className={classes.title}>Custom Dimensions</div>
<Tree
structure={structure}
title={"Choose an item"}
onSelect={item => alert(item)}
width={200}
height={200}
/>
</div>
</div>
);
};

export const MaterialTheme = () => {
const classes = useStyles();
return (
<div className={classes.wrapper}>
<div className={classes.item}>
<div className={classes.title}>Default Dimensions</div>
<MaterialTree
structure={structure}
title={"Choose an item"}
onSelect={item => alert(item)}
/>
</div>
<div className={classes.item}>
<div className={classes.title}>Custom Dimensions</div>
<MaterialTree
structure={structure}
title={"Choose an item"}
onSelect={item => alert(item)}
width={250}
height={350}
/>
</div>
</div>
);
};

Basic.story = {
name: "basic configuration"
name: "Basic configuration"
};

MaterialTheme.story = {
name: "Material Theme"
};
22 changes: 22 additions & 0 deletions packages/material_ui_tree/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@kenshooui/material-tree",
"version": "1.0.0",
"main": "dist/material-tree.cjs.js",
"module": "dist/material-tree.esm.js",
"scripts": {},
"repository": "https://github.com/kenshoo/react-tree.git",
"author": "ui@kenshoo.com",
"license": "MIT",
"peerDependencies": {
"@kenshooui/react-tree": "^1.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add this to dev as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liorheber please publish react-tree

"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"react": "^16.12.0"
},
"devDependencies": {
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"react": "^16.12.0"
},
"dependencies": {}
}
Loading