Skip to content

Instantly share code, notes, and snippets.

@floyd0987
Created April 22, 2018 16:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save floyd0987/a28ae322dd63732f9c58f399ed93ff8f to your computer and use it in GitHub Desktop.
Save floyd0987/a28ae322dd63732f9c58f399ed93ff8f to your computer and use it in GitHub Desktop.
react filter by category
<div id="root"></div>
// COMPONENTS
// ----------
// Main
// UI
// ButtonCategory
// ProductItems
// ProductItem
// Components in reverse order of above
const ProductItem = ({ category, name }) => (
<div className="category__list-item box flex-spread">
{name}
<div className={`category--${category} circle`} />
</div>
);
const ProductItems = ({ state: { products, displayCategory } }) => (
<div>
{products
.filter(
({ category }) =>
displayCategory === category || displayCategory === "all"
)
.map(({ category, name }) => (
<ProductItem key={`ProductItems-name`} category={category} name={name} />
))}
</div>
);
const ButtonCategory = ({ setCategory, category }) => (
<button className={`btn-${category}`} onClick={() => setCategory(category)}>
{category}
</button>
);
const ButtonCategories = (productCategories, setCategory ) => (
productCategories.map((category,i) => (
<ButtonCategory key={category} setCategory={setCategory} category={category} />
))
);
const UI = ({
state,
state: { productCategories },
setCategory,
allProducts
}) => (
<div className="box flex-row">
<div className="box flex-col">
<h3>Filter by Category</h3>
{ButtonCategories(productCategories, setCategory )}
</div>
<div className="box flex-col">
<h3>Results</h3>
<ProductItems state={state} />
</div>
</div>
);
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
displayCategory: "all",
products: PRODUCTS,
productCategories: PRODUCT_CATEGORIES
};
this.setCategory = this.setCategory.bind(this);
}
setCategory(category) {
this.setState({
displayCategory: category
});
}
render() {
return <UI setCategory={this.setCategory} state={this.state} />;
}
}
// data
const PRODUCTS = [
{ category: "entertainment", name: "Football" },
{ category: "entertainment", name: "Baseball" },
{ category: "entertainment", name: "Basketball" },
{ category: "fashion", name: "iPod Touch" },
{ category: "design", name: "iPhone 5" },
{ category: "design", name: "Nexus 7" },
{ category: "leisure", name: "Holiday" }
];
// get unique category items
const uniqueItems = (x, i, a) => a.indexOf(x) === i;
const PRODUCT_CATEGORIES = PRODUCTS.map(prod => prod.category).filter(
uniqueItems
);
PRODUCT_CATEGORIES.push("all");
PRODUCT_CATEGORIES.sort();
ReactDOM.render(<Main products={PRODUCTS} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
* {
box-sizing: border-box;
}
.box,
button {
font-family: 'Open Sans', sans-serif;
border: 1px solid grey;
border-radius: 3px;
padding: .5rem;
margin: .15rem;
/* float: left; */
background-color: rgba(0, 20, 50, 0.05);
font-size: 1rem;
}
.category--fashion,
.btn-fashion {
background-color: orange;
}
.category--design,
.btn-design {
background-color: green;
color: white;
}
.category--leisure,
.btn-leisure {
background-color: purple;
color: white;
}
.category--entertainment,
.btn-entertainment {
background-color: pink;
}
.btn-all {
background-color: white;
}
.category__list-item {
background-color: white;
}
.flex-row {
display: flex;
flex-direction: row;
justify-content: center;
}
.flex-col {
display: flex;
flex-direction: column;
/* align-items: flex-start; */
/* justify-content: center; */
}
.flex-spread {
display: flex;
justify-content: space-between;
align-items: center;
}
.circle{
border:1px solid grey;
width: 0.8rem;
height: 0.8rem;
border-radius: 50%;
margin:0 0 0 1rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment