Skip to content

Commit 47ed4a4

Browse files
feat: change preview dimension
1 parent 89102b2 commit 47ed4a4

File tree

11 files changed

+331
-0
lines changed

11 files changed

+331
-0
lines changed

packages/demo/src/components/NonModalView.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { UserContextRequester } from './UserContextRequester'
88
import { PluginComponent } from './FieldPluginDemo'
99
import { LanguageView } from './LanguageView'
1010
import { PromptAI } from './PromptAI'
11+
import { PreviewWidth } from './PreviewWidth'
1112

1213
export const NonModalView: PluginComponent = (props) => (
1314
<Paper>
@@ -20,6 +21,7 @@ export const NonModalView: PluginComponent = (props) => (
2021
<HeightChangeDemo {...props} />
2122
<LanguageView {...props} />
2223
<PromptAI {...props} />
24+
<PreviewWidth {...props} />
2325
</Stack>
2426
</Paper>
2527
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Button, Stack, Typography } from '@mui/material'
2+
import { PluginComponent } from './FieldPluginDemo'
3+
4+
export const PreviewWidth: PluginComponent = (props) => {
5+
const { data, actions } = props
6+
7+
const handleClickIncrement = () =>
8+
actions?.setContent(
9+
(typeof data.content === 'number' ? data.content : 0) + 1,
10+
)
11+
const handleClickReset = () => actions?.setContent(0)
12+
13+
const label =
14+
typeof data.content === 'undefined'
15+
? 'undefined'
16+
: JSON.stringify(data.content)
17+
18+
return (
19+
<Stack gap={2}>
20+
<Typography variant="subtitle1">Field Value</Typography>
21+
<Typography textAlign="center">{label}</Typography>
22+
<Button
23+
variant="outlined"
24+
color="secondary"
25+
onClick={handleClickIncrement}
26+
>
27+
Increment
28+
</Button>
29+
<Button
30+
variant="outlined"
31+
color="secondary"
32+
onClick={handleClickReset}
33+
>
34+
Reset
35+
</Button>
36+
</Stack>
37+
)
38+
}

packages/field-plugin/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
"test": "vitest",
4444
"build": "unbuild"
4545
},
46+
"dependencies": {
47+
"pure-parse": "^1.0.1"
48+
},
4649
"devDependencies": {
4750
"@types/core-js": "2.5.8",
4851
"@types/node": "18.19.85",

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ export type PromptAI = (payload: PromptAIPayload) => Promise<PromptAIResponse>
2020
export type RequestUserContext = () => Promise<UserData>
2121
export type SelectAsset = () => Promise<Asset>
2222
export type Initialize<Content> = () => Promise<FieldPluginData<Content>>
23+
export type SetPreviewWidth = (
24+
previewWidth:
25+
| {
26+
tag: 'desktop'
27+
}
28+
| {
29+
tag: 'tablet'
30+
}
31+
| {
32+
tag: 'mobile'
33+
}
34+
| {
35+
tag: 'custom'
36+
width: number
37+
},
38+
) => Promise<void>
2339

2440
export type FieldPluginActions<Content> = {
2541
setContent: SetContent<Content>
@@ -28,4 +44,5 @@ export type FieldPluginActions<Content> = {
2844
promptAI: PromptAI
2945
requestUserContext: RequestUserContext
3046
selectAsset: SelectAsset
47+
setPreviewDimension: SetPreviewWidth
3148
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
LoadedMessage,
77
OnMessage,
88
StateChangedMessage,
9+
PreviewDimensionChangeMessage,
910
} from '../../messaging'
1011
import { getRandomUid } from '../../utils'
1112

@@ -18,6 +19,7 @@ type CallbackMap = {
1819
stateChanged: Record<CallbackId, OnMessage<StateChangedMessage>>
1920
loaded: Record<CallbackId, OnMessage<LoadedMessage>>
2021
promptAI: Record<CallbackId, OnMessage<PromptAIResponseMessage>>
22+
previewDimension: Record<CallbackId, OnMessage<PreviewDimensionChangeMessage>>
2123
}
2224
type CallbackType = keyof CallbackMap
2325

@@ -29,6 +31,7 @@ export const callbackQueue = () => {
2931
stateChanged: {},
3032
loaded: {},
3133
promptAI: {},
34+
previewDimension: {},
3235
}
3336

3437
const pushCallback = <T extends CallbackType>(

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
pluginLoadedMessage,
1212
getPluginPromptAIMessage,
1313
valueChangeMessage,
14+
previewDimensionsChangeMessage,
1415
type OnAssetSelectMessage,
1516
type OnContextRequestMessage,
1617
type OnUserContextRequestMessage,
@@ -176,6 +177,18 @@ export const createPluginActions: CreatePluginActions = ({
176177
postToContainer(getUserContextMessage({ uid, callbackId }))
177178
})
178179
},
180+
setPreviewDimension: (previewWidth) => {
181+
return new Promise((resolve) => {
182+
const callbackId = pushCallback('previewDimension', () => resolve())
183+
postToContainer(
184+
previewDimensionsChangeMessage({
185+
uid,
186+
callbackId,
187+
data: previewWidth,
188+
}),
189+
)
190+
})
191+
},
179192
},
180193
messageCallbacks,
181194
onHeightChange,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import {
2+
isPreviewDimensionChangeMessage,
3+
previewDimensionsChangeMessage,
4+
PreviewDimensionChangeMessage,
5+
} from './PreviewDimensionChangeMessage'
6+
import { isMessageToContainer } from './MessageToContainer'
7+
import { expect } from 'vitest'
8+
9+
const uid = '-preview-abc-123'
10+
const callbackId = 'test-callback-id'
11+
const stub: PreviewDimensionChangeMessage = {
12+
action: 'plugin-changed',
13+
event: 'previewDimension',
14+
uid,
15+
data: {
16+
tag: 'desktop',
17+
},
18+
}
19+
20+
describe('PreviewDimensionsChangeMessage', () => {
21+
describe('validator', () => {
22+
it('is a MessageToContainer', () => {
23+
expect(isMessageToContainer(stub)).toEqual(true)
24+
})
25+
it('requires event to be "previewDimension"', () => {
26+
expect(
27+
isPreviewDimensionChangeMessage({
28+
...stub,
29+
event: 'previewDimension',
30+
}),
31+
).toEqual(true)
32+
expect(
33+
isPreviewDimensionChangeMessage({
34+
...stub,
35+
event: 'somethingElse',
36+
}),
37+
).toEqual(false)
38+
})
39+
test('that the data property is present', () => {
40+
const { data: _data, ...withoutModel } = stub
41+
expect(isPreviewDimensionChangeMessage(withoutModel)).toEqual(false)
42+
})
43+
test('that the data property can be one of the tagged objects', () => {
44+
expect(
45+
isPreviewDimensionChangeMessage({
46+
...stub,
47+
data: {
48+
tag: 'desktop',
49+
},
50+
}),
51+
).toEqual(true)
52+
expect(
53+
isPreviewDimensionChangeMessage({
54+
...stub,
55+
data: {
56+
tag: 'tablet',
57+
},
58+
}),
59+
).toEqual(true)
60+
expect(
61+
isPreviewDimensionChangeMessage({
62+
...stub,
63+
data: {
64+
tag: 'mobile',
65+
},
66+
}),
67+
).toEqual(true)
68+
expect(
69+
isPreviewDimensionChangeMessage({
70+
...stub,
71+
data: {
72+
tag: 'custom',
73+
width: 1234,
74+
},
75+
}),
76+
).toEqual(true)
77+
})
78+
test('that the data property cannot be any value', () => {
79+
expect(
80+
isPreviewDimensionChangeMessage({
81+
...stub,
82+
data: undefined,
83+
}),
84+
).toEqual(false)
85+
expect(
86+
isPreviewDimensionChangeMessage({
87+
...stub,
88+
data: null,
89+
}),
90+
).toEqual(false)
91+
expect(
92+
isPreviewDimensionChangeMessage({
93+
...stub,
94+
data: {},
95+
}),
96+
).toEqual(false)
97+
expect(
98+
isPreviewDimensionChangeMessage({
99+
...stub,
100+
data: 'a string',
101+
}),
102+
).toEqual(false)
103+
expect(
104+
isPreviewDimensionChangeMessage({
105+
...stub,
106+
data: true,
107+
}),
108+
).toEqual(false)
109+
expect(
110+
isPreviewDimensionChangeMessage({
111+
...stub,
112+
data: 123.123,
113+
}),
114+
).toEqual(false)
115+
expect(
116+
isPreviewDimensionChangeMessage({
117+
...stub,
118+
data: [],
119+
}),
120+
).toEqual(false)
121+
})
122+
})
123+
describe('constructor', () => {
124+
it('includes the uid', () => {
125+
expect(
126+
previewDimensionsChangeMessage({
127+
uid,
128+
callbackId,
129+
data: {
130+
tag: 'desktop',
131+
},
132+
}),
133+
).toHaveProperty('uid', uid)
134+
})
135+
it('includes the data', () => {
136+
expect(
137+
previewDimensionsChangeMessage({
138+
uid,
139+
callbackId,
140+
data: {
141+
tag: 'desktop',
142+
},
143+
}),
144+
).toHaveProperty('data', {
145+
tag: 'desktop',
146+
})
147+
expect(
148+
previewDimensionsChangeMessage({
149+
uid,
150+
callbackId,
151+
data: {
152+
tag: 'tablet',
153+
},
154+
}),
155+
).toHaveProperty('data', {
156+
tag: 'tablet',
157+
})
158+
expect(
159+
previewDimensionsChangeMessage({
160+
uid,
161+
callbackId,
162+
data: {
163+
tag: 'mobile',
164+
},
165+
}),
166+
).toHaveProperty('data', {
167+
tag: 'mobile',
168+
})
169+
expect(
170+
previewDimensionsChangeMessage({
171+
uid,
172+
callbackId,
173+
data: {
174+
tag: 'custom',
175+
width: 1234,
176+
},
177+
}),
178+
).toHaveProperty('data', {
179+
tag: 'custom',
180+
width: 1234,
181+
})
182+
})
183+
})
184+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { MessageToContainer } from './MessageToContainer'
2+
import {
3+
equalsGuard,
4+
isNumber,
5+
isString,
6+
objectGuard,
7+
oneOfGuard,
8+
optionalGuard,
9+
} from 'pure-parse'
10+
11+
export type PreviewDimensionChangeMessage =
12+
MessageToContainer<'previewDimension'> & {
13+
data:
14+
| {
15+
tag: 'desktop'
16+
}
17+
| {
18+
tag: 'tablet'
19+
}
20+
| {
21+
tag: 'mobile'
22+
}
23+
| {
24+
tag: 'custom'
25+
width: number
26+
}
27+
}
28+
export const isPreviewDimensionChangeMessage =
29+
objectGuard<PreviewDimensionChangeMessage>({
30+
action: equalsGuard('plugin-changed'),
31+
uid: isString,
32+
callbackId: optionalGuard(isString),
33+
event: equalsGuard('previewDimension'),
34+
data: oneOfGuard(
35+
objectGuard({
36+
tag: equalsGuard('desktop'),
37+
}),
38+
objectGuard({
39+
tag: equalsGuard('tablet'),
40+
}),
41+
objectGuard({
42+
tag: equalsGuard('mobile'),
43+
}),
44+
objectGuard({
45+
tag: equalsGuard('custom'),
46+
width: isNumber,
47+
}),
48+
),
49+
})
50+
51+
export const previewDimensionsChangeMessage = (
52+
options: Pick<PreviewDimensionChangeMessage, 'uid' | 'callbackId' | 'data'>,
53+
): PreviewDimensionChangeMessage => ({
54+
action: 'plugin-changed',
55+
event: 'previewDimension',
56+
...options,
57+
})

packages/field-plugin/src/messaging/pluginMessage/pluginToContainerMessage/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './MessageToContainer'
22
export * from './ValueChangeMessage'
33
export * from './ModalChangeMessage'
44
export * from './PluginLoadedMessage'
5+
export * from './PreviewDimensionChangeMessage'
56
export * from './HeightChangeMessage'
67
export * from './GetContextMessage'
78
export * from './GetUserContextMessage'

0 commit comments

Comments
 (0)