Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/contentLayout/__tests__/contentLayout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('test contentLayout', () => {
</ContentLayout>
);
expect(container.querySelector<HTMLDivElement>('.ant-table-body')?.style.maxHeight).toBe(
'calc(calc(calc(100vh - 96px) - 0px) - 88px)'
'calc(calc(calc(100vh - 96px) - 0px - 0px) - 88px)'
);
});
test('should support contentLayout small table height', () => {
Expand All @@ -94,7 +94,7 @@ describe('test contentLayout', () => {
</ContentLayout>
);
expect(container.querySelector<HTMLDivElement>('.ant-table-body')?.style.maxHeight).toBe(
'calc(calc(calc(100vh - 96px) - 0px) - 72px)'
'calc(calc(calc(100vh - 96px) - 0px - 0px) - 88px)'
);
});
});
49 changes: 0 additions & 49 deletions src/contentLayout/components.tsx

This file was deleted.

128 changes: 101 additions & 27 deletions src/contentLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,142 @@
import React, { Children, cloneElement, useCallback, useMemo, useRef } from 'react';
import { Table, TableProps } from 'antd';
import classNames from 'classnames';

import { Header, TableLayout } from './components';
import './index.scss';

interface IProps {
header?: React.ReactElement;
content?: React.ReactElement;
footer?: React.ReactElement;
height?: string;
children?: React.ReactElement | React.ReactElement[];
children?: React.ReactElement[];
style?: React.CSSProperties;
className?: string;
padding?: number | string;
}

export const NAME = 'dtc-content-layout';
const NAME = 'dtc-content-layout';

const ContentLayout = (props: IProps) => {
const { height = 'calc(100vh - 96px)', style, className, children } = props;
const { height = 'calc(100vh - 96px)', className, style, padding, children } = props;
const headerRef: any = useRef(null);
const footerRef: any = useRef(null);

const contentHeight = useMemo(() => {
return `calc(${height} - ${headerRef?.current?.clientHeight || 0}px)`;
}, [height, headerRef?.current]);
return `calc(${height} - ${headerRef?.current?.clientHeight || 0}px - ${
footerRef?.current?.clientHeight || 0
}px)`;
}, [height, headerRef?.current, footerRef?.current]);

const render = useCallback(() => {
let header;
const content: React.ReactElement<any, string | React.JSXElementConstructor<any>>[] = [];

let herder = props?.header && (
<ContentLayout.Header thisRef={headerRef}>{props?.header}</ContentLayout.Header>
);
const content = [props?.content];
let footer = props?.footer && (
<ContentLayout.Footer thisRef={footerRef}>{props?.footer}</ContentLayout.Footer>
);
Children.forEach(children, (child) => {
if (child?.type === Header) {
header = cloneElement(child, {
key: 'header',
ref: headerRef,
if (child?.type === ContentLayout.Header) {
herder = cloneElement(child, {
thisRef: headerRef,
});
}
if (child?.type === TableLayout) {
} else if (child?.type === ContentLayout.Footer) {
footer = cloneElement(child, {
thisRef: footerRef,
});
} else if (child) {
content.push(
cloneElement(child, {
key: 'table',
cloneElement(child as React.ReactElement<any>, {
height: contentHeight,
})
);
}
});

return [header, ...content];
return [herder, ...content, footer];
}, [children, contentHeight]);

return (
<div
className={classNames(NAME, className)}
style={height ? { ...style, height } : { ...style }}
style={{
...style,
height,
padding,
}}
>
{render()}
</div>
);
};

type OriginalInterface = typeof ContentLayout;
interface LayoutInterface extends OriginalInterface {
Header: typeof Header;
Table: typeof TableLayout;
interface ContentLayoutChildProps {
thisRef?: React.Ref<HTMLDivElement>;
children?: React.ReactElement | React.ReactElement[] | React.ReactNode;
style?: React.CSSProperties;
}
interface HeaderProps extends ContentLayoutChildProps {}

ContentLayout.Header = ({ thisRef, children, style }: HeaderProps) => {
return (
<div className={`${NAME}__header`} ref={thisRef} style={style}>
{children}
</div>
);
};

type ITableProps<T> = {
height?: string;
children?: any;
} & TableProps<T> &
ContentLayoutChildProps;

ContentLayout.Table = ({ height, children, ...otherProps }: ITableProps<any>) => {
let lineHeight = 44;

if (otherProps.footer) {
lineHeight = lineHeight * 2;
}
const scroll: TableProps<any>['scroll'] = {
y: `calc(${height} - ${lineHeight}px)`,
...otherProps?.scroll,
};

return children ? (
cloneElement(children, {
scroll,
})
) : (
<Table {...otherProps} scroll={scroll} />
);
};

interface FooterProps extends ContentLayoutChildProps {}

ContentLayout.Footer = ({ thisRef, children }: FooterProps) => {
return (
<div className={`${NAME}__footer`} ref={thisRef}>
{children}
</div>
);
};

interface ContentProps extends ContentLayoutChildProps {
style?: React.CSSProperties;
className?: string;
height?: string | number;
}

const LayoutWrapper = ContentLayout;
(LayoutWrapper as LayoutInterface).Header = Header;
(LayoutWrapper as LayoutInterface).Table = TableLayout;
ContentLayout.Content = ({ style = {}, className, height, children }: ContentProps) => {
return (
<div
className={classNames(`${NAME}__content`, className)}
style={height ? { ...style, height } : { ...style }}
>
{children}
</div>
);
};

export default LayoutWrapper as LayoutInterface;
export default ContentLayout;
Loading