mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-21 10:25:40 +08:00
feat(fieldset): extract content wrapper
This commit is contained in:
41
components/fieldset/fieldset-content.tsx
Normal file
41
components/fieldset/fieldset-content.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
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 FieldsetContentProps = Props & typeof defaultProps & NativeAttrs
|
||||
|
||||
const FieldsetContent: React.FC<React.PropsWithChildren<FieldsetContentProps>> = ({
|
||||
className, children, ...props
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<div className={`content ${className}`} {...props}>
|
||||
{children}
|
||||
<style jsx>{`
|
||||
.content {
|
||||
padding: ${theme.layout.gap};
|
||||
}
|
||||
|
||||
.content :global(*:first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.content :global(*:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withDefaults(FieldsetContent, defaultProps)
|
||||
@@ -35,6 +35,7 @@ const FieldsetFooter: React.FC<React.PropsWithChildren<FieldsetFooterProps>> = R
|
||||
color: ${theme.palette.accents_6};
|
||||
padding: ${theme.layout.gapHalf} ${theme.layout.gap};
|
||||
font-size: .875rem;
|
||||
min-height: 2.875rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
`}</style>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { ReactNode, useEffect, useState } from 'react'
|
||||
import React, { ReactNode, useEffect, useMemo, useState } from 'react'
|
||||
import useTheme from '../styles/use-theme'
|
||||
import FieldsetTitle from './fieldset-title'
|
||||
import FieldsetSubtitle from './fieldset-subtitle'
|
||||
import FieldsetFooter from './fieldset-footer'
|
||||
import FieldsetGroup from './fieldset-group'
|
||||
import FieldsetContent from './fieldset-content'
|
||||
import { hasChild, pickChild } from '../utils/collections'
|
||||
import { useFieldset } from './fieldset-context'
|
||||
import useWarning from '../utils/use-warning'
|
||||
@@ -34,9 +35,11 @@ const Fieldset: React.FC<React.PropsWithChildren<FieldsetProps>> = React.memo(({
|
||||
const theme = useTheme()
|
||||
const { inGroup, currentValue, register } = useFieldset()
|
||||
const [hidden, setHidden] = useState<boolean>(inGroup)
|
||||
const hasTitle = hasChild(children, FieldsetTitle)
|
||||
const hasSubtitle = hasChild(children, FieldsetSubtitle)
|
||||
|
||||
const [withoutFooterChildren, FooterChildren] = pickChild(children, FieldsetFooter)
|
||||
const hasTitle = hasChild(withoutFooterChildren, FieldsetTitle)
|
||||
const hasSubtitle = hasChild(withoutFooterChildren, FieldsetSubtitle)
|
||||
const hasContent = hasChild(withoutFooterChildren, FieldsetContent)
|
||||
|
||||
if (inGroup) {
|
||||
if (!label) {
|
||||
@@ -59,13 +62,23 @@ const Fieldset: React.FC<React.PropsWithChildren<FieldsetProps>> = React.memo(({
|
||||
}, [currentValue])
|
||||
}
|
||||
|
||||
const content = useMemo(() => (
|
||||
<>
|
||||
{withoutFooterChildren}
|
||||
{(!hasTitle && title) && (
|
||||
<FieldsetTitle>{title}</FieldsetTitle>
|
||||
)}
|
||||
{(!hasSubtitle && subtitle) && (
|
||||
<FieldsetSubtitle>{subtitle}</FieldsetSubtitle>
|
||||
)}
|
||||
</>
|
||||
), [withoutFooterChildren, hasTitle, hasSubtitle, title, subtitle])
|
||||
|
||||
return (
|
||||
<div className={`fieldset ${className}`} {...props}>
|
||||
<div className="content">
|
||||
{withoutFooterChildren}
|
||||
{!hasTitle && <FieldsetTitle>{title}</FieldsetTitle>}
|
||||
{!hasSubtitle && <FieldsetSubtitle>{subtitle}</FieldsetSubtitle>}
|
||||
</div>
|
||||
{hasContent ? content : (
|
||||
<FieldsetContent>{content}</FieldsetContent>
|
||||
)}
|
||||
{FooterChildren && FooterChildren}
|
||||
<style jsx>{`
|
||||
.fieldset {
|
||||
@@ -75,10 +88,6 @@ const Fieldset: React.FC<React.PropsWithChildren<FieldsetProps>> = React.memo(({
|
||||
overflow: hidden;
|
||||
display: ${hidden ? 'none' : 'block'};
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: ${theme.layout.gap};
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
@@ -91,6 +100,8 @@ type FieldsetComponent<P = {}> = React.FC<P> & {
|
||||
Subtitle: typeof FieldsetSubtitle
|
||||
Footer: typeof FieldsetFooter
|
||||
Group: typeof FieldsetGroup
|
||||
Content: typeof FieldsetContent
|
||||
Body: typeof FieldsetContent
|
||||
}
|
||||
|
||||
type ComponentProps = Partial<typeof defaultProps> & Omit<Props, keyof typeof defaultProps> & NativeAttrs
|
||||
|
||||
@@ -5,6 +5,7 @@ import FieldsetFooter from './fieldset-footer'
|
||||
import FieldsetFooterStatus from './fieldset-footer-status'
|
||||
import FieldsetFooterActions from './fieldset-footer-actions'
|
||||
import FieldsetGroup from './fieldset-group'
|
||||
import FieldsetContent from './fieldset-content'
|
||||
|
||||
FieldsetFooter.Status = FieldsetFooterStatus
|
||||
FieldsetFooter.Actions = FieldsetFooterActions
|
||||
@@ -12,5 +13,7 @@ Fieldset.Title = FieldsetTitle
|
||||
Fieldset.Subtitle = FieldsetSubtitle
|
||||
Fieldset.Footer = FieldsetFooter
|
||||
Fieldset.Group = FieldsetGroup
|
||||
Fieldset.Content = FieldsetContent
|
||||
Fieldset.Body = FieldsetContent
|
||||
|
||||
export default Fieldset
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Card, Fieldset, Button, Text } from 'components'
|
||||
import { Card, Fieldset, Button, Text, Divider } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'fieldset',
|
||||
@@ -92,6 +92,27 @@ Display a collection of related information in a single unit.
|
||||
}
|
||||
`} />
|
||||
|
||||
<Playground
|
||||
title="With Divider"
|
||||
desc="Use `Divider` and `Fieldset.Content` to combine different layouts."
|
||||
scope={{ Fieldset, Divider }}
|
||||
code={`
|
||||
<Fieldset>
|
||||
<Fieldset.Content style={{ paddingTop: '10pt', paddingBottom: '10pt' }}>
|
||||
<h4>Prerequisites</h4>
|
||||
</Fieldset.Content>
|
||||
<Divider y={0} />
|
||||
<Fieldset.Content>
|
||||
<Fieldset.Title>Basic knowledge of HTML and CSS would also be useful.</Fieldset.Title>
|
||||
<p>To get the most out of this module, you should have worked your way through the previous JavaScript modules in the series.
|
||||
Those modules typically involve simple API usage, as it is often difficult to write client-side JavaScript examples without them. </p>
|
||||
</Fieldset.Content>
|
||||
<Fieldset.Footer>
|
||||
<small>Client-side web APIs</small>
|
||||
</Fieldset.Footer>
|
||||
</Fieldset>
|
||||
`} />
|
||||
|
||||
<Attributes edit="/pages/en-us/components/fieldset.mdx">
|
||||
<Attributes.Title>Fieldset.Props</Attributes.Title>
|
||||
|
||||
@@ -103,6 +124,12 @@ Display a collection of related information in a single unit.
|
||||
| **subtitle** | subtitle of fieldset | `ReactNode` / `string` | - | - |
|
||||
| ... | native props | `FieldsetHTMLAttributes` | `'name', 'className', ...` | - |
|
||||
|
||||
<Attributes.Title alias="Fieldset.Body">Fieldset.Content.Props</Attributes.Title>
|
||||
|
||||
| Attribute | Description | Type | Accepted values | Default
|
||||
| ---------- | ---------- | ---- | -------------- | ------ |
|
||||
| ... | native props | `HTMLAttributes` | - | - |
|
||||
|
||||
<Attributes.Title>Fieldset.Footer.Props</Attributes.Title>
|
||||
|
||||
| Attribute | Description | Type | Accepted values | Default
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Card, Fieldset, Button, Text } from 'components'
|
||||
import { Card, Fieldset, Button, Text, Divider } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: '控件组 Fieldset',
|
||||
@@ -49,7 +49,7 @@ export const meta = {
|
||||
|
||||
<Playground
|
||||
title="选项卡"
|
||||
desc="同时展示多个组件组"
|
||||
desc="同时展示多个组件组。"
|
||||
scope={{ Fieldset, Button }}
|
||||
code={`
|
||||
() => {
|
||||
@@ -91,6 +91,27 @@ export const meta = {
|
||||
}
|
||||
`} />
|
||||
|
||||
<Playground
|
||||
title="组合分割线"
|
||||
desc="使用 `Fieldset.Content` 与其他组件组合成不同布局。"
|
||||
scope={{ Fieldset, Divider }}
|
||||
code={`
|
||||
<Fieldset>
|
||||
<Fieldset.Content style={{ paddingTop: '10pt', paddingBottom: '10pt' }}>
|
||||
<h4>预备知识</h4>
|
||||
</Fieldset.Content>
|
||||
<Divider y={0} />
|
||||
<Fieldset.Content>
|
||||
<Fieldset.Title>若知道 HTML 和 CSS 的基本知识会对理解内容大有裨益。</Fieldset.Title>
|
||||
<p>若想深入理解这个单元的内容, 你必须能够以自己的能力较好地学完之前的几个章节。
|
||||
这几部分涉及到了许多简单的API的使用,如果没有它们我们将很难做一些实际的事情。</p>
|
||||
</Fieldset.Content>
|
||||
<Fieldset.Footer>
|
||||
<small>客户端 Web API</small>
|
||||
</Fieldset.Footer>
|
||||
</Fieldset>
|
||||
`} />
|
||||
|
||||
<Attributes edit="/pages/zh-cn/components/fieldset.mdx">
|
||||
<Attributes.Title>Fieldset.Props</Attributes.Title>
|
||||
|
||||
@@ -102,6 +123,12 @@ export const meta = {
|
||||
| **subtitle** | 副标题 | `ReactNode` / `string` | - | - |
|
||||
| ... | 原生属性 | `FieldsetHTMLAttributes` | `'name', 'className', ...` | - |
|
||||
|
||||
<Attributes.Title alias="Fieldset.Body">Fieldset.Content.Props</Attributes.Title>
|
||||
|
||||
| 属性 | 描述 | 类型 | 推荐值 | 默认
|
||||
| ---------- | ---------- | ---- | -------------- | ------ |
|
||||
| ... | 原生属性 | `HTMLAttributes` | - | - |
|
||||
|
||||
<Attributes.Title>Fieldset.Footer.Props</Attributes.Title>
|
||||
|
||||
| 属性 | 描述 | 类型 | 推荐值 | 默认
|
||||
|
||||
Reference in New Issue
Block a user