feat(toastNotification): adds toast notification component#48
feat(toastNotification): adds toast notification component#48priley86 merged 1 commit intopatternfly:masterfrom
Conversation
| children: PropTypes.node | ||
| } | ||
| TimedToastNotification.defaultProps = { | ||
| type: 'error', |
There was a problem hiding this comment.
I think we did the same with Alert. Happy to change this if you want...I will just make Alert match the same.
| const { notificationClass, type, onDismiss, children } = this.props | ||
| return ( | ||
| <ToastNotification | ||
| notificationClass={notificationClass} |
There was a problem hiding this comment.
you can use {...} operator instead of reassigning most of the props.
There was a problem hiding this comment.
i'll try this out soon..
ohadlevy
left a comment
There was a problem hiding this comment.
overall looks good code wize, could you please add:
- tests
- storybook with timer
| return ( | ||
| <div className={notificationClasses}> | ||
| {onDismiss && | ||
| <button |
There was a problem hiding this comment.
not sure if it matters, but should we use bootstrap Button vs html button?
| aria-hidden="true" | ||
| onClick={onDismiss} | ||
| > | ||
| <span className="pficon pficon-close" /> |
There was a problem hiding this comment.
not sure if matters either, but I would prefer to have an Icon component?
There was a problem hiding this comment.
i like this idea (have seen it used in other frameworks), but I am only seeing Glyphicons in React Bootstrap. Can you propose one you'd like me to try or maybe file a subsequent PR after this? Also not sure as to the syntax we'd like...
| /** callback when alert is dismissed */ | ||
| onDismiss: PropTypes.func, | ||
| /** the type of alert */ | ||
| type: PropTypes.oneOf(['danger', 'error', 'warning', 'success', 'info']) |
There was a problem hiding this comment.
DRY: maybe extract to a common const?
There was a problem hiding this comment.
hmm not sure if this warrants a shared const, as it is singular to this component? (even though Alert is similar, in my mind they are different components sharing common css). It also conceivable these components change in the future. I'm fine with using a shared const if you want though ;)
| @@ -0,0 +1,20 @@ | |||
| class Timer { | |||
There was a problem hiding this comment.
nitpick: not sure if it makes sense here, but should we in general retain copyright of copy/pasted code?
There was a problem hiding this comment.
heh ;) I think this warrants it's own comments now in this file...which could subsequently change here...
My hope is to start collectively making our shared inventions available, to aid in making our work easier to share :)
this is a singularly consumed/piece wise block, not a library consumption. It's also evident that consuming React itself makes our entire solution susceptible to the Facebook BSD+patents license. 😸
|
I've kept the There are a few snapshots...what else do you want to test? |
| /** timer delay */ | ||
| timerDelay: PropTypes.number, | ||
| /** additional notification classes */ | ||
| notificationClass: PropTypes.string, |
There was a problem hiding this comment.
This prop should be called 'className' which is standard for css classes in React
src/DropdownKebab/DropdownKebab.js
Outdated
| import PropTypes from 'prop-types' | ||
|
|
||
| const DropdownKebab = ({ children, id, pullRight }) => { | ||
| const DropdownKebab = ({ dropdownClass, children, id, pullRight }) => { |
There was a problem hiding this comment.
This is better called 'className'
| } | ||
| render() { | ||
| const { notificationClass, type, onDismiss, children } = this.props | ||
| return ( |
There was a problem hiding this comment.
If I understand it correctly, you'll need to wrap this in additional div and give it onMouseEnter and onMouseLeave props. Otherwise those won't ever get triggered.
Also we'll need to think about this further as notification pausing should happen for all notifications in the 'notification toaster' - a container of all toast notification. Because in case when 3 notification appear at once, user is not able to pause them all at once by hovering.
There was a problem hiding this comment.
'toast-notifications-list-pf' see https://rawgit.com/patternfly/patternfly/master-dist/dist/tests/toast.html
|
@jtomasek @ohadlevy i've made updates per suggestions... please have a look at the timer example in the updated storybook (see actions logger tab as you are hovering)...it shows that |
|
@jtomasek @ohadlevy i've added a helper @maryclarke @LHinson @jgiardino are we OK w/ the language/story layout on this one now? |
10316b2 to
01c8dd9
Compare
src/DropdownKebab/DropdownKebab.js
Outdated
| const kebabClass = ClassNames( | ||
| { | ||
| 'dropdown-kebab-pf': true | ||
| }, |
There was a problem hiding this comment.
can be simplified to
'dropdown-kebab-pf'
| <ToastNotification | ||
| {...this.props} | ||
| onMouseEnter={this.onMouseEnter} | ||
| onMouseLeave={this.onMouseLeave} |
There was a problem hiding this comment.
The onMouseEnter and onMouseLeave functions should be run when user hovers on ToastNotificationList rather than each individual ToastNotification. User wants to pause all notifications timers when hovering over ToastNotificationList.
So to achieve this, ToastNotificationList will keep 'paused' boolean in its state and toggle it with it's onMouseEnter and onMouseLeave callbacks.
TimedToastNotification will receive 'paused' prop from ToastNotificationList via passing props to children:
React.Children.map(
children,
child => React.cloneElement(child, {
paused: this.state.paused
})
);
TimedToastNotification then updates it's timer in componentWillReceiveProps instead of doing it in onMouseEnter/Leave functions.
With this onMouseEnter/Leave props are not needed in ToastNotification unless we really want to keep it around for flexibility.
There was a problem hiding this comment.
thanks for the detailed feedback @jtomasek ... i think this works better (and agree it would be weird to see other alerts dismiss if not hovered while hovering another one). I prefer with leaving the onMouseEnter/Leave available at the ToastNotification level as well as providing onMouseEnter/Leave on the ToastNotificationList (for more fine grained control if desired). i will make this update soon :)
There was a problem hiding this comment.
@jtomasek i've made updates to account for this now...
ToastNotificationList now has paused state and propogates this to children TimeToastNotification (ensuring that no other toast notifications will dismiss if a single one is hovered). If any notification is hovered, all notifications will reset their timer.
I am also allowing the consumer to observe onMouseEnter/onMouseLeave on the entire list or on each individual notification. I am aiming for as much flexibility as possible!
|
Hey @priley86, I like how you present this component in the storybook. I compared the html in this implementation to the html on patternfly.org, and there are a few things I noticed. Order of elements in DOM:
Whereas this implementation uses the following order:
Please switch the order so that It doesn’t matter so much what order the icon is in, since it’s displayed absolute and provides no content to screenreaders. The order in your implementation is actually better, in that both sighted users and screenreader users would get the contents in the same order. And in the future, the html/css is expected to change to use flex, to match the order you have now. But until then, we should use the order that matches the current html. Dismissible Toasts with Kebab: Is it possible to build this aspect of the pattern into the implementation of the component so that if a notification is dismissible and has a menu, then the close action is automatically included in the menu? If not, can we modify the behavior of the knobs so that this combination is not possible? Right now, this documentation detail is cited on the angular documentation for the component, but core design documentation is expected to be updated to match. Toast header vs toast message: |
1557322 to
65229ef
Compare
|
thanks for the thorough review here @jgiardino ! I've tried to address each, but let me know if this works for you... Order of elements in DOM:
The message now comes after the kebabs/actions, but i've left the icon rendered before. Moving the icon after kebabs/actions will come at a tradeoff of rendering the icon within the Notification component vs outside the component and alongside other children. As we have it now, numbers 2,3, and 4 above are rendered as children, and 1 is rendered inline (depending on if Dismissible Toasts with Kebab: Toast header vs toast message: |
|
@priley86 do you have any thoughts on breaking out the changes unrelated to toast notifications into separate PRs? I think having PRs that address one specific bug/feature/enhancement will make reviews easier. |
|
@waldenraines i will do my best there ;). I believe there was some common changes associated with this PR. Please defer reviewing my other PRs for now (I will label them WIP to denote). This one is most likely the closest to being ready. Would you mind reviewing it after ListView? I know it's a lot... |
|
Thanks for the updates, @priley86! Regarding this comment in your previous post:
This is great! However, I still see that the X for close remains in this case. Is it possible to remove the X when both the Dismiss and Menu knobs are selected? |
|
Hey @priley86 |
|
As a follow up to Leslie's comment, in the Storybook example for Toast Notification List, are we supposed to see the behavior of the toast notification automatically disappearing after eight seconds? These notifications are always displaying. |
65229ef to
ad6bf88
Compare
|
@jgiardino @LHinson after discussing in the design review today, I will update the sticky notification to say "A persistent notification will remain on the screen until closed.". "Sticky" is not consistent with angular-pf and doesn't imply exactly the same meaning (so will just update the verbiage in the visual presentation of the story). Also - we are awaiting confirmation on the behavior of hover effect on the notification list in the following upstream design issue: |
|
@jgiardino i've updated the Toast Notification List example to allow the notifications to dismiss after the specified delay (8 seconds), and included a "reset notification state" button which resets the timers and the notification state. You can now see that hovering the notifications will pause the dismiss. Let me know if this works! |
|
will rebase this PR after #55 is merged. |
|
The updates look good to me! Thanks!! |
9415be9 to
15d5c30
Compare
|
i've rebased this PR w/ latest after merging #55 |
71685a7 to
9f43445
Compare
|
merging this PR as a baseline for notification/notification list. we can iterate in subsequent PRs if necessary. |
Closes #47
What:
ToastNotificationandToastNotificationListReact component and toast notification stories to Storybook.dropdownClasstoDropdownKebabcomponentTimedToastNotificationstateful component for consumers using a timer componentStorybook:
https://rawgit.com/priley86/patternfly-react/toast-notification/index.html