Skip to content

Additions: add clear button in core + add selected item support #146

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 3 commits into from
Jan 20, 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
2 changes: 1 addition & 1 deletion packages/core/src/hooks/use_item_callbacks.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";

const useItemCallbacks = onSelect => {
const useItemCallbacks = ({ onSelect }) => {
const [currentDepth, setCurrentDepth] = useState(0);
const [parents, setParents] = useState([]);

Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/input/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { jsx } from "@emotion/core";
import React from "react";

export const InputIconRenderer = () => <>🔍</>;
export const ClearIconRenderer = () => <>✘️</>;

const Input = props => {
const {
inputRef,
searchTerm,
onInputChange,
getStyles,
inputIconRenderer: InputIcon = InputIconRenderer
inputIconRenderer: InputIcon = InputIconRenderer,
clearIconRenderer: ClearIcon = ClearIconRenderer
} = props;
return (
<div ref={inputRef} css={getStyles("inputWrapper", props)}>
Expand All @@ -22,6 +24,11 @@ const Input = props => {
value={searchTerm}
onChange={onInputChange}
/>
{searchTerm !== "" && (
<button css={getStyles("clearInput", props)} onClick={onInputChange}>
<ClearIcon />
</button>
)}
</div>
);
};
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/input/inputStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ export const searchIconCss = () => ({
left: "8px"
});

export const clearIconCss = () => ({
position: "absolute",
top: "8px",
right: "8px",
cursor: "pointer"
});

export const wrapperCss = () => ({
position: "relative"
});
7 changes: 5 additions & 2 deletions packages/core/src/item/basic_item.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/** @jsx jsx */
import { jsx } from "@emotion/core";
import React from "react";

const BasicItem = ({ label = "" }) => {
return <span>{label}</span>;
const BasicItem = props => {
const { label = "", getStyles } = props;
return <span css={getStyles("selectedItem", props)}>{label}</span>;
};

export default BasicItem;
14 changes: 11 additions & 3 deletions packages/core/src/item/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ const ItemRenderer = props => {
currentDepth: 0
},
onClick,
forwardIconRenderer: ForwardIcon = ForwardIconRenderer
forwardIconRenderer: ForwardIcon = ForwardIconRenderer,
selectedItem
} = props;

const isItemSelected = item.toString() === selectedItem?.item?.toString();
const searchIndex = item[item.length - 1]
.toLowerCase()
.indexOf(searchTerm.trim().toLowerCase());
Expand All @@ -33,13 +36,18 @@ const ItemRenderer = props => {
searchIndex={searchIndex}
searchTerm={searchTerm.trim()}
getStyles={getStyles}
isSelected={
isItemSelected && item[item.length - 1] === selectedItem.leaf
}
/>
)}
{searchTerm === "" && (
<BasicItem
label={item[currentDepth]}
searchIndex={searchIndex}
searchTerm={searchTerm.trim()}
getStyles={getStyles}
isSelected={
isItemSelected && item[currentDepth] === selectedItem.leaf
}
/>
)}
{hasChild && (
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/item/itemStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ export const css = props => ({
});

export const forwardIconCss = () => ({});

export const selectedItem = props => ({
fontWeight: props.isSelected ? 600 : 400
});
9 changes: 5 additions & 4 deletions packages/core/src/item/searched_item/searchedItemStyle.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
export const initialCss = props => ({
color: "#545769"
color: "#545769",
fontWeight: props.isSelected ? 600 : 400
});

export const highlightCss = props => ({
export const highlightCss = () => ({
fontWeight: 600,
color: "#2020e1"
color: "#268DEC"
});

export const parentsCss = props => ({
export const parentsCss = () => ({
color: "#98A1B8",
marginTop: "2px"
});
9 changes: 8 additions & 1 deletion packages/core/src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import {
wrapperCss as headerWrapperCss,
backIconCss as headerBackIconCss
} from "../header/headerStyle";
import { css as itemCss, forwardIconCss } from "../item/itemStyle";
import {
css as itemCss,
forwardIconCss,
selectedItem as selectedItemCss
} from "../item/itemStyle";
import {
highlightCss,
initialCss as searchItemInitialCss,
Expand All @@ -13,6 +17,7 @@ import itemsCss from "../items/itemsStyle";
import {
css as inputCss,
searchIconCss as inputSearchIconCss,
clearIconCss as clearSearchIconCss,
wrapperCss as inputWrapperCss
} from "../input/inputStyle";
import {
Expand All @@ -35,7 +40,9 @@ export const defaultStyles = {
noResultsText: noResultsTextCss,
input: inputCss,
searchInput: inputSearchIconCss,
clearInput: clearSearchIconCss,
forwardIcon: forwardIconCss,
selectedItem: selectedItemCss,
inputWrapper: inputWrapperCss
};

Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ const Tree = props => {
backIconRenderer,
inputRenderer: Input = InputDefault,
inputIconRenderer,
clearIconRenderer,
noResultsRenderer: NoResults = NoResultsDefault,
noResultsIconRenderer,
itemRenderer: Item = ItemDefault,
itemsRenderer: Items = ItemsRenderer,
forwardIconRenderer,
treeContainerRenderer: TreeContainer = TreeContainerRenderer
treeContainerRenderer: TreeContainer = TreeContainerRenderer,
selectedItem
} = props;

const getStyles = (key, props = {}) => {
Expand All @@ -53,9 +55,9 @@ const Tree = props => {
itemsHeight
} = useContainerHeight();

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

const { searchTerm, onInputChange, leaves } = useLeavesManager({
structure,
Expand Down Expand Up @@ -89,6 +91,7 @@ const Tree = props => {
searchTerm={searchTerm}
onInputChange={onInputChange}
inputIconRenderer={inputIconRenderer}
clearIconRenderer={clearIconRenderer}
/>
<Items styles={styles} getStyles={getStyles} height={itemsHeight}>
{leaves &&
Expand All @@ -100,6 +103,7 @@ const Tree = props => {
item={item}
onClick={onClick}
forwardIconRenderer={forwardIconRenderer}
selectedItem={selectedItem}
/>
))}
</Items>
Expand Down
12 changes: 12 additions & 0 deletions packages/docs/stories/core.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CustomSearchIcon,
customStyles
} from "./custom_renderers";
import { MarkSelectedItemTree } from "./mark_selected_items_tree";

const useStyles = makeStyles({
wrapper: {
Expand Down Expand Up @@ -90,6 +91,10 @@ export const Basic = () => {
styles={customStyles}
/>
</div>
<div className={classes.item}>
<div className={classes.title}>Mark selected item</div>
<MarkSelectedItemTree structure={structure} treeComponent={Tree} />
</div>
<div className={classes.item}>
<div className={classes.title}>Custom Dimensions</div>
<Tree
Expand Down Expand Up @@ -127,6 +132,13 @@ export const MaterialTheme = () => {
inputIconRenderer={CustomSearchIcon}
/>
</div>
<div className={classes.item}>
<div className={classes.title}>Mark selected item</div>
<MarkSelectedItemTree
structure={structure}
treeComponent={MaterialTree}
/>
</div>
<div className={classes.item}>
<div className={classes.title}>Custom Dimensions</div>
<MaterialTree
Expand Down
19 changes: 19 additions & 0 deletions packages/docs/stories/mark_selected_items_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { useState } from "react";

export const MarkSelectedItemTree = ({
structure,
treeComponent: TreeComponent
}) => {
const [selectedItem, setSelectedItem] = useState({ item: [], leaf: "" });
return (
<TreeComponent
structure={structure}
title={"Choose an item"}
onSelect={item => {
setSelectedItem({ item, leaf: item[item.length - 1] });
alert(item);
}}
selectedItem={selectedItem}
/>
);
};
14 changes: 12 additions & 2 deletions packages/material_tree/src/item/basic_item.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import React from "react";
import ListItemText from "@material-ui/core/ListItemText";
import { makeStyles } from "@material-ui/core/styles";

const BasicItem = ({ label = "" }) => {
return <ListItemText primary={label} />;
const useStyles = makeStyles({
selected: {
fontWeight: props => (props.isSelected ? 600 : 400)
}
});

const BasicItem = ({ label = "", isSelected = false }) => {
const classes = useStyles({ isSelected });
return (
<ListItemText primary={<span className={classes.selected}>{label}</span>} />
);
};

export default BasicItem;
15 changes: 14 additions & 1 deletion packages/material_tree/src/item/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ const MaterialItemRenderer = props => {
currentDepth: 0
},
onClick = noop,
selectedItem,
forwardIconRenderer: ForwardIcon = ChevronRight
} = props;

const isItemSelected = item.toString() === selectedItem?.item?.toString();
const searchIndex = item[item.length - 1]
.toLowerCase()
.indexOf(searchTerm.trim().toLowerCase());
Expand All @@ -30,9 +33,19 @@ const MaterialItemRenderer = props => {
item={item}
searchIndex={searchIndex}
searchTerm={searchTerm.trim()}
isSelected={
isItemSelected && item[item.length - 1] === selectedItem.leaf
}
/>
)}
{searchTerm === "" && (
<BasicItem
label={item[currentDepth]}
isSelected={
isItemSelected && item[currentDepth] === selectedItem.leaf
}
/>
)}
{searchTerm === "" && <BasicItem label={item[currentDepth]} />}
{hasChild && <ForwardIcon />}
</ListItem>
);
Expand Down
23 changes: 16 additions & 7 deletions packages/material_tree/src/item/searched_item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,37 @@ import ListItemText from "@material-ui/core/ListItemText";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles(() => ({
const useStyles = makeStyles({
boldText: {
fontWeight: "bold"
fontWeight: 600,
color: "#268DEC"
},
selected: {
fontWeight: props => (props.isSelected ? 600 : 400)
}
}));
});

const SearchedItem = ({ item = [""], searchIndex = 0, searchTerm = "" }) => {
const classes = useStyles();
const SearchedItem = ({
item = [""],
searchIndex = 0,
searchTerm = "",
isSelected = false
}) => {
const classes = useStyles({ isSelected });
const leaf = item[item.length - 1];
const parents = item.slice(0, item.length - 1).join(" / ");

return (
<ListItemText
primary={
<>
<Typography component="span">
<Typography component="span" className={classes.selected}>
{leaf.substring(0, searchIndex)}
</Typography>
<Typography component="span" className={classes.boldText}>
{leaf.substring(searchIndex, searchIndex + searchTerm.length)}
</Typography>
<Typography component="span">
<Typography component="span" className={classes.selected}>
{leaf.substring(searchIndex + searchTerm.length)}
</Typography>
</>
Expand Down
4 changes: 3 additions & 1 deletion packages/material_tree/src/material_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const MaterialTree = ({
itemsRenderer = MaterialItemsRenderer,
noResultsRenderer = MaterialNoResultsRenderer,
noResultsText,
noResultsIconRenderer
noResultsIconRenderer,
selectedItem
}) => {
return (
<Tree
Expand All @@ -47,6 +48,7 @@ const MaterialTree = ({
noResultsRenderer={noResultsRenderer}
noResultsText={noResultsText}
noResultsIconRenderer={noResultsIconRenderer}
selectedItem={selectedItem}
/>
);
};
Expand Down