Skip to content

Commit

Permalink
Merge pull request #38 from yamitrvg12/main
Browse files Browse the repository at this point in the history
Create Alert component
  • Loading branch information
vczb authored Oct 4, 2022
2 parents d6debec + ed3dfb9 commit b64b1ef
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/icons/Error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
const Error = () => (
<svg
viewBox="0 0 32 32"
width="1em"
height="1em"
fill="currentColor"
aria-label="error"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M23.936 20.711c0-.363-.133-.672-.393-.937L19.769 16l3.771-3.769a1.28 1.28 0 00.393-.937c0-.377-.133-.695-.393-.958l-1.877-1.874a1.312 1.312 0 00-.962-.395c-.361 0-.67.133-.937.395l-3.765 3.769L12.23 8.46a1.293 1.293 0 00-.939-.395c-.375 0-.697.133-.958.395l-1.874 1.874a1.312 1.312 0 00-.395.958c0 .361.133.67.395.937L12.23 16l-3.771 3.771a1.278 1.278 0 00-.395.937c0 .375.133.695.395.96l1.874 1.874c.263.263.583.393.958.393.361 0 .672-.13.937-.393l3.771-3.771 3.769 3.771c.265.263.576.393.937.393.377 0 .697-.13.962-.393l1.877-1.874c.258-.265.391-.587.391-.958zM32 16c0 2.903-.715 5.579-2.144 8.03a15.931 15.931 0 01-5.822 5.826c-2.457 1.429-5.131 2.142-8.034 2.142s-5.579-.711-8.034-2.142a15.924 15.924 0 01-5.822-5.826C.715 21.58 0 18.903 0 16s.715-5.579 2.146-8.032 3.369-4.393 5.822-5.822S13.097.002 16 .002s5.577.715 8.034 2.146a15.928 15.928 0 015.822 5.822C31.282 10.42 32 13.097 32 16z"
fill="currentColor"
/>
</svg>
)

export default Error
20 changes: 20 additions & 0 deletions src/icons/Info.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
const Info = () => (
<svg
viewBox="0 0 14 14"
width="1em"
height="1em"
fill="currentColor"
aria-label="info"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7 14A7 7 0 117 0a7 7 0 010 14zm0-9.333a1.167 1.167 0 100-2.334 1.167 1.167 0 000 2.334zm0 1.166c-.644 0-1.167.522-1.167 1.167v3.5a1.167 1.167 0 002.334 0V7c0-.644-.522-1.167-1.167-1.167z"
fill="currentColor"
/>
</svg>
)

export default Info
20 changes: 20 additions & 0 deletions src/icons/Success.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
const Success = () => (
<svg
viewBox="0 0 14 14"
width="1em"
height="1em"
fill="currentColor"
aria-label="success"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7 14A7 7 0 117 0a7 7 0 010 14zM5.848 7.702L4.342 6.196a1.166 1.166 0 10-1.65 1.65l2.333 2.333a1.166 1.166 0 001.707-.061l4.61-4.61a1.166 1.166 0 10-1.65-1.65L5.848 7.702z"
fill="currentColor"
/>
</svg>
)

export default Success
20 changes: 20 additions & 0 deletions src/icons/Warning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
const Warning = () => (
<svg
viewBox="0 0 14 14"
width="1em"
height="1em"
fill="currentColor"
aria-label="warning"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8.021 1.101l5.832 10.509a1.168 1.168 0 01-1.021 1.734H1.167a1.167 1.167 0 01-1.02-1.734L5.979 1.101a1.167 1.167 0 012.041 0zM7 12.177a1.167 1.167 0 100-2.334 1.167 1.167 0 000 2.334zm0-9.34c-.645 0-1.167.523-1.167 1.167v3.502a1.167 1.167 0 002.334 0V4.004c0-.645-.523-1.167-1.167-1.167z"
fill="currentColor"
/>
</svg>
)

export default Warning
4 changes: 4 additions & 0 deletions src/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ export { default as Up } from './Up'
export { default as Minus } from './Minus'
export { default as Plus } from './Plus'
export { default as Elipsis } from './Elipsis'
export { default as Info } from './Info'
export { default as Success } from './Success'
export { default as Error } from './Error'
export { default as Warning } from './Warning'
64 changes: 64 additions & 0 deletions src/packages/Alert/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { BaseHTMLAttributes, useCallback, useState } from 'react'
import { STATUS_ICONS } from '../../utils/statusIcons'
import Button from '../Button'
import * as S from './styles'

export type AlertProps = {
children: React.ReactNode
severity?: 'error' | 'warning' | 'info' | 'success'
header?: React.ReactNode
showIcon?: boolean
closable?: boolean
onClose?: (event?: React.MouseEvent<HTMLButtonElement>) => void
} & BaseHTMLAttributes<HTMLDivElement>

type DisplayType = 'show' | 'hide'

