Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 1x 1x 1x 7x 7x 7x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x | import { DRAWER_INDEX } from '@/constants/common';
import { useAppContext } from '@/context';
import { i18n } from '@/helpers/i18n';
import HistoryIcon from '@mui/icons-material/History';
import SearchIcon from '@mui/icons-material/Search';
import SettingsIcon from '@mui/icons-material/Settings';
import { Drawer, Tab, Tabs } from '@mui/material';
import { useState, FC, SyntheticEvent } from 'react';
import DrawerSearchPanel from './DrawerSearchPanel';
import styles from './DrawerSystem.module.scss';
import HistoryPanel from './HistoryPanel';
import SettingsPanel from './SettingsPanel';
// TabPanelProps is declared globally in types/props.d.ts
/**
* Renders its children only when the active drawer tab `value` matches this
* panel's `index`, hiding the panel otherwise. Used to switch between the
* Search, History, and Settings drawer tabs.
* @param props - The {@link TabPanelProps}: `children`, the active `value`, and
* this panel's `index`.
* @returns A `tabpanel` element that shows `children` when active, otherwise hidden.
* @example
* ```tsx
* <TabPanel value={activeTab} index={DRAWER_INDEX.SEARCH}>
* <DrawerSearchPanel />
* </TabPanel>
* // Renders DrawerSearchPanel only when activeTab === DRAWER_INDEX.SEARCH.
* ```
* @source
*/
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`drawer-tabpanel-${index}`}
aria-labelledby={`drawer-tab-${index}`}
className={styles['drawer-system__tabpanel']}
{...other}
>
{value === index && children}
</div>
);
}
/**
* The right-hand slide-out drawer hosting the Search, History, and Settings
* tabs. Driven by `appContext.drawerTab`: opens when a tab is selected, closes
* on backdrop click, and renders the matching panel via the local `TabPanel`.
* @returns The drawer element; an empty (closed) drawer when no tab is active.
* @example
* ```tsx
* // Mounted once near the app root; visibility is controlled via app context.
* <DrawerSystem />
* // appContext.setDrawerTab(DRAWER_INDEX.SETTINGS) opens it to the Settings tab.
* ```
* @source
*/
const DrawerSystem: FC = () => {
const appContext = useAppContext();
const [expandedAccordion, setExpandedAccordion] = useState<string | false>('search-availability');
const handleTabChange = (_event: SyntheticEvent, newValue: DRAWER_INDEX) => {
appContext.setDrawerTab(newValue);
// Reset accordion when switching tabs
if (newValue === DRAWER_INDEX.SEARCH) {
setExpandedAccordion('search-availability');
} else if (newValue === DRAWER_INDEX.SETTINGS) {
setExpandedAccordion('settings-general');
} else {
setExpandedAccordion(false);
}
};
const handleAccordionChange =
(panel: string) => (_event: SyntheticEvent, isExpanded: boolean) => {
setExpandedAccordion(isExpanded ? panel : false);
};
return (
<Drawer
anchor="right"
open={appContext.drawerTab !== DRAWER_INDEX.CLOSED}
onClose={() => appContext.setDrawerTab(DRAWER_INDEX.CLOSED)}
variant="temporary"
>
<div className={styles['drawer-container']}>
{appContext.drawerTab !== DRAWER_INDEX.CLOSED && (
<Tabs
value={appContext.drawerTab ?? DRAWER_INDEX.CLOSED}
onChange={handleTabChange}
variant="fullWidth"
className={styles['drawer-tabs']}
>
<Tab icon={<SearchIcon />} label={i18n('drawer_tab_search')} iconPosition="start" />
<Tab icon={<HistoryIcon />} label={i18n('drawer_tab_history')} iconPosition="start" />
<Tab icon={<SettingsIcon />} label={i18n('drawer_tab_settings')} iconPosition="start" />
</Tabs>
)}
<TabPanel value={appContext.drawerTab ?? DRAWER_INDEX.CLOSED} index={DRAWER_INDEX.SEARCH}>
<DrawerSearchPanel
expandedAccordion={expandedAccordion}
onAccordionChange={handleAccordionChange}
/>
</TabPanel>
<TabPanel value={appContext.drawerTab ?? DRAWER_INDEX.CLOSED} index={DRAWER_INDEX.HISTORY}>
<HistoryPanel />
</TabPanel>
<TabPanel value={appContext.drawerTab ?? DRAWER_INDEX.CLOSED} index={DRAWER_INDEX.SETTINGS}>
<SettingsPanel />
</TabPanel>
</div>
</Drawer>
);
};
export default DrawerSystem;
|