feat: drawers registry
This commit is contained in:
101
src/drawers/DrawersContext.tsx
Normal file
101
src/drawers/DrawersContext.tsx
Normal file
@ -0,0 +1,101 @@
|
||||
"use client";
|
||||
|
||||
import React, { createContext, FC, useContext, useState } from "react";
|
||||
import drawerRegistry from "@/drawers/drawersRegistry";
|
||||
import {
|
||||
DrawerKey,
|
||||
DrawersStackState,
|
||||
OpenDrawerParams,
|
||||
} from "@/drawers/types";
|
||||
|
||||
type DrawersContextState = {
|
||||
stack: DrawersStackState[];
|
||||
openDrawer: <TKey extends DrawerKey>(
|
||||
params: OpenDrawerParams<TKey>
|
||||
) => void;
|
||||
closeDrawer: (key?: DrawerKey) => void;
|
||||
};
|
||||
|
||||
const DrawersContext = createContext<DrawersContextState | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
const useDrawersContextState = () => {
|
||||
const [stack, setStack] = useState<DrawersStackState[]>([]);
|
||||
|
||||
const openDrawer = <TKey extends DrawerKey>(
|
||||
params: OpenDrawerParams<TKey>
|
||||
) => {
|
||||
setStack(prev => {
|
||||
const filtered = prev.filter(d => d.key !== params.key);
|
||||
return [...filtered, { ...params, opened: false }];
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
setStack(prev =>
|
||||
prev.map(d =>
|
||||
d.key === params.key ? { ...d, opened: true } : d
|
||||
)
|
||||
);
|
||||
}, 10);
|
||||
};
|
||||
|
||||
const closeDrawer = (key?: DrawerKey) => {
|
||||
setStack(prev =>
|
||||
prev.map(d => (d.key === key ? { ...d, opened: false } : d))
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
setStack(prev =>
|
||||
key ? prev.filter(d => d.key !== key) : prev.slice(0, -1)
|
||||
);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
return {
|
||||
stack,
|
||||
openDrawer,
|
||||
closeDrawer,
|
||||
};
|
||||
};
|
||||
|
||||
type BoardsContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const DrawersContextProvider: FC<BoardsContextProviderProps> = ({
|
||||
children,
|
||||
}) => {
|
||||
const state = useDrawersContextState();
|
||||
|
||||
return (
|
||||
<DrawersContext.Provider value={state}>
|
||||
{children}
|
||||
|
||||
{state.stack.map(({ key, props, onClose, opened }) => {
|
||||
const Component = drawerRegistry[key];
|
||||
return (
|
||||
<Component
|
||||
key={key}
|
||||
opened={opened || false}
|
||||
onClose={() => {
|
||||
state.closeDrawer(key);
|
||||
onClose && onClose();
|
||||
}}
|
||||
props={props}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</DrawersContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useDrawersContext = () => {
|
||||
const context = useContext(DrawersContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useDrawersContext must be used within a DrawersContextProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
11
src/drawers/drawersRegistry.tsx
Normal file
11
src/drawers/drawersRegistry.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import BoardStatusesEditorDrawer from "@/app/deals/drawers/BoardStatusesEditorDrawer";
|
||||
import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer";
|
||||
import ProjectBoardsEditorDrawer from "@/app/deals/drawers/ProjectBoardsEditorDrawer";
|
||||
|
||||
const drawerRegistry = {
|
||||
projectsEditorDrawer: ProjectsEditorDrawer,
|
||||
boardStatusesEditorDrawer: BoardStatusesEditorDrawer,
|
||||
projectBoardsEditorDrawer: ProjectBoardsEditorDrawer,
|
||||
};
|
||||
|
||||
export default drawerRegistry;
|
||||
24
src/drawers/types.ts
Normal file
24
src/drawers/types.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import drawerRegistry from "./drawersRegistry";
|
||||
|
||||
export type DrawerRegistry = typeof drawerRegistry;
|
||||
|
||||
export type DrawerKey = keyof DrawerRegistry;
|
||||
|
||||
export type DrawerProps<T = unknown> = {
|
||||
opened: boolean;
|
||||
onClose: () => void;
|
||||
props: T;
|
||||
};
|
||||
|
||||
export type DrawersStackState = {
|
||||
key: DrawerKey;
|
||||
props?: any;
|
||||
onClose?: () => void;
|
||||
opened?: boolean;
|
||||
};
|
||||
|
||||
export type OpenDrawerParams<TKey extends DrawerKey> = {
|
||||
key: TKey;
|
||||
props?: Parameters<DrawerRegistry[TKey]>[0]["props"];
|
||||
onClose?: () => void;
|
||||
};
|
||||
Reference in New Issue
Block a user