feat(card): extract content wrapper

This commit is contained in:
unix
2020-04-29 00:34:08 +08:00
parent 5d717e6ba2
commit 74b00f7951
5 changed files with 93 additions and 8 deletions

View File

@@ -0,0 +1,34 @@
import React from 'react'
import useTheme from '../styles/use-theme'
import withDefaults from '../utils/with-defaults'
interface Props {
className?: string
}
const defaultProps = {
className: '',
}
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
export type CardContentProps = Props & typeof defaultProps & NativeAttrs
const CardContent: React.FC<React.PropsWithChildren<CardContentProps>> = ({
className, children, ...props
}) => {
const theme = useTheme()
return (
<div className={`content ${className}`} {...props}>
{children}
<style jsx>{`
.content {
width: 100%;
padding: ${theme.layout.gap} ${theme.layout.gap};
}
`}</style>
</div>
)
}
export default withDefaults(CardContent, defaultProps)

View File

@@ -3,8 +3,9 @@ import useTheme from '../styles/use-theme'
import { CardTypes } from '../utils/prop-types'
import { getStyles } from './styles'
import CardFooter from './card-footer'
import CardContent from './card-content'
import Image from '../image'
import { pickChild } from '../utils/collections'
import { hasChild, pickChild } from '../utils/collections'
interface Props {
hoverable?: boolean
@@ -40,16 +41,15 @@ const Card: React.FC<React.PropsWithChildren<CardProps>> = React.memo(({
const [withoutFooterChildren, footerChildren] = pickChild(children, CardFooter)
const [withoutImageChildren, imageChildren] = pickChild(withoutFooterChildren, Image)
const hasContent = hasChild(withoutImageChildren, CardContent)
return (
<div className={`card ${className}`} {...props}>
{imageChildren}
<div className="content">
{withoutImageChildren}
</div>
{hasContent ? withoutImageChildren : (
<CardContent>{withoutImageChildren}</CardContent>
)}
{footerChildren}
<style jsx>{`
.card {
background: ${theme.palette.background};
@@ -98,6 +98,8 @@ const Card: React.FC<React.PropsWithChildren<CardProps>> = React.memo(({
type CardComponent<P = {}> = React.FC<P> & {
Footer: typeof CardFooter
Actions: typeof CardFooter
Content: typeof CardContent
Body: typeof CardContent
}
type ComponentProps = Partial<typeof defaultProps> & Omit<Props, keyof typeof defaultProps> & NativeAttrs

View File

@@ -1,7 +1,10 @@
import Card from './card'
import CardFooter from './card-footer'
import CardContent from './card-content'
Card.Footer = CardFooter
Card.Actions = CardFooter
Card.Content = CardContent
Card.Body = CardContent
export default Card

View File

@@ -1,5 +1,5 @@
import { Layout, Playground, Attributes } from 'lib/components'
import { Card, Spacer, Row, Col, Link, Image, Text } from 'components'
import { Card, Spacer, Row, Col, Link, Image, Text, Divider, Code } from 'components'
export const meta = {
title: 'card',
@@ -106,6 +106,23 @@ A common container component.
</Card>
`} />
<Playground
title="With Divider"
desc="Show different types of content using `Divider`"
scope={{ Card, Text, Divider, Code }}
code={`
<Card width="400px">
<Card.Content>
<Text b>Description</Text>
</Card.Content>
<Divider y={0} />
<Card.Content>
<Text>The Object constructor creates an object wrapper for the given value.</Text>
<Text>When called in a non-constructor context, Object behaves identically to <Code>new Object()</Code>.</Text>
</Card.Content>
</Card>
`} />
<Attributes edit="/pages/en-us/components/card.mdx">
<Attributes.Title>Card.Props</Attributes.Title>
@@ -117,6 +134,12 @@ A common container component.
| **width** | CSS width value | `string` | - | `100%` |
| ... | native props | `HTMLAttributes` | `'id', className', ...` | - |
<Attributes.Title alias="Card.Body">Card.Content.Props</Attributes.Title>
| Attribute | Description | Type | Accepted values | Default
| ---------- | ---------- | ---- | -------------- | ------ |
| ... | native props | `HTMLAttributes` | `'id', className', ...` | - |
<Attributes.Title alias="Card.Actions">Card.Footer.Props</Attributes.Title>
| Attribute | Description | Type | Accepted values | Default

View File

@@ -1,5 +1,5 @@
import { Layout, Playground, Attributes } from 'lib/components'
import { Card, Row, Col, Link, Spacer, Text, Image } from 'components'
import { Card, Row, Col, Link, Spacer, Text, Image, Divider, Code } from 'components'
export const meta = {
title: '卡片 Card',
@@ -110,6 +110,23 @@ export const meta = {
</Card>
`} />
<Playground
title="组合分割线"
desc="使用分割线展示不同类型的内容。"
scope={{ Card, Text, Divider, Code }}
code={`
<Card width="400px">
<Card.Content>
<Text b>语法描述</Text>
</Card.Content>
<Divider y={0} />
<Card.Content>
<Text>Object 构造函数为给定值创建一个对象包装器,返回一个与给定值对应类型的对象。</Text>
<Text>当以非构造函数形式被调用时Object 等同于 <Code>new Object()</Code>.</Text>
</Card.Content>
</Card>
`} />
<Attributes edit="/pages/zh-cn/components/card.mdx">
<Attributes.Title>Card.Props</Attributes.Title>
@@ -121,6 +138,12 @@ export const meta = {
| **width** | CSS 宽度属性 | `string` | - | `100%` |
| ... | 原生属性 | `HTMLAttributes` | `'id', className', ...` | - |
<Attributes.Title alias="Card.Body">Card.Content.Props</Attributes.Title>
| 属性 | 描述 | 类型 | 推荐值 | 默认
| ---------- | ---------- | ---- | -------------- | ------ |
| ... | 原生属性 | `HTMLAttributes` | `'id', className', ...` | - |
<Attributes.Title alias="Card.Actions">Card.Footer.Props</Attributes.Title>
| 属性 | 描述 | 类型 | 推荐值 | 默认