Files
toco-react-template/src/layout/index.tsx

82 lines
2.2 KiB
TypeScript
Raw Normal View History

2024-12-24 14:25:06 +08:00
import { Theme } from '@/app/enum';
import { useAppSelector } from '@/app/hooks';
import { SettingOutlined } from '@ant-design/icons';
import { Button, Image, Popover } from '@toco-design/components';
2024-12-24 14:25:06 +08:00
import classNames from 'classnames';
2025-02-14 17:22:20 +08:00
import { useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
2024-12-24 14:25:06 +08:00
import styles from './index.module.css';
import { HeaderOnly, HeaderSider, SiderOnly } from './layouts';
import Settings from './settings';
import SuspenseLayout from './suspense-layout';
2024-10-14 18:51:44 +08:00
2024-12-24 14:25:06 +08:00
export enum LayoutType {
Default = 0,
Header = 1 << 1,
Sider = 1 << 2,
}
2024-10-14 18:51:44 +08:00
2024-12-24 14:25:06 +08:00
type LayoutProps = {
type?: LayoutType;
};
2024-10-14 18:51:44 +08:00
2024-12-24 14:25:06 +08:00
const Layout: React.FC<LayoutProps> = (props) => {
const { type: typeProp } = props;
const theme = useAppSelector((state) => state.common.theme);
2025-02-14 17:22:20 +08:00
const navigate = useNavigate();
2024-10-14 18:51:44 +08:00
2024-12-24 14:25:06 +08:00
const Component = useMemo(() => {
const type = typeProp ?? LayoutType.Default;
const hasHeader = type & LayoutType.Header;
const hasSider = type & LayoutType.Sider;
if (hasHeader && hasSider) {
return HeaderSider;
} else if (hasHeader) {
return HeaderOnly;
} else if (hasSider) {
return SiderOnly;
2024-10-14 18:51:44 +08:00
}
2024-12-24 14:25:06 +08:00
return HeaderSider;
}, [typeProp]);
2024-10-14 18:51:44 +08:00
2025-02-14 17:22:20 +08:00
const gotoHome = useCallback(() => {
navigate('/');
}, [navigate]);
2024-10-14 18:51:44 +08:00
return (
2024-12-24 14:25:06 +08:00
<SuspenseLayout>
<Component
theme={theme}
siderWidth={250}
logo={
<div
className={classNames(styles.logo, { dark: theme === Theme.DARK })}
2025-02-14 17:22:20 +08:00
onClick={gotoHome}
2024-12-24 14:25:06 +08:00
>
<Image
className={styles.icon}
preview={false}
src={
process.env.PUBLIC_URL +
(theme === Theme.DEFAULT ? '/logo.png' : '/logo_dark.png')
}
/>
</div>
}
extra={
<div
className={classNames(styles.extra, { dark: theme === Theme.DARK })}
>
<Popover content={<Settings />}>
<Button type="text">
<SettingOutlined />
</Button>
</Popover>
</div>
}
/>
</SuspenseLayout>
2024-10-14 18:51:44 +08:00
);
};
2024-12-24 14:25:06 +08:00
export default Layout;