Updated Sidebar, NavigationBar components, Added layouts
• Updated: - Sidebar, NavigationBar components - file structures for both • Added: - layouts for compnents
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { openSidebar } from '../../actions/sidebar'
|
||||
import { openPopover } from '../../actions/popover'
|
||||
import { BREAKPOINT_EXTRA_SMALL } from '../../constants'
|
||||
import { me } from '../../initial_state'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import Responsive from '../../features/ui/util/responsive_component'
|
||||
import {
|
||||
CX,
|
||||
POPOVER_NAV_SETTINGS,
|
||||
} from '../../constants'
|
||||
import Avatar from '../avatar'
|
||||
import BackButton from '../back_button'
|
||||
import Button from '../button'
|
||||
import Heading from '../heading'
|
||||
import Icon from '../icon'
|
||||
import NavigationBarButton from '../navigation_bar_button'
|
||||
import Search from '../search'
|
||||
import Text from '../text'
|
||||
|
||||
class DefaultNavigationBar extends ImmutablePureComponent {
|
||||
|
||||
handleOnOpenNavSettingsPopover = () => {
|
||||
this.props.onOpenNavSettingsPopover(this.avatarNode)
|
||||
}
|
||||
|
||||
setAvatarNode = (c) => {
|
||||
this.avatarNode = c
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
title,
|
||||
showBackBtn,
|
||||
actions,
|
||||
tabs,
|
||||
account,
|
||||
onOpenSidebar,
|
||||
noActions,
|
||||
noSearch,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.z4, _s.minH53PX, _s.w100PC].join(' ')}>
|
||||
<div className={[_s.d, _s.minH53PX, _s.bgNavigation, _s.aiCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
|
||||
|
||||
<div className={[_s.d, _s.saveAreaInsetPT, _s.saveAreaInsetPL, _s.saveAreaInsetPR, _s.flexRow, _s.w1255PX].join(' ')}>
|
||||
|
||||
{ /** Default */}
|
||||
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||
|
||||
<div className={[_s.d, _s.flexRow].join(' ')}>
|
||||
|
||||
<h1 className={[_s.d, _s.mr15].join(' ')}>
|
||||
<Button
|
||||
to='/'
|
||||
isText
|
||||
title='Gab'
|
||||
aria-label='Gab'
|
||||
color='none'
|
||||
backgroundColor='none'
|
||||
className={[_s.d, _s.jcCenter, _s.noSelect, _s.noUnderline, _s.h53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}
|
||||
>
|
||||
<Icon id='logo' className={_s.fillNavigationBrand} />
|
||||
</Button>
|
||||
</h1>
|
||||
|
||||
{
|
||||
!noSearch &&
|
||||
<div className={[_s.d, _s.w340PX, _s.mr10].join(' ')}>
|
||||
<Search isInNav />
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
<div className={[_s.d, _s.mlAuto].join(' ')}>
|
||||
{
|
||||
!noActions &&
|
||||
<div className={[_s.d, _s.h53PX, _s.pl15, _s.flexRow, _s.aiCenter, _s.jcSpaceBetween].join(' ')}>
|
||||
|
||||
<NavigationBarButton title='Home' icon='home' to='/home' />
|
||||
<NavigationBarButton title='Explore' icon='explore' to='/explore' />
|
||||
<NavigationBarButton title='News' icon='news' to='/news' />
|
||||
<NavigationBarButton title='TV' icon='gab-tv' href='https://tv.gab.com' />
|
||||
|
||||
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
||||
|
||||
<NavigationBarButton attrTitle='Notifications' icon='notifications' to='/notifications' />
|
||||
<NavigationBarButton attrTitle='Settings' icon='cog' href='/settings/preferences' />
|
||||
|
||||
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
||||
|
||||
{
|
||||
!!account &&
|
||||
<button
|
||||
ref={this.setAvatarNode}
|
||||
title={account.get('display_name')}
|
||||
onClick={this.handleOnOpenNavSettingsPopover}
|
||||
className={[_s.h53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.d, _s.jcCenter, _s.ml15].join(' ')}
|
||||
>
|
||||
<Avatar account={account} size={32} noHover />
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
</Responsive>
|
||||
|
||||
{ /** Mobile */}
|
||||
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
|
||||
<div className={[_s.d, _s.w84PX, _s.aiStart, _s.pl10].join(' ')}>
|
||||
{
|
||||
!!account && !showBackBtn && !noActions &&
|
||||
<button
|
||||
title={account.get('display_name')}
|
||||
onClick={onOpenSidebar}
|
||||
className={[_s.h53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.d, _s.jcCenter].join(' ')}
|
||||
>
|
||||
<Avatar account={account} size={32} noHover />
|
||||
</button>
|
||||
}
|
||||
{
|
||||
showBackBtn &&
|
||||
<BackButton
|
||||
className={_s.h53PX}
|
||||
icon='angle-left'
|
||||
iconSize='18px'
|
||||
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
|
||||
/>
|
||||
}
|
||||
{
|
||||
noActions &&
|
||||
<h1 className={[_s.d, _s.mr15].join(' ')}>
|
||||
<Button
|
||||
to='/'
|
||||
isText
|
||||
title='Gab'
|
||||
aria-label='Gab'
|
||||
color='none'
|
||||
backgroundColor='none'
|
||||
className={[_s.d, _s.jcCenter, _s.noSelect, _s.noUnderline, _s.h53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}
|
||||
>
|
||||
<Icon id='logo' className={_s.fillNavigationBrand} />
|
||||
</Button>
|
||||
</h1>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className={[_s.d, _s.h53PX, _s.jcCenter, _s.mlAuto, _s.mrAuto].join(' ')}>
|
||||
<Heading size='h1'>
|
||||
<span className={_s.colorNavigation}>
|
||||
{title}
|
||||
</span>
|
||||
</Heading>
|
||||
</div>
|
||||
|
||||
<div className={[_s.d, _s.w84PX, _s.pr15].join(' ')}>
|
||||
<div className={[_s.d, _s.bgTransparent, _s.flexRow, _s.aiCenter, _s.jcCenter, _s.mlAuto].join(' ')}>
|
||||
{
|
||||
actions && actions.map((action, i) => (
|
||||
<Button
|
||||
isNarrow
|
||||
backgroundColor='none'
|
||||
color='primary'
|
||||
to={action.to || undefined}
|
||||
onClick={action.onClick ? () => action.onClick() : undefined}
|
||||
key={`action-btn-${i}`}
|
||||
className={[_s.ml5, _s.h53PX, _s.jcCenter, _s.px5].join(' ')}
|
||||
icon={action.icon}
|
||||
iconClassName={_s.fillNavigation}
|
||||
iconSize='18px'
|
||||
/>
|
||||
))
|
||||
}
|
||||
{
|
||||
!noSearch &&
|
||||
<Button
|
||||
isNarrow
|
||||
backgroundColor='none'
|
||||
color='primary'
|
||||
to='/search'
|
||||
key={`action-btn-search`}
|
||||
className={[_s.ml5, _s.h53PX, _s.jcCenter, _s.px5].join(' ')}
|
||||
icon='search'
|
||||
iconClassName={_s.fillNavigation}
|
||||
iconSize='18px'
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Responsive>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
account: makeGetAccount()(state, me),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onOpenSidebar() {
|
||||
dispatch(openSidebar())
|
||||
},
|
||||
|
||||
onOpenNavSettingsPopover(targetRef) {
|
||||
dispatch(openPopover(POPOVER_NAV_SETTINGS, {
|
||||
targetRef,
|
||||
position: 'left-end',
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
DefaultNavigationBar.propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
actions: PropTypes.array,
|
||||
tabs: PropTypes.array,
|
||||
title: PropTypes.string,
|
||||
showBackBtn: PropTypes.bool,
|
||||
onOpenSidebar: PropTypes.func.isRequired,
|
||||
onOpenNavSettingsPopover: PropTypes.func.isRequired,
|
||||
noActions: PropTypes.bool,
|
||||
noSearch: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DefaultNavigationBar)
|
||||
@@ -0,0 +1,106 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { BREAKPOINT_EXTRA_SMALL } from '../../constants'
|
||||
import Button from '../button'
|
||||
import NavigationBarButton from '../navigation_bar_button'
|
||||
import Search from '../search'
|
||||
import Text from '../text'
|
||||
import ResponsiveComponent from '../../features/ui/util/responsive_component'
|
||||
import ResponsiveClassesComponent from '../../features/ui/util/responsive_classes_component'
|
||||
|
||||
class LoggedOutNavigationBar extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const { isProfile } = this.props
|
||||
|
||||
return (
|
||||
<ResponsiveClassesComponent
|
||||
classNames={[_s.d, _s.z4, _s.minH53PX, _s.w100PC].join(' ')}
|
||||
classNamesXS={[_s.d, _s.z4, _s.minH98PX, _s.w100PC].join(' ')}
|
||||
>
|
||||
<ResponsiveClassesComponent
|
||||
classNames={[_s.d, _s.minH53PX, _s.bgNavigation, _s.aiCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')}
|
||||
classNamesXS={[_s.d, _s.minH98PX, _s.bgNavigation, _s.aiCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')}
|
||||
>
|
||||
|
||||
<div className={[_s.d, _s.w1255PX, _s.flexRow, _s.flexWrap, _s.h100PC].join(' ')}>
|
||||
|
||||
<ResponsiveClassesComponent
|
||||
classNames={[_s.d, _s.aiCenter, _s.jcCenter, _s.flexRow, _s.flexGrow1, _s.saveAreaInsetPT, _s.saveAreaInsetPL, _s.saveAreaInsetPR].join(' ')}
|
||||
classNamesXS={[_s.d, _s.flexRow, _s.saveAreaInsetPT, _s.saveAreaInsetPL, _s.saveAreaInsetPR, _s.w100PC].join(' ')}
|
||||
>
|
||||
|
||||
<Button
|
||||
href='/'
|
||||
color='none'
|
||||
backgroundColor='none'
|
||||
icon='logo'
|
||||
title='Gab'
|
||||
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
|
||||
/>
|
||||
|
||||
{
|
||||
isProfile &&
|
||||
<ResponsiveComponent min={BREAKPOINT_EXTRA_SMALL}>
|
||||
<div className={[_s.d, _s.flexRow, _s.mr15].join(' ')}>
|
||||
<NavigationBarButton title='Home' icon='home' href='/home' />
|
||||
<NavigationBarButton title='Explore' icon='explore' to='/explore' />
|
||||
<NavigationBarButton title='News' icon='news' to='/news' />
|
||||
<NavigationBarButton title='TV' icon='gab-tv' href='https://tv.gab.com' />
|
||||
</div>
|
||||
</ResponsiveComponent>
|
||||
}
|
||||
|
||||
<div className={[_s.d, _s.flexGrow1, _s.pr10, _s.mrAuto, _s.maxW640PX].join(' ')}>
|
||||
<Search isInNav />
|
||||
</div>
|
||||
|
||||
</ResponsiveClassesComponent>
|
||||
|
||||
<ResponsiveClassesComponent
|
||||
classNames={[_s.d, _s.flexRow, _s.py5, _s.px10, _s.w330PX, _s.mlAuto].join(' ')}
|
||||
classNamesXS={[_s.d, _s.flexRow, _s.pb5, _s.px10, _s.w100PC].join(' ')}
|
||||
>
|
||||
|
||||
<Button
|
||||
isNarrow
|
||||
isOutline
|
||||
color='white'
|
||||
backgroundColor='none'
|
||||
href='/auth/sign_in'
|
||||
className={[_s.borderColorWhite, _s.mr5, _s.flexGrow1, _s.aiCenter, _s.jcCenter, _s.py7].join(' ')}
|
||||
>
|
||||
<Text color='inherit' weight='medium' align='center'>
|
||||
Log in
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
isNarrow
|
||||
color='brand'
|
||||
backgroundColor='white'
|
||||
href='/auth/sign_up'
|
||||
className={[_s.jcCenter, _s.aiCenter, _s.ml5, _s.flexGrow1, _s.py7].join(' ')}
|
||||
>
|
||||
<Text color='inherit' weight='bold' align='center'>
|
||||
Sign up
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
</ResponsiveClassesComponent>
|
||||
</div>
|
||||
|
||||
</ResponsiveClassesComponent>
|
||||
</ResponsiveClassesComponent>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LoggedOutNavigationBar.propTypes = {
|
||||
isProfile: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
showBackBtn: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default LoggedOutNavigationBar
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import BackButton from '../back_button'
|
||||
import Heading from '../heading'
|
||||
|
||||
class ProfileNavigationBar extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const { titleHTML } = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.z4, _s.minH53PX, _s.w100PC].join(' ')}>
|
||||
<div className={[_s.d, _s.minH53PX, _s.bgNavigation, _s.aiCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
|
||||
|
||||
<div className={[_s.d, _s.flexRow, _s.saveAreaInsetPT, _s.saveAreaInsetPL, _s.saveAreaInsetPR, _s.w100PC].join(' ')}>
|
||||
|
||||
<BackButton
|
||||
className={[_s.minH53PX, _s.pl10, _s.pr10].join(' ')}
|
||||
iconSize='18px'
|
||||
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
|
||||
/>
|
||||
|
||||
<div className={[_s.d, _s.minH53PX, _s.jcCenter, _s.mrAuto].join(' ')}>
|
||||
<Heading size='h1'>
|
||||
<span className={[_s.textOverflowEllipsis, _s.colorNavigation].join(' ')}>
|
||||
<div dangerouslySetInnerHTML={{ __html: titleHTML }} />
|
||||
</span>
|
||||
</Heading>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ProfileNavigationBar.propTypes = {
|
||||
titleHTML: PropTypes.string,
|
||||
showBackBtn: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default ProfileNavigationBar
|
||||
Reference in New Issue
Block a user