From 47ed4a4d8f873fc6d4d744b2cc89fd8871fa1a84 Mon Sep 17 00:00:00 2001
From: Johannes Lindgren <14206504+johannes-lindgren@users.noreply.github.com>
Date: Tue, 22 Jul 2025 17:05:05 +0200
Subject: [PATCH 01/11] feat: change preview dimension
---
packages/demo/src/components/NonModalView.tsx | 2 +
packages/demo/src/components/PreviewWidth.tsx | 38 ++++
packages/field-plugin/package.json | 3 +
.../createFieldPlugin/FieldPluginActions.ts | 17 ++
.../createPluginActions/callbackQueue.ts | 3 +
.../createPluginActions.ts | 13 ++
.../PreviewDimensionChangeMessage.test.ts | 184 ++++++++++++++++++
.../PreviewDimensionChangeMessage.ts | 57 ++++++
.../pluginToContainerMessage/index.ts | 1 +
.../src/dom/createSandboxMessageListener.ts | 5 +
yarn.lock | 8 +
11 files changed, 331 insertions(+)
create mode 100644 packages/demo/src/components/PreviewWidth.tsx
create mode 100644 packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.test.ts
create mode 100644 packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
diff --git a/packages/demo/src/components/NonModalView.tsx b/packages/demo/src/components/NonModalView.tsx
index 9fc22751..b34957d9 100644
--- a/packages/demo/src/components/NonModalView.tsx
+++ b/packages/demo/src/components/NonModalView.tsx
@@ -8,6 +8,7 @@ import { UserContextRequester } from './UserContextRequester'
import { PluginComponent } from './FieldPluginDemo'
import { LanguageView } from './LanguageView'
import { PromptAI } from './PromptAI'
+import { PreviewWidth } from './PreviewWidth'
export const NonModalView: PluginComponent = (props) => (
@@ -20,6 +21,7 @@ export const NonModalView: PluginComponent = (props) => (
+
)
diff --git a/packages/demo/src/components/PreviewWidth.tsx b/packages/demo/src/components/PreviewWidth.tsx
new file mode 100644
index 00000000..f3217bc1
--- /dev/null
+++ b/packages/demo/src/components/PreviewWidth.tsx
@@ -0,0 +1,38 @@
+import { Button, Stack, Typography } from '@mui/material'
+import { PluginComponent } from './FieldPluginDemo'
+
+export const PreviewWidth: PluginComponent = (props) => {
+ const { data, actions } = props
+
+ const handleClickIncrement = () =>
+ actions?.setContent(
+ (typeof data.content === 'number' ? data.content : 0) + 1,
+ )
+ const handleClickReset = () => actions?.setContent(0)
+
+ const label =
+ typeof data.content === 'undefined'
+ ? 'undefined'
+ : JSON.stringify(data.content)
+
+ return (
+
+ Field Value
+ {label}
+
+
+
+ )
+}
diff --git a/packages/field-plugin/package.json b/packages/field-plugin/package.json
index 7e038f4d..21f74f8d 100644
--- a/packages/field-plugin/package.json
+++ b/packages/field-plugin/package.json
@@ -43,6 +43,9 @@
"test": "vitest",
"build": "unbuild"
},
+ "dependencies": {
+ "pure-parse": "^1.0.1"
+ },
"devDependencies": {
"@types/core-js": "2.5.8",
"@types/node": "18.19.85",
diff --git a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
index f7b5488f..845e52ab 100644
--- a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
+++ b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
@@ -20,6 +20,22 @@ export type PromptAI = (payload: PromptAIPayload) => Promise
export type RequestUserContext = () => Promise
export type SelectAsset = () => Promise
export type Initialize = () => Promise>
+export type SetPreviewWidth = (
+ previewWidth:
+ | {
+ tag: 'desktop'
+ }
+ | {
+ tag: 'tablet'
+ }
+ | {
+ tag: 'mobile'
+ }
+ | {
+ tag: 'custom'
+ width: number
+ },
+) => Promise
export type FieldPluginActions = {
setContent: SetContent
@@ -28,4 +44,5 @@ export type FieldPluginActions = {
promptAI: PromptAI
requestUserContext: RequestUserContext
selectAsset: SelectAsset
+ setPreviewDimension: SetPreviewWidth
}
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
index 0f533414..c70465f8 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
@@ -6,6 +6,7 @@ import type {
LoadedMessage,
OnMessage,
StateChangedMessage,
+ PreviewDimensionChangeMessage,
} from '../../messaging'
import { getRandomUid } from '../../utils'
@@ -18,6 +19,7 @@ type CallbackMap = {
stateChanged: Record>
loaded: Record>
promptAI: Record>
+ previewDimension: Record>
}
type CallbackType = keyof CallbackMap
@@ -29,6 +31,7 @@ export const callbackQueue = () => {
stateChanged: {},
loaded: {},
promptAI: {},
+ previewDimension: {},
}
const pushCallback = (
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
index 1a4206b9..c7efcbd0 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
@@ -11,6 +11,7 @@ import {
pluginLoadedMessage,
getPluginPromptAIMessage,
valueChangeMessage,
+ previewDimensionsChangeMessage,
type OnAssetSelectMessage,
type OnContextRequestMessage,
type OnUserContextRequestMessage,
@@ -176,6 +177,18 @@ export const createPluginActions: CreatePluginActions = ({
postToContainer(getUserContextMessage({ uid, callbackId }))
})
},
+ setPreviewDimension: (previewWidth) => {
+ return new Promise((resolve) => {
+ const callbackId = pushCallback('previewDimension', () => resolve())
+ postToContainer(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: previewWidth,
+ }),
+ )
+ })
+ },
},
messageCallbacks,
onHeightChange,
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.test.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.test.ts
new file mode 100644
index 00000000..cd0aba20
--- /dev/null
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.test.ts
@@ -0,0 +1,184 @@
+import {
+ isPreviewDimensionChangeMessage,
+ previewDimensionsChangeMessage,
+ PreviewDimensionChangeMessage,
+} from './PreviewDimensionChangeMessage'
+import { isMessageToContainer } from './MessageToContainer'
+import { expect } from 'vitest'
+
+const uid = '-preview-abc-123'
+const callbackId = 'test-callback-id'
+const stub: PreviewDimensionChangeMessage = {
+ action: 'plugin-changed',
+ event: 'previewDimension',
+ uid,
+ data: {
+ tag: 'desktop',
+ },
+}
+
+describe('PreviewDimensionsChangeMessage', () => {
+ describe('validator', () => {
+ it('is a MessageToContainer', () => {
+ expect(isMessageToContainer(stub)).toEqual(true)
+ })
+ it('requires event to be "previewDimension"', () => {
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ event: 'previewDimension',
+ }),
+ ).toEqual(true)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ event: 'somethingElse',
+ }),
+ ).toEqual(false)
+ })
+ test('that the data property is present', () => {
+ const { data: _data, ...withoutModel } = stub
+ expect(isPreviewDimensionChangeMessage(withoutModel)).toEqual(false)
+ })
+ test('that the data property can be one of the tagged objects', () => {
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: {
+ tag: 'desktop',
+ },
+ }),
+ ).toEqual(true)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: {
+ tag: 'tablet',
+ },
+ }),
+ ).toEqual(true)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: {
+ tag: 'mobile',
+ },
+ }),
+ ).toEqual(true)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: {
+ tag: 'custom',
+ width: 1234,
+ },
+ }),
+ ).toEqual(true)
+ })
+ test('that the data property cannot be any value', () => {
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: undefined,
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: null,
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: {},
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: 'a string',
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: true,
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: 123.123,
+ }),
+ ).toEqual(false)
+ expect(
+ isPreviewDimensionChangeMessage({
+ ...stub,
+ data: [],
+ }),
+ ).toEqual(false)
+ })
+ })
+ describe('constructor', () => {
+ it('includes the uid', () => {
+ expect(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: {
+ tag: 'desktop',
+ },
+ }),
+ ).toHaveProperty('uid', uid)
+ })
+ it('includes the data', () => {
+ expect(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: {
+ tag: 'desktop',
+ },
+ }),
+ ).toHaveProperty('data', {
+ tag: 'desktop',
+ })
+ expect(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: {
+ tag: 'tablet',
+ },
+ }),
+ ).toHaveProperty('data', {
+ tag: 'tablet',
+ })
+ expect(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: {
+ tag: 'mobile',
+ },
+ }),
+ ).toHaveProperty('data', {
+ tag: 'mobile',
+ })
+ expect(
+ previewDimensionsChangeMessage({
+ uid,
+ callbackId,
+ data: {
+ tag: 'custom',
+ width: 1234,
+ },
+ }),
+ ).toHaveProperty('data', {
+ tag: 'custom',
+ width: 1234,
+ })
+ })
+ })
+})
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
new file mode 100644
index 00000000..1c75e505
--- /dev/null
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
@@ -0,0 +1,57 @@
+import { MessageToContainer } from './MessageToContainer'
+import {
+ equalsGuard,
+ isNumber,
+ isString,
+ objectGuard,
+ oneOfGuard,
+ optionalGuard,
+} from 'pure-parse'
+
+export type PreviewDimensionChangeMessage =
+ MessageToContainer<'previewDimension'> & {
+ data:
+ | {
+ tag: 'desktop'
+ }
+ | {
+ tag: 'tablet'
+ }
+ | {
+ tag: 'mobile'
+ }
+ | {
+ tag: 'custom'
+ width: number
+ }
+ }
+export const isPreviewDimensionChangeMessage =
+ objectGuard({
+ action: equalsGuard('plugin-changed'),
+ uid: isString,
+ callbackId: optionalGuard(isString),
+ event: equalsGuard('previewDimension'),
+ data: oneOfGuard(
+ objectGuard({
+ tag: equalsGuard('desktop'),
+ }),
+ objectGuard({
+ tag: equalsGuard('tablet'),
+ }),
+ objectGuard({
+ tag: equalsGuard('mobile'),
+ }),
+ objectGuard({
+ tag: equalsGuard('custom'),
+ width: isNumber,
+ }),
+ ),
+ })
+
+export const previewDimensionsChangeMessage = (
+ options: Pick,
+): PreviewDimensionChangeMessage => ({
+ action: 'plugin-changed',
+ event: 'previewDimension',
+ ...options,
+})
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/index.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/index.ts
index 1b404cd3..9082eead 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/index.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/index.ts
@@ -2,6 +2,7 @@ export * from './MessageToContainer'
export * from './ValueChangeMessage'
export * from './ModalChangeMessage'
export * from './PluginLoadedMessage'
+export * from './PreviewDimensionChangeMessage'
export * from './HeightChangeMessage'
export * from './GetContextMessage'
export * from './GetUserContextMessage'
diff --git a/packages/sandbox/src/dom/createSandboxMessageListener.ts b/packages/sandbox/src/dom/createSandboxMessageListener.ts
index 1fceecaa..563a76c4 100644
--- a/packages/sandbox/src/dom/createSandboxMessageListener.ts
+++ b/packages/sandbox/src/dom/createSandboxMessageListener.ts
@@ -6,10 +6,12 @@ import {
isMessageToContainer,
isModalChangeMessage,
isPluginLoadedMessage,
+ isPreviewWidthChangeMessage,
isValueChangeMessage,
type ModalChangeMessage,
type PluginLoadedMessage,
type PluginPromptAIMessage,
+ type PreviewDimensionChangeMessage,
type ValueChangeMessage,
type AssetModalChangeMessage,
type GetContextMessage,
@@ -21,6 +23,7 @@ import {
type SandboxActions = {
setHeight: (message: HeightChangeMessage) => void
setContent: (message: ValueChangeMessage) => void
+ setPreviewDimension: (message: PreviewDimensionChangeMessage) => void
setModalOpen: (message: ModalChangeMessage) => void
setPluginReady: (message: PluginLoadedMessage) => void
requestContext: (message: GetContextMessage) => void
@@ -70,6 +73,8 @@ export const createSandboxMessageListener: CreateSandboxListener = (
eventHandlers.promptAI(message)
} else if (isGetUserContextMessage(message)) {
eventHandlers.requestUserContext(message)
+ } else if (isPreviewWidthChangeMessage(message)) {
+ eventHandlers.setPreviewDimension(message)
} else {
console.warn(
`The Sandbox received unknown message from plugin: ${JSON.stringify(
diff --git a/yarn.lock b/yarn.lock
index 5409c7ad..cd3a7d00 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2160,6 +2160,7 @@ __metadata:
core-js: 3.41.0
execa: 8.0.1
jsdom: 25.0.0
+ pure-parse: ^1.0.1
typescript: 5.8.2
unbuild: 2.0.0
vite: 5.4.16
@@ -8987,6 +8988,13 @@ __metadata:
languageName: node
linkType: hard
+"pure-parse@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "pure-parse@npm:1.0.1"
+ checksum: 907d71f16d7d13dbe482aaf42c6bc0b7cc372ac1627e09d81c06b3ac8c6dba53909953f6f23e34b4704e7d6f2acaaf1bb9a70f2881d4f0ca19a7bb4baf5406ff
+ languageName: node
+ linkType: hard
+
"querystringify@npm:^2.1.1":
version: 2.2.0
resolution: "querystringify@npm:2.2.0"
From 926cb49cf9c6669b75b2cb950f55d82a46246fa6 Mon Sep 17 00:00:00 2001
From: Johannes Lindgren <14206504+johannes-lindgren@users.noreply.github.com>
Date: Tue, 22 Jul 2025 17:32:03 +0200
Subject: [PATCH 02/11] feat: sandbox and demo
---
packages/demo/src/components/NonModalView.tsx | 14 +++-
.../demo/src/components/PreviewDimension.tsx | 77 +++++++++++++++++++
packages/demo/src/components/PreviewWidth.tsx | 38 ---------
.../src/components/FieldPluginSandbox.tsx | 25 ++++++
.../src/components/PreviewDimension.tsx | 44 +++++++++++
.../src/dom/createSandboxMessageListener.ts | 6 +-
6 files changed, 160 insertions(+), 44 deletions(-)
create mode 100644 packages/demo/src/components/PreviewDimension.tsx
delete mode 100644 packages/demo/src/components/PreviewWidth.tsx
create mode 100644 packages/sandbox/src/components/PreviewDimension.tsx
diff --git a/packages/demo/src/components/NonModalView.tsx b/packages/demo/src/components/NonModalView.tsx
index b34957d9..8824a18b 100644
--- a/packages/demo/src/components/NonModalView.tsx
+++ b/packages/demo/src/components/NonModalView.tsx
@@ -1,4 +1,4 @@
-import { Paper, Stack } from '@mui/material'
+import { Divider, Paper, Stack } from '@mui/material'
import { ModalToggle } from './ModalToggle'
import { ValueMutator } from './ValueMutator'
import { HeightChangeDemo } from './HeightChangeDemo'
@@ -8,20 +8,28 @@ import { UserContextRequester } from './UserContextRequester'
import { PluginComponent } from './FieldPluginDemo'
import { LanguageView } from './LanguageView'
import { PromptAI } from './PromptAI'
-import { PreviewWidth } from './PreviewWidth'
+import { PreviewDimension } from './PreviewDimension'
export const NonModalView: PluginComponent = (props) => (
+
+
+
+
+
+
+
-
+
+
)
diff --git a/packages/demo/src/components/PreviewDimension.tsx b/packages/demo/src/components/PreviewDimension.tsx
new file mode 100644
index 00000000..2d857608
--- /dev/null
+++ b/packages/demo/src/components/PreviewDimension.tsx
@@ -0,0 +1,77 @@
+import { Button, Input, Stack, Typography } from '@mui/material'
+import { PluginComponent } from './FieldPluginDemo'
+import { useState } from 'react'
+
+export const PreviewDimension: PluginComponent = (props) => {
+ const { data, actions } = props
+
+ const label =
+ typeof data.content === 'undefined'
+ ? 'undefined'
+ : JSON.stringify(data.content)
+
+ const [width, setWidth] = useState(300)
+
+ const handleClickMobile = () => {
+ actions.setPreviewDimension({
+ tag: 'mobile',
+ })
+ }
+ const handleClickTablet = () => {
+ actions.setPreviewDimension({
+ tag: 'tablet',
+ })
+ }
+ const handleClickDesktop = () => {
+ actions.setPreviewDimension({
+ tag: 'desktop',
+ })
+ }
+ const handleClickCustom = () => {
+ actions.setPreviewDimension({
+ tag: 'custom',
+ width: 1234,
+ })
+ }
+
+ return (
+
+ Field Value
+ {label}
+
+
+
+
+ setWidth(Number(e.target.value))}
+ placeholder="Custom Width"
+ />
+
+ )
+}
diff --git a/packages/demo/src/components/PreviewWidth.tsx b/packages/demo/src/components/PreviewWidth.tsx
deleted file mode 100644
index f3217bc1..00000000
--- a/packages/demo/src/components/PreviewWidth.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Button, Stack, Typography } from '@mui/material'
-import { PluginComponent } from './FieldPluginDemo'
-
-export const PreviewWidth: PluginComponent = (props) => {
- const { data, actions } = props
-
- const handleClickIncrement = () =>
- actions?.setContent(
- (typeof data.content === 'number' ? data.content : 0) + 1,
- )
- const handleClickReset = () => actions?.setContent(0)
-
- const label =
- typeof data.content === 'undefined'
- ? 'undefined'
- : JSON.stringify(data.content)
-
- return (
-
- Field Value
- {label}
-
-
-
- )
-}
diff --git a/packages/sandbox/src/components/FieldPluginSandbox.tsx b/packages/sandbox/src/components/FieldPluginSandbox.tsx
index a3eabd56..6615c41a 100644
--- a/packages/sandbox/src/components/FieldPluginSandbox.tsx
+++ b/packages/sandbox/src/components/FieldPluginSandbox.tsx
@@ -26,6 +26,7 @@ import {
UserData,
urlSearchParamsFromPluginUrlParams,
ValueChangeMessage,
+ PreviewDimensionChangeMessage,
} from '@storyblok/field-plugin'
import '@fontsource/roboto/300.css'
import '@fontsource/roboto/400.css'
@@ -56,6 +57,7 @@ import { UrlView } from './UrlView'
import { usePluginParams } from './usePluginParams'
import { LanguageView } from './LanguageView'
import { TranslatableCheckbox } from './TranslatableCheckbox'
+import { PreviewDimension } from './PreviewDimension'
const defaultUrl = 'http://localhost:8080'
const initialStory: StoryData = {
@@ -130,6 +132,11 @@ const useSandbox = (
translatable: false,
})
const [content, setContent] = useState(initialContent)
+ const [previewDimension, setPreviewDimension] = useState<
+ PreviewDimensionChangeMessage['data']
+ >({
+ tag: 'desktop',
+ })
const [language, setLanguage] = useState('default')
const [stateChangedCallbackId, setStateChangedCallbackId] = useState()
@@ -321,6 +328,13 @@ const useSandbox = (
[onError],
)
+ const onSetPreviewDimension = useCallback(
+ (message: PreviewDimensionChangeMessage) => {
+ setPreviewDimension(message.data)
+ },
+ [],
+ )
+
useEffect(
() =>
createSandboxMessageListener(
@@ -333,6 +347,7 @@ const useSandbox = (
requestUserContext: onUserContextRequested,
selectAsset: onAssetSelected,
promptAI: onPromptAI,
+ setPreviewDimension: onSetPreviewDimension,
},
{
iframeOrigin: fieldPluginURL?.origin,
@@ -380,6 +395,7 @@ const useSandbox = (
url,
fieldTypeIframe,
iframeSrc,
+ previewDimension,
},
{
setContent,
@@ -407,6 +423,7 @@ export const FieldPluginSandbox: FunctionComponent = () => {
url,
fieldTypeIframe,
iframeSrc,
+ previewDimension,
},
{ setModalOpen, setContent, setLanguage, setSchema, setUrl, randomizeUid },
] = useSandbox(error)
@@ -526,6 +543,14 @@ export const FieldPluginSandbox: FunctionComponent = () => {
/>
+
+
+ Data
+
+
+
+
+
)
}
diff --git a/packages/sandbox/src/components/PreviewDimension.tsx b/packages/sandbox/src/components/PreviewDimension.tsx
new file mode 100644
index 00000000..f7e2f692
--- /dev/null
+++ b/packages/sandbox/src/components/PreviewDimension.tsx
@@ -0,0 +1,44 @@
+import { FunctionComponent } from 'react'
+import { PreviewDimensionChangeMessage } from '@storyblok/field-plugin'
+import {
+ FormControl,
+ FormControlLabel,
+ FormLabel,
+ Radio,
+ RadioGroup,
+} from '@mui/material'
+
+export const PreviewDimension: FunctionComponent<{
+ previewDimension: PreviewDimensionChangeMessage['data']
+}> = (props) => {
+ const { previewDimension } = props
+
+ return (
+
+
+ Preview Dimension
+
+
+ }
+ label="Desktop"
+ />
+ }
+ label="Tablet"
+ />
+ }
+ label="Mobile"
+ />
+
+
+ )
+}
diff --git a/packages/sandbox/src/dom/createSandboxMessageListener.ts b/packages/sandbox/src/dom/createSandboxMessageListener.ts
index 563a76c4..c70a0d30 100644
--- a/packages/sandbox/src/dom/createSandboxMessageListener.ts
+++ b/packages/sandbox/src/dom/createSandboxMessageListener.ts
@@ -6,8 +6,9 @@ import {
isMessageToContainer,
isModalChangeMessage,
isPluginLoadedMessage,
- isPreviewWidthChangeMessage,
isValueChangeMessage,
+ isPluginPromptAIMessage,
+ isPreviewDimensionChangeMessage,
type ModalChangeMessage,
type PluginLoadedMessage,
type PluginPromptAIMessage,
@@ -17,7 +18,6 @@ import {
type GetContextMessage,
type GetUserContextMessage,
type HeightChangeMessage,
- isPluginPromptAIMessage,
} from '@storyblok/field-plugin'
type SandboxActions = {
@@ -73,7 +73,7 @@ export const createSandboxMessageListener: CreateSandboxListener = (
eventHandlers.promptAI(message)
} else if (isGetUserContextMessage(message)) {
eventHandlers.requestUserContext(message)
- } else if (isPreviewWidthChangeMessage(message)) {
+ } else if (isPreviewDimensionChangeMessage(message)) {
eventHandlers.setPreviewDimension(message)
} else {
console.warn(
From 5d8cb27016cc4351df40b59ac047b55c626589a8 Mon Sep 17 00:00:00 2001
From: Johannes Lindgren <14206504+johannes-lindgren@users.noreply.github.com>
Date: Tue, 22 Jul 2025 17:33:24 +0200
Subject: [PATCH 03/11] feat: add custom option to preview dimension selection
---
packages/sandbox/src/components/PreviewDimension.tsx | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/packages/sandbox/src/components/PreviewDimension.tsx b/packages/sandbox/src/components/PreviewDimension.tsx
index f7e2f692..432cf937 100644
--- a/packages/sandbox/src/components/PreviewDimension.tsx
+++ b/packages/sandbox/src/components/PreviewDimension.tsx
@@ -38,6 +38,11 @@ export const PreviewDimension: FunctionComponent<{
control={}
label="Mobile"
/>
+ }
+ label="Custom"
+ />
)
From b4c727e373fe1951a0e85b63472adec106ce86f3 Mon Sep 17 00:00:00 2001
From: Johannes Lindgren <14206504+johannes-lindgren@users.noreply.github.com>
Date: Tue, 22 Jul 2025 17:48:40 +0200
Subject: [PATCH 04/11] docs: comment
---
.../field-plugin/src/createFieldPlugin/createFieldPlugin.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/packages/field-plugin/src/createFieldPlugin/createFieldPlugin.ts b/packages/field-plugin/src/createFieldPlugin/createFieldPlugin.ts
index 9cf30cfa..ed6c87fd 100644
--- a/packages/field-plugin/src/createFieldPlugin/createFieldPlugin.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createFieldPlugin.ts
@@ -55,6 +55,9 @@ export const createFieldPlugin: CreateFieldPlugin = ({
const { uid, host } = params
// ToDo: In development we need to load localhost:3300
+ // const origin = 'http://localhost:7070'
+ // const origin = 'http://localhost:3300'
+
const origin =
typeof targetOrigin === 'string'
? targetOrigin
From 6c989d417e3f430b3107572fbbf765384c5df2c4 Mon Sep 17 00:00:00 2001
From: Johannes Lindgren <14206504+johannes-lindgren@users.noreply.github.com>
Date: Tue, 22 Jul 2025 17:52:46 +0200
Subject: [PATCH 05/11] feat: update custom preview dimension width to dynamic
value
---
packages/demo/src/components/PreviewDimension.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/demo/src/components/PreviewDimension.tsx b/packages/demo/src/components/PreviewDimension.tsx
index 2d857608..22c0fd0b 100644
--- a/packages/demo/src/components/PreviewDimension.tsx
+++ b/packages/demo/src/components/PreviewDimension.tsx
@@ -30,7 +30,7 @@ export const PreviewDimension: PluginComponent = (props) => {
const handleClickCustom = () => {
actions.setPreviewDimension({
tag: 'custom',
- width: 1234,
+ width: width,
})
}
From 98ea17cf71656fbb90ae72f335b58d688abfc047 Mon Sep 17 00:00:00 2001
From: Fernanda Nogueira
Date: Wed, 23 Jul 2025 13:36:23 -0300
Subject: [PATCH 06/11] feat: reorganize the custom width on preview
---
.../demo/src/components/PreviewDimension.tsx | 45 ++++++++++---------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/packages/demo/src/components/PreviewDimension.tsx b/packages/demo/src/components/PreviewDimension.tsx
index 22c0fd0b..bf6efe1c 100644
--- a/packages/demo/src/components/PreviewDimension.tsx
+++ b/packages/demo/src/components/PreviewDimension.tsx
@@ -1,15 +1,10 @@
-import { Button, Input, Stack, Typography } from '@mui/material'
+import { Button, Input, Stack, Typography, InputLabel } from '@mui/material'
import { PluginComponent } from './FieldPluginDemo'
import { useState } from 'react'
export const PreviewDimension: PluginComponent = (props) => {
const { data, actions } = props
- const label =
- typeof data.content === 'undefined'
- ? 'undefined'
- : JSON.stringify(data.content)
-
const [width, setWidth] = useState(300)
const handleClickMobile = () => {
@@ -36,8 +31,7 @@ export const PreviewDimension: PluginComponent = (props) => {
return (
- Field Value
- {label}
+ Dimension
-
- setWidth(Number(e.target.value))}
- placeholder="Custom Width"
- />
+ Set custom width:
+
+
+ setWidth(Number(e.target.value))}
+ placeholder="Custom Width"
+ />
+
+
)
}
From 9bbe66432196f94f536c5ad96cecd26b5ce6b7e8 Mon Sep 17 00:00:00 2001
From: Fernanda Nogueira
Date: Wed, 23 Jul 2025 13:36:53 -0300
Subject: [PATCH 07/11] feat: create the dimension type
---
.../createFieldPlugin/FieldPluginActions.ts | 16 ++--------
.../PreviewDimensionChangeMessage.ts | 30 ++++++++++---------
.../src/components/FieldPluginSandbox.tsx | 2 +-
3 files changed, 19 insertions(+), 29 deletions(-)
diff --git a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
index 845e52ab..97604687 100644
--- a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
+++ b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
@@ -5,6 +5,7 @@ import type {
ModalSize,
PromptAIPayload,
PromptAIResponse,
+ Dimension,
} from '../messaging'
import type { FieldPluginData } from './FieldPluginData'
@@ -21,20 +22,7 @@ export type RequestUserContext = () => Promise
export type SelectAsset = () => Promise
export type Initialize = () => Promise>
export type SetPreviewWidth = (
- previewWidth:
- | {
- tag: 'desktop'
- }
- | {
- tag: 'tablet'
- }
- | {
- tag: 'mobile'
- }
- | {
- tag: 'custom'
- width: number
- },
+ previewWidth: Dimension
) => Promise
export type FieldPluginActions = {
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
index 1c75e505..2faa69bc 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
@@ -8,22 +8,24 @@ import {
optionalGuard,
} from 'pure-parse'
+export type Dimension =
+ | {
+ tag: 'desktop'
+ }
+ | {
+ tag: 'tablet'
+ }
+ | {
+ tag: 'mobile'
+ }
+ | {
+ tag: 'custom'
+ width: number
+ }
+
export type PreviewDimensionChangeMessage =
MessageToContainer<'previewDimension'> & {
- data:
- | {
- tag: 'desktop'
- }
- | {
- tag: 'tablet'
- }
- | {
- tag: 'mobile'
- }
- | {
- tag: 'custom'
- width: number
- }
+ data: Dimension
}
export const isPreviewDimensionChangeMessage =
objectGuard({
diff --git a/packages/sandbox/src/components/FieldPluginSandbox.tsx b/packages/sandbox/src/components/FieldPluginSandbox.tsx
index 6615c41a..a553d05a 100644
--- a/packages/sandbox/src/components/FieldPluginSandbox.tsx
+++ b/packages/sandbox/src/components/FieldPluginSandbox.tsx
@@ -545,7 +545,7 @@ export const FieldPluginSandbox: FunctionComponent = () => {
- Data
+ Editor Preview
From a087aab787c1ec7a120c368e15ad0acecf589e59 Mon Sep 17 00:00:00 2001
From: Fernanda Nogueira
Date: Wed, 23 Jul 2025 14:18:31 -0300
Subject: [PATCH 08/11] chore: run prettier
---
.../field-plugin/src/createFieldPlugin/FieldPluginActions.ts | 4 +---
.../pluginToContainerMessage/PreviewDimensionChangeMessage.ts | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
index 97604687..34bae3c9 100644
--- a/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
+++ b/packages/field-plugin/src/createFieldPlugin/FieldPluginActions.ts
@@ -21,9 +21,7 @@ export type PromptAI = (payload: PromptAIPayload) => Promise
export type RequestUserContext = () => Promise
export type SelectAsset = () => Promise
export type Initialize = () => Promise>
-export type SetPreviewWidth = (
- previewWidth: Dimension
-) => Promise
+export type SetPreviewWidth = (previewWidth: Dimension) => Promise
export type FieldPluginActions = {
setContent: SetContent
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
index 2faa69bc..176469c0 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
@@ -8,7 +8,7 @@ import {
optionalGuard,
} from 'pure-parse'
-export type Dimension =
+export type Dimension =
| {
tag: 'desktop'
}
From bed4f89dfa35be0a6747180a2dbebe12ccf203f9 Mon Sep 17 00:00:00 2001
From: Fernanda Nogueira
Date: Wed, 23 Jul 2025 16:03:28 -0300
Subject: [PATCH 09/11] chore: remove pure-parse and add valibot
---
packages/field-plugin/package.json | 6 +-
.../PreviewDimensionChangeMessage.ts | 59 +++++++++----------
yarn.lock | 21 ++++---
3 files changed, 45 insertions(+), 41 deletions(-)
diff --git a/packages/field-plugin/package.json b/packages/field-plugin/package.json
index 21f74f8d..8421c20e 100644
--- a/packages/field-plugin/package.json
+++ b/packages/field-plugin/package.json
@@ -43,9 +43,6 @@
"test": "vitest",
"build": "unbuild"
},
- "dependencies": {
- "pure-parse": "^1.0.1"
- },
"devDependencies": {
"@types/core-js": "2.5.8",
"@types/node": "18.19.85",
@@ -57,5 +54,8 @@
"vite": "5.4.16",
"vite-plugin-dts": "4.2.1",
"vitest": "2.1.9"
+ },
+ "dependencies": {
+ "valibot": "1.1.0"
}
}
diff --git a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
index 176469c0..a6a9e5b4 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/PreviewDimensionChangeMessage.ts
@@ -1,12 +1,5 @@
+import { is, object, string, literal, optional, number, variant } from 'valibot'
import { MessageToContainer } from './MessageToContainer'
-import {
- equalsGuard,
- isNumber,
- isString,
- objectGuard,
- oneOfGuard,
- optionalGuard,
-} from 'pure-parse'
export type Dimension =
| {
@@ -27,28 +20,34 @@ export type PreviewDimensionChangeMessage =
MessageToContainer<'previewDimension'> & {
data: Dimension
}
-export const isPreviewDimensionChangeMessage =
- objectGuard({
- action: equalsGuard('plugin-changed'),
- uid: isString,
- callbackId: optionalGuard(isString),
- event: equalsGuard('previewDimension'),
- data: oneOfGuard(
- objectGuard({
- tag: equalsGuard('desktop'),
- }),
- objectGuard({
- tag: equalsGuard('tablet'),
- }),
- objectGuard({
- tag: equalsGuard('mobile'),
- }),
- objectGuard({
- tag: equalsGuard('custom'),
- width: isNumber,
- }),
- ),
- })
+
+export const isPreviewDimensionChangeMessage = (
+ data: unknown,
+): data is PreviewDimensionChangeMessage =>
+ is(
+ object({
+ action: literal('plugin-changed'),
+ uid: string(),
+ callbackId: optional(string()),
+ event: literal('previewDimension'),
+ data: variant('tag', [
+ object({
+ tag: literal('desktop'),
+ }),
+ object({
+ tag: literal('tablet'),
+ }),
+ object({
+ tag: literal('mobile'),
+ }),
+ object({
+ tag: literal('custom'),
+ width: number(),
+ }),
+ ]),
+ }),
+ data,
+ )
export const previewDimensionsChangeMessage = (
options: Pick,
diff --git a/yarn.lock b/yarn.lock
index cd3a7d00..0496ecc7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2160,9 +2160,9 @@ __metadata:
core-js: 3.41.0
execa: 8.0.1
jsdom: 25.0.0
- pure-parse: ^1.0.1
typescript: 5.8.2
unbuild: 2.0.0
+ valibot: 1.1.0
vite: 5.4.16
vite-plugin-dts: 4.2.1
vitest: 2.1.9
@@ -8988,13 +8988,6 @@ __metadata:
languageName: node
linkType: hard
-"pure-parse@npm:^1.0.1":
- version: 1.0.1
- resolution: "pure-parse@npm:1.0.1"
- checksum: 907d71f16d7d13dbe482aaf42c6bc0b7cc372ac1627e09d81c06b3ac8c6dba53909953f6f23e34b4704e7d6f2acaaf1bb9a70f2881d4f0ca19a7bb4baf5406ff
- languageName: node
- linkType: hard
-
"querystringify@npm:^2.1.1":
version: 2.2.0
resolution: "querystringify@npm:2.2.0"
@@ -10840,6 +10833,18 @@ __metadata:
languageName: node
linkType: hard
+"valibot@npm:1.1.0":
+ version: 1.1.0
+ resolution: "valibot@npm:1.1.0"
+ peerDependencies:
+ typescript: ">=5"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: c1b95d4f783cd62713a1c32a7fd25eb42b588037135dbc2cf2b4788acc720306374f831576d29e91da42f716a497503842c457a3332a04dab92c00cb2fa3227a
+ languageName: node
+ linkType: hard
+
"validator@npm:^13.7.0":
version: 13.12.0
resolution: "validator@npm:13.12.0"
From f46e28ab46132fac73c43d5a00d200b6525ce332 Mon Sep 17 00:00:00 2001
From: Fernanda Nogueira
Date: Wed, 23 Jul 2025 16:49:44 -0300
Subject: [PATCH 10/11] chore: add custom label on sandbox
---
packages/sandbox/src/components/PreviewDimension.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/packages/sandbox/src/components/PreviewDimension.tsx b/packages/sandbox/src/components/PreviewDimension.tsx
index 432cf937..d228925d 100644
--- a/packages/sandbox/src/components/PreviewDimension.tsx
+++ b/packages/sandbox/src/components/PreviewDimension.tsx
@@ -13,6 +13,11 @@ export const PreviewDimension: FunctionComponent<{
}> = (props) => {
const { previewDimension } = props
+ let customLabel = 'Custom'
+ if (previewDimension.tag === 'custom') {
+ customLabel += ` (${previewDimension.width})`
+ }
+
return (
@@ -41,7 +46,7 @@ export const PreviewDimension: FunctionComponent<{
}
- label="Custom"
+ label={customLabel}
/>
From f7da506e55f6fc35a831ab991e4dc24f5ed6b5ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Demetrius=20Feij=C3=B3o?=
Date: Mon, 28 Jul 2025 11:35:32 -0300
Subject: [PATCH 11/11] feat: remove preview dimension callback from the queue
list
---
.../createPluginActions/callbackQueue.ts | 7 ++--
.../createPluginActions.ts | 6 ++++
.../createPluginMessageListener.ts | 2 ++
.../handlePluginMessage.test.ts | 1 +
.../handlePluginMessage.ts | 3 ++
.../ContainerToPlugin.ts | 4 +++
.../PreviewDimensionResponseMessage.test.ts | 32 +++++++++++++++++++
.../PreviewDimensionResponseMessage.ts | 9 ++++++
.../containerToPluginMessage/index.ts | 1 +
.../src/components/FieldPluginSandbox.tsx | 6 ++++
10 files changed, 69 insertions(+), 2 deletions(-)
create mode 100644 packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.test.ts
create mode 100644 packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.ts
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
index c70465f8..e3382873 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/callbackQueue.ts
@@ -6,7 +6,7 @@ import type {
LoadedMessage,
OnMessage,
StateChangedMessage,
- PreviewDimensionChangeMessage,
+ PreviewDimensionResponseMessage,
} from '../../messaging'
import { getRandomUid } from '../../utils'
@@ -19,7 +19,10 @@ type CallbackMap = {
stateChanged: Record>
loaded: Record>
promptAI: Record>
- previewDimension: Record>
+ previewDimension: Record<
+ CallbackId,
+ OnMessage
+ >
}
type CallbackType = keyof CallbackMap
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
index c7efcbd0..04f092b8 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts
@@ -20,6 +20,7 @@ import {
type OnUnknownPluginMessage,
type OnPromptAIMessage,
type PromptAIPayload,
+ type OnPreviewDimensionMessage,
} from '../../messaging'
import { FieldPluginActions, Initialize } from '../FieldPluginActions'
import { pluginStateFromStateChangeMessage } from './partialPluginStateFromStateChangeMessage'
@@ -82,6 +83,10 @@ export const createPluginActions: CreatePluginActions = ({
popCallback('promptAI', data.callbackId)?.(data)
}
+ const onPreviewDimension: OnPreviewDimensionMessage = (data) => {
+ popCallback('previewDimension', data.callbackId)
+ }
+
const onUnknownMessage: OnUnknownPluginMessage = (data) => {
// TODO remove side-effect, making functions in this file pure.
// perhaps only show this message in development mode?
@@ -101,6 +106,7 @@ export const createPluginActions: CreatePluginActions = ({
onUserContextRequest,
onAssetSelect,
onPromptAI,
+ onPreviewDimension,
onUnknownMessage,
}
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/createPluginMessageListener.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/createPluginMessageListener.ts
index 840ee69c..e8cb612e 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/createPluginMessageListener.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/createPluginMessageListener.ts
@@ -6,6 +6,7 @@ import type {
OnPromptAIMessage,
OnStateChangeMessage,
OnUnknownPluginMessage,
+ OnPreviewDimensionMessage,
} from '../../../messaging'
import { handlePluginMessage } from './handlePluginMessage'
@@ -16,6 +17,7 @@ export type PluginMessageCallbacks = {
onUserContextRequest: OnUserContextRequestMessage
onAssetSelect: OnAssetSelectMessage
onPromptAI: OnPromptAIMessage
+ onPreviewDimension: OnPreviewDimensionMessage
onUnknownMessage: OnUnknownPluginMessage
}
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.test.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.test.ts
index 595326f0..591d1cc7 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.test.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.test.ts
@@ -18,6 +18,7 @@ const mockCallbacks = (): PluginMessageCallbacks => ({
onAssetSelect: vi.fn(),
onUnknownMessage: vi.fn(),
onLoaded: vi.fn(),
+ onPreviewDimension: vi.fn(),
onPromptAI: vi.fn(),
})
diff --git a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.ts b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.ts
index f4ff49b8..34791c82 100644
--- a/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.ts
+++ b/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginMessageListener/handlePluginMessage.ts
@@ -8,6 +8,7 @@ import {
} from '../../../messaging'
import { PluginMessageCallbacks } from './createPluginMessageListener'
import { isStateMessage } from '../../../messaging/pluginMessage/containerToPluginMessage/StateChangedMessage'
+import { isPreviewDimensionResponse } from '../../../messaging/pluginMessage/containerToPluginMessage//PreviewDimensionResponseMessage'
export const handlePluginMessage = (
data: unknown,
@@ -38,6 +39,8 @@ export const handlePluginMessage = (
callbacks.onAssetSelect(data)
} else if (isPromptAIMessage(data)) {
callbacks.onPromptAI(data)
+ } else if (isPreviewDimensionResponse(data)) {
+ callbacks.onPreviewDimension(data)
} else {
callbacks.onUnknownMessage(data)
}
diff --git a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/ContainerToPlugin.ts b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/ContainerToPlugin.ts
index 38771653..06755d16 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/ContainerToPlugin.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/ContainerToPlugin.ts
@@ -5,6 +5,7 @@ import { UserContextRequestMessage } from './UserContextRequestMessage'
import { MessageToPlugin } from './MessageToPlugin'
import { StateChangedMessage } from './StateChangedMessage'
import { PromptAIResponseMessage } from './PromptAIResponseMessage'
+import { PreviewDimensionResponseMessage } from './PreviewDimensionResponseMessage'
/**
* The plugin container's sends it's state to the plugin
@@ -14,6 +15,9 @@ export type OnStateChangeMessage = (message: StateChangedMessage) => void
export type OnLoadedMessage = (message: LoadedMessage) => void
export type OnAssetSelectMessage = (message: AssetSelectedMessage) => void
export type OnPromptAIMessage = (message: PromptAIResponseMessage) => void
+export type OnPreviewDimensionMessage = (
+ message: PreviewDimensionResponseMessage,
+) => void
export type OnContextRequestMessage = (message: ContextRequestMessage) => void
export type OnUserContextRequestMessage = (
message: UserContextRequestMessage,
diff --git a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.test.ts b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.test.ts
new file mode 100644
index 00000000..8b949dda
--- /dev/null
+++ b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.test.ts
@@ -0,0 +1,32 @@
+import {
+ type PreviewDimensionResponseMessage,
+ isPreviewDimensionResponse,
+} from './PreviewDimensionResponseMessage'
+
+const stub: PreviewDimensionResponseMessage = {
+ action: 'preview-dimension',
+ uid: '-preview',
+ callbackId: 'test-callback-id',
+}
+
+describe('PreviewDimensionResponseMessage', function () {
+ it('is a message to plugin', () => {
+ expect(isPreviewDimensionResponse(stub)).toEqual(true)
+ })
+ describe('the action property', () => {
+ it('equals "preview-dimension"', () => {
+ expect(
+ isPreviewDimensionResponse({
+ ...stub,
+ action: 'preview-dimension',
+ }),
+ ).toEqual(true)
+ expect(
+ isPreviewDimensionResponse({
+ ...stub,
+ action: 'something-else',
+ }),
+ ).toEqual(false)
+ })
+ })
+})
diff --git a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.ts b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.ts
new file mode 100644
index 00000000..d2bf2b45
--- /dev/null
+++ b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/PreviewDimensionResponseMessage.ts
@@ -0,0 +1,9 @@
+import { isMessageToPlugin, type MessageToPlugin } from './MessageToPlugin'
+
+export type PreviewDimensionResponseMessage =
+ MessageToPlugin<'preview-dimension'>
+
+export const isPreviewDimensionResponse = (
+ data: unknown,
+): data is PreviewDimensionResponseMessage =>
+ isMessageToPlugin(data) && data.action === 'preview-dimension'
diff --git a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/index.ts b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/index.ts
index 0b375c4a..1cecdd58 100644
--- a/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/index.ts
+++ b/packages/field-plugin/src/messaging/pluginMessage/containerToPluginMessage/index.ts
@@ -9,5 +9,6 @@ export * from './UserContextRequestMessage'
export * from './MessageToPlugin'
export * from './StoryData'
export * from './Asset'
+export * from './PreviewDimensionResponseMessage'
export * from './PromptAIResponseMessage'
export * from './UserData'
diff --git a/packages/sandbox/src/components/FieldPluginSandbox.tsx b/packages/sandbox/src/components/FieldPluginSandbox.tsx
index a553d05a..ff1b9f9e 100644
--- a/packages/sandbox/src/components/FieldPluginSandbox.tsx
+++ b/packages/sandbox/src/components/FieldPluginSandbox.tsx
@@ -331,6 +331,12 @@ const useSandbox = (
const onSetPreviewDimension = useCallback(
(message: PreviewDimensionChangeMessage) => {
setPreviewDimension(message.data)
+
+ postToPlugin({
+ uid,
+ action: 'preview-dimension',
+ callbackId: message.callbackId,
+ })
},
[],
)