Skip to content

Commit

Permalink
[components] Add new snackbars (#1426)
Browse files Browse the repository at this point in the history
* [snackbar] add new snackbar

* [snackbar] put default snackbar back and create provider part

* [snackbar] fix old and new parts

* [snackbar] update provider part path

* [snackbar] add height handler for stack offsets

* [snackbar] add action handler

* [snackbar] improve naming

* [snackbar] add children as props

* [snackbar] add context

* [snackbar] update styles

* [snackbar] make snackbar accessible

* [snackbar] linting

* [snackbar] add default icons to snacks

* [snackbar] refactor provider and item

* [snackbar] update DefaultSnackbar.js + its instances

* [snackbar] fix persist status

* [components] Queue snackbar story

* [components] improve var naming

* [components] flatten snackbar props

* [components] refactor, and improve a11y

* [components] refactor and fix transitions

* [components] add snackbar stories

* [components] refactor props, improve readability

* [components] refactor hide and action behaviours

* [components] improve snackbar on smaller screens

* [components] clear timeouts on unmount

* [components] fix css class names and id generator

* [components] fix possible message types

* [components] dismiss snack on willUnmount

* [components] remove danger state

* [components] fix default icons

* [components] fix tabindex and outline focus

* [components] fix icon and content alignment

* [components] update storybook

* [components] fix close icon color inheritance

* [components] fix snackbar styles and sizes

* [components] fix with and w/o icon spacing

* [components] fix tabindex on snack item

* [components] remove transitionDuration as prop

* [components] remove another transitionDuration

* [components] update with discussed changes

* [components] update text and icon alignment

* [components] add title and subtitle

* [components] fix margins and alignments

* [components] update story

* [components] simplify story

* [components] fix action and close bleed

* [components] float action and close buttons

* [components] Last changes made together with Victoria

* [components] fix action title bug

* [components] updates according to kris' review
  • Loading branch information
vicmeow authored Aug 12, 2019
1 parent b55701f commit 8464b68
Show file tree
Hide file tree
Showing 21 changed files with 828 additions and 183 deletions.
10 changes: 9 additions & 1 deletion packages/@sanity/base/sanity.json
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@
},
{
"implements": "part:@sanity/base/circle-check-icon",
"path": "components/icons/CircleCheck.js"
"path": "components/icons/CheckCircle.js"
},
{
"implements": "part:@sanity/base/check-icon",
Expand Down Expand Up @@ -823,6 +823,10 @@
"implements": "part:@sanity/base/time-icon",
"path": "components/icons/Time.js"
},
{
"implements": "part:@sanity/base/info-icon",
"path": "components/icons/Info.js"
},
{
"implements": "part:@sanity/base/error-icon",
"path": "components/icons/Error.js"
Expand All @@ -831,6 +835,10 @@
"implements": "part:@sanity/base/warning-icon",
"path": "components/icons/Warning.js"
},
{
"implements": "part:@sanity/base/danger-icon",
"path": "components/icons/Danger.js"
},
{
"implements": "part:@sanity/base/file-icon",
"path": "components/icons/File.js"
Expand Down
12 changes: 6 additions & 6 deletions packages/@sanity/base/src/components/ErrorHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ export default class ErrorHandler extends React.PureComponent {
const message = __DEV__ ? `An error occured: ${error.message}` : 'An error occured'

return (
<Snackbar kind="error" action={{title: 'Close'}} onAction={this.handleClose} timeout={2500}>
<div className={styles.errorMessageHeader}>
<strong>{message}</strong>
</div>
<div>Check browser javascript console for details</div>
</Snackbar>
<Snackbar
kind="error"
onAction={this.handleClose}
title={<strong>{message}</strong>}
subtitle={<div>Check browser javascript console for details</div>}
/>
)
}
}
9 changes: 6 additions & 3 deletions packages/@sanity/base/src/components/SanityRoot.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import config from 'config:sanity'
import RootComponent from 'part:@sanity/base/root'
import SnackbarProvider from 'part:@sanity/components/snackbar/provider'
import ErrorHandler from './ErrorHandler'
import VersionChecker from './VersionChecker'
import MissingProjectConfig from './MissingProjectConfig'
Expand All @@ -14,9 +15,11 @@ function SanityRoot() {

return (
<div className={styles.root}>
<ErrorHandler />
<RootComponent />
<VersionChecker />
<SnackbarProvider>
<ErrorHandler />
<RootComponent />
<VersionChecker />
</SnackbarProvider>
</div>
)
}
Expand Down
3 changes: 3 additions & 0 deletions packages/@sanity/base/src/components/icons/CheckCircle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CheckCircle from 'react-icons/lib/md/check-circle'

