feat(tag): append types to tag component

This commit is contained in:
unix
2020-04-09 09:38:58 +08:00
parent 5eadb6f538
commit a4604ef633
3 changed files with 150 additions and 31 deletions

View File

@@ -1,51 +1,97 @@
import React, { useMemo } from 'react'
import withDefaults from '../utils/with-defaults'
import useTheme from '../styles/use-theme'
import { NormalTypes } from '../utils/prop-types'
import { ZeitUIThemes } from '../styles/themes'
import { SnippetTypes } from '../utils/prop-types'
import { ZeitUIThemesPalette } from '../styles/themes'
interface Props {
type?: NormalTypes
type?: SnippetTypes
invert?: boolean
className?: string
}
const defaultProps = {
type: 'default' as NormalTypes,
type: 'default' as SnippetTypes,
invert: false,
className: '',
}
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
export type TagProps = Props & typeof defaultProps & NativeAttrs
const getColor = (type: NormalTypes, theme: ZeitUIThemes): string => {
const colors: { [key in NormalTypes]?: string } = {
default: theme.palette.foreground,
success: theme.palette.success,
warning: theme.palette.warning,
error: theme.palette.error,
export type TagColors = {
color: string
bgColor: string
borderColor: string
}
const getColors = (
type: SnippetTypes,
palette: ZeitUIThemesPalette,
invert: boolean,
) => {
const colors: { [key in SnippetTypes]: Pick<TagColors, 'color'> & Partial<TagColors> } = {
default: {
color: palette.foreground,
},
success: {
color: palette.success,
},
warning: {
color: palette.warning,
},
error: {
color: palette.error,
},
secondary: {
color: palette.secondary,
},
dark: {
color: palette.foreground,
bgColor: palette.background,
},
lite: {
color: palette.foreground,
bgColor: palette.accents_2,
}
}
const hideBorder = invert || type === 'lite'
const cardStyle = {
...colors[type],
bgColor: colors[type].bgColor || palette.background,
borderColor: hideBorder ? 'transparent' : colors[type].color
}
return !invert ? cardStyle : {
...cardStyle,
color: cardStyle.bgColor,
bgColor: cardStyle.color,
}
return colors[type] || colors.default as string
}
const Tag: React.FC<React.PropsWithChildren<TagProps>> = React.memo(({
type, children, className, ...props
type, children, className, invert, ...props
}) => {
const theme = useTheme()
const color = useMemo(() => getColor(type, theme), [type, theme])
const { color, bgColor, borderColor } = useMemo(
() => getColors(type, theme.palette, invert),
[type, theme.palette, invert],
)
return (
<span className={className} {...props}>
{children}
<style jsx>{`
span {
color: ${color};
display: inline-block;
line-height: .875rem;
font-size: .875rem;
height: 1.75rem;
border-radius: ${theme.layout.radius};
border: 1px solid ${theme.palette.accents_2};
background-color: ${theme.palette.accents_1};
border: 1px solid ${borderColor};
background-color: ${bgColor};
color: ${color};
padding: 6px;
}
`}</style>

View File

@@ -1,5 +1,5 @@
import { Layout, Playground, Attributes } from 'lib/components'
import { Tag } from 'components'
import { Tag, Spacer } from 'components'
export const meta = {
title: 'Tag',
@@ -19,14 +19,39 @@ Display a unique keyword, optionally as a part of a set.
`} />
<Playground
title="types"
scope={{ Tag }}
title="Types"
desc="Show different states with colors."
scope={{ Tag, Spacer }}
code={`
<div>
<Tag type="success" style={{ marginRight: '15px' }}>Status: Success</Tag>
<Tag type="warning" style={{ marginRight: '15px' }}>Status: Warning</Tag>
<Tag type="error">Status: Error</Tag>
</div>
<>
<Tag type="success">Success</Tag>
<Spacer y={.5} />
<Tag type="warning">Warning</Tag>
<Spacer y={.5} />
<Tag type="error">Error</Tag>
<Spacer y={.5} />
<Tag type="secondary">Secondary</Tag>
<Spacer y={.5} />
<Tag type="lite">Lite</Tag>
</>
`} />
<Playground
title="Invert"
desc="Invert color and background."
scope={{ Tag, Spacer }}
code={`
<>
<Tag type="default" invert>Default</Tag>
<Spacer y={.5} />
<Tag type="success" invert>Success</Tag>
<Spacer y={.5} />
<Tag type="warning" invert>Warning</Tag>
<Spacer y={.5} />
<Tag type="error" invert>Error</Tag>
<Spacer y={.5} />
<Tag type="secondary" invert>Secondary</Tag>
</>
`} />
<Attributes edit="/pages/en-us/components/tag.mdx">
@@ -34,9 +59,22 @@ Display a unique keyword, optionally as a part of a set.
| Attribute | Description | Type | Accepted values | Default
| ---------- | ---------- | ---- | -------------- | ------ |
| **type** | tag type | `NormalTypes` | `'default', 'secondary', 'success', 'warning', 'error'` | `default` |
| **type** | tag type | [TagTypes](#tagtypes) | - | `default` |
| **invert** | invert color and background | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
<Attributes.Title>TagTypes</Attributes.Title>
```ts
type TagTypes = 'default'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'dark'
| 'lite'
```
</Attributes>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>

View File

@@ -25,11 +25,33 @@ export const meta = {
scope={{ Tag, Spacer }}
code={`
<>
<Tag type="success">状态: 成功</Tag>
<Spacer />
<Tag type="warning">状态: 警告</Tag>
<Spacer />
<Tag type="error">状态: 错误</Tag>
<Tag type="success">成功</Tag>
<Spacer y={.5} />
<Tag type="warning">警告</Tag>
<Spacer y={.5} />
<Tag type="error">错误</Tag>
<Spacer y={.5} />
<Tag type="secondary">次要的</Tag>
<Spacer y={.5} />
<Tag type="lite">精简的</Tag>
</>
`} />
<Playground
title="反转"
desc="反转展示背景与主色。"
scope={{ Tag, Spacer }}
code={`
<>
<Tag type="default" invert>默认的</Tag>
<Spacer y={.5} />
<Tag type="success" invert>成功</Tag>
<Spacer y={.5} />
<Tag type="warning" invert>警告</Tag>
<Spacer y={.5} />
<Tag type="error" invert>错误</Tag>
<Spacer y={.5} />
<Tag type="secondary" invert>次要的</Tag>
</>
`} />
@@ -38,9 +60,22 @@ export const meta = {
| 属性 | 描述 | 类型 | 推荐值 | 默认
| ---------- | ---------- | ---- | -------------- | ------ |
| **type** | 标签类型 | `NormalTypes` | `'default', 'secondary', 'success', 'warning', 'error'` | `default` |
| **type** | 标签类型 | [TagTypes](#tagtypes) | - | `default` |
| **invert** | 反转背景与主色 | `boolean` | - | `false` |
| ... | 原生属性 | `HTMLAttributes` | `'id', 'className', ...` | - |
<Attributes.Title>TagTypes</Attributes.Title>
```ts
type TagTypes = 'default'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'dark'
| 'lite'
```
</Attributes>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>