1- import React , { createRef , MouseEvent } from 'react' ;
1+ import React , { MouseEvent , useCallback , useState } from 'react' ;
22import block from 'bem-cn-lite' ;
3+
4+ import { HeaderData , NavigationLogo } from '../../../../models' ;
35import { Col , Grid , Row } from '../../../../grid' ;
46import OutsideClick from '../../../OutsideClick/OutsideClick' ;
57import Control from '../../../Control/Control' ;
6-
7- import Logo from '../Logo/Logo' ;
8-
9- import { HeaderData , NavigationLogo } from '../../../../models' ;
108import Navigation from '../Navigation/Navigation' ;
119import MobileNavigation from '../MobileNavigation/MobileNavigation' ;
1210import NavigationItem from '../NavigationItem/NavigationItem' ;
11+ import Logo from '../Logo/Logo' ;
1312
1413import { NavigationClose , NavigationOpen } from '../../../../icons' ;
1514
@@ -22,136 +21,99 @@ export interface HeaderProps {
2221 data : HeaderData ;
2322}
2423
25- interface HeaderState {
26- isSidebarOpened : boolean ;
27- activeItemIndex : number ;
28- }
29-
30- class Header extends React . Component < HeaderProps , HeaderState > {
31- ref = createRef ( ) ;
32- state = {
33- isSidebarOpened : false ,
34- activeItemIndex : - 1 ,
35- } ;
36-
37- render ( ) {
38- return (
39- < Grid className = { b ( ) } >
40- < Row >
41- < Col >
42- < header className = { b ( 'wrapper' ) } >
43- { this . renderLogo ( ) }
44- { this . renderLeft ( ) }
45- { this . renderRight ( ) }
46- { this . renderMobileNavigation ( ) }
47- </ header >
48- </ Col >
49- </ Row >
50- </ Grid >
51- ) ;
52- }
53-
54- private renderLeft ( ) {
55- const { activeItemIndex} = this . state ;
56- const { leftItems} = this . props . data ;
57-
58- return (
59- leftItems && (
60- < div className = { b ( 'navigation-container' ) } >
61- < Navigation
62- className = { b ( 'navigation' ) }
63- links = { leftItems }
64- activeItemIndex = { activeItemIndex }
65- onActiveItemChange = { this . onActiveItemChange }
66- />
67- </ div >
68- )
69- ) ;
70- }
71-
72- private renderLogo ( ) {
73- const { logo} = this . props ;
74-
75- if ( ! logo ) {
76- return null ;
77- }
78-
79- return (
80- < div className = { b ( 'left' ) } >
81- < Logo { ...logo } className = { b ( 'logo' ) } />
82- </ div >
83- ) ;
84- }
85-
86- private renderRight ( ) {
87- return (
88- < div className = { b ( 'right' ) } >
89- { this . renderMobileMenuButton ( ) }
90- { this . renderRightItems ( ) }
91- </ div >
92- ) ;
93- }
94-
95- private renderRightItems ( ) {
96- const { rightItems} = this . props . data ;
97-
98- return (
99- rightItems && (
100- < div className = { b ( 'buttons' ) } >
101- { rightItems . map ( ( button ) => (
102- < NavigationItem key = { button . text } data = { button } className = { b ( 'button' ) } />
103- ) ) }
104- </ div >
105- )
106- ) ;
107- }
24+ export const Header : React . FC < HeaderProps > = ( { data, logo} ) => {
25+ const { leftItems, rightItems} = data ;
26+ const [ isSidebarOpened , setIsSidebarOpened ] = useState ( false ) ;
27+ const [ activeItemIndex , setActiveItemIndex ] = useState ( - 1 ) ;
28+
29+ const onActiveItemChange = useCallback ( ( index ) => {
30+ setActiveItemIndex ( index ) ;
31+ } , [ ] ) ;
32+
33+ const onSidebarOpenedChange = useCallback ( ( isOpen : boolean ) => {
34+ setIsSidebarOpened ( isOpen ) ;
35+ } , [ ] ) ;
36+
37+ const hideSidebar = useCallback ( ( ) => {
38+ setIsSidebarOpened ( false ) ;
39+ } , [ ] ) ;
40+
41+ const renderLogo = (
42+ < div className = { b ( 'left' ) } >
43+ < Logo { ...logo } className = { b ( 'logo' ) } />
44+ </ div >
45+ ) ;
46+
47+ const renderLeft = (
48+ < div className = { b ( 'navigation-container' ) } >
49+ < Navigation
50+ className = { b ( 'navigation' ) }
51+ links = { leftItems }
52+ activeItemIndex = { activeItemIndex }
53+ onActiveItemChange = { onActiveItemChange }
54+ />
55+ </ div >
56+ ) ;
10857
109- private renderMobileMenuButton ( ) {
110- const { isSidebarOpened} = this . state ;
58+ const renderMobileMenuButton = ( ) => {
11159 const iconProps = { icon : isSidebarOpened ? NavigationClose : NavigationOpen , iconSize : 36 } ;
11260
11361 return (
11462 < Control
11563 className = { b ( 'mobile-menu-button' ) }
11664 onClick = { ( e : MouseEvent ) => {
11765 e . stopPropagation ( ) ;
118- this . onSidebarOpenedChange ( ! isSidebarOpened ) ;
66+ onSidebarOpenedChange ( ! isSidebarOpened ) ;
11967 } }
12068 size = "l"
12169 { ...iconProps }
12270 />
12371 ) ;
124- }
125-
126- private renderMobileNavigation ( ) {
127- const { leftItems, rightItems} = this . props . data ;
128- const { isSidebarOpened, activeItemIndex} = this . state ;
129-
130- return (
131- < OutsideClick onOutsideClick = { ( ) => this . onSidebarOpenedChange ( false ) } >
132- < MobileNavigation
133- topItems = { leftItems }
134- bottomItems = { rightItems }
135- isOpened = { isSidebarOpened }
136- activeItemIndex = { activeItemIndex }
137- onActiveItemChange = { this . onActiveItemChange }
138- onClose = { this . hideSidebar }
139- />
140- </ OutsideClick >
141- ) ;
142- }
143-
144- private onActiveItemChange = ( index : number ) => {
145- this . setState ( { activeItemIndex : index } ) ;
14672 } ;
14773
148- private onSidebarOpenedChange = ( isSidebarOpened : boolean ) => {
149- this . setState ( { isSidebarOpened} ) ;
150- } ;
151-
152- private hideSidebar = ( ) => {
153- this . setState ( { isSidebarOpened : false } ) ;
154- } ;
155- }
74+ const renderRightItems = (
75+ < div className = { b ( 'buttons' ) } >
76+ { rightItems &&
77+ rightItems . map ( ( button ) => (
78+ < NavigationItem key = { button . text } data = { button } className = { b ( 'button' ) } />
79+ ) ) }
80+ </ div >
81+ ) ;
82+
83+ const renderRight = (
84+ < div className = { b ( 'right' ) } >
85+ { renderMobileMenuButton ( ) }
86+ { rightItems && renderRightItems }
87+ </ div >
88+ ) ;
89+
90+ const renderMobileNavigation = (
91+ < OutsideClick onOutsideClick = { ( ) => onSidebarOpenedChange ( false ) } >
92+ < MobileNavigation
93+ topItems = { leftItems }
94+ bottomItems = { rightItems }
95+ isOpened = { isSidebarOpened }
96+ activeItemIndex = { activeItemIndex }
97+ onActiveItemChange = { onActiveItemChange }
98+ onClose = { hideSidebar }
99+ />
100+ </ OutsideClick >
101+ ) ;
102+
103+ return (
104+ < Grid className = { b ( ) } >
105+ < Row >
106+ < Col >
107+ < header className = { b ( 'wrapper' ) } >
108+ { logo && renderLogo }
109+ { leftItems && renderLeft }
110+ { renderRight }
111+ { renderMobileNavigation }
112+ </ header >
113+ </ Col >
114+ </ Row >
115+ </ Grid >
116+ ) ;
117+ } ;
156118
157119export default Header ;
0 commit comments