Skip to content
This repository has been archived by the owner on Jun 20, 2022. It is now read-only.

Commit

Permalink
feat(Alert): add alerts
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Mixins are now a function that takes props and return another function.
  • Loading branch information
gregberge committed Apr 1, 2018
1 parent 2e7daf8 commit ec57ee4
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ module.exports = {
'import/prefer-default-export': 'off',

'no-return-assign': 'off',
'no-param-reassign': 'off',
'no-shadow': 'off',
},
}
69 changes: 69 additions & 0 deletions src/Alert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import styled, { css } from 'styled-components'
import handleRef from './internal/handleRef'
import setWithComponent from './internal/setWithComponent'
import * as defaultTheme from './style/defaultTheme'
import { th, mixin } from './utils'

const variants = [
'primary',
'secondary',
'success',
'danger',
'warning',
'info',
'light',
'dark',
]

const AlertComponent = ({
className,
component: Component = 'div',
theme,
variant,
...props
}) => (
<Component
{...props}
className={classNames(
'sui-alert',
{
[`sui-alert-${variant}`]: variant,
},
className,
)}
/>
)

const Alert = styled(handleRef(AlertComponent))`
position: relative;
padding: ${th('alertPaddingY')} ${th('alertPaddingX')};
margin-bottom: ${th('alertMarginBottom')};
border: 1px solid transparent;
border-radius: ${th('borderRadius')};
${variants.map(
variant => css`
&.sui-alert-${variant} {
${mixin('alertVariant', variant)};
}
`,
)};
`

Alert.propTypes = {
variant: PropTypes.oneOf(variants),
theme: PropTypes.object,
}

Alert.defaultProps = {
variant: 'primary',
theme: defaultTheme,
}

setWithComponent(Alert, AlertComponent)

/** @component */
export default Alert
32 changes: 32 additions & 0 deletions src/Alert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
### Variants

Set sizes using `variant` prop.

```js
<div>
<span style={{ margin: '5px' }}>
<Alert variant="primary">Primary</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="secondary">Secondary</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="success">Success</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="danger">Danger</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="warning">Warning</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="info">Info</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="light">Light</Alert>
</span>
<span style={{ margin: '5px' }}>
<Alert variant="dark">Dark</Alert>
</span>
</div>
```
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as defaultTheme from './style/defaultTheme'

export { default as Alert } from './Alert'
export { default as Box } from './Box'
export { default as Button } from './Button'
export { default as Checkbox } from './Checkbox'
Expand Down
52 changes: 47 additions & 5 deletions src/style/defaultTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
modularScale,
darken,
parseToRgb,
mix,
} from 'polished'
import { th, mixin } from '../utils'

Expand Down Expand Up @@ -151,6 +152,16 @@ export const controlFocusBorderColor = th('primary', color =>
export const controlFocusBoxShadow = color =>
css`0 0 0 0.2rem ${th(color, c => transparentize(0.75, c))}`

// Alerts

export const alertPaddingY = '.75rem'
export const alertPaddingX = '1.25rem'
export const alertMarginBottom = '1rem'

export const alertBgLevel = -10
export const alertBorderLevel = -9
export const alertColorLevel = 6

// Z-indexes

export const zIndexControl = 1
Expand All @@ -170,15 +181,20 @@ export const breakPoints = {
xl: 1200,
}

// Color levels

export const yiqContrastedThreshold = 150
export const colorInterval = 0.08

// Mixins

export const controlFocus = (baseColor = 'primary') => css`
export const controlFocus = props => (baseColor = 'primary') => css`
outline: 0;
box-shadow: 0 0 2px ${th(baseColor, color => transparentize(0.1, color))};
`

export const btnVariant = baseColor => css`
color: ${props => props.theme.colorYik(th(baseColor)(props))};
export const btnVariant = props => baseColor => css`
color: ${mixin('colorYik', th(baseColor))};
background-color: ${th(baseColor)};
&:focus {
Expand All @@ -191,8 +207,34 @@ export const btnVariant = baseColor => css`
}
`

export const colorYik = color => {
export const alertVariant = props => baseColor =>
css`
color: ${mixin('colorLevel', th(baseColor), th('alertColorLevel'))};
background-color: ${mixin('colorLevel', th(baseColor), th('alertBgLevel'))};
border-color: ${mixin('colorLevel', th(baseColor), th('alertBorderLevel'))};
hr {
border-top-color: ${props =>
darken(
0.05,
mixin('colorLevel', th(baseColor), th('alertColorLevel'))(props),
)};
}
`

export const colorLevel = props => (color, level) => {
color = typeof color === 'function' ? color(props) : color
level = typeof level === 'function' ? level(props) : level
const baseColor = level > 0 ? th('black')(props) : th('white')(props)
const absLevel = Math.abs(level)
return mix(absLevel * colorInterval, baseColor, color)
}

export const colorYik = props => color => {
color = typeof color === 'function' ? color(props) : color
const { red: r, green: g, blue: b } = parseToRgb(color)
const yik = (r * 299 + g * 587 + b * 114) / 1000
return yik >= 150 ? th('yikTextDark') : th('yikTextLight')
return yik >= th('yiqContrastedThreshold')(props)
? th('yikTextDark')(props)
: th('yikTextLight')(props)
}
3 changes: 2 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export const th = (name, modifier = x => x) => props => {
return modifier(result)
}

export const mixin = (name, ...args) => props => props.theme[name](...args)
export const mixin = (name, ...args) => props =>
props.theme[name](props)(...args)
1 change: 1 addition & 0 deletions styleguide.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = {
{
name: 'Components',
components: () => [
path.resolve(__dirname, 'src/Alert.js'),
path.resolve(__dirname, 'src/Box.js'),
path.resolve(__dirname, 'src/Button.js'),
path.resolve(__dirname, 'src/Checkbox.js'),
Expand Down

0 comments on commit ec57ee4

Please sign in to comment.