Ajoute le composant Chip au design system

pull/2431/head
Johan Girod 2022-12-13 17:19:40 +01:00
parent dea83c3836
commit b8bf9e0ae4
5 changed files with 168 additions and 14 deletions

View File

@ -0,0 +1,59 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'
import { Chip } from '@/design-system'
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
export default {
component: Chip,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {
children: { type: 'string' },
},
} as ComponentMeta<typeof Chip>
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template: ComponentStory<typeof Chip> = (args) => <Chip {...args} />
export const Notification = Template.bind({})
// More on args: https://storybook.js.org/docs/react/writing-stories/args
Notification.args = {
children: '4',
type: 'info',
}
export const DifferentChips: ComponentStory<typeof Chip> = (args) => (
<>
<Chip {...args} type="error">
Panique !
</Chip>
<Chip {...args} type="info">
Attention
</Chip>
<Chip {...args} type="success">
Ouiiiiiii
</Chip>
<Chip {...args} type="primary">
4 messages non lus
</Chip>
<Chip {...args} type="secondary">
SASU
</Chip>
</>
)
DifferentChips.args = {
icon: true,
}
export const ChipWithCustomIcon: ComponentStory<typeof Chip> = (args) => (
<>
<Chip {...args} icon="🚧" type="info">
Bêta
</Chip>
<Chip {...args} type="secondary" icon="😃">
Everything is awesome
</Chip>
</>
)
ChipWithCustomIcon.args = {}

View File

@ -0,0 +1,87 @@
import React from 'react'
import styled, { ThemeProvider, css } from 'styled-components'
import Emoji from '@/components/utils/Emoji'
import { Palette, SmallPalette } from '@/types/styled'
import { ErrorIcon, InfoIcon, SuccessIcon } from '../icons'
import { textColorFromType } from '../message'
export type ChipType = 'primary' | 'secondary' | 'info' | 'error' | 'success'
type ChipProps = {
children: React.ReactNode
icon?: boolean | string
type?: ChipType
className?: string
}
export function Chip({
type = 'primary',
icon = false,
children,
className,
}: ChipProps) {
return (
<ThemeProvider theme={(theme) => ({ ...theme, darkMode: false })}>
<StyledChip className={className} type={type}>
{icon && (
<StyledIconWrapper type={type}>
{typeof icon === 'string' ? (
<Emoji emoji={icon} aria-hidden />
) : type === 'success' ? (
<SuccessIcon />
) : type === 'error' ? (
<ErrorIcon />
) : type === 'info' ? (
<InfoIcon />
) : (
<></>
)}
</StyledIconWrapper>
)}
{children}
</StyledChip>
</ThemeProvider>
)
}
const StyledIconWrapper = styled.span<{
type: ChipProps['type']
}>`
margin-right: ${({ theme }) => theme.spacings.xxs};
vertical-align: middle;
svg {
fill: ${({ theme, type }) =>
type === 'error'
? theme.colors.extended.grey[100]
: textColorFromType(type, theme)};
}
`
const StyledChip = styled.strong<
Pick<ChipProps, 'type'> & {
type: NonNullable<ChipProps['type']>
}
>`
white-space: nowrap;
${({ theme, type }) => {
const colorSpace: Palette | SmallPalette =
type === 'secondary' || type === 'primary'
? theme.colors.bases[type]
: theme.colors.extended[type]
return css`
margin: 0 ${theme.spacings.xxs};
border-radius: ${theme.spacings.md};
font-family: ${theme.fonts.main};
padding: ${theme.spacings.xxs} ${theme.spacings.xs};
background-color: ${type === 'error' ? colorSpace[400] : colorSpace[300]};
font-size: ${theme.baseFontSize};
text-align: center;
color: ${type === 'error'
? theme.colors.extended.grey[100]
: textColorFromType(type, theme)};
`
}}
`

View File

@ -1,10 +1,11 @@
export { Accordion } from './accordion'
export * as button from './buttons'
export * from './chip'
export * from './field'
export { GlobalStyle } from './global-style'
export * as layout from './layout'
export * from './message'
export { default as Popover } from './popover/Popover'
export { default as PopoverWithTrigger } from './popover/PopoverWithTrigger'
export * as typography from './typography'
export * from './message'
export { Accordion } from './accordion'
export { Step, Stepper } from './stepper'
export * as typography from './typography'

View File

@ -24,6 +24,7 @@ AccompanyingMessage.args = {
children:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam',
type: 'primary',
icon: true,
}
const AlertTemplate: ComponentStory<typeof Message> = (args) => (

View File

@ -1,5 +1,5 @@
import React from 'react'
import styled, { ThemeProvider, css } from 'styled-components'
import styled, { DefaultTheme, ThemeProvider, css } from 'styled-components'
import Emoji from '@/components/utils/Emoji'
import { Palette, SmallPalette } from '@/types/styled'
@ -71,16 +71,7 @@ const StyledIconWrapper = styled.div<{
top: ${({ theme }) => theme.spacings.xxs};
width: ${({ theme }) => theme.spacings.xl};
svg {
fill: ${({ theme, type }) =>
type === 'success'
? theme.colors.extended.success[600]
: type === 'error'
? theme.colors.extended.error[600]
: type === 'info'
? theme.colors.extended.info[600]
: type === 'secondary'
? theme.colors.bases.secondary[700]
: theme.colors.bases.primary[700]};
fill: ${({ theme, type }) => textColorFromType(type, theme)};
}
`
@ -124,3 +115,18 @@ const Wrapper = styled.div`
`
Message.Wrapper = Wrapper
export function textColorFromType(
type: MessageProps['type'],
theme: DefaultTheme
) {
return type === 'success'
? theme.colors.extended.success[600]
: type === 'error'
? theme.colors.extended.error[600]
: type === 'info'
? theme.colors.extended.info[600]
: type === 'secondary'
? theme.colors.bases.secondary[700]
: theme.colors.bases.primary[700]
}