import React, { AriaRole, ComponentClass, CSSProperties } from 'react';
import cls from 'classnames';
import PropTypes from 'prop-types';
import { cssClasses } from '@douyinfe/semi-foundation/layout/constants';
import '@douyinfe/semi-foundation/layout/layout.scss';
import LayoutContext, { ContextType } from './layout-context';
import Sider from './Sider';
export { ResponsiveMap, SiderProps } from './Sider';
const htmlTag = {
Header: 'header',
Footer: 'footer',
Content: 'main',
Layout: 'section'
};
function generator
(type: string): (ComponentType: ComponentClass<{ type?: string; tagName?: string } & P>) => ComponentClass
{
const tagName = htmlTag[type];
const typeName = type.toLowerCase();
return (BasicComponent): ComponentClass
=> class Adapter extends React.PureComponent
{
render() {
return ;
}
};
}
export interface BasicProps {
prefixCls?: string;
style?: CSSProperties;
className?: string;
tagName?: keyof HTMLElementTagNameMap;
type?: string;
children?: React.ReactNode | undefined;
}
class Basic extends React.PureComponent {
static propTypes = {
prefixCls: PropTypes.string,
style: PropTypes.object,
className: PropTypes.string,
};
static defaultProps = {
prefixCls: cssClasses.PREFIX,
};
render() {
const { prefixCls, type, className, children, tagName, ...others } = this.props;
const classString = cls(className, `${prefixCls}-${type}`);
return React.createElement(tagName, { className: classString, ...others }, children);
}
}
const Header = generator('Header')(Basic);
const Footer = generator('Footer')(Basic);
const Content = generator('Content')(Basic);
export interface BasicLayoutProps {
prefixCls?: string;
style?: CSSProperties;
className?: string;
children?: React.ReactNode | undefined;
hasSider?: boolean;
tagName?: keyof HTMLElementTagNameMap;
}
export interface BasicLayoutState {
siders: Array;
}
class Layout extends React.Component {
static propTypes = {
prefixCls: PropTypes.string,
style: PropTypes.object,
className: PropTypes.string,
};
static defaultProps = {
prefixCls: cssClasses.PREFIX,
tagName: 'section'
};
static Header = Header;
static Footer = Footer;
static Content = Content;
static Sider = Sider;
constructor(props: BasicLayoutProps) {
super(props);
this.state = {
siders: [],
};
}
getSiderHook(): ContextType['siderHook'] {
return {
addSider: (id: string): void => {
this.setState(state => ({
siders: [...state.siders, id],
}));
},
removeSider: (id: string): void => {
this.setState(state => ({
siders: state.siders.filter(curr => curr !== id),
}));
},
};
}
render() {
const { prefixCls, className, children, hasSider, tagName, ...others } = this.props;
const { siders } = this.state;
const classString = cls(className, prefixCls, {
[`${prefixCls}-has-sider`]: typeof hasSider === 'boolean' ? hasSider : siders.length > 0,
});
const Tag: any = tagName;
return (
{children}
);
}
}
export { Layout };
export default Layout;