11import { bodyFreeze } from './bodyFreeze'
22
3+ export type ModalInstance = {
4+ open : ( freeze ?: boolean ) => void
5+ close : ( ) => void
6+ replaceWith : ( modal : ModalInstance ) => void
7+ remove : ( ) => void
8+ }
9+
310export type ModalCallback = {
411 trigger : Element | null
512 modal : HTMLElement
@@ -12,7 +19,7 @@ export type Modal = {
1219 onClose ?: ( args : ModalCallback ) => unknown
1320}
1421
15- export const modal = ( config : Modal | string ) => {
22+ export const modal = ( config : Modal | string ) : ModalInstance | undefined => {
1623 const {
1724 trigger,
1825 modal,
@@ -23,44 +30,51 @@ export const modal = (config: Modal | string) => {
2330 const modalSelector = typeof config === 'string' ? config : modal
2431
2532 const triggerDOM = document . querySelector ( trigger )
26- const modalDOM = document . querySelector ( modalSelector ) as HTMLElement
33+ const modalDOM = document . querySelector ( modalSelector )
2734
28- if ( modalDOM ) {
35+ if ( modalDOM instanceof HTMLElement ) {
2936 const closeOptions = modalDOM . dataset . close ?. split ( ',' )
3037
31- const handleClose = {
32- icon ( ) {
33- const close = modalDOM . querySelector ( '[data-id="close"]' )
38+ const handleOpen = ( _e ?: Event , freeze = true ) => {
39+ modalDOM . dataset . show = 'true'
40+
41+ if ( freeze ) {
42+ bodyFreeze ( )
43+ }
44+
45+ onOpen ?.( {
46+ trigger : triggerDOM ,
47+ modal : modalDOM
48+ } )
49+ }
3450
35- const listener = ( ) => {
36- modalDOM . dataset . show = ''
51+ const handleClose = ( _e ?: Event , unfreeze = true ) => {
52+ modalDOM . dataset . show = ''
3753
38- bodyFreeze ( false )
54+ if ( unfreeze ) {
55+ bodyFreeze ( false )
56+ }
3957
40- onClose ?.( {
41- trigger : triggerDOM ,
42- modal : modalDOM
43- } )
44- }
58+ onClose ?.( {
59+ trigger : triggerDOM ,
60+ modal : modalDOM
61+ } )
62+ }
63+
64+ const closeHandlers = {
65+ icon ( ) {
66+ const close = modalDOM . querySelector ( '[data-id="close"]' )
4567
4668 return {
47- add : ( ) => close ?. addEventListener ( 'click' , listener ) ,
48- remove : ( ) => close ?. removeEventListener ( 'click' , listener )
69+ add : ( ) => close ?. addEventListener ( 'click' , handleClose ) ,
70+ remove : ( ) => close ?. removeEventListener ( 'click' , handleClose )
4971 }
5072 } ,
5173
5274 esc ( ) {
5375 const listener = ( event : KeyboardEvent ) => {
5476 if ( modalDOM . dataset . show && event . key === 'Escape' ) {
55- modalDOM . dataset . show = ''
56-
57- bodyFreeze ( false )
58-
59- onClose ?.( {
60- trigger : triggerDOM ,
61- modal : modalDOM
62- } )
63-
77+ handleClose ( )
6478 }
6579 }
6680
@@ -73,60 +87,45 @@ export const modal = (config: Modal | string) => {
7387 overlay ( ) {
7488 const close = modalDOM . nextElementSibling
7589
76- const listener = ( ) => {
77- modalDOM . dataset . show = ''
78-
79- bodyFreeze ( false )
80-
81- onClose ?.( {
82- trigger : triggerDOM ,
83- modal : modalDOM
84- } )
85- }
86-
8790 return {
88- add : ( ) => close ?. addEventListener ( 'click' , listener ) ,
89- remove : ( ) => close ?. removeEventListener ( 'click' , listener )
91+ add : ( ) => close ?. addEventListener ( 'click' , handleClose ) ,
92+ remove : ( ) => close ?. removeEventListener ( 'click' , handleClose )
9093 }
9194 }
9295 }
9396
94- const handleOpen = ( ) => {
95- modalDOM . dataset . show = 'true'
96-
97- bodyFreeze ( )
98-
99- onOpen ?.( {
100- trigger : triggerDOM ,
101- modal : modalDOM
102- } )
103- }
104-
10597 triggerDOM ?. addEventListener ( 'click' , handleOpen )
10698
10799 closeOptions ?. forEach ( option => {
108- handleClose [ option as keyof typeof handleClose ] ( ) . add ( )
100+ closeHandlers [ option as keyof typeof closeHandlers ] ( ) . add ( )
109101 } )
110102
111103 return {
112- open ( ) {
113- handleOpen ( )
104+ open ( freeze ?: boolean ) {
105+ handleOpen ( undefined , freeze )
106+ } ,
107+ close ( ) {
108+ handleClose ( )
109+ } ,
110+ replaceWith ( modal : ModalInstance ) {
111+ modal . open ( false )
112+ handleClose ( undefined , false )
114113 } ,
115114 remove ( ) {
116115 triggerDOM ?. removeEventListener ( 'click' , handleOpen )
117116
118117 closeOptions ?. forEach ( option => {
119- handleClose [ option as keyof typeof handleClose ] ( ) . remove ( )
118+ closeHandlers [ option as keyof typeof closeHandlers ] ( ) . remove ( )
120119 } )
121120 }
122121 }
123122 }
124123}
125124
126125export const closeModal = ( modal : string ) => {
127- const modalDOM = document . querySelector ( modal ) as HTMLElement
126+ const modalDOM = document . querySelector ( modal )
128127
129- if ( modalDOM ) {
128+ if ( modalDOM instanceof HTMLElement ) {
130129 modalDOM . dataset . show = ''
131130
132131 bodyFreeze ( false )
0 commit comments