11import React from "react" ;
2- import { Classes , OverlaysProvider } from "@blueprintjs/core" ;
2+ import { OverlaysProvider } from "@blueprintjs/core" ;
33import { Meta , StoryFn } from "@storybook/react" ;
44import { fn } from "@storybook/test" ;
55
66import { SimpleCard } from "../../Card/stories/Card.stories" ;
77
8- import {
9- Button ,
10- Card ,
11- CardContent ,
12- Modal ,
13- ModalContext ,
14- ModalSize ,
15- Spacing ,
16- useModalContext ,
17- } from "./../../../../index" ;
8+ import { Card , Modal } from "./../../../../index" ;
189
1910export default {
2011 title : "Components/Dialog/Modal" ,
@@ -24,15 +15,18 @@ export default {
2415 control : false ,
2516 } ,
2617 } ,
18+ decorators : [
19+ ( Story ) => (
20+ < OverlaysProvider >
21+ < div style = { { height : "400px" } } >
22+ < Story />
23+ </ div >
24+ </ OverlaysProvider >
25+ ) ,
26+ ] ,
2727} as Meta < typeof Modal > ;
2828
29- const Template : StoryFn < typeof Modal > = ( args ) => (
30- < OverlaysProvider >
31- < div style = { { height : "400px" } } >
32- < Modal { ...args } />
33- </ div >
34- </ OverlaysProvider >
35- ) ;
29+ const Template : StoryFn < typeof Modal > = ( args ) => < Modal { ...args } /> ;
3630
3731export const Default = Template . bind ( { } ) ;
3832Default . args = {
@@ -42,135 +36,3 @@ Default.args = {
4236 onOpening : fn ( ) ,
4337 onClosing : fn ( ) ,
4438} ;
45-
46- const ContextTemplate = ( { children } : React . HTMLAttributes < HTMLDivElement > ) => {
47- const { setModalOpen, openModalStack } = useModalContext ( ) ;
48-
49- return (
50- < OverlaysProvider >
51- < div style = { { height : "70vh" , position : "relative" } } id = { "modalPortal" } >
52- < ModalContext . Provider value = { { setModalOpen, openModalStack } } > { children } </ ModalContext . Provider >
53- </ div >
54- </ OverlaysProvider >
55- ) ;
56- } ;
57-
58- const ModalContent = ( { children } : React . HTMLAttributes < HTMLDivElement > ) => {
59- return (
60- < Card style = { { height : "100%" } } >
61- < CardContent > { children } </ CardContent >
62- </ Card >
63- ) ;
64- } ;
65-
66- /** Component for nested modals. */
67- const ExampleModal = ( {
68- id,
69- size,
70- children,
71- } : {
72- id ?: string ;
73- size : ModalSize ;
74- children ?: React . HTMLAttributes < HTMLDivElement > [ "children" ] ;
75- } ) => {
76- const [ isOpen , setIsOpen ] = React . useState ( true ) ;
77- const [ portalElement , setPortalElement ] = React . useState < HTMLElement | undefined > ( ) ;
78-
79- React . useEffect ( ( ) => {
80- setPortalElement ( document . getElementById ( "modalPortal" ) ! ) ;
81- } , [ ] ) ;
82-
83- return (
84- < Modal
85- modalId = { id }
86- size = { size }
87- isOpen = { isOpen }
88- usePortal = { true }
89- portalContainer = { portalElement }
90- hasBackdrop = { true }
91- onOpened = { ( ) => {
92- // workaround, Blueprint attach a class to body tht prevents scrolling, probably it is attached to the wrong portal
93- document . body . classList . remove ( Classes . OVERLAY_OPEN ) ;
94- } }
95- >
96- < ModalContent >
97- Modal with constant modal ID "{ id } ".
98- < Spacing />
99- < TrackingContent />
100- < Spacing />
101- { children }
102- < Spacing />
103- < Button key = { "close" } onClick = { ( ) => setIsOpen ( false ) } >
104- Close
105- </ Button >
106- </ ModalContent >
107- </ Modal >
108- ) ;
109- } ;
110-
111- const InnerModal = ( ) => {
112- return < ExampleModal id = "innerModal" size = "small" /> ;
113- } ;
114-
115- const MiddleModal = ( ) => {
116- return (
117- < ExampleModal id = "middleModal" size = "regular" >
118- < InnerModal />
119- </ ExampleModal >
120- ) ;
121- } ;
122-
123- /** Shows the current stack of open modals. */
124- const TrackingContent = ( ) => {
125- const modalContext = React . useContext ( ModalContext ) ;
126-
127- return (
128- < ul >
129- { ( modalContext . openModalStack ( ) ?? [ ] ) . map ( ( modalId , idx ) => (
130- < li key = { modalId } >
131- { idx + 1 } . { modalId }
132- </ li >
133- ) ) }
134- </ ul >
135- ) ;
136- } ;
137-
138- /**
139- * `ModalContext` can be used as provider to track a stack of modals.
140- *
141- * ```(Javascript)
142- * const ContextTemplate = () => {
143- * const { setModalOpen, openModalStack } = useModalContext();
144- * return (
145- * <ModalContext.Provider value={{ setModalOpen, openModalStack }}>
146- * <SimpleDialog size="large" isOpen>
147- * <OtherModal />
148- * </SimpleDialog>
149- * </ModalContext.Provider>
150- * );
151- * };
152- *
153- * const OtherModal = () => {
154- * const modalContext = React.useContext(ModalContext);
155- * return (
156- * <SimpleDialog size="small">
157- * <ul>
158- * {(modalContext.openModalStack ?? []).map((modalId, idx) => (
159- * <li key={modalId}>
160- * {idx + 1}. {modalId}
161- * </li>
162- * ))}
163- * </ul>
164- * </SimpleDialog>
165- * );
166- * };
167- * ```
168- */
169- export const NestedModalWithContext = ContextTemplate . bind ( { } ) ;
170- NestedModalWithContext . args = {
171- children : [
172- < ExampleModal id = "rootModal" size = "large" >
173- < MiddleModal />
174- </ ExampleModal > ,
175- ] ,
176- } ;
0 commit comments