1
1
import { ServiceMixin } from '@spuxx/js-utils' ;
2
- import { Component , ComponentProps } from 'solid-js' ;
3
2
import { ModalComponent , ModalOptions } from './modal.types' ;
4
- import { render } from 'solid-js/web' ;
3
+ import { createSignal } from 'solid-js' ;
4
+
5
+ interface ModalState {
6
+ open : boolean ;
7
+ component : ModalComponent < never > | null ;
8
+ options ?: ModalOptions ;
9
+ }
5
10
6
11
/**
7
12
* The `Modal` service provides global access to modal dialogs.
@@ -16,43 +21,38 @@ import { render } from 'solid-js/web';
16
21
* ```
17
22
*/
18
23
export class Modal extends ServiceMixin < Modal > ( ) {
19
- protected portal : Node | undefined ;
20
- protected dispose = ( ) => { } ;
24
+ state = createSignal < ModalState > ( { open : false , component : null } ) ;
21
25
22
26
/**
23
27
* Shows the modal dialog of the given type and with the given options.
24
28
* @param key The key of the modal to open.
25
29
* @param options The options to pass to the modal.
26
30
*/
27
31
static show < TOptions extends ModalOptions > ( modal : ModalComponent < TOptions > , options : TOptions ) {
28
- if ( ! this . portal ) {
29
- throw new Error (
30
- 'No modal portal node has been registered. Please register a portal node first.' ,
31
- ) ;
32
- }
33
- this . instance . dispose = render ( ( ) => modal ( options ) , this . portal ) ;
32
+ this . setState ( { open : true , component : modal , options } ) ;
34
33
}
35
34
36
35
/**
37
36
* Closes the modal dialog that is currently open, if there is one.
38
37
*/
39
- static close ( ) {
40
- this . instance . dispose ( ) ;
38
+ static async close ( ) {
39
+ this . setState ( { ... this . state , open : false } ) ;
41
40
}
42
41
43
42
/**
44
- * Returns the portal node that is used to render the modal .
43
+ * Returns the current state of the modal. The state is read-only .
45
44
*/
46
- static get portal ( ) : Node | undefined {
47
- return this . instance . portal ;
45
+ static get state ( ) : ModalState {
46
+ const [ state ] = this . instance . state ;
47
+ return state ( ) ;
48
48
}
49
49
50
50
/**
51
- * Registers the given node as the portal node that is used to render the modal.
52
- * Only one portal node can be registered at a time.
53
- * @param node The node to register as the portal node.
51
+ * Sets the current state of the modal. You should avoid manipulating the modal state directly
52
+ * and instead use `Modal.show()` and `Modal.close()`.
54
53
*/
55
- static setPortal ( node : Node ) {
56
- this . instance . portal = node ;
54
+ static setState ( newState : ModalState ) : void {
55
+ const [ _state , setModalState ] = this . instance . state ;
56
+ setModalState ( newState ) ;
57
57
}
58
58
}
0 commit comments