Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Props } from 'react'
- export interface IHeaderProps extends Props<{}> {
- offset?: number
- header?: boolean
- }
- export interface IAddressProps extends Props<{}> {
- isVisible: boolean
- }
- export interface ILogoImgProps extends Props<{}> {
- mobile: boolean
- }
- export interface ISidebarProps extends IAddressProps { }
- import * as React from 'react'
- import { observable, action, autorun } from 'mobx'
- import { inject, observer } from 'mobx-react'
- import styled, { css } from 'styled-components'
- import { NavLink } from 'react-router-dom'
- import MediaQuery from 'react-responsive'
- const throttle = require('lodash.throttle')
- import {
- Sidebar,
- Navigation,
- MobileMenu,
- AccessibleHiddenText
- } from '~/components/common'
- import {
- IconBtn,
- IconName,
- TooltipPosition,
- HamburgerBtn,
- SecondaryBtn,
- SecondaryBtnIcon,
- SecondaryBtnIconPos,
- SecondaryBtnSize
- } from '~/components/pru'
- import { STORE_MODALS, STORE_UI, STORE_AUTH } from '~/constants/stores'
- import { MODAL_REQUEST } from '~/constants/modals'
- import { MEDIA } from '~/constants/media-queries'
- import {
- IHeaderProps,
- IAddressProps,
- ILogoImgProps,
- ISidebarProps
- } from './Header.d'
- import { LIGHT_LINES } from '~/components/pru/ui-colors'
- import { IReactionDisposer } from 'mobx/lib/core/reaction'
- const logo = require('./img/logo.svg')
- const mobileLogo = require('./img/logo_mobile.svg')
- const HeaderElem = styled.header`
- display: flex;
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- background-color: #fff;
- box-shadow: 0 1px 0 ${LIGHT_LINES};
- z-index: 10;
- ${(props: IHeaderProps) =>
- props.offset !== 0 ? `margin-right: ${props.offset}px` : ''};
- `
- const HeaderLeft = styled.section`
- display: flex;
- flex: 1 0;
- align-items: center;
- padding: 10px 20px 13px 27px;
- @media ${MEDIA.untilTablet} {
- position: relative;
- background-color: #fff;
- padding: 0 20px;
- }
- }`
- const HeaderRight = HeaderLeft.extend`
- justify-content: center;
- flex: 0 1;
- padding: 0 22px;
- @media ${MEDIA.untilTablet} {
- position: relative;
- background-color: #fff;
- border-left: 1px solid ${LIGHT_LINES};
- padding: 0;
- }
- `
- const LogoLink = styled(NavLink).attrs({ exact: true })`
- margin-right: 42px;
- &.active {
- pointer-events: none;
- }
- @media ${MEDIA.untilTablet} {
- margin-right: 0;
- }
- `
- const LogoImg = styled.img.attrs({
- src: (props: ILogoImgProps) => (props.mobile ? mobileLogo : logo),
- alt: 'ПИК-комфорт'
- })`
- width: 145px;
- height: 41px;
- @media ${MEDIA.untilTablet} {
- // Функцию не удалять, помогает ts в определении типа props для выражение выше.
- // внутри styled.attrs определения типа работает не корректно
- ${(props: ILogoImgProps) => css`
- width: 135px;
- height: 33px;
- `};
- }
- `
- const AddressBlock = styled.p`
- position: relative;
- display: flex;
- align-items: center;
- font-size: 13px;
- font-weight: 500;
- line-height: 1.23;
- letter-spacing: 0.6px;
- text-align: right;
- color: #7f7f7f;
- min-height: 32px;
- background: url(${require('./img/building.svg')}) no-repeat right center;
- padding-right: 35px;
- margin: 0 0 0 auto;
- &::after {
- content: '';
- display: block;
- width: 1px;
- position: absolute;
- top: 0;
- right: -20px;
- bottom: 0;
- background-color: ${LIGHT_LINES};
- }
- ${(props: IAddressProps) =>
- props.isVisible
- ? `opacity: 1;
- transition: opacity 0.2s linear;`
- : `opacity: 0;
- transition: opacity 0.1s linear;`};
- `
- const IconButton = styled(IconBtn)`
- &:not(:last-child) {
- margin-right: 14px;
- }
- `
- const Dropdown = styled(Sidebar)`
- position: absolute;
- top: calc(50% + 23px);
- right: 22px;
- visibility: hidden;
- opacity: 0;
- transform: translate(0, 3px);
- transition: opacity 0.15s linear, transform 0.15s ease-in-out,
- visibility 0.15s linear;
- ${(props: ISidebarProps) =>
- props.isVisible
- ? `
- visibility: visible;
- opacity: 1;
- transform: translate(0, 0);
- `
- : ``};
- `
- const LogoutBtn = styled(SecondaryBtn)`
- min-width: 85px;
- `
- @inject(STORE_MODALS, STORE_UI, STORE_AUTH)
- @observer
- export default class Header extends React.Component<IHeaderProps> {
- @observable addressIsVisible = location.pathname !== '/'
- static defaultProps = {
- header: true
- }
- private scrollListener = throttle(this.handleScroll, 150)
- private handleDropdownDisposer: IReactionDisposer
- constructor(props: React.Props<{}>) {
- super(props)
- this.handleHideDropdownClick = this.handleHideDropdownClick.bind(this)
- this.handleRequestBtnClick = this.handleRequestBtnClick.bind(this)
- this.handleSidebarBtnClick = this.handleSidebarBtnClick.bind(this)
- this.handleHamburgerBtnClick = this.handleHamburgerBtnClick.bind(this)
- }
- componentDidMount() {
- const isDesktop =
- window.matchMedia && window.matchMedia(MEDIA.fromDesktop_S).matches
- if (isDesktop && location.pathname === '/') {
- window.addEventListener('scroll', this.scrollListener)
- }
- this.props[STORE_UI].toggleMenu(false)
- if (this.props[STORE_UI].sidebarIsVisible) {
- setTimeout(() => {
- this.props[STORE_UI].toggleSidebar(false)
- }, 100)
- }
- this.handleDropdownDisposer = autorun(() => {
- if (this.props[STORE_UI].sidebarIsVisible) {
- document.addEventListener('click', this.handleHideDropdownClick)
- } else {
- document.removeEventListener('click', this.handleHideDropdownClick)
- }
- })
- }
- componentWillUnmount() {
- window.removeEventListener('scroll', this.scrollListener)
- document.removeEventListener('click', this.handleHideDropdownClick)
- this.handleDropdownDisposer()
- }
- handleHideDropdownClick({ target }: MouseEvent) {
- const isMenuElem = target && (target as Element).closest('#js-sidebar-root')
- if (!isMenuElem) this.props[STORE_UI].toggleSidebar(false)
- }
- handleRequestBtnClick() {
- this.props[STORE_MODALS].openModal(MODAL_REQUEST)
- }
- handleSidebarBtnClick() {
- this.props[STORE_UI].toggleSidebar()
- }
- handleHamburgerBtnClick() {
- this.props[STORE_UI].toggleMenu()
- }
- @action.bound
- handleScroll() {
- this.addressIsVisible = window.pageYOffset !== 0
- }
- render() {
- const {
- layoutOffset,
- sidebarIsVisible,
- menuIsVisible,
- isMobile
- } = this.props[STORE_UI]
- const { header, [STORE_AUTH]: auth } = this.props
- return (
- <HeaderElem offset={layoutOffset}>
- <HeaderLeft>
- <LogoLink to="/">
- <LogoImg mobile={isMobile} />
- </LogoLink>
- { header && (<MediaQuery query={MEDIA.fromTablet}>
- <nav>
- <Navigation />
- </nav>
- <AddressBlock isVisible={this.addressIsVisible}>
- Шмидтовский пр-кт<br />
- д. 20, кв. 145
- </AddressBlock>
- </MediaQuery>) }
- </HeaderLeft>
- <HeaderRight>
- <MediaQuery query={MEDIA.untilTablet}>
- <HamburgerBtn
- isPressed={menuIsVisible}
- onClick={this.handleHamburgerBtnClick}
- >
- <AccessibleHiddenText>Меню</AccessibleHiddenText>
- </HamburgerBtn>
- </MediaQuery>
- { header ? (<MediaQuery query={MEDIA.fromTablet}>
- <IconButton
- icon={IconName.WRITE}
- tooltip="Электронное обращение"
- onClick={this.handleRequestBtnClick}
- />
- <IconButton
- icon={IconName.USER}
- tooltip="Вкабинетус Вкабинетовский"
- tooltipPosition={TooltipPosition.LEFT}
- onClick={this.handleSidebarBtnClick}
- >
- <AccessibleHiddenText>Профиль</AccessibleHiddenText>
- </IconButton>
- </MediaQuery>) : <MediaQuery query={MEDIA.fromTablet}>
- <LogoutBtn
- icon={SecondaryBtnIcon.LOGOUT}
- iconPos={SecondaryBtnIconPos.RIGHT}
- size={SecondaryBtnSize.SMALL}
- onClick={auth.logout}
- >
- Выйти
- </LogoutBtn>
- </MediaQuery>}
- </HeaderRight>
- <Dropdown isVisible={sidebarIsVisible} />
- <MediaQuery query={MEDIA.untilTablet}>
- <MobileMenu isVisible={menuIsVisible} />
- </MediaQuery>
- </HeaderElem>
- )
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement