forked from colorfy-software/react-native-modalfy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.ts
425 lines (397 loc) · 13.7 KB
/
types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
import { ComponentType } from 'react'
import { Animated, ViewStyle } from 'react-native'
/* ======================== ========================
*
* ======================== INTERNAL TYPES ========================
*
* ======================== ========================
*/
export type ModalfyParams = { [key: string]: any }
export type ModalTransitionValue =
| Animated.AnimatedInterpolation
| string
| number
| undefined
| null
export type ModalTransitionOptions = (
animatedValue: Animated.Value,
) => {
[key: string]:
| {
[key: string]: ModalTransitionValue
}[]
| ModalTransitionValue
}
export type ModalEventName = 'onAnimate'
export type ModalEventAction = 'add'
export type ModalEventPayload = {
eventName: ModalEventName
handler: ModalEventCallback
}
export type ModalEventCallback = (value?: number) => void
export type ModalEventListener = { remove: () => boolean }
export type ModalListener = (
eventName: ModalEventName,
callback: ModalEventCallback,
) => ModalEventListener
export type ModalEventListeners = Set<{
event: string
handler: ModalEventCallback
}>
export interface ModalStackItem<P extends ModalfyParams> {
name: Exclude<keyof P, symbol | number>
component: ComponentType<any> & { modalOptions?: ModalOptions }
hash: string
index: number
options?: ModalOptions
params?: any
}
export interface ModalStack<P extends ModalfyParams> {
names: Array<Exclude<keyof P, symbol | number>>
content: ModalStackItem<P>[]
defaultOptions: ModalOptions
openedItems: Set<ModalStackItem<P>>
openedItemsSize: number
}
export interface ModalContextProvider<
P extends ModalfyParams,
M extends Exclude<keyof P, symbol | number> = Exclude<
keyof P,
symbol | number
>
> {
currentModal: M | null
closeAllModals: () => void
closeModal: (stackItem?: M | ModalStackItem<P>) => void
closeModals: (modalName: M) => boolean
getParam: <N extends keyof P[M], D extends P[M][N]>(
hash: ModalStackItem<P>['hash'],
paramName: N,
defaultValue?: D,
) => D extends P[M][N] ? P[M][N] : undefined
openModal: (modalName: M, params?: P[M]) => void
stack: ModalStack<P>
}
export interface ModalStateSubscriber<P> {
state: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
}
equalityFn: ModalStateEqualityChecker<P>
error: boolean
listener: ModalStateListener<P>
unsubscribe: () => void
}
export interface ModalStateSubscription<P> {
unsubscribe: ModalStateSubscriber<P>['unsubscribe']
}
export type ModalStateListener<P> = (
state: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
} | null,
error?: Error,
) => void
export type ModalStateEqualityChecker<P> = (
currentState: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
},
newState: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
},
) => boolean
export type ModalState<P> = Omit<
ModalContextProvider<P>,
'currentModal' | 'stack' | 'openModal'
> & {
openModal: <M extends Exclude<keyof P, symbol | number>>(
modalName: M,
params?: P[M],
isCalledOutsideOfContext?: boolean,
) => void
handleBackPress(): boolean
init: <P>(newState: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
}) => {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
}
getState: <P>() => {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
}
setState: <P>(newState: {
currentModal: ModalContextProvider<P>['currentModal']
stack: ModalContextProvider<P>['stack']
}) => void
subscribe: <P>(
listener: ModalStateListener<P>,
equalityFn?: ModalStateEqualityChecker<P>,
) => ModalStateSubscription<P>
}
export interface SharedProps<P extends ModalfyParams>
extends ModalContextProvider<P> {
clearListeners: (hash: string) => void
eventListeners: ModalEventListeners
registerListener: (
hash: ModalStackItem<P>['hash'],
eventName: ModalEventName,
handler: ModalEventCallback,
) => ModalEventListener
}
export type UsableModalProp<P extends ModalfyParams> = Pick<
ModalContextProvider<P>,
'closeAllModals' | 'closeModals' | 'currentModal' | 'openModal'
> & {
closeModal: (modalName?: Exclude<keyof P, symbol | number>) => void
}
export interface UsableModalComponentProp<
P extends ModalfyParams,
M extends keyof P
> extends Omit<ModalContextProvider<P>, 'closeModal' | 'stack' | 'getParam'> {
addListener: ModalListener
closeModal: (modalName?: M) => void
getParam: <N extends keyof P[M], D extends P[M][N]>(
paramName: N,
defaultValue?: D,
) => D extends P[M][N] ? P[M][N] : undefined
removeAllListeners: () => void
params?: P[M]
}
/* ======================== ========================
*
* ======================== CONSUMER TYPES ========================
*
* ======================== ========================
*/
/**
* Interface of the modal stack configuration.
* These settings will let Modalfy know what modals
* you will be rendering and how.
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#config-and-options
*/
export interface ModalStackConfig {
[key: string]: ComponentType<any> | ModalOptions
}
/**
* Interface of the modal configuration options.
* These settings will let Modalfy how to render and animate a modal.
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#config-and-options
*/
export interface ModalOptions {
/**
* Animation configuration used to animate a modal in, at the top of the stack.
* It uses Animated.timing() so if you want to use another animation type, see `animationIn`.
*
* Note: only `easing` and `duration` are needed.
*
* @default { easing: Easing.inOut(Easing.exp), duration: 450 }
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#animateinconfig
*/
animateInConfig?: Pick<Animated.TimingAnimationConfig, 'duration' | 'easing'>
/**
* Animation function that receives the `animatedValue` used by the library to animate the modal opening,
* and a `toValue` argument representing the modal position in the stack.
*
* Note: If you just want to use Animated.timing(), check `animateInConfig`.
*
* @default -
* @example
* animationIn: (modalAnimatedValue, modalToValue) => {
* Animated.parallel([
* Animated.timing(modalAnimatedValue, {
* toValue: modalToValue,
* duration: 300,
* easing: Easing.inOut(Easing.exp),
* useNativeDriver: true,
* }),
* Animated.timing(myOtherAnimatedValue, {
* toValue: 1,
* duration: 300,
* easing: Easing.inOut(Easing.exp),
* useNativeDriver: true,
* }),
* ]).start()
* }
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#animationin
*/
animationIn?: (
animatedValue: Animated.Value,
toValue: number,
) => Animated.CompositeAnimation | void
/**
* Animation configuration used to animate a modal out (underneath other modals or when closing the last one).
* Uses Animated.timing(), if you want to use another animation type, use `animationOut`.
*
* Note: only `easing` and `duration` are needed.
*
* @default { easing: Easing.inOut(Easing.exp), duration: 450 }
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#animationout
*/
animateOutConfig?: Pick<Animated.TimingAnimationConfig, 'duration' | 'easing'>
/**
* Animation function that receives the `animatedValue` used by the library to animate the modal closing,
* and a `toValue` argument representing the modal position in the stack.
*
* Note: If you just want to use Animated.timing(), check `animateOutConfig`.
*
* @default -
* @example
* animationOut: (modalAnimatedValue, modalToValue) => {
* Animated.parallel([
* Animated.timing(modalAnimatedValue, {
* toValue: modalToValue,
* duration: 300,
* easing: Easing.inOut(Easing.exp),
* useNativeDriver: true,
* }),
* Animated.timing(myOtherAnimatedValue, {
* toValue: 1,
* duration: 300,
* easing: Easing.inOut(Easing.exp),
* useNativeDriver: true,
* }),
* ]).start()
* }
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#animationout
*/
animationOut?: (
animatedValue: Animated.Value,
toValue: number,
) => Animated.CompositeAnimation | void
/**
* How you want the modal stack to behave when users press the backdrop, but also when the physical back button is pressed on Android.
*
* @default 'pop'
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#backbehavior
*/
backBehavior?: 'clear' | 'pop' | 'none'
/**
* Color of the modal stack backdrop.
*
* @default 'black'
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#backdropcolor
*/
backdropColor?: ViewStyle['backgroundColor']
/**
* Number between `0` and `1` that defines the backdrop opacity.
*
* @default 0.6
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#backdropopacity
*/
backdropOpacity?: number
/**
* Styles applied to the `<View>` directly wrapping your modal component.
*
* @default '{}'
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#containerstyle
*/
containerStyle?: ViewStyle
/**
* Disable fling gesture detection to close the modal.
*
* Note: the fling gesture handler is not enabled when `position` is `center`.
*
* @default false
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#disableflinggesture
*/
disableFlingGesture?: boolean
/**
* React component that will be rendered when you'll open the modal.
*
* Note: only needed when you're using this inside createModalStack() 1st argument.
*
* @default -
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#modal
*/
modal?: ComponentType<any>
/**
* Vertical positioning of the modal.
*
* @default 'center'
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#position
*/
position?: 'center' | 'top' | 'bottom'
/**
* Should closing a modal be animated.
*
* @deprecated since v2.0 | Use `animateConfigOut` instead.
* @default false
*/
shouldAnimateOut?: boolean
/**
* `transitionOptions(animatedValue)` returns a React Native style object containing values that can use the provided `animatedValue` to run animation interpolations on a modal.
*
* Note: the object returned by `transitionOptions()` must contain keys that work with `useNativeDriver: true`.
*
* @default -
* @see https://colorfy-software.gitbook.io/react-native-modalfy/api/types/modaloptions#transitionoptions
*/
transitionOptions?: ModalTransitionOptions
}
/**
* Interface of the `modal` prop exposed by the library to regular components.
*
* @argument { unknown } ModalStackParamsList? - Interface of the whole modal stack params.
* @argument { unknown } Props? - Component's props interface.
*
* Note: Modal components used in `createModalStack()`'s config should employ `ModalComponentProp` .
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#modalprop
*/
export type ModalProp<P extends ModalfyParams, Props = unknown> = Props & {
/**
* Interface of the `modal` prop exposed by the library to regular components.
*
* Note: Modal components used in `createModalStack()`'s config should employ `ModalComponentProp` .
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#modalprop
*/
modal: UsableModalProp<P>
}
/**
* Interface of the `modal` prop exposed by the library specifically to modal components.
*
* @argument { unknown } ModalStackParamsList? - Interface of the whole modal stack params.
* @argument { unknown } Props? - Component's props interface.
* @argument { string } ModalName? - Name of the current modal
*
* Note: Components that are not used from `createModalStack()`'s config should employ `ModalProp` .
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#modalcomponentprop
*/
export type ModalComponentProp<
P extends ModalfyParams,
Props = unknown,
M = keyof P
> = Props & {
/**
* Interface of the `modal` prop exposed by the library specifically to modal components.
*
* Note: Components that are not used from `createModalStack()`'s config should employ `ModalProp` .
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#modalcomponentprop
*/
// @ts-ignore
modal: UsableModalComponentProp<P, M>
}
/**
* Interface for a React component containing its props and the `modalOption` static property.
*
* Note: Only use with Hooks modal components (present in your `createModalStack()`'s config).
* If you're working with a Class modal component, you can directly use `static modalOptions: ModalOptions`.
*
* @argument { unknown } Props? - Component's props interface.
*
* Note: Modal components used in your `createModalStack()`'s config.
*
* @see https://colorfy-software.gitbook.io/react-native-modalfy/guides/typing#modalcomponentwithoptions
*/
export type ModalComponentWithOptions<P = unknown> = ComponentType<P> & {
modalOptions?: ModalOptions
}