11import React , { Children , cloneElement , useCallback , useMemo , useRef } from 'react' ;
22import classNames from 'classnames' ;
33
4- import { Header , TableLayout } from './components' ;
4+ import { Content , Footer , Header , TableLayout } from './components' ;
55import './index.scss' ;
66
77interface IProps {
8+ header ?: React . ReactElement ;
9+ content ?: React . ReactElement ;
10+ footer ?: React . ReactElement ;
811 height ?: string ;
9- children ?: React . ReactElement | React . ReactElement [ ] ;
12+ children ?: React . ReactElement [ ] ;
1013 style ?: React . CSSProperties ;
1114 className ?: string ;
1215}
@@ -16,34 +19,61 @@ export const NAME = 'dtc-content-layout';
1619const ContentLayout = ( props : IProps ) => {
1720 const { height = 'calc(100vh - 96px)' , style, className, children } = props ;
1821 const headerRef : any = useRef ( null ) ;
22+ const footerRef : any = useRef ( null ) ;
1923
2024 const contentHeight = useMemo ( ( ) => {
21- return `calc(${ height } - ${ headerRef ?. current ?. clientHeight || 0 } px)` ;
22- } , [ height , headerRef ?. current ] ) ;
25+ return `calc(${ height } - ${ headerRef ?. current ?. clientHeight || 0 } px - ${
26+ footerRef ?. current ?. clientHeight || 0
27+ } px)`;
28+ } , [ height , headerRef ?. current , footerRef ?. current ] ) ;
2329
2430 const render = useCallback ( ( ) => {
25- let header ;
26- const content : React . ReactElement < any , string | React . JSXElementConstructor < any > > [ ] = [ ] ;
31+ let header = null ;
32+ let footer = null ;
33+ const content : React . ReactElement [ ] = [ ] ;
2734
28- Children . forEach ( children , ( child ) => {
35+ if ( props ?. content ) {
36+ content . push (
37+ cloneElement ( props . content , {
38+ key : 'content-prop' ,
39+ } )
40+ ) ;
41+ }
42+
43+ Children . forEach ( children , ( child , index ) => {
2944 if ( child ?. type === Header ) {
3045 header = cloneElement ( child , {
3146 key : 'header' ,
3247 ref : headerRef ,
3348 } ) ;
34- }
35- if ( child ?. type === TableLayout ) {
49+ } else if ( child ?. type === TableLayout ) {
50+ footer = cloneElement ( child , {
51+ key : 'footer-table' ,
52+ ref : footerRef ,
53+ height : contentHeight ,
54+ } ) ;
55+ } else if ( child ?. type === Footer ) {
56+ footer = cloneElement ( child , {
57+ key : 'footer' ,
58+ ref : footerRef ,
59+ } ) ;
60+ } else {
61+ const childKey = ( child as React . ReactElement ) ?. key || `content-${ index } ` ;
3662 content . push (
37- cloneElement ( child , {
38- key : 'table' ,
63+ cloneElement ( child as React . ReactElement , {
64+ key : childKey ,
3965 height : contentHeight ,
4066 } )
4167 ) ;
4268 }
4369 } ) ;
4470
45- return [ header , ...content ] ;
46- } , [ children , contentHeight ] ) ;
71+ const result : ( React . ReactElement | null ) [ ] = [ ] ;
72+ if ( header ) result . push ( header ) ;
73+ result . push ( ...content ) ;
74+ if ( footer ) result . push ( footer ) ;
75+ return result ;
76+ } , [ children , contentHeight , props ?. content ] ) ;
4777
4878 return (
4979 < div
@@ -59,10 +89,14 @@ type OriginalInterface = typeof ContentLayout;
5989interface LayoutInterface extends OriginalInterface {
6090 Header : typeof Header ;
6191 Table : typeof TableLayout ;
92+ Footer : typeof Footer ;
93+ Content : typeof Content ;
6294}
6395
6496const LayoutWrapper = ContentLayout ;
6597( LayoutWrapper as LayoutInterface ) . Header = Header ;
6698( LayoutWrapper as LayoutInterface ) . Table = TableLayout ;
99+ ( LayoutWrapper as LayoutInterface ) . Content = Content ;
100+ ( LayoutWrapper as LayoutInterface ) . Footer = Footer ;
67101
68102export default LayoutWrapper as LayoutInterface ;
0 commit comments