Make <Notifications /> drop down on focus

This commit is contained in:
Jerko Steiner 2019-11-18 00:19:43 -03:00
parent b88889665f
commit 11727714ec
4 changed files with 32 additions and 23 deletions

View File

@ -143,7 +143,7 @@ function Options(props: OptionsProps) {
const label = labels[props.type] const label = labels[props.type]
return ( return (
<React.Fragment> <React.Fragment>
<option value='false'>{label} disabled</option> <option value='false'>Disable {label}</option>
<option value={props.default}>Default {label}</option> <option value={props.default}>Default {label}</option>
{ {
props.devices props.devices

View File

@ -34,11 +34,9 @@ describe('Notifications', () => {
} }
describe('render', () => { describe('render', () => {
it('renders and sets a timeout for notification', async () => { it('renders', async () => {
await render() await render()
expect(dismiss.mock.calls).toEqual([])
ReactDOM.unmountComponentAtNode(div) ReactDOM.unmountComponentAtNode(div)
expect(dismiss.mock.calls).toEqual([[ 'one' ]])
}) })
}) })

View File

@ -24,13 +24,13 @@ export interface NotificationProps {
const Notification = React.memo( const Notification = React.memo(
function Notification(props: NotificationProps) { function Notification(props: NotificationProps) {
const { dismiss, notification } = props const { dismiss, notification } = props
React.useEffect(() => { // React.useEffect(() => {
const timeout = setTimeout(dismiss, props.timeout, notification.id) // const timeout = setTimeout(dismiss, props.timeout, notification.id)
return () => { // return () => {
clearTimeout(timeout) // clearTimeout(timeout)
dismiss(notification.id) // dismiss(notification.id)
} // }
}, []) // }, [])
return ( return (
<div className={classnames(notification.type, 'notification')}> <div className={classnames(notification.type, 'notification')}>
{notification.message} {notification.message}
@ -42,24 +42,24 @@ const Notification = React.memo(
export default class Notifications export default class Notifications
extends React.PureComponent<NotificationsProps> { extends React.PureComponent<NotificationsProps> {
static defaultProps = { static defaultProps = {
max: 5, max: 20,
} }
render () { render () {
const { dismiss, notifications, max } = this.props const { dismiss, notifications, max } = this.props
return ( return (
<div className="notifications"> <div className="notifications" tabIndex={0}>
<TransitionGroup> <TransitionGroup>
{Object.keys(notifications).slice(-max).map(id => ( {Object.keys(notifications).slice(-max).reverse().map(id => (
<CSSTransition <CSSTransition
key={id} key={id}
classNames='fade' classNames='fade'
timeout={transitionTimeout} timeout={transitionTimeout}
> >
<Notification <Notification
notification={notifications[id]} notification={notifications[id]}
dismiss={dismiss} dismiss={dismiss}
timeout={10000} timeout={10000}
/> />
</CSSTransition> </CSSTransition>
))} ))}
</TransitionGroup> </TransitionGroup>

View File

@ -1,11 +1,15 @@
.notifications { .notifications {
pointer-events: none; position: absolute;
right: 0;
left: 0;
top: 0;
height: 20px;
overflow-y: hidden;
transition: height 200ms ease-in, background-color 200ms ease-in;
font-family: $font-monospace; font-family: $font-monospace;
font-size: 10px; font-size: 10px;
text-align: right; text-align: right;
width: 100%;
padding: 1rem;
height: 100px;
.notification { .notification {
color: $color-info; color: $color-info;
@ -20,4 +24,11 @@
.notification.warning { .notification.warning {
color: $color-warning; color: $color-warning;
} }
&:focus {
outline: none;
top: 0;
height: 200px;
background-color: rgba(0, 0, 0, 0.3);
}
} }