From 792f8acc42cce6b167c69e93fdbf77e5eafe0825 Mon Sep 17 00:00:00 2001 From: Javi Velasco Date: Sat, 21 Jan 2017 13:03:38 +0100 Subject: [PATCH] Add ripple for Tabs. Fixes #377 --- components/tabs/Tab.js | 126 ++++++++++++++++++++------------------ components/tabs/Tabs.js | 1 + components/tabs/index.js | 5 +- components/tabs/readme.md | 1 + components/tabs/theme.css | 5 ++ spec/components/tabs.js | 2 +- 6 files changed, 79 insertions(+), 61 deletions(-) diff --git a/components/tabs/Tab.js b/components/tabs/Tab.js index 60a30ae7..1c6db6f7 100644 --- a/components/tabs/Tab.js +++ b/components/tabs/Tab.js @@ -3,70 +3,80 @@ import classnames from 'classnames'; import { FontIcon } from '../font_icon'; import { themr } from 'react-css-themr'; import { TABS } from '../identifiers.js'; +import rippleFactory from '../ripple/Ripple.js'; -class Tab extends Component { - static propTypes = { - active: PropTypes.bool, - activeClassName: PropTypes.string, - className: PropTypes.string, - disabled: PropTypes.bool, - hidden: PropTypes.bool, - icon: PropTypes.node, - index: PropTypes.number, - label: PropTypes.node, - onActive: PropTypes.func, - onClick: PropTypes.func, - theme: PropTypes.shape({ - active: PropTypes.string, - disabled: PropTypes.string, - hidden: PropTypes.string, - label: PropTypes.string, - withIcon: PropTypes.string, - withText: PropTypes.string - }) - }; +const factory = (ripple) => { + class Tab extends Component { + static propTypes = { + active: PropTypes.bool, + activeClassName: PropTypes.string, + children: PropTypes.node, + className: PropTypes.string, + disabled: PropTypes.bool, + hidden: PropTypes.bool, + icon: PropTypes.node, + index: PropTypes.number, + label: PropTypes.node, + onActive: PropTypes.func, + onClick: PropTypes.func, + theme: PropTypes.shape({ + active: PropTypes.string, + disabled: PropTypes.string, + hidden: PropTypes.string, + label: PropTypes.string, + rippleWrapper: PropTypes.string, + withIcon: PropTypes.string, + withText: PropTypes.string + }) + }; - static defaultProps = { - active: false, - className: '', - disabled: false, - hidden: false - }; + static defaultProps = { + active: false, + className: '', + disabled: false, + hidden: false + }; - componentDidUpdate (prevProps) { - if (!prevProps.active && this.props.active && this.props.onActive) { - this.props.onActive(); + componentDidUpdate (prevProps) { + if (!prevProps.active && this.props.active && this.props.onActive) { + this.props.onActive(); + } + } + + handleClick = (event) => { + if (!this.props.disabled && this.props.onClick) { + this.props.onClick(event, this.props.index); + } + }; + + render () { + const { + index, onActive, // eslint-disable-line + active, activeClassName, children, className, disabled, hidden, label, icon, theme, ...other + } = this.props; + const _className = classnames(theme.label, { + [theme.active]: active, + [theme.hidden]: hidden, + [theme.withText]: label, + [theme.withIcon]: icon, + [theme.disabled]: disabled, + [activeClassName]: active + }, className); + + return ( + + ); } } - handleClick = (event) => { - if (!this.props.disabled && this.props.onClick) { - this.props.onClick(event, this.props.index); - } - }; - - render () { - const { - index, onActive, // eslint-disable-line - active, activeClassName, className, disabled, hidden, label, icon, theme, ...other - } = this.props; - const _className = classnames(theme.label, { - [theme.active]: active, - [theme.hidden]: hidden, - [theme.withText]: label, - [theme.withIcon]: icon, - [theme.disabled]: disabled, - [activeClassName]: active - }, className); - - return ( - - ); - } -} + return ripple(Tab); +}; +const Tab = factory(rippleFactory({ centered: false })); export default themr(TABS)(Tab); +export { factory as tabFactory }; export { Tab }; diff --git a/components/tabs/Tabs.js b/components/tabs/Tabs.js index 1653aa16..a46054a9 100644 --- a/components/tabs/Tabs.js +++ b/components/tabs/Tabs.js @@ -137,6 +137,7 @@ const factory = (Tab, TabContent, FontIcon) => { renderHeaders (headers) { return headers.map((item, idx) => { return React.cloneElement(item, { + children: null, key: idx, index: idx, theme: this.props.theme, diff --git a/components/tabs/index.js b/components/tabs/index.js index 8772cd22..7ca9bb07 100644 --- a/components/tabs/index.js +++ b/components/tabs/index.js @@ -2,13 +2,14 @@ import { themr } from 'react-css-themr'; import { TABS } from '../identifiers.js'; import { tabsFactory } from './Tabs.js'; import { TabContent } from './TabContent.js'; -import { Tab } from './Tab.js'; +import { tabFactory } from './Tab.js'; +import themedRippleFactory from '../ripple'; import FontIcon from '../font_icon/FontIcon.js'; import theme from './theme.css'; const applyTheme = (Component) => themr(TABS, theme)(Component); const ThemedTabContent = applyTheme(TabContent); -const ThemedTab = applyTheme(Tab); +const ThemedTab = applyTheme(tabFactory(themedRippleFactory({ centered: false }))); const ThemedTabs = applyTheme(tabsFactory(ThemedTab, ThemedTabContent, FontIcon)); export { ThemedTab as Tab }; diff --git a/components/tabs/readme.md b/components/tabs/readme.md index 07680ce9..192465fe 100644 --- a/components/tabs/readme.md +++ b/components/tabs/readme.md @@ -116,3 +116,4 @@ It is required to provide either a label or an icon (or both). | `disabled` | Added to the navigation tab element in case it's disabled.| | `hidden` | Added to the navigation tab element in case it's hidden.| | `label` | Added to the navigation tab element in case it's active.| +| `rippleWrapper` | Used for the ripple wrapper element.| diff --git a/components/tabs/theme.css b/components/tabs/theme.css index cff083e8..72245d2e 100644 --- a/components/tabs/theme.css +++ b/components/tabs/theme.css @@ -43,11 +43,16 @@ font-weight: var(--font-weight-semi-bold); line-height: 1; padding: var(--tab-label-v-padding) var(--tab-label-h-padding); + position: relative; text-transform: uppercase; transition-duration: var(--animation-duration); transition-property: box-shadow, color; transition-timing-function: var(--animation-curve-default); + & > .rippleWrapper { + overflow: hidden; + } + &.active { color: var(--tab-text-color); } diff --git a/spec/components/tabs.js b/spec/components/tabs.js index c4b85b6c..2a363d45 100644 --- a/spec/components/tabs.js +++ b/spec/components/tabs.js @@ -30,7 +30,7 @@ class TabsTest extends React.Component {
Tabs

This tabs can be disabled or hidden

- Primary content + Primary content (no ripple) Secondary content Disabled content