gab-social/app/javascript/gabsocial/components/tab_bar_item.js

109 lines
2.6 KiB
JavaScript
Raw Normal View History

2020-03-26 03:11:32 +00:00
import { withRouter } from 'react-router-dom'
2020-05-01 06:50:27 +01:00
import { CX } from '../constants'
2020-03-26 03:11:32 +00:00
import Button from './button'
2020-02-22 23:26:23 +00:00
import Text from './text'
2020-04-23 07:13:29 +01:00
/**
* Renders a tab bar item component
* @param {bool} [props.isLarge] - to style the tab bar larger
* @param {bool} [props.isActive] - if item is active
* @param {func} [props.onClick] - function to call on click
* @param {string} [props.title] - title to use
* @param {string} [props.to] - location to direct to on click
*/
2020-02-22 23:26:23 +00:00
export default
@withRouter
class TabBarItem extends PureComponent {
2020-04-23 07:13:29 +01:00
2020-02-22 23:26:23 +00:00
static propTypes = {
2020-04-23 07:13:29 +01:00
isLarge: PropTypes.bool,
isActive: PropTypes.bool,
onClick: PropTypes.func,
title: PropTypes.string,
2020-02-22 23:26:23 +00:00
to: PropTypes.string,
}
state = {
2020-05-01 06:50:27 +01:00
isCurrent: false,
2020-02-22 23:26:23 +00:00
}
componentDidUpdate(prevProps) {
2020-04-23 07:13:29 +01:00
// If user navigates to different page, ensure tab bar item
// with this.props.to that is on location is set to active.
2020-02-22 23:26:23 +00:00
if (this.props.location !== prevProps.location) {
const isCurrent = this.props.to === this.props.location.pathname
2020-04-07 02:53:23 +01:00
if (this.state.isCurrent !== isCurrent) {
this.setState({ isCurrent })
2020-02-22 23:26:23 +00:00
}
}
}
render() {
2020-03-26 03:11:32 +00:00
const {
title,
to,
onClick,
location,
2020-04-23 07:13:29 +01:00
isLarge,
isActive,
2020-03-26 03:11:32 +00:00
} = this.props
2020-04-07 02:53:23 +01:00
const { isCurrent } = this.state
2020-02-22 23:26:23 +00:00
2020-04-23 07:13:29 +01:00
// Combine state, props, location to make absolutely
// sure of active status.
2020-05-01 06:50:27 +01:00
const active = isActive || to === location.pathname || isCurrent
2020-02-22 23:26:23 +00:00
2020-05-01 06:50:27 +01:00
const containerClasses = CX({
2020-02-22 23:26:23 +00:00
default: 1,
2020-05-09 03:17:19 +01:00
height100PC: 1,
2020-02-22 23:26:23 +00:00
noUnderline: 1,
text: 1,
displayFlex: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
borderBottom2PX: 1,
2020-03-11 23:56:18 +00:00
py5: 1,
2020-04-09 20:18:14 +01:00
outlineNone: 1,
2020-04-03 02:05:49 +01:00
cursorPointer: 1,
2020-04-29 23:32:49 +01:00
bgTransparent: 1,
2020-04-23 07:13:29 +01:00
borderColorTransparent: !active,
borderColorBrand: active,
mr5: isLarge,
mr2: !isLarge,
2020-02-28 15:20:47 +00:00
})
2020-05-01 06:50:27 +01:00
const textParentClasses = CX({
2020-02-28 15:20:47 +00:00
default: 1,
height100PC: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
radiusSmall: 1,
2020-04-23 07:13:29 +01:00
px10: !isLarge,
px15: isLarge,
2020-04-29 23:32:49 +01:00
bgSecondaryDark_onHover: !active,
2020-02-22 23:26:23 +00:00
})
const textOptions = {
2020-04-23 07:13:29 +01:00
size: !!isLarge ? 'normal' : 'small',
color: active ? 'brand' : isLarge ? 'secondary' : 'primary',
weight: active ? 'bold' : isLarge ? 'medium' : 'normal',
2020-02-22 23:26:23 +00:00
}
return (
2020-03-26 03:11:32 +00:00
<Button
onClick={onClick}
className={containerClasses}
2020-04-07 02:53:23 +01:00
to={to || undefined}
2020-03-26 03:11:32 +00:00
noClasses
>
2020-02-28 15:20:47 +00:00
<span className={textParentClasses}>
2020-04-29 23:32:49 +01:00
<Text {...textOptions}>
{title}
</Text>
2020-02-28 15:20:47 +00:00
</span>
2020-03-26 03:11:32 +00:00
</Button>
2020-02-22 23:26:23 +00:00
)
}
2020-04-23 07:13:29 +01:00
2020-02-22 23:26:23 +00:00
}