Skip to content

Commit e00402d

Browse files
committed
feat: read default overlay options in different way
1 parent 31f7030 commit e00402d

File tree

9 files changed

+109
-57
lines changed

9 files changed

+109
-57
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [1.1.0](https://github.com/react-leaf/modal/tree/1.1.0) (2023-08-14)
4+
5+
### Breaking changes
6+
7+
- each modal's `defaultOverlayOptions` are set by modal's exports.
8+
39
## [1.0.1](https://github.com/react-leaf/modal/tree/1.0.1) (2023-01-13)
410

511
- `useModal()` returns `closeSelf()`, that works only in the opened modal.

README-ko.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,43 @@ export interface ModalEvents {
218218

219219
열려있는 모달 목록을 반환합니다. 모달이 하나라도 열려있는지, 특정 타입 모달이 열려있는지, 등을 체크할 수 있습니다.
220220

221+
### OverlayOptions
222+
223+
모달의 오버레이 설정은 세 곳에서 이루어집니다.
224+
225+
1. `openModal({ type: "...", overlayOptions: 여기 })`
226+
227+
- 여기에 설정한 옵션은 이 함수를 통해 연 모달에만 적용됩니다.
228+
229+
2. 모달 컴포넌트의 선언부
230+
231+
- 여기에 설정한 옵션은 이 컴포넌트 타입의 모달을 열 때, 적용됩니다.
232+
233+
```tsx
234+
// register
235+
...
236+
'common/Alert': () => import('./Alert'),
237+
238+
// ./Alert.tsx
239+
export const defaultOverlayOptions = { 여기 };
240+
241+
export default function Alert(props) {
242+
return ...
243+
}
244+
```
245+
246+
3. `<MoalProvider />` 에서
247+
248+
- 여기에 설정한 옵션은 **모든** 모달에 적용됩니다.
249+
250+
```tsx
251+
<ModalProvider register={register} defaultOverlayOptions={여기}>
252+
<YourApp />
253+
</ModalProvider>
254+
```
255+
256+
첫 번째 것이 우선순위가 가장 높고, 마지막에 소개한 방식이 우선순위가 가장 낮습니다.
257+
221258
## 모달이 열리고 닫히는 애니메이션을 넣으려면 어떻게 해야 하나요?
222259

223260
애니메이션이 돌아가게 하기 위해, 모달은 사실 `openModal()` 실행 시점보다 한 프레임 뒤늦게 열립니다.

README.md

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ useEffect(() => {
121121
How to use `defaultOverlayOptions`:
122122

123123
```tsx
124-
type defaultOverlayOptions = {
125-
[key in keyof Register]?: Partial<OverlayOptions>;
126-
} & { default?: Partial<OverlayOptions> };
124+
type defaultOverlayOptions = Partial<OverlayOptions>;
127125

128126
// just use as default. default values are decribed on openModal()'s description.
129127
return (
@@ -135,29 +133,7 @@ return (
135133
return (
136134
<ModalProvider
137135
register={register}
138-
defaultOverlayOptions={{ default: { closeDelay: 300 } }}
139-
>
140-
<App />
141-
</ModalProvider>
142-
);
143-
// or apply to specific modal
144-
return (
145-
<ModalProvider
146-
register={register}
147-
defaultOverlayOptions={{ MyAnimatingModal: { closeDelay: 500 } }}
148-
>
149-
<App />
150-
</ModalProvider>
151-
);
152-
153-
// or both. surely, settings on specific modal will override default
154-
return (
155-
<ModalProvider
156-
register={register}
157-
defaultOverlayOptions={{
158-
default: { closeDelay: 300 },
159-
MyAnimatingModal: { closeDelay: 500 },
160-
}}
136+
defaultOverlayOptions={{ closeDelay: 300 }}
161137
>
162138
<App />
163139
</ModalProvider>
@@ -221,6 +197,43 @@ Close all opened modals
221197

222198
Returns opened modals. It is an array of the OpenModalPayload, so you can check any modal is opened, or some type of modal is opened or not.
223199

200+
### OverlayOptions
201+
202+
There are three points that you could set overlay options.
203+
204+
1. `openModal({ type: "...", overlayOptions: HERE })`
205+
206+
- This options are applied ONLY that modal opens.
207+
208+
2. When you exports Modal Components
209+
210+
- This options are applied to ALL of these type modals.
211+
212+
```tsx
213+
// register
214+
...
215+
'common/Alert': () => import('./Alert'),
216+
217+
// ./Alert.tsx
218+
export const defaultOverlayOptions = { HERE };
219+
220+
export default function Alert(props) {
221+
return ...
222+
}
223+
```
224+
225+
3. When setting MoalProvider
226+
227+
- This options are applied to ALL TYPE OF modals.
228+
229+
```tsx
230+
<ModalProvider register={register} defaultOverlayOptions={HERE}>
231+
<YourApp />
232+
</ModalProvider>
233+
```
234+
235+
The first one has higher priority, and last one has lower.
236+
224237
## How to add opening / closing animation?
225238

226239
For animation, modal opening is delayed for a frame.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@reactleaf/modal",
3-
"version": "1.1.0-beta.0",
3+
"version": "1.1.0",
44
"description": "React Modal Library with context",
55
"main": "index.js",
66
"types": "index.d.ts",

src/Container.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,33 @@ function OpenedModal<R extends Register>({
4444
events,
4545
}: OpenedModalProps<R>) {
4646
const context = useModal();
47-
const [Component, setComponent] = useState<React.ComponentType>();
47+
const [module, setModule] = useState<Awaited<ReturnType<Importer>>>();
4848

4949
// asynchronously import modal file: for reduce bundle size.
5050
// this may trigger initial openModal could be delayed.
5151
// if you don't want to be delayed, use usePreloadModal hook
5252
useEffect(() => {
53-
void importer().then((modal) => {
54-
setComponent(() => modal.default);
55-
});
53+
void importer().then(setModule);
5654
}, [type]);
5755

5856
function close() {
5957
events?.onClose?.();
6058
context.closeModal({ id });
6159
}
6260

63-
if (!Component) return null;
61+
if (!module) return null;
62+
63+
const Component = module.default;
64+
const overlayProps = Object.assign(
65+
{},
66+
context.defaultOverlayOptions,
67+
module.defaultOverlayOptions,
68+
overlayOptions
69+
);
70+
6471
return (
6572
<ModalContext.Provider value={{ ...context, closeSelf: close }}>
66-
<ModalOverlay {...overlayOptions} closeSelf={close}>
73+
<ModalOverlay {...overlayProps} closeSelf={close}>
6774
<Component {...props} />
6875
</ModalOverlay>
6976
</ModalContext.Provider>

src/ModalProvider.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@ import { OpenModalPayload, Register, OverlayOptions } from "./types";
77

88
interface Props<R extends Register> {
99
register: R;
10-
defaultOverlayOptions?: { default?: Partial<OverlayOptions> } & {
11-
[key in keyof R]?: Partial<OverlayOptions>;
12-
};
10+
defaultOverlayOptions?: Partial<OverlayOptions>;
1311
}
1412
export const ModalProvider = <R extends Register>({
1513
register,
1614
defaultOverlayOptions,
1715
children,
1816
}: React.PropsWithChildren<Props<R>>) => {
19-
const { openedModals, ...actions } = useModalReducer<R>(
20-
defaultOverlayOptions
21-
);
17+
const { openedModals, ...actions } = useModalReducer<R>();
2218

2319
// can open modal with window.postMessage
2420
useEffect(() => {
@@ -40,7 +36,9 @@ export const ModalProvider = <R extends Register>({
4036
console.error("closeSelf is not available outside of modal");
4137

4238
return (
43-
<TypedModalContext.Provider value={{ openedModals, ...actions, closeSelf }}>
39+
<TypedModalContext.Provider
40+
value={{ openedModals, defaultOverlayOptions, ...actions, closeSelf }}
41+
>
4442
{children}
4543
<ModalContainer register={register} openedModals={openedModals} />
4644
</TypedModalContext.Provider>

src/context.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { createContext } from "react";
2-
import { OpenModalPayload, Register } from "./types";
2+
import { OpenModalPayload, OverlayOptions, Register } from "./types";
33

44
export type ModalContextType<R extends Register> = {
55
openedModals: OpenModalPayload<R, keyof R>[];
6+
defaultOverlayOptions?: Partial<OverlayOptions>;
67
openModal: <T extends keyof R>(payload: OpenModalPayload<R, T>) => string;
78
closeModal: (payload: { id: string }) => void;
89
closeAll: () => void;

src/reducer.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,10 @@ import {
33
CloseModalPayload,
44
EnhancedModalPayload,
55
OpenModalPayload,
6-
OverlayOptions,
76
Register,
87
} from "./types";
98

10-
export default function useModalReducer<R extends Register>(
11-
defaultOverlayOptions?: { default?: Partial<OverlayOptions> } & {
12-
[key in keyof R]?: Partial<OverlayOptions>;
13-
}
14-
) {
9+
export default function useModalReducer<R extends Register>() {
1510
function reducer(
1611
state: EnhancedModalPayload<R, keyof R>[],
1712
action: ModalAction
@@ -39,15 +34,7 @@ export default function useModalReducer<R extends Register>(
3934
return {
4035
type: "@modal/OPEN_MODAL" as const,
4136
payload: {
42-
type: payload.type,
43-
props: payload.props,
44-
overlayOptions: Object.assign(
45-
{},
46-
defaultOverlayOptions?.default,
47-
defaultOverlayOptions?.[payload.type],
48-
payload.overlayOptions
49-
),
50-
events: payload.events,
37+
...payload,
5138
id: `${String(payload.type)}_${key}`,
5239
} as EnhancedModalPayload<R, keyof R>,
5340
};

src/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React from "react";
22

3-
export type Importer = () => Promise<{ default: React.ComponentType<any> }>;
3+
export type Importer = () => Promise<{
4+
default: React.ComponentType<any>;
5+
defaultOverlayOptions?: Partial<OverlayOptions>;
6+
}>;
47
export interface Register {
58
[key: string]: Importer;
69
}

0 commit comments

Comments
 (0)