Skip to content

Commit 1ceeda4

Browse files
feat(sandbox,lib,demo): modal in portal (#416)
* feat: introduce usePortalModal to PluginLoadedMessage * feat: modal in portal * fix(sandbox): implementation for sandbox * fix(sandbox): close modal from the parent app * refactor(sandbox): better state management of modal * feat: enablePortalModal option * fix: ts errors * feat: enable by default in templates * Update packages/demo/src/components/FieldPluginDemo.tsx * fix: templates * fix: tests --------- Co-authored-by: Gustavo Melki Portaluri <[email protected]>
1 parent 175048a commit 1ceeda4

File tree

13 files changed

+295
-44
lines changed

13 files changed

+295
-44
lines changed

packages/cli/templates/js/src/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ let previousType = 'loading'
1515

1616
// Establish communication with the Visual Editor
1717
createFieldPlugin({
18+
enablePortalModal: true,
1819
validateContent: (content) => ({
1920
content: typeof content === 'number' ? content : 0,
2021
}),

packages/cli/templates/react/src/components/FieldPlugin.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useFieldPlugin } from '@storyblok/field-plugin/react'
33

44
const FieldPlugin: FunctionComponent = () => {
55
const plugin = useFieldPlugin({
6+
enablePortalModal: true,
67
/*
78
The `validateContent` parameter is optional. It allows you to
89
- validate the content

packages/cli/templates/react/src/components/FieldPluginExample/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useFieldPlugin } from '@storyblok/field-plugin/react'
77

88
const FieldPlugin: FunctionComponent = () => {
99
const { type, data, actions } = useFieldPlugin({
10+
enablePortalModal: true,
1011
validateContent: (content: unknown) => ({
1112
content: typeof content === 'number' ? content : 0,
1213
}),

packages/cli/templates/vue2/src/fieldPlugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createFieldPlugin } from '@storyblok/field-plugin'
44
export const fieldPluginMixin = {
55
created() {
66
createFieldPlugin({
7+
enablePortalModal: true,
78
validateContent: (content) => ({
89
content: typeof content === 'number' ? content : 0,
910
}),

packages/cli/templates/vue3/src/components/FieldPlugin.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { useFieldPlugin } from '@storyblok/field-plugin/vue3'
33
44
const plugin = useFieldPlugin({
5+
enablePortalModal: true,
56
/*
67
The `validateContent` parameter is optional. It allows you to
78
- validate the content

packages/cli/templates/vue3/src/components/FieldPluginExample/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import AssetSelector from './AssetSelector.vue'
66
import { useFieldPlugin } from '@storyblok/field-plugin/vue3'
77
88
const plugin = useFieldPlugin({
9+
enablePortalModal: true,
910
validateContent: (content: unknown) => ({
1011
content: typeof content === 'number' ? content : 0,
1112
}),

packages/demo/src/components/FieldPluginDemo.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type PluginComponent = FunctionComponent<{
1919
export const FieldPluginDemo: FunctionComponent = () => {
2020
const { type, data, actions } = useFieldPlugin({
2121
validateContent,
22+
enablePortalModal: true,
2223
})
2324

2425
if (type === 'loading') {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type CreateFieldPluginOptions<Content> = {
1212
onUpdateState: (state: FieldPluginResponse<Content>) => void
1313
validateContent?: ValidateContent<Content>
1414
targetOrigin?: string
15+
enablePortalModal?: boolean
1516
}
1617

1718
export type CreateFieldPlugin = <Content = unknown>(
@@ -25,6 +26,7 @@ export const createFieldPlugin: CreateFieldPlugin = ({
2526
onUpdateState,
2627
validateContent,
2728
targetOrigin,
29+
enablePortalModal,
2830
}) => {
2931
const isEmbedded = window.parent !== window
3032

@@ -107,6 +109,7 @@ export const createFieldPlugin: CreateFieldPlugin = ({
107109
validateContent:
108110
validateContent ||
109111
((content) => ({ content: content as InferredContent })),
112+
enablePortalModal,
110113
})
111114

112115
const cleanupHeightChangeListener = createHeightChangeListener(onHeightChange)

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type CreatePluginActions = <Content>(options: {
2828
postToContainer: (message: unknown) => void
2929
onUpdateState: (state: FieldPluginData<Content>) => void
3030
validateContent: ValidateContent<Content>
31+
enablePortalModal?: boolean
3132
}) => {
3233
// These functions are to be called by the field plugin when the user performs actions in the UI
3334
actions: FieldPluginActions<Content>
@@ -46,6 +47,7 @@ export const createPluginActions: CreatePluginActions = ({
4647
postToContainer,
4748
onUpdateState,
4849
validateContent,
50+
enablePortalModal,
4951
}) => {
5052
const { pushCallback, popCallback } = callbackQueue()
5153

@@ -143,7 +145,9 @@ export const createPluginActions: CreatePluginActions = ({
143145
resolve(pluginStateFromStateChangeMessage(message, validateContent)),
144146
)
145147
// Request the initial state from the Visual Editor.
146-
postToContainer(pluginLoadedMessage({ uid, callbackId }))
148+
postToContainer(
149+
pluginLoadedMessage({ uid, callbackId, enablePortalModal }),
150+
)
147151
})
148152
},
149153
}

packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PluginLoadedMessage.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,92 @@ describe('PluginLoadedMessage', () => {
7676
).toEqual(false)
7777
})
7878
})
79+
describe('subscribeState', () => {
80+
it('is optional', () => {
81+
expect(
82+
isPluginLoadedMessage({
83+
...stub,
84+
subscribeState: undefined,
85+
}),
86+
).toEqual(true)
87+
})
88+
it('is a boolean', () => {
89+
expect(
90+
isPluginLoadedMessage({
91+
...stub,
92+
subscribeState: true,
93+
}),
94+
).toEqual(true)
95+
expect(
96+
isPluginLoadedMessage({
97+
...stub,
98+
subscribeState: false,
99+
}),
100+
).toEqual(true)
101+
const { subscribeState: _subscribeState, ...subWithoutSubscribeState } =
102+
stub
103+
expect(isPluginLoadedMessage(subWithoutSubscribeState)).toEqual(true)
104+
expect(
105+
isPluginLoadedMessage({
106+
...stub,
107+
subscribeState: 'false',
108+
}),
109+
).toEqual(false)
110+
expect(
111+
isPluginLoadedMessage({
112+
...stub,
113+
subscribeState: 123,
114+
}),
115+
).toEqual(false)
116+
expect(
117+
isPluginLoadedMessage({
118+
...stub,
119+
subscribeState: null,
120+
}),
121+
).toEqual(false)
122+
})
123+
})
124+
describe('enablePortalModal', () => {
125+
it('is optional', () => {
126+
expect(
127+
isPluginLoadedMessage({
128+
...stub,
129+
}),
130+
).toEqual(true)
131+
})
132+
it('is a boolean', () => {
133+
expect(
134+
isPluginLoadedMessage({
135+
...stub,
136+
enablePortalModal: true,
137+
}),
138+
).toEqual(true)
139+
expect(
140+
isPluginLoadedMessage({
141+
...stub,
142+
enablePortalModal: false,
143+
}),
144+
).toEqual(true)
145+
expect(
146+
isPluginLoadedMessage({
147+
...stub,
148+
enablePortalModal: 'false',
149+
}),
150+
).toEqual(false)
151+
expect(
152+
isPluginLoadedMessage({
153+
...stub,
154+
enablePortalModal: 123,
155+
}),
156+
).toEqual(false)
157+
expect(
158+
isPluginLoadedMessage({
159+
...stub,
160+
enablePortalModal: null,
161+
}),
162+
).toEqual(false)
163+
})
164+
})
79165
})
80166
describe('constructor', () => {
81167
it('includes the uid', () => {
@@ -90,5 +176,27 @@ describe('PluginLoadedMessage', () => {
90176
true,
91177
)
92178
})
179+
it('sets subscribeState to true', () => {
180+
expect(pluginLoadedMessage({ uid, callbackId })).toHaveProperty(
181+
'subscribeState',
182+
true,
183+
)
184+
})
185+
it('does not define enablePortalModal by default', () => {
186+
expect(pluginLoadedMessage({ uid, callbackId })).not.toHaveProperty(
187+
'enablePortalModal',
188+
)
189+
})
190+
it('lets you define enablePortalModal', () => {
191+
expect(
192+
pluginLoadedMessage({ uid, callbackId, enablePortalModal: true }),
193+
).toHaveProperty('enablePortalModal', true)
194+
expect(
195+
pluginLoadedMessage({ uid, callbackId, enablePortalModal: false }),
196+
).toHaveProperty('enablePortalModal', false)
197+
expect(
198+
pluginLoadedMessage({ uid, callbackId, enablePortalModal: undefined }),
199+
).toHaveProperty('enablePortalModal', undefined)
200+
})
93201
})
94202
})

0 commit comments

Comments
 (0)