feat: implement badge component

This commit is contained in:
jinhojang6 2023-04-05 00:58:00 +09:00
parent e2a3311360
commit c51ebb8482
No known key found for this signature in database
GPG Key ID: 0E7AA62CB0D9E6F3
7 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,10 @@
export const badgeClasses = {
root: `lsd-badge`,
outlined: `lsd-badge--outlined`,
filled: `lsd-badge--filled`,
disabled: 'lsd-badge--disabled',
small: 'lsd-badge--small',
large: 'lsd-badge--large',
}

View File

@ -0,0 +1,47 @@
import { Meta, Story } from '@storybook/react'
import { FolderIcon } from '../Icons'
import { Badge, BadgeProps } from './Badge'
export default {
title: 'Badge',
component: Badge,
argTypes: {
variant: {
type: {
name: 'enum',
value: ['outlined', 'filled'],
},
},
size: {
type: {
name: 'enum',
value: ['large', 'small'],
},
defaultValue: 'large',
},
iconDirection: {
type: {
name: 'enum',
value: ['left', 'right', 'none'],
},
},
disabled: {
type: {
name: 'boolean',
value: [true, false],
},
},
},
} as Meta
export const Root: Story<BadgeProps> = (args) => (
<Badge {...args} icon={<FolderIcon color="primary" />} />
)
Root.args = {
variant: 'outlined',
label: 'Badge',
iconDirection: 'left',
disabled: false,
size: 'large',
}

View File

@ -0,0 +1,52 @@
import { css } from '@emotion/react'
import { badgeClasses } from './Badge.classes'
export const BadgeStyles = css`
.${badgeClasses.root} {
width: fit-content;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border: 1px solid rgb(var(--lsd-icon-primary));
border-radius: 20px;
&:hover,
&:focus {
text-decoration: underline;
cursor: pointer;
}
}
.${badgeClasses.large} {
padding: 4px 12px;
gap: 12px;
height: 28px;
}
.${badgeClasses.small} {
padding: 4px 8px;
gap: 8px;
height: 24px;
}
.${badgeClasses.filled} {
background-color: rgb(var(--lsd-icon-primary));
color: rgb(var(--lsd-text-secondary));
svg {
--lsd-icon-primary: var(--lsd-icon-secondary);
}
}
.${badgeClasses.outlined} {
color: rgb(var(--lsd-text-primary));
}
.${badgeClasses.disabled} {
opacity: 0.3;
cursor: initial;
pointer-events: none;
}
`

View File

@ -0,0 +1,57 @@
import clsx from 'clsx'
import React from 'react'
import { Typography } from '../Typography'
import { badgeClasses } from './Badge.classes'
export type BadgeProps = React.HTMLAttributes<HTMLDivElement> & {
variant?: 'outlined' | 'filled'
label: string
icon?: React.ReactNode
iconDirection?: 'left' | 'right'
size?: 'large' | 'small'
disabled?: boolean
}
export const Badge: React.FC<BadgeProps> & {
classes: typeof badgeClasses
} = ({
label,
variant = 'outlined',
disabled = 'false',
size = 'large',
icon,
iconDirection = 'left',
children,
...props
}) => {
const renderItems = () => (
<>
{iconDirection === 'left' && icon}
<Typography
variant={size === 'small' ? 'label2' : 'label1'}
className={badgeClasses[variant]}
>
{label}
</Typography>
{iconDirection === 'right' && icon}
</>
)
return (
<div
aria-label={label}
{...props}
className={clsx(
props.className,
badgeClasses.root,
badgeClasses[variant],
disabled && badgeClasses.disabled,
badgeClasses[size],
)}
>
{renderItems()}
</div>
)
}
Badge.classes = badgeClasses

View File

@ -0,0 +1 @@
export * from './Badge'

View File

@ -1,6 +1,7 @@
import { Global, SerializedStyles } from '@emotion/react' import { Global, SerializedStyles } from '@emotion/react'
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { AutocompleteStyles } from '../Autocomplete/Autocomplete.styles' import { AutocompleteStyles } from '../Autocomplete/Autocomplete.styles'
import { BadgeStyles } from '../Badge/Badge.styles'
import { BreadcrumbStyles } from '../Breadcrumb/Breadcrumb.styles' import { BreadcrumbStyles } from '../Breadcrumb/Breadcrumb.styles'
import { BreadcrumbItemStyles } from '../BreadcrumbItem/BreadcrumbItem.styles' import { BreadcrumbItemStyles } from '../BreadcrumbItem/BreadcrumbItem.styles'
import { ButtonStyles } from '../Button/Button.styles' import { ButtonStyles } from '../Button/Button.styles'
@ -48,6 +49,7 @@ const componentStyles: Array<ReturnType<typeof withTheme> | SerializedStyles> =
CollapseStyles, CollapseStyles,
CollapseHeaderStyles, CollapseHeaderStyles,
CheckboxGroupStyles, CheckboxGroupStyles,
BadgeStyles,
] ]
export const CSSBaseline: React.FC<{ theme?: Theme }> = ({ export const CSSBaseline: React.FC<{ theme?: Theme }> = ({

View File

@ -20,3 +20,4 @@ export * from './components/Tag'
export * from './components/Theme' export * from './components/Theme'
export * from './components/Checkbox' export * from './components/Checkbox'
export * from './components/CheckboxGroup' export * from './components/CheckboxGroup'
export * from './components/Badge'