feat(card): append types to card

This commit is contained in:
unix
2020-04-09 08:58:18 +08:00
parent d35d9bf43c
commit 29876a3b4f
5 changed files with 202 additions and 9 deletions

View File

@@ -1,14 +1,18 @@
import React, { useMemo } from 'react'
import withDefaults from '../utils/with-defaults'
import useTheme from '../styles/use-theme'
import { CardTypes } from '../utils/prop-types'
import { getStyles } from './styles'
interface Props {
hoverable?: boolean
shadow?: boolean
className?: string
type?: CardTypes
}
const defaultProps = {
type: 'default' as CardTypes,
hoverable: false,
shadow: false,
className: '',
@@ -18,13 +22,17 @@ type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
export type CardProps = Props & typeof defaultProps & NativeAttrs
const Card: React.FC<React.PropsWithChildren<CardProps>> = React.memo(({
children, hoverable, className, shadow, ...props
children, hoverable, className, shadow, type, ...props
}) => {
const theme = useTheme()
const hoverShadow = useMemo(() => {
if (shadow) return theme.expressiveness.shadowMedium
return hoverable ? theme.expressiveness.shadowSmall : 'none'
}, [hoverable, shadow, theme.expressiveness])
const { color, bgColor, borderColor } = useMemo(
() => getStyles(type, theme.palette, shadow),
[type, theme.palette, shadow],
)
return (
<div className={`card ${className}`} {...props}>
@@ -37,19 +45,23 @@ const Card: React.FC<React.PropsWithChildren<CardProps>> = React.memo(({
transition: all .2s ease;
padding: ${theme.layout.gap} ${theme.layout.gap};
border-radius: ${theme.layout.radius};
border: 1px solid ${shadow ? 'transparent' : theme.palette.border};
box-shadow: ${shadow ? theme.expressiveness.shadowSmall : 'none'};
box-sizing: border-box;
color: ${color};
background-color: ${bgColor};
border: 1px solid ${borderColor};
}
.card:hover {
box-shadow: ${hoverShadow};
}
.card :global(p), .card :global(h1), .card :global(h2),
.card :global(h3), .card :global(h4), .card :global(h5),
.card :global(h6) {
margin: 0;
.card :global(*:first-child) {
margin-top: 0;
}
.card :global(*:last-child) {
margin-bottom: 0;
}
`}</style>
</div>

66
components/card/styles.ts Normal file
View File

@@ -0,0 +1,66 @@
import { CardTypes } from '../utils/prop-types'
import { ZeitUIThemesPalette } from '../styles/themes'
export type CardStyles = {
color: string
bgColor: string
borderColor: string
}
export const getStyles = (
type: CardTypes,
palette: ZeitUIThemesPalette,
isShadow?: boolean,
): CardStyles => {
const colors: { [key in CardTypes]: Omit<CardStyles, 'borderColor'> } = {
default: {
color: palette.foreground,
bgColor: palette.background,
},
dark: {
color: palette.background,
bgColor: palette.foreground,
},
secondary: {
color: palette.background,
bgColor: palette.secondary,
},
success: {
color: palette.background,
bgColor: palette.success,
},
warning: {
color: palette.background,
bgColor: palette.warning,
},
error: {
color: palette.background,
bgColor: palette.error,
},
lite: {
color: palette.foreground,
bgColor: palette.background,
},
alert: {
color: 'white',
bgColor: palette.alert,
},
purple: {
color: 'white',
bgColor: palette.purple,
},
violet: {
color: 'white',
bgColor: palette.violet,
},
cyan: {
color: 'black',
bgColor: palette.cyan,
},
}
const showBorder = type === 'default' && !isShadow
return {
...colors[type],
borderColor: showBorder ? palette.border : 'transparent',
}
}

View File

@@ -40,6 +40,20 @@ const snippetTypes = tuple(
'lite',
)
const cardTypes = tuple(
'default',
'secondary',
'success',
'warning',
'error',
'dark',
'lite',
'alert',
'purple',
'violet',
'cyan',
)
const copyTypes = tuple(
'default',
'slient',
@@ -76,6 +90,8 @@ export type ThemeTypes = typeof themeTypes[number]
export type SnippetTypes = typeof snippetTypes[number]
export type CardTypes = typeof cardTypes[number]
export type CopyTypes = typeof copyTypes[number]
export type TriggerTypes = typeof triggerTypes[number]