From 094a90dbf06eebe98c1b99a5f6e1315994200fbb Mon Sep 17 00:00:00 2001 From: NewOldMax Date: Sat, 28 Jan 2017 17:03:13 +0300 Subject: [PATCH] Add support for custom icons in actions [ActionButton] (#66) * [ActionButton] Add support for custom icons in actions. * Fix key prop * Fix eslint errors. * Moved action item key calculation to function. --- docs/ActionButton.md | 10 +- src/ActionButton/ActionButton.react.js | 152 +++++++++++++++++++------ 2 files changed, 128 insertions(+), 34 deletions(-) mode change 100644 => 100755 docs/ActionButton.md diff --git a/docs/ActionButton.md b/docs/ActionButton.md old mode 100644 new mode 100755 index fdc3eac0..5d160ddb --- a/docs/ActionButton.md +++ b/docs/ActionButton.md @@ -21,13 +21,19 @@ render() { ```js const propTypes = { /** - * Array of names of icons that will be shown after the main button is pressed + * Array of names of icons (or elements) that will be shown after the main button is pressed + * Remember, you should specify key for each element, if you use array of elements */ actions: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.string), + PropTypes.arrayOf(PropTypes.element), PropTypes.arrayOf(PropTypes.shape({ - icon: PropTypes.string, + icon: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element, + ]), label: PropTypes.string, + name: PropTypes.string, })), ]), /** diff --git a/src/ActionButton/ActionButton.react.js b/src/ActionButton/ActionButton.react.js index d137d6c9..d7d64259 100755 --- a/src/ActionButton/ActionButton.react.js +++ b/src/ActionButton/ActionButton.react.js @@ -18,13 +18,19 @@ import getPlatformElevation from '../styles/getPlatformElevation'; const propTypes = { /** - * Array of names of icons that will be shown after the main button is pressed + * Array of names of icons (or elements) that will be shown after the main button is pressed + * Remember, you should specify key for each element, if you use array of elements */ actions: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.string), + PropTypes.arrayOf(PropTypes.element), PropTypes.arrayOf(PropTypes.shape({ - icon: PropTypes.string, + icon: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element, + ]), label: PropTypes.string, + name: PropTypes.string, })), ]), /** @@ -190,6 +196,15 @@ class ActionButton extends PureComponent { onPress(action); } } + getActionItemKey = ({ icon, name }) => { + let key = icon; + if (name) { + key = name; + } else if (React.isValidElement(icon) && icon.key) { + key = icon.key; + } + return key; + } toggleState = () => { const { transition } = this.props; @@ -225,16 +240,16 @@ class ActionButton extends PureComponent { return ( - {actions.map(action => ( - - this.onPress(action)} - style={{ icon: styles.icon }} - /> - - ))} + {actions.map((action) => { + if (typeof action === 'string') { + return this.renderToolbarAction(styles, action); + } + if (React.isValidElement(action)) { + return this.renderToolbarElementAction(styles, action); + } + return this.renderToolbarLabelAction( + styles, action.icon, action.label, action.name); + })} ); @@ -253,8 +268,12 @@ class ActionButton extends PureComponent { return this.renderAction(styles, action); } + if (React.isValidElement(action)) { + return this.renderElementAction(styles, action); + } + return this.renderLabelAction( - styles, action.icon, action.label); + styles, action.icon, action.label, action.name); })} {this.renderMainButton(styles)} @@ -285,32 +304,101 @@ class ActionButton extends PureComponent { ); } - renderAction = (styles, icon) => ( - - + renderToolbarAction = (styles, icon, name) => { + let content; + const key = this.getActionItemKey({ icon, name }); + + if (React.isValidElement(icon)) { + content = ( this.onPress(icon)} + onPress={() => this.onPress(key)} delayPressIn={20} > {this.renderIconButton(styles, icon)} - + ); + } else { + content = ( + this.onPress(key)} + style={{ icon: styles.icon }} + />); + } + return ( + + {content} - - ) - renderLabelAction = (styles, icon, label) => ( - - - {label} + ); + } + renderToolbarElementAction = (styles, icon) => { + const key = this.getActionItemKey({ icon }); + return ( + + {this.renderToolbarAction(styles, icon)} + + ); + } + /** + * TODO: implement labels for toolbar? + */ + renderToolbarLabelAction = (styles, icon, label, name) => { + const key = this.getActionItemKey({ icon, name }); + return ( + + {this.renderToolbarAction(styles, icon, name)} - {this.renderAction(styles, icon)} - - ) - renderIconButton = (styles, name) => ( - - - - ) + ); + } + renderAction = (styles, icon, name) => { + const key = this.getActionItemKey({ icon, name }); + return ( + + + this.onPress(key)} + delayPressIn={20} + > + {this.renderIconButton(styles, icon)} + + + + ); + } + renderElementAction = (styles, icon) => { + const key = this.getActionItemKey({ icon }); + return ( + + {this.renderAction(styles, icon)} + + ); + } + renderLabelAction = (styles, icon, label, name) => { + const key = this.getActionItemKey({ icon, name }); + return ( + + + {label} + + {this.renderAction(styles, icon, name)} + + ); + } + renderIconButton = (styles, icon) => { + let result; + if (React.isValidElement(icon)) { + result = icon; + } else { + result = ; + } + return ( + + {result} + + ); + } renderButton = styles => (