mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-26 23:04:55 +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
|
||||
|
||||
Reference in New Issue
Block a user