page-select.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { useCallback } from 'react';
  2. import { atom, useAtomValue, useSetAtom } from 'jotai';
  3. import type { IPageForItem } from '~/interfaces/page';
  4. import type { OnSelectedFunction } from '../../../interfaces/ui';
  5. type IPageSelectModalOption = {
  6. isHierarchicalSelectionMode?: boolean;
  7. onSelected?: OnSelectedFunction;
  8. };
  9. export type PageSelectModalStatus = {
  10. isOpened: boolean;
  11. opts?: IPageSelectModalOption;
  12. };
  13. export type PageSelectModalActions = {
  14. open: (opts?: IPageSelectModalOption) => void;
  15. close: () => void;
  16. };
  17. // Atom for page select modal state
  18. const pageSelectModalAtom = atom<PageSelectModalStatus>({
  19. isOpened: false,
  20. });
  21. // Atom for selected page in modal
  22. const selectedPageAtom = atom<IPageForItem | null>(null);
  23. /**
  24. * Hook for managing page select modal state
  25. * Returns read-only modal status for optimal performance
  26. */
  27. export const usePageSelectModalStatus = (): PageSelectModalStatus => {
  28. return useAtomValue(pageSelectModalAtom);
  29. };
  30. /**
  31. * Hook for managing page select modal actions
  32. * Returns actions for opening and closing the modal with stable references
  33. */
  34. export const usePageSelectModalActions = (): PageSelectModalActions => {
  35. const setStatus = useSetAtom(pageSelectModalAtom);
  36. const setSelectedPage = useSetAtom(selectedPageAtom);
  37. const open = useCallback(
  38. (opts?: IPageSelectModalOption) => {
  39. setStatus({ isOpened: true, opts });
  40. setSelectedPage(null); // Reset selected page when modal opens
  41. },
  42. [setStatus, setSelectedPage],
  43. );
  44. const close = useCallback(() => {
  45. setStatus({ isOpened: false, opts: undefined });
  46. setSelectedPage(null); // Reset selected page when modal closes
  47. }, [setStatus, setSelectedPage]);
  48. return { open, close };
  49. };
  50. /**
  51. * Hook for getting selected page in modal
  52. */
  53. export const useSelectedPageInModal = (): IPageForItem | null => {
  54. return useAtomValue(selectedPageAtom);
  55. };
  56. /**
  57. * Hook for selecting a page in modal
  58. */
  59. export const useSelectPageInModal = (): ((page: IPageForItem) => void) => {
  60. const setSelectedPage = useSetAtom(selectedPageAtom);
  61. return useCallback(
  62. (page: IPageForItem) => {
  63. if (page.path == null) {
  64. return;
  65. }
  66. setSelectedPage(page);
  67. },
  68. [setSelectedPage],
  69. );
  70. };