export default CheckCircle
3 changes: 0 additions & 3 deletions packages/@sanity/base/src/components/icons/CircleCheck.js

This file was deleted.

3 changes: 3 additions & 0 deletions packages/@sanity/base/src/components/icons/Danger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FaTimesCircle from 'react-icons/lib/fa/times-circle'

export default FaTimesCircle
3 changes: 3 additions & 0 deletions packages/@sanity/base/src/components/icons/Info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MdInfo from 'react-icons/lib/md/info'

export default MdInfo
26 changes: 25 additions & 1 deletion packages/@sanity/components/sanity.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,23 @@
},
{
"name": "part:@sanity/components/snackbar/default",
"description": "Deprecated snackbar."
},
{
"name": "part:@sanity/components/snackbar/item",
"description": "Shows messages with an action and a timeout."
},
{
"name": "part:@sanity/components/snackbar/default-style",
"description": "Styling for snackbar"
"description": "Styling for the deprecated default snackbar"
},
{
"name": "part:@sanity/components/snackbar/provider",
"description": "Snackbar provider to show messages."
},
{
"name": "part:@sanity/components/snackbar/snackbar-style",
"description": "Styling for new snackbars."
},
{
"name": "part:@sanity/components/menus/default",
Expand Down Expand Up @@ -602,6 +614,14 @@
"implements": "part:@sanity/components/snackbar/default",
"path": "snackbar/DefaultSnackbar.js"
},
{
"implements": "part:@sanity/components/snackbar/item",
"path": "snackbar/SnackbarItem.js"
},
{
"implements": "part:@sanity/components/snackbar/provider",
"path": "snackbar/SnackbarProvider.js"
},
{
"implements": "part:@sanity/components/edititem/fold",
"path": "edititem/EditItemFoldOut.js"
Expand Down Expand Up @@ -766,6 +786,10 @@
"implements": "part:@sanity/components/snackbar/default-style",
"path": "snackbar/styles/DefaultSnackbar.css"
},
{
"implements": "part:@sanity/components/snackbar/snackbar-style",
"path": "snackbar/styles/SnackbarItem.css"
},
{
"implements": "part:@sanity/components/menus/default",
"path": "menus/DefaultMenu.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ span.content {
}
}

.padding_none.bleed.onlyIcon .content {
margin: 0 !important;
}

