feat: drawers registry

This commit is contained in:
2025-08-22 17:04:59 +04:00
parent cb67c913ad
commit b5753ed3a2
28 changed files with 680 additions and 285 deletions

View 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;
};

View 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
View 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;
};