split jotai atom into selectedCell and anchorEle atom

This commit is contained in:
Gibson Han
2022-02-03 15:20:28 +07:00
parent 4e1ed254f0
commit afdd98fe70
4 changed files with 48 additions and 44 deletions

View File

@@ -1,30 +1,40 @@
import { useAtom } from "jotai";
import { atomWithReset, useResetAtom } from "jotai/utils";
import { atomWithReset, useResetAtom, useUpdateAtom } from "jotai/utils";
export type SelectedCell = {
rowIndex: number;
colIndex: number;
};
export interface IContextMenuAtom {
selectedCell: SelectedCell | null;
anchorEl: HTMLElement | null;
export type anchorEl = HTMLElement;
const selectedCellAtom = atomWithReset<SelectedCell | null>(null);
const anchorEleAtom = atomWithReset<HTMLElement | null>(null);
export function useSetAnchorEle() {
const setAnchorEle = useUpdateAtom(anchorEleAtom);
return { setAnchorEle };
}
const INIT_VALUE = {
selectedCell: null,
anchorEl: null,
};
export function useSetSelectedCell() {
const setSelectedCell = useUpdateAtom(selectedCellAtom);
return { setSelectedCell };
}
export default function useContextMenuAtom() {
const [contextMenu, setContextMenu] = useAtom(contextMenuAtom);
const resetContextMenu = useResetAtom(contextMenuAtom);
export function useContextMenuAtom() {
const [anchorEle] = useAtom(anchorEleAtom);
const [selectedCell] = useAtom(selectedCellAtom);
const resetAnchorEle = useResetAtom(anchorEleAtom);
const resetSelectedCell = useResetAtom(selectedCellAtom);
const resetContextMenu = async () => {
await resetAnchorEle();
await resetSelectedCell();
};
return {
contextMenu,
setContextMenu,
anchorEle,
selectedCell,
resetContextMenu,
};
}
export const contextMenuAtom = atomWithReset<IContextMenuAtom>(INIT_VALUE);

View File

@@ -2,12 +2,12 @@ import _find from "lodash/find";
import { getFieldProp } from "@src/components/fields";
import { useProjectContext } from "@src/contexts/ProjectContext";
import { MenuContents } from "./MenuContent";
import useContextMenuAtom from "@src/atoms/ContextMenu";
import { useContextMenuAtom, useSetSelectedCell } from "@src/atoms/ContextMenu";
export default function ContextMenu() {
const { tableState }: any = useProjectContext();
const { contextMenu, resetContextMenu } = useContextMenuAtom();
const { anchorEl, selectedCell } = contextMenu;
const { anchorEle, selectedCell, resetContextMenu }: any =
useContextMenuAtom();
const columns = tableState?.columns;
const selectedColIndex = selectedCell?.colIndex;
const selectedCol = _find(columns, { index: selectedColIndex });
@@ -15,13 +15,12 @@ export default function ContextMenu() {
getFieldProp("contextMenuActions", selectedCol?.type) ||
function empty() {};
const actions = configActions(selectedCell, resetContextMenu) || [];
const hasNoActions = Boolean(actions.length === 0);
if (!contextMenu || hasNoActions) return <></>;
if (!anchorEle || actions.length === 0) return <></>;
return (
<MenuContents
anchorEl={anchorEl as HTMLElement}
open={Boolean(contextMenu.anchorEl)}
anchorEl={anchorEle}
open={Boolean(anchorEle)}
handleClose={resetContextMenu}
items={actions}
/>

View File

@@ -1,26 +1,24 @@
import useContextMenuAtom from "@src/atoms/ContextMenu";
import { useSetAnchorEle } from "@src/atoms/ContextMenu";
import { Fragment } from "react";
import { Row, RowRendererProps } from "react-data-grid";
import OutOfOrderIndicator from "./OutOfOrderIndicator";
export default function TableRow(props: RowRendererProps<any>) {
const { setContextMenu } = useContextMenuAtom();
function handleContextMenu(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
const { setAnchorEle } = useSetAnchorEle();
const handleContextMenu = (
e: React.MouseEvent<HTMLDivElement, MouseEvent>
) => {
e.preventDefault();
if (setContextMenu)
setContextMenu((prev) => ({
...prev,
anchorEl: e?.target as HTMLElement,
}));
}
setAnchorEle?.(e?.target as HTMLElement);
};
if (props.row._rowy_outOfOrder)
return (
<Fragment key={props.row.id}>
<OutOfOrderIndicator top={props.top} height={props.height} />
<Row onContextMenu={(e) => handleContextMenu(e)} {...props} />
<Row onContextMenu={handleContextMenu} {...props} />
</Fragment>
);
return <Row onContextMenu={(e) => handleContextMenu(e)} {...props} />;
return <Row onContextMenu={handleContextMenu} {...props} />;
}

View File

@@ -31,8 +31,8 @@ import { formatSubTableName } from "@src/utils/fns";
import { useAppContext } from "@src/contexts/AppContext";
import { useProjectContext } from "@src/contexts/ProjectContext";
import useContextMenuAtom from "@src/atoms/ContextMenu";
import useWindowSize from "@src/hooks/useWindowSize";
import { useSetSelectedCell } from "@src/atoms/ContextMenu";
export type TableColumn = Column<any> & {
isNew?: boolean;
@@ -54,7 +54,7 @@ export default function Table() {
updateCell,
} = useProjectContext();
const { userDoc, userClaims } = useAppContext();
const { setContextMenu } = useContextMenuAtom();
const { setSelectedCell } = useSetSelectedCell();
const userDocHiddenFields =
userDoc.state.doc?.tables?.[formatSubTableName(tableState?.config.id)]
@@ -265,15 +265,12 @@ export default function Table() {
});
}
}}
onSelectedCellChange={({ rowIdx, idx }) => {
setContextMenu((prev) => ({
...prev,
selectedCell: {
rowIndex: rowIdx,
colIndex: idx,
},
}));
}}
onSelectedCellChange={({ rowIdx, idx }) =>
setSelectedCell({
rowIndex: rowIdx,
colIndex: idx,
})
}
/>
</DndProvider>
) : (