Skip to content

Commit

Permalink
feat: panel context to handle default open panel when toggling
Browse files Browse the repository at this point in the history
  • Loading branch information
hamed-musallam committed Jan 8, 2025
1 parent c64fbd4 commit 3d4922b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 36 deletions.
27 changes: 16 additions & 11 deletions src/component/main/InnerNMRiumContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ExportManagerController } from '../elements/export/ExportManager.js';
import { PrintContent } from '../elements/print/PrintContent.js';
import { Header } from '../header/Header.js';
import DropZone from '../loader/DropZone.js';
import { Panels } from '../panels/Panels.js';
import { PanelOpenProviderProvider, Panels } from '../panels/Panels.js';
import { PanelsBar } from '../panels/PanelsBar.js';
import ToolBar from '../toolbar/ToolBar.js';

Expand Down Expand Up @@ -151,16 +151,21 @@ export function InnerNMRiumContents(props: InnerNMRiumContentsProps) {
height: '100%',
}}
>
<ToolBar />
<SplitPaneWrapper>
<div css={viewerContainerStyle}>
<KeysListenerTracker mainDivRef={mainDivRef} />

<NMRiumViewer emptyText={emptyText} viewerRef={viewerRef} />
</div>
<Panels />
</SplitPaneWrapper>
<PanelsBar />
<PanelOpenProviderProvider>
<ToolBar />
<SplitPaneWrapper>
<div css={viewerContainerStyle}>
<KeysListenerTracker mainDivRef={mainDivRef} />

<NMRiumViewer
emptyText={emptyText}
viewerRef={viewerRef}
/>
</div>
<Panels />
</SplitPaneWrapper>
<PanelsBar />
</PanelOpenProviderProvider>
<div
ref={elementsWrapperRef}
key={String(isFullScreen)}
Expand Down
63 changes: 42 additions & 21 deletions src/component/panels/Panels.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,62 @@
import type { NMRiumPanelPreferences } from 'nmr-load-save';
import { memo, useCallback } from 'react';
import { createContext, memo, useContext, useMemo, useState } from 'react';
import { FaRegEdit } from 'react-icons/fa';
import type { ToolbarItemProps } from 'react-science/ui';
import { Accordion, Toolbar } from 'react-science/ui';

import { useActiveSpectrum } from '../hooks/useActiveSpectrum.js';
import useCheckExperimentalFeature from '../hooks/useCheckExperimentalFeature.js';
import { useDialogToggle } from '../hooks/useDialogToggle.js';

import type { AccordionItem } from './accordionItems.js';
import { checkAccordionItemMode } from './checkAccordionItemMode.js';
import { InformationEditionModal } from './informationPanel/InformationEditionModal.js';
import { useAccordionItems } from './hooks/useAccordionItems.js';
import { useGetPanelOptions } from './hooks/useGetPanelOptions.js';
import { useTogglePanel } from './hooks/useTogglePanel.js';
import { InformationEditionModal } from './informationPanel/InformationEditionModal.js';

export function useCheckPanel(displayerMode) {
const getPanelPreferences = useGetPanelOptions();
const isExperimental = useCheckExperimentalFeature();

return useCallback(
(item) => {
const panelOptions = getPanelPreferences(item);

return (
(panelOptions?.display &&
item.isExperimental === undefined &&
checkAccordionItemMode(item, displayerMode)) ||
(item.isExperimental && isExperimental)
);
},
[displayerMode, getPanelPreferences, isExperimental],
type PanelOpenState = Partial<Record<keyof NMRiumPanelPreferences, boolean>>;
interface PanelStateContext {
setPanelOpenState: (id: keyof NMRiumPanelPreferences, value: boolean) => void;
panelOpenState: PanelOpenState;
}

const AccordionContext = createContext<PanelStateContext | null>(null);

export function usePanelOpenState() {
const context = useContext(AccordionContext);

if (!context) {
throw new Error('Panel open context must be used within PanelOpenProvider');
}

return context;
}

export function PanelOpenProviderProvider({ children }) {
const [panelOpenState, toggleAccordionItem] = useState<PanelOpenState>({});

const state = useMemo(() => {
function setPanelOpenState(
id: keyof NMRiumPanelPreferences,
value: boolean,
) {
toggleAccordionItem((prev) => ({
...prev,
[id]: value,
}));
}
return { setPanelOpenState, panelOpenState };
}, [panelOpenState]);

return (
<AccordionContext.Provider value={state}>
{children}
</AccordionContext.Provider>
);
}

function PanelsInner() {
const getPanelPreferences = useGetPanelOptions();
const { panelOpenState } = usePanelOpenState();
const { dialog, openDialog, closeDialog } = useDialogToggle({
informationModal: false,
});
Expand Down Expand Up @@ -65,7 +86,7 @@ function PanelsInner() {
<Accordion.Item
key={title}
title={title}
defaultOpened={isOpened(item)}
defaultOpened={isOpened(item) || panelOpenState[id]}
toolbar={
<RightButtons
id={id}
Expand Down
14 changes: 10 additions & 4 deletions src/component/panels/hooks/useTogglePanel.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import lodashGet from 'lodash/get.js';
import type { NMRiumPanelPreferences } from 'nmr-load-save';

import { usePreferences } from '../../context/PreferencesContext.js';
import { usePanelOpenState } from '../Panels.js';

export function useTogglePanel() {
const { dispatch } = usePreferences();
const { dispatch, current } = usePreferences();
const { setPanelOpenState } = usePanelOpenState();

function togglePanel(id?: string) {
if (!id) {
return;
function togglePanel(id: keyof NMRiumPanelPreferences) {
const flag = lodashGet(current, `display.panels.${id}.display`);
if (typeof flag === 'boolean') {
setPanelOpenState(id, !flag);
}

dispatch({ type: 'TOGGLE_PANEL', payload: { id } });
Expand Down

0 comments on commit 3d4922b

Please sign in to comment.