11import _ from 'lodash' ;
22import block from 'bem-cn-lite' ;
3- import React , { Fragment , createRef , RefObject } from 'react' ;
3+ import React , { Fragment , useRef , useState , useEffect , useCallback } from 'react' ;
44import { Portal } from '@gravity-ui/uikit' ;
55
66import { OutsideClick } from '../../../index' ;
7- import { NavigationLinkItem } from '../../../../models/navigation ' ;
7+ import { NavigationLinkItem } from '../../../../models' ;
88import NavigationItem from '../NavigationItem/NavigationItem' ;
99
1010import './NavigationPopup.scss' ;
@@ -18,73 +18,54 @@ export interface NavigationPopupProps {
1818 className ?: string ;
1919}
2020
21- interface NavigationPopupState {
22- calculatedLeft ?: number ;
23- }
24-
25- export default class NavigationPopup extends React . Component <
26- NavigationPopupProps ,
27- NavigationPopupState
28- > {
29- ref : RefObject < HTMLDivElement > = createRef ( ) ;
30- state = {
31- calculatedLeft : this . props . left ,
32- } ;
33-
34- private calculateLeft = _ . debounce ( ( ) => {
35- const { left} = this . props ;
21+ export const NavigationPopup : React . FC < NavigationPopupProps > = ( { items, left, onClose} ) => {
22+ const [ calculatedLeft , setCalculatedLeft ] = useState ( left ) ;
23+ const popupRef = useRef < HTMLDivElement > ( null ) ;
3624
37- if ( this . ref && this . ref . current && left ) {
38- const right = left + this . ref . current . offsetWidth ;
25+ const calculateLeft = useCallback ( ( ) => {
26+ if ( popupRef && popupRef . current && left ) {
27+ const right = left + popupRef . current . offsetWidth ;
3928 const docWidth = document . body . clientWidth ;
40- const calculatedLeft = right > docWidth ? left - ( right - docWidth ) : left ;
41- this . setState ( { calculatedLeft } ) ;
29+ const currentLeft = right > docWidth ? left - ( right - docWidth ) : left ;
30+ setCalculatedLeft ( currentLeft ) ;
4231 } else {
43- this . setState ( { calculatedLeft : left } ) ;
32+ setCalculatedLeft ( left ) ;
4433 }
45- } , 100 ) ;
34+ } , [ left ] ) ;
4635
47- componentDidMount ( ) {
48- this . calculateLeft ( ) ;
49- window . addEventListener ( 'resize' , this . calculateLeft ) ;
50- }
36+ useEffect ( ( ) => {
37+ const debounceCalculateLeft = _ . debounce ( calculateLeft , 100 ) ;
38+ calculateLeft ( ) ;
39+ window . addEventListener ( 'resize' , debounceCalculateLeft ) ;
5140
52- componentDidUpdate ( prevProps : NavigationPopupProps ) {
53- if ( prevProps . left !== this . props . left ) {
54- this . calculateLeft ( ) ;
55- }
56- }
41+ return ( ) => {
42+ window . removeEventListener ( 'resize' , debounceCalculateLeft ) ;
43+ } ;
44+ } , [ calculateLeft ] ) ;
5745
58- componentWillUnmount ( ) {
59- window . removeEventListener ( 'resize' , this . calculateLeft ) ;
60- }
46+ useEffect ( ( ) => {
47+ calculateLeft ( ) ;
48+ } , [ calculateLeft , left ] ) ;
6149
62- render ( ) {
63- if ( ! document || ! document . body ) {
64- return null ;
65- }
50+ if ( ! document || ! document . body ) {
51+ return null ;
52+ }
6653
67- const { onClose} = this . props ;
68- const { calculatedLeft} = this . state ;
54+ const renderDefaultPopup = (
55+ < Fragment >
56+ { items . map ( ( item ) => (
57+ < NavigationItem key = { item . text } className = { b ( 'link' ) } data = { item } />
58+ ) ) }
59+ </ Fragment >
60+ ) ;
6961
70- return (
71- < Portal >
72- < div ref = { this . ref } className = { b ( ) } style = { { left : calculatedLeft } } >
73- < OutsideClick onOutsideClick = { onClose } >
74- { this . renderDefaultPopup ( ) }
75- </ OutsideClick >
76- </ div >
77- </ Portal >
78- ) ;
79- }
62+ return (
63+ < Portal >
64+ < div ref = { popupRef } className = { b ( ) } style = { { left : calculatedLeft } } >
65+ < OutsideClick onOutsideClick = { onClose } > { renderDefaultPopup } </ OutsideClick >
66+ </ div >
67+ </ Portal >
68+ ) ;
69+ } ;
8070
81- private renderDefaultPopup ( ) {
82- return (
83- < Fragment >
84- { this . props . items . map ( ( item ) => (
85- < NavigationItem key = { item . text } className = { b ( 'link' ) } data = { item } />
86- ) ) }
87- </ Fragment >
88- ) ;
89- }
90- }
71+ export default NavigationPopup ;
0 commit comments