mirror of https://github.com/acid-info/lsd.git
feat: implement badge component
This commit is contained in:
parent
e2a3311360
commit
c51ebb8482
|
@ -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',
|
||||||
|
}
|
|
@ -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',
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
`
|
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './Badge'
|
|
@ -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 }> = ({
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Loading…
Reference in New Issue