From 078ecdedb3aac60c6285633c262c142038a7bcd2 Mon Sep 17 00:00:00 2001 From: Aziz Ali Date: Wed, 15 Nov 2017 13:29:46 -0600 Subject: [PATCH] Feature: - Custom delete element can be added - No force uppercase of text - Children key if not available, provide empty array - onDeleteCb(), default returns true - SCSS file provided as part of the project CSS - SCSS variables added - Font size, and weight normalized - Cleanup: CSS --- package.json | 1 + readme.md | 27 +++++++++++++++++++-------- src/index.js | 25 +++++++++++++------------ src/style.scss | 39 +++++++++++++++++++++------------------ webpack.config.js | 7 ++++++- 5 files changed, 60 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index f1921fb..aa8f9cb 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", + "copy-webpack-plugin": "^4.2.0", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.0", "html-webpack-plugin": "^2.30.1", diff --git a/readme.md b/readme.md index a8a8be2..34cb2ec 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,7 @@ React Component that is highly customizable, which creates unlimited deep nested - Delete animation - Unlimited nesting - Granular control over when to show expand, checkbox or delete options +- Multi-(un)select checkbox (shift + Check) like Gmail ### How to install `npm install expandable-tree` @@ -73,20 +74,29 @@ constructor() { #### Step 2: Import styles to project -The styles of the component are in the file `node_modules/expandable-tree/dist/style.css` +Import Expandable Tree styles with `css` or `scss` file. + +The styles of the component are in the file `node_modules/expandable-tree/dist/style.css or style.scss` + +Note: When you use the `scss` file, you can modify the style variables for quick styling. ##### Using webpack If you are using webpack, put this in your project's styles. -the tilda `~` tells webpack to pick-up the file from `node_modules` folder ``` -~expandable-tree/dist/style.css +~expandable-tree/dist/style.css +``` +or `scss` if your project has the ability to process it ``` +~expandable-tree/dist/style.scss +``` + +the tilda `~` tells webpack to pick-up the file from `node_modules` folder ##### Manually importing styles -You can also manually copy the css file from `node_modules/expandable-tree/dist/style.css` and put it in your project files +You can also manually copy the `css/scss` file from `node_modules/expandable-tree/dist/style.(s)css` and put it in your project files ### Examples @@ -112,16 +122,17 @@ keywordLabel | string | `'name'` | k loadingElement | element | `null` | Element that shows when data is loading noChildrenAvailableMessage | string | `'No data found'` | Message that shows when the expanded node has no children onCheckToggleCb | function | `(arrayOfNodes, depth) => {}` | Function callback when checkbox gets toggled -onDeleteCb | function | `(node, updatedData, depth) => {}` | Function callback when node delete button gets clicked +onDeleteCb | function | `(node, updatedData, depth) => { return true; }` | Function callback when node delete button gets clicked onExpandToggleCb | function | `(node, depth) => {}` | Function callback when node Expand/Collapse gets toggled onUpdateCb | function | `(updatedData, depth) => {}` | Function callback when data gets updated transitionEnterTimeout | number | `1200` | Time in milliseconds for node appear animation transitionExitTimeout | number | `1200` | Time in milliseconds for node remove animation + ### Shoutout -Shoutout to [@oandrew](https://github.com/oandrew) for suggesting a clean API exposing strategy. +Shoutout to [Andrew Onyshchuk](https://github.com/oandrew) for suggesting a clean API exposing strategy. -Thank you [@tjhubert](https://github.com/tjhubert) and [@prashanth0926](https://github.com/prashanth0926) for your contribution to the animation feature and the bug fixes. +Thank you [TJ Hubert](https://github.com/tjhubert) and [Prashanth Naika](https://github.com/prashanth0926) for your contribution to the animation feature and the bug fixes. ### TODO: @@ -129,7 +140,7 @@ Thank you [@tjhubert](https://github.com/tjhubert) and [@prashanth0926](https:// - [ ] Feature: Add click event for text - [ ] Feature: Add css class on nodes based on its state i.e `
Text
` - [ ] Feature: Stretch goal: Add ability to add custom decorator/element per node -- [ ] Feature: Provide .scss file with configurable variables +- [X] Feature: Provide .scss file with configurable variables - [ ] Workflow: Provide auto-launch browser feature when examples are run with `npm run examples` - [ ] Performance: Remove the need for lodash diff --git a/src/index.js b/src/index.js index d169b7e..17a726c 100644 --- a/src/index.js +++ b/src/index.js @@ -114,16 +114,17 @@ class ExpandableTree extends Component { } printDeleteButton(node) { - const { isDeletable, depth } = this.props; + const { isDeletable, depth, deleteElement } = this.props; if (isDeletable(node, depth)) { return ( - { this.handleDelete(node); }} - /> + > + {deleteElement} + ); } } @@ -206,11 +207,7 @@ class ExpandableTree extends Component { {isEmpty(nodeArray) ? this.printNoChildrenMessage() : nodeArray.map((node, index) => { - const nodeText = get( - node, - keywordLabel, - '' - ).toUpperCase(); + const nodeText = get(node, keywordLabel, ''); return ( @@ -294,6 +291,8 @@ ExpandableTree.propTypes = { data: PropTypes.array.isRequired, depth: PropTypes.number, + deleteElement: PropTypes.element, + getStyleClassCb: PropTypes.func, isCheckable: PropTypes.func, @@ -320,6 +319,8 @@ ExpandableTree.propTypes = { ExpandableTree.defaultProps = { depth: 0, + deleteElement:
(X)
, + getStyleClassCb: (/* node, depth */) => { return ''; }, @@ -338,12 +339,12 @@ ExpandableTree.defaultProps = { keywordLabel: 'name', keywordKey: 'id', - loadingElement: null, + loadingElement:
loading...
, noChildrenAvailableMessage: 'No data found', onCheckToggleCb: (/* Array of nodes, depth */) => {}, - onDeleteCb: (/* node, updatedData, depth */) => {}, + onDeleteCb: (/* node, updatedData, depth */) => { return true }, onExpandToggleCb: (/* node, depth */) => {}, onUpdateCb: (/* updatedData, depth */) => {}, diff --git a/src/style.scss b/src/style.scss index 446e0e1..c8473d5 100644 --- a/src/style.scss +++ b/src/style.scss @@ -1,6 +1,10 @@ +// VARIABLES +$expandable-tree-text-color: #000; +$expandable-tree-arrow-color: #000; +$expandable-tree-tree-stem-color: #000; + .expandable-tree { - font-size: 13px; - font-weight: 300; + font-size: 100%; > div { > .expandable-tree-no-children-transition { @@ -19,50 +23,48 @@ > .expandable-tree-no-children { > .expandable-tree-no-children-content { - margin-bottom: 6px; + margin: 3px 0; } } > .expandable-tree-node { - padding: 0 3px; - border-radius: 3px; - > .expandable-tree-children-container { margin-left: 5px; padding-left: 20px; - border-left: 1px solid #ccc; + border-left: 1px solid $expandable-tree-tree-stem-color; > .expandable-tree-loading { padding: 0 3px; - margin-bottom: 6px; + margin: 3px 0; } } > .expandable-tree-node-content { - margin-bottom: 6px; + padding: 0 3px; + margin: 3px 0; > label { vertical-align: top; text-overflow: ellipsis; - width: calc(100% - 35px); + width: calc(100% - 55px); overflow: hidden; white-space: nowrap; display: inline-block; margin: 0; - font-weight: 300; - font-size: 13px; + font-weight: normal; + font-size: 100%; } > input[type=checkbox] { float: left; - margin-right: 5px; + margin: 4px 5px 0 0; + line-height: normal; } > .expandable-tree-triangle-btn { + float: left; margin-right: 5px; cursor: pointer; - display: inline-block; - float: left; } > .expandable-tree-triangle-btn-right { @@ -71,7 +73,7 @@ margin-top: 2px; margin-left: 2px; border-top: 5px solid transparent; - border-left: 6px solid #fff; + border-left: 6px solid $expandable-tree-arrow-color; border-bottom: 5px solid transparent; } @@ -81,10 +83,11 @@ margin-top: 5px; border-left: 5px solid transparent; border-right: 5px solid transparent; - border-top: 6px solid #fff; + border-top: 6px solid $expandable-tree-arrow-color; } - > .delete-icon { + > .delete-btn { + float: right; cursor: pointer; } } diff --git a/webpack.config.js b/webpack.config.js index d181300..e6389c3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,6 +4,7 @@ const path = require('path'); const webpack = require('webpack'); const nodeExternals = require('webpack-node-externals'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); +const CopyWebpackPlugin = require("copy-webpack-plugin"); const config = { entry : { @@ -33,7 +34,11 @@ const config = { ] }, plugins: [ - new ExtractTextPlugin('style.css') + new ExtractTextPlugin('style.css'), + new CopyWebpackPlugin([{ + from: 'src/style.scss', + dest: 'dist/[name].[ext]' + }]) ], externals: [