.default {
composes: root;
background-color: var(--default-button-color);
Expand Down
4 changes: 2 additions & 2 deletions packages/@sanity/components/src/selects/StyleSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ArrowKeyNavigation from 'boundless-arrow-key-navigation/build'
import styles from 'part:@sanity/components/selects/style-style'
import ArrowIcon from 'part:@sanity/base/angle-down-icon'
import CircleThinIcon from 'part:@sanity/base/circle-thin-icon'
import CircleCheckIcon from 'part:@sanity/base/circle-check-icon'
import CheckCircleIcon from 'part:@sanity/base/circle-check-icon'
import {List} from 'part:@sanity/components/lists/default'
import Poppable from 'part:@sanity/components/utilities/poppable'

Expand Down Expand Up @@ -195,7 +195,7 @@ class StyleSelect extends React.PureComponent {
ref={index === 0 && this.firstItemElement}
>
<div className={styles.itemIcon}>
{isSelected && <CircleCheckIcon />}
{isSelected && <CheckCircleIcon />}
{isSemiSelected && <CircleThinIcon />}
</div>
<div className={styles.itemContent}>{renderItem(item)}</div>
Expand Down
145 changes: 45 additions & 100 deletions packages/@sanity/components/src/snackbar/DefaultSnackbar.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,64 @@
import PropTypes from 'prop-types'
import React from 'react'
import styles from 'part:@sanity/components/snackbar/default-style'
import Button from 'part:@sanity/components/buttons/default'
import {Portal} from '../utilities/Portal'

export default class DefaultSnackbar extends React.PureComponent {
static propTypes = {
kind: PropTypes.oneOf(['danger', 'info', 'warning', 'error', 'success']),
children: PropTypes.node.isRequired,
timeout: PropTypes.number,
onHide: PropTypes.func,
onAction: PropTypes.func,
kind: PropTypes.oneOf(['info', 'warning', 'error', 'success']),
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
isPersisted: PropTypes.bool,
children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
onClose: PropTypes.func,
action: PropTypes.shape({
title: PropTypes.string
})
}

static defaultProps = {
kind: 'info',
timeout: 0,
onHide: () => {}
// Title is also a legacy prop
title: PropTypes.string,
callback: PropTypes.func
}),
// Legacy props
onAction: PropTypes.func,
actionTitle: PropTypes.string,
timeout: PropTypes.number
}

constructor(props, context) {
super(props, context)
this.state = {
visible: true
}
static contextTypes = {
addToSnackQueue: PropTypes.func,
handleDismissSnack: PropTypes.func
}

componentDidMount() {
this.scheduleHide()
}

hide = () => {
this.setState({visible: false})
setTimeout(this.props.onHide(), 200)
}

show = () => {
this.setState({visible: true})
}

cancelHide() {
clearTimeout(this._timerId)
}

scheduleHide() {
const {timeout} = this.props
this.cancelHide()
if (timeout > 0) {
this._timerId = setTimeout(this.hide, timeout * 1000)
}
const {
action,
actionTitle,
kind,
title,
subtitle,
timeout,
children,
onClose,
onAction,
isPersisted
} = this.props

this.snackId = this.context.addToSnackQueue({
kind,
title,
subtitle,
children,
onClose,
action: {
title: actionTitle || (action && action.title),
callback: onAction || (action && action.callback)
},
isPersisted,
autoDismissTimeout: timeout
})
}

componentWillUnmount() {
this.cancelHide()
}

componentDidUpdate(prevProps) {
if (prevProps.timeout !== this.props.timeout) {
this.scheduleHide()
}
if (prevProps.children !== this.props.children) {
this.scheduleHide()
}
}

componentWillReceiveProps(nextProps) {
if (nextProps.timeout !== this.props.timeout) {
this.show()
}
if (nextProps.children !== this.props.children) {
this.show()
}
}

handleAction = () => {
this.props.onAction(this.props.action)
}

handleMouseOver = () => {
this.cancelHide()
}

handleMouseLeave = () => {
this.scheduleHide()
this.context.handleDismissSnack(this.snackId)
}

render() {
const {kind, action, children} = this.props

const style = `${styles[kind] || styles.root} ${
this.state.visible ? styles.visible : styles.hidden
}`

return (
<Portal>
<div className={style}>
<div
className={styles.inner}
onMouseOver={this.handleMouseOver}
onMouseLeave={this.handleMouseLeave}
>
{action && (
<div className={styles.action}>
<Button inverted color="white" onClick={this.handleAction}>
{action.title}
</Button>
</div>
)}
<div className={styles.content}>{children}</div>
</div>
</div>
</Portal>
)
return <div />
}
}
Loading

0 comments on commit 8464b68

Please sign in to comment.