at main 1.5 kB view raw
1import React, { createContext, useContext } from 'react'; 2import * as styles from './Layout.styles'; 3import { DEFAULT_THEME } from './Layout.constants'; 4import { AsideProps, LayoutProps, PageTheme, MainProps } from './Layout.types'; 5import { Divider } from '@/components/Divider/Divider'; 6 7// Context to share page theme with child components 8const PageThemeContext = createContext<PageTheme>(DEFAULT_THEME); 9 10export const usePageTheme = () => useContext(PageThemeContext); 11 12export const Layout: React.FC<LayoutProps> = ({ children, theme = DEFAULT_THEME }) => { 13 // Split children into Main and Aside 14 const childArray = React.Children.toArray(children); 15 const mainComponent = childArray.find( 16 (child) => React.isValidElement(child) && child.type === Main 17 ); 18 const asideComponent = childArray.find( 19 (child) => React.isValidElement(child) && child.type === Aside 20 ); 21 22 return ( 23 <PageThemeContext.Provider value={theme}> 24 <div className={styles.getLayoutStyles(theme)}> 25 {mainComponent} 26 {asideComponent && <Divider orientation="vertical" className="hidden md:block" />} 27 {asideComponent} 28 </div> 29 </PageThemeContext.Provider> 30 ); 31}; 32 33export const Main: React.FC<MainProps> = ({ children }) => { 34 return <main className={styles.main}>{children}</main>; 35}; 36 37export const Aside: React.FC<AsideProps> = ({ children }) => { 38 const theme = usePageTheme(); 39 return <aside className={styles.getAsideStyles(theme)}>{children}</aside>; 40};