react-flow-modal 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-flow-modal",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Promise-based modal flows for React",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,9 +23,6 @@
23
23
  "require": "./dist/index.cjs"
24
24
  }
25
25
  },
26
- "files": [
27
- "dist"
28
- ],
29
26
  "scripts": {
30
27
  "build": "tsup",
31
28
  "prepublishOnly": "pnpm build"
@@ -0,0 +1,12 @@
1
+ import React, { FC, Fragment } from 'react';
2
+ import { useModalContext } from './useModalContext';
3
+
4
+ export const ModalHost: FC = () => {
5
+ const { stack } = useModalContext();
6
+
7
+ return (
8
+ <Fragment>
9
+ {stack.map((item) => (item))}
10
+ </Fragment>
11
+ );
12
+ };
@@ -0,0 +1,12 @@
1
+ import React, { FC, PropsWithChildren, useState } from "react";
2
+ import { ModalContext } from "./modalContext";
3
+
4
+ export const ModalProvider: FC<PropsWithChildren> = ({ children }) => {
5
+ const [stack, setStack] = useState<React.ReactNode[]>([]);
6
+
7
+ return (
8
+ <ModalContext.Provider value={{ stack, setStack }}>
9
+ {children}
10
+ </ModalContext.Provider>
11
+ );
12
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { ModalProvider } from './ModalProvider';
2
+ export { ModalHost } from './ModalHost';
3
+ export { useModal } from './useModal';
@@ -0,0 +1,9 @@
1
+ import { createContext, Dispatch, SetStateAction } from "react";
2
+
3
+ export const ModalContext = createContext<{
4
+ stack: React.ReactNode[];
5
+ setStack: Dispatch<SetStateAction<React.ReactNode[]>>
6
+ }>({
7
+ stack: [],
8
+ setStack: () => [] as React.ReactNode[],
9
+ });
@@ -0,0 +1,37 @@
1
+ import React, { Fragment } from "react";
2
+ import { useModalContext } from "./useModalContext";
3
+
4
+ export const useModal = () => {
5
+ const { setStack } = useModalContext();
6
+
7
+ const pop = () => {
8
+ setStack((prev) => prev.slice(0, -1));
9
+ };
10
+
11
+ const push = (element: React.ReactNode) => {
12
+ setStack((prev) => [...prev, element]);
13
+ };
14
+
15
+ /**
16
+ * 모달을 열고 닫는 함수
17
+ * @caution 모달을 열고 닫는 함수는 비동기 함수이므로, 모달을 열고 닫는 함수를 호출하면, 반드시 resolve 또는 reject 함수를 호출해야 합니다.
18
+ * 그렇지 않으면 pending 상태가 되어 무한 대기 상태가 됩니다.
19
+ * @param key - 모달의 고유 키
20
+ * @param render - 모달을 렌더링하는 함수
21
+ * @returns - 모달 컴포넌트가 반환하는 값을 반환하는 Promise
22
+ */
23
+ const open = <T,>(key: string, render: (resolve: (value: T) => void, reject: (reason?: unknown) => void) => React.ReactNode) => {
24
+ return new Promise<T>((resolve, reject) => {
25
+ const element = render((value) => {
26
+ resolve(value);
27
+ pop();
28
+ }, (reason) => {
29
+ reject(reason);
30
+ pop();
31
+ });
32
+ push(<Fragment key={key}>{element}</Fragment>);
33
+ });
34
+ };
35
+
36
+ return { open };
37
+ };
@@ -0,0 +1,12 @@
1
+ import { useContext } from "react";
2
+ import { ModalContext } from "./modalContext";
3
+
4
+ export const useModalContext = () => {
5
+ const context = useContext(ModalContext);
6
+
7
+ if (!context) {
8
+ throw new Error('useModalContext must be used within a ModalProvider');
9
+ }
10
+
11
+ return context;
12
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2019",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+
7
+ "jsx": "react-jsx",
8
+
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "emitDeclarationOnly": false,
12
+
13
+ "strict": true,
14
+ "skipLibCheck": true,
15
+
16
+ "esModuleInterop": true,
17
+ "forceConsistentCasingInFileNames": true,
18
+
19
+ "outDir": "dist",
20
+ "rootDir": "src"
21
+ },
22
+ "include": ["src"]
23
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.ts"],
5
+ format: ["esm", "cjs"],
6
+ dts: true,
7
+ clean: true,
8
+ });