From 57c781b951f65056c404acf5b51b6e3931202cb6 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Mon, 24 Jul 2023 23:27:44 +0530 Subject: [PATCH] Move notification to function component --- lib/components/notification.tsx | 179 +++++++++++++++----------------- lib/hyper.d.ts | 4 - 2 files changed, 85 insertions(+), 98 deletions(-) diff --git a/lib/components/notification.tsx b/lib/components/notification.tsx index 1b394cc7..256ea8c4 100644 --- a/lib/components/notification.tsx +++ b/lib/components/notification.tsx @@ -1,118 +1,109 @@ -import React from 'react'; -import type {NotificationProps, NotificationState} from '../hyper'; +import React, {forwardRef, useEffect, useRef, useState} from 'react'; +import type {NotificationProps} from '../hyper'; -export default class Notification extends React.PureComponent< - React.PropsWithChildren, - NotificationState -> { - dismissTimer!: NodeJS.Timeout; - constructor(props: NotificationProps) { - super(props); - this.state = { - dismissing: false - }; - } +const Notification = forwardRef>((props, ref) => { + const dismissTimer = useRef(undefined); + const [dismissing, setDismissing] = useState(false); - componentDidMount() { - if (this.props.dismissAfter) { - this.setDismissTimer(); - } - } + useEffect(() => { + setDismissTimer(); + }, []); - componentDidUpdate(prevProps: NotificationProps, prevState: NotificationState) { + useEffect(() => { // if we have a timer going and the notification text // changed we reset the timer - if (this.props.text !== prevProps.text) { - if (prevProps.dismissAfter) { - this.resetDismissTimer(); - } - if (prevState.dismissing) { - this.setState({dismissing: false}); - } - } - } + resetDismissTimer(); + setDismissing(false); + }, [props.text]); - handleDismiss = () => { - this.setState({dismissing: true}); + const handleDismiss = () => { + setDismissing(true); }; - onElement = (el: HTMLDivElement | null) => { + const onElement = (el: HTMLDivElement | null) => { if (el) { el.addEventListener('webkitTransitionEnd', () => { - if (this.state.dismissing) { - this.props.onDismiss(); + if (dismissing) { + props.onDismiss(); } }); - const {backgroundColor} = this.props; + const {backgroundColor} = props; if (backgroundColor) { el.style.setProperty('background-color', backgroundColor, 'important'); } + + if (ref) { + if (typeof ref === 'function') ref(el); + else ref.current = el; + } } }; - setDismissTimer() { - this.dismissTimer = setTimeout(() => { - this.handleDismiss(); - }, this.props.dismissAfter); - } + const setDismissTimer = () => { + if (typeof props.dismissAfter === 'number') { + dismissTimer.current = setTimeout(() => { + handleDismiss(); + }, props.dismissAfter); + } + }; - resetDismissTimer() { - clearTimeout(this.dismissTimer); - this.setDismissTimer(); - } + const resetDismissTimer = () => { + clearTimeout(dismissTimer.current); + setDismissTimer(); + }; - componentWillUnmount() { - clearTimeout(this.dismissTimer); - } + useEffect(() => { + return () => { + clearTimeout(dismissTimer.current); + }; + }, []); - render() { - const {backgroundColor, color} = this.props; - const opacity = this.state.dismissing ? 0 : 1; - return ( -
- {this.props.customChildrenBefore} - {this.props.children || this.props.text} - {this.props.userDismissable ? ( - - [x] - - ) : null} - {this.props.customChildren} + const {backgroundColor, color} = props; + const opacity = dismissing ? 0 : 1; + return ( +
+ {props.customChildrenBefore} + {props.children || props.text} + {props.userDismissable ? ( + + [x] + + ) : null} + {props.customChildren} - -
- ); - } -} + .notification_dismissLink:hover, + .notification_dismissLink:focus { + font-weight: 900; + } + `} +
+ ); +}); + +Notification.displayName = 'Notification'; + +export default Notification; diff --git a/lib/hyper.d.ts b/lib/hyper.d.ts index 264d01e2..8ec0820b 100644 --- a/lib/hyper.d.ts +++ b/lib/hyper.d.ts @@ -259,10 +259,6 @@ export type NotificationProps = { userDismissColor?: string; } & extensionProps; -export type NotificationState = { - dismissing: boolean; -}; - export type SplitPaneProps = { borderColor: string; direction: 'horizontal' | 'vertical';