const Alert = ({
children,
severity = 'info',
header,
showIcon = false,
closable = false,
onClose,
...props
}: AlertProps) => {
const [display, setDisplay] = useState<DisplayType>('show')

const handleClose = useCallback(
(event: React.MouseEvent<HTMLButtonElement>) => {
setDisplay('hide')
onClose?.(event)
},
[onClose]
)

if (display === 'hide') {
return null
}

return (
<S.Wrapper role="alert" severity={severity} {...props}>
<S.Container>
{closable && (
<S.CloseButton>
<Button outline={false} size="xsmall" onClick={handleClose}>
X
</Button>
</S.CloseButton>
)}
{showIcon && (
<S.IconWrapper severity={severity} header={header}>
{STATUS_ICONS[severity as keyof typeof STATUS_ICONS]}
</S.IconWrapper>
)}
<S.Content>
{header && <S.Header>{header}</S.Header>}
<S.Body>{children}</S.Body>
</S.Content>
</S.Container>
</S.Wrapper>
)
}

export default Alert
17 changes: 17 additions & 0 deletions src/packages/Alert/stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import { Story, Meta } from '@storybook/react/types-6-0'
import Alert, { AlertProps } from '.'

export default {
title: 'Alert',
component: Alert,
args: {
children: 'This is an info alert',
severity: 'info',
header: '',
showIcon: true,
closable: false
}
} as Meta

export const Default: Story<AlertProps> = (args) => <Alert {...args} />
105 changes: 105 additions & 0 deletions src/packages/Alert/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import styled, { css, DefaultTheme } from 'styled-components'
import { AlertProps } from '.'

const severityShape = {
error: (theme: DefaultTheme) => css`
background-color: ${theme.colors.status.error}1f;
`,
warning: (theme: DefaultTheme) => css`
background-color: ${theme.colors.status.warning}1f;
`,
info: (theme: DefaultTheme) => css`
background-color: ${theme.colors.status.info}1f;
`,
success: (theme: DefaultTheme) => css`
background-color: ${theme.colors.status.success}1f;
`
}

const severityIconColor = {
error: (theme: DefaultTheme) => css`
color: ${theme.colors.status.error};
`,
warning: (theme: DefaultTheme) => css`
color: ${theme.colors.status.warning};
`,
info: (theme: DefaultTheme) => css`
color: ${theme.colors.status.info};
`,
success: (theme: DefaultTheme) => css`
color: ${theme.colors.status.success};
`
}

export const Wrapper = styled.div<Pick<AlertProps, 'severity'>>`
${({ theme, severity = 'info' }) => css`
animation-fill-mode: forwards;
border-radius: ${theme.border.radius};
position: relative;
transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
${!!severity && severityShape[severity](theme)}}
`}
`

export const Container = styled.div`
${({ theme }) => css`
display: flex;
padding: ${theme.spacings.xsmall} ${theme.spacings.small}
${theme.spacings.xsmall} ${theme.spacings.xsmall};
`}
`

export const Content = styled.div`
${() => css`
flex-grow: 1;
`}
`

export const Body = styled.div`
${({ theme }) => css`
color: ${theme.colors.neutral.xdarkest};
font-size: ${theme.font.sizes.small};
`}
`

export const Header = styled.div`
${({ theme }) => css`
font-size: ${theme.font.sizes.medium};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
color: ${theme.colors.neutral.xdarkest};
line-height: 1.3;
margin-bottom: ${theme.spacings.mini};
`}
`

export const IconWrapper = styled.div<Pick<AlertProps, 'severity' | 'header'>>`
${({ theme, severity = 'info', header }) => css`
align-self: ${header ? 'flex-start' : 'center'};
font-size: 0;
margin-right: ${theme.spacings.xxsmall};
svg {
align-items: center;
font-size: ${header ? theme.font.sizes.xlarge : theme.font.sizes.xsmall};
${!!severity && severityIconColor[severity](theme)}}
}
`}
`

export const CloseButton = styled.div`
${({ theme }) => css`
background: transparent;
border: none;
cursor: pointer;
font-size: ${theme.font.sizes.xsmall};
line-height: 1;
outline: none;
padding-top: ${theme.spacings.mini};
position: absolute;
right: 0;
top: 0;
`}
`
1 change: 1 addition & 0 deletions src/packages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export { default as TextContent } from './TextContent'
export { default as Divider } from './Divider'
export { default as Card } from './Card'
export { default as Avatar } from './Avatar'
export { default as Alert } from './Alert'
10 changes: 9 additions & 1 deletion src/styles/theme/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ export const neutral = {
xdarkest: '#4D4D4D'
}

export const status = {
error: '#f44336',
warning: '#ffb300',
info: '#2196f3',
success: '#4caf50'
}

export default {
base,
primary,
secondary,
neutral
neutral,
status
}
9 changes: 9 additions & 0 deletions src/utils/statusIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'
import { Info, Success, Error, Warning } from '../icons'

export const STATUS_ICONS = {
info: <Info />,
success: <Success />,
error: <Error />,
warning: <Warning />
}

0 comments on commit b64b1ef

Please sign in to comment.