Skip to content

Commit 43b4c30

Browse files
refactor(sandbox): better state management of modal
1 parent c4f98a6 commit 43b4c30

File tree

3 files changed

+53
-41
lines changed

3 files changed

+53
-41
lines changed

packages/field-plugin/src/createFieldPlugin/createFieldPlugin.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export type CreateFieldPluginOptions<Content> = {
1212
onUpdateState: (state: FieldPluginResponse<Content>) => void
1313
validateContent?: ValidateContent<Content>
1414
targetOrigin?: string
15-
// TODO add enablePortalModal
1615
}
1716

1817
export type CreateFieldPlugin = <Content = unknown>(

packages/sandbox/src/components/FieldPluginSandbox.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ const defaultManifest = { options: [] }
6565
const urlQueryParam = withDefault(StringParam, defaultUrl)
6666
const manifestQueryParam = withDefault(JsonParam, defaultManifest)
6767

68+
export type ModalState =
69+
| 'non-modal'
70+
| 'modal-with-portal'
71+
| 'modal-without-portal'
72+
6873
const useSandbox = (
6974
onError: (message: { title: string; message?: string }) => void,
7075
) => {
@@ -304,14 +309,23 @@ const useSandbox = (
304309
],
305310
)
306311

312+
const modalState = useMemo<ModalState>(() => {
313+
if (!isModalOpen) {
314+
return 'non-modal'
315+
} else if (enablePortalModal) {
316+
return 'modal-with-portal'
317+
} else {
318+
return 'modal-without-portal'
319+
}
320+
}, [isModalOpen, enablePortalModal])
321+
307322
return [
308323
{
309324
content,
310325
language,
311-
isModalOpen,
312326
height,
313327
fullHeight,
314-
enablePortalModal,
328+
modalState,
315329
schema,
316330
url,
317331
fieldTypeIframe,
@@ -334,9 +348,8 @@ export const FieldPluginSandbox: FunctionComponent = () => {
334348
{
335349
content,
336350
language,
337-
isModalOpen,
351+
modalState,
338352
fullHeight,
339-
enablePortalModal,
340353
height,
341354
schema,
342355
url,
@@ -375,8 +388,7 @@ export const FieldPluginSandbox: FunctionComponent = () => {
375388
<FieldTypePreview
376389
src={iframeSrc}
377390
height={height}
378-
isModal={isModalOpen}
379-
enablePortalModal={enablePortalModal}
391+
modalState={modalState}
380392
fullHeight={fullHeight}
381393
ref={fieldTypeIframe}
382394
onModalChange={setModalOpen}
@@ -451,7 +463,7 @@ export const FieldPluginSandbox: FunctionComponent = () => {
451463
output={
452464
{
453465
content,
454-
isModalOpen,
466+
isModalOpen: modalState !== 'non-modal',
455467
translatable: schema.translatable,
456468
storyLang: language,
457469
options: recordFromFieldPluginOptions(schema.options),

packages/sandbox/src/components/FieldTypePreview.tsx

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ import {
1616
} from '@mui/material'
1717
import { DisableShieldsNotification } from './DisableShieldsNotification'
1818
import { CloseIcon } from '@storyblok/mui'
19+
import { ModalState } from './FieldPluginSandbox'
1920

2021
const NonPortalModal: FunctionComponent<
2122
PropsWithChildren<{
22-
isNonPortalModalOpen: boolean
23+
isModal: boolean
2324
}>
2425
> = (props) => (
2526
<Box
2627
sx={
27-
props.isNonPortalModalOpen
28+
props.isModal
2829
? {
2930
position: 'fixed',
3031
left: 0,
@@ -46,12 +47,12 @@ const NonPortalModal: FunctionComponent<
4647

4748
const FieldTypeSandbox: FunctionComponent<
4849
PropsWithChildren<{
49-
isNonPortalModalOpen: boolean
50+
isModal: boolean
5051
}>
5152
> = (props) => (
5253
<Box
5354
sx={
54-
props.isNonPortalModalOpen
55+
props.isModal
5556
? {
5657
bgcolor: 'background.paper',
5758
p: 6,
@@ -69,7 +70,7 @@ const FieldTypeSandbox: FunctionComponent<
6970
style={{
7071
display: 'flex',
7172
margin: 'auto',
72-
width: props.isNonPortalModalOpen ? '90%' : '100%',
73+
width: props.isModal ? '90%' : '100%',
7374
}}
7475
>
7576
{props.children}
@@ -132,28 +133,23 @@ export const FieldTypePreview = forwardRef<
132133
{
133134
src: string | undefined
134135
height: number
135-
isModal: boolean
136-
enablePortalModal: boolean
136+
modalState: ModalState
137137
fullHeight: boolean
138138
// Allows the iframe to be refreshed
139139
iframeKey?: number
140140
sx?: SxProps
141141
onModalChange: (isModal: boolean) => void
142142
}
143143
>(function FieldTypePreview(props, ref) {
144-
const { height, isModal, fullHeight, enablePortalModal, onModalChange } =
145-
props
146-
147-
const isNonPortalModalOpen = !enablePortalModal && isModal
148-
const isPortalModalOpen = enablePortalModal && isModal
144+
const { height, fullHeight, modalState, onModalChange } = props
149145

150146
const setTeleported = (el: HTMLIFrameElement | null) => {
151-
if (isPortalModalOpen) {
147+
if (modalState === 'modal-with-portal') {
152148
setRef(ref, el)
153149
}
154150
}
155151
const setNonTeleported = (el: HTMLIFrameElement | null) => {
156-
if (!isPortalModalOpen) {
152+
if (modalState !== 'modal-with-portal') {
157153
setRef(ref, el)
158154
}
159155
}
@@ -166,7 +162,7 @@ export const FieldTypePreview = forwardRef<
166162
<Box sx={props.sx}>
167163
<DisableShieldsNotification />
168164
<Dialog
169-
open={isPortalModalOpen}
165+
open={modalState === 'modal-with-portal'}
170166
fullScreen
171167
sx={{
172168
padding: 10,
@@ -197,28 +193,33 @@ export const FieldTypePreview = forwardRef<
197193
src={props.src}
198194
ref={setTeleported}
199195
fullHeight={fullHeight}
200-
modal={isModal}
196+
modal={modalState === 'modal-with-portal'}
201197
height={height}
202198
/>
203199
</Dialog>
204-
<Backdrop
205-
open={isNonPortalModalOpen}
206-
sx={{ zIndex: ({ zIndex }) => zIndex.drawer }}
207-
/>
208-
<NonPortalModal isNonPortalModalOpen={isNonPortalModalOpen}>
209-
<FieldTypeSandbox isNonPortalModalOpen={isNonPortalModalOpen}>
210-
{!isPortalModalOpen && (
211-
<FieldPluginIframe
212-
key={props.iframeKey}
213-
src={props.src}
214-
ref={setNonTeleported}
215-
fullHeight={fullHeight}
216-
modal={isModal}
217-
height={height}
200+
{
201+
// Always render it unless the modal with portal is open; then we don't want to render thois
202+
modalState !== 'modal-with-portal' && (
203+
<>
204+
<Backdrop
205+
open={modalState === 'modal-without-portal'}
206+
sx={{ zIndex: ({ zIndex }) => zIndex.drawer }}
218207
/>
219-
)}
220-
</FieldTypeSandbox>
221-
</NonPortalModal>
208+
<NonPortalModal isModal={modalState === 'modal-without-portal'}>
209+
<FieldTypeSandbox isModal={modalState === 'modal-without-portal'}>
210+
<FieldPluginIframe
211+
key={props.iframeKey}
212+
src={props.src}
213+
ref={setNonTeleported}
214+
fullHeight={fullHeight}
215+
modal={modalState === 'modal-without-portal'}
216+
height={height}
217+
/>
218+
</FieldTypeSandbox>
219+
</NonPortalModal>
220+
</>
221+
)
222+
}
222223
</Box>
223224
)
224225
})

0 commit comments

Comments
 (0)