Skip to content

Commit e571668

Browse files
committed
feat: sync composition live control types
1 parent 4027a76 commit e571668

File tree

1 file changed

+141
-20
lines changed

1 file changed

+141
-20
lines changed

scopes/compositions/compositions/ui/compositions-panel/live-control.type.ts

Lines changed: 141 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,5 @@
11
// TODO: put the whole file into a sharable Bit component for custom preview mounters
22

3-
export type LiveControlUpdateEventData = {
4-
type: 'composition-live-controls:update';
5-
payload: {
6-
key: string;
7-
value: any;
8-
timestamp: number;
9-
};
10-
};
11-
12-
export type LiveControlReadyEventData = {
13-
type: 'composition-live-controls:ready';
14-
payload: {
15-
controls: Array<Control>;
16-
values: Record<string, any>;
17-
timestamp: number;
18-
};
19-
};
20-
21-
export type LiveControlEventData = LiveControlUpdateEventData | LiveControlReadyEventData;
22-
233
export type SelectOption =
244
| string
255
| {
@@ -81,6 +61,16 @@ export type ControlRange = {
8161
step?: number;
8262
};
8363

64+
export type ControlDate = {
65+
input: 'date'; // <input type="date">
66+
defaultValue?: string;
67+
};
68+
69+
export type ControlJSON = {
70+
input: 'json'; // <textarea>
71+
defaultValue?: any;
72+
};
73+
8474
export type ControlColor = {
8575
input: 'color'; // <input type="color">
8676
defaultValue?: string;
@@ -102,7 +92,138 @@ export type Control = ControlBase &
10292
| ControlLongText
10393
| ControlNumber
10494
| ControlRange
95+
| ControlDate
96+
| ControlJSON
10597
| ControlColor
10698
| ControlCustom
10799
| ControlUnknown
108100
);
101+
102+
export type Controls = Array<Control> | Record<string, Omit<Control, 'id'>>;
103+
104+
export function resolveControls(controls: Controls): Control[] {
105+
if (Array.isArray(controls)) {
106+
return controls;
107+
}
108+
if (typeof controls === 'object') {
109+
return Object.keys(controls).map((key) => ({
110+
...controls[key],
111+
id: key,
112+
}));
113+
}
114+
return [];
115+
}
116+
117+
export function resolveValues(props: Record<string, any>, control: Control[]): Record<string, any> {
118+
const initValue: Record<string, any> = {};
119+
control.forEach((field) => {
120+
const { id, defaultValue } = field;
121+
if (id in props) {
122+
initValue[id] = props[id];
123+
} else {
124+
initValue[id] = defaultValue;
125+
}
126+
});
127+
return initValue;
128+
}
129+
130+
export const BROADCAST_READY_KEY = 'composition-live-controls:ready';
131+
132+
export const BROADCAST_UPDATE_KEY = 'composition-live-controls:update';
133+
134+
export const BROADCAST_DESTROY_KEY = 'composition-live-controls:destroy';
135+
136+
export function broadcastReady(target: Window, id: number, controls: Control[], values: Record<string, any>) {
137+
target.postMessage({
138+
type: BROADCAST_READY_KEY,
139+
payload: JSON.parse(
140+
JSON.stringify({
141+
timestamp: id,
142+
controls,
143+
values,
144+
})
145+
),
146+
});
147+
}
148+
149+
export function broadcastUpdate(target: Window, id: number, values: Record<string, any>) {
150+
target.postMessage({
151+
type: BROADCAST_UPDATE_KEY,
152+
payload: JSON.parse(
153+
JSON.stringify({
154+
timestamp: id,
155+
values,
156+
})
157+
),
158+
});
159+
}
160+
161+
export function broadcastDestroy(target: Window, id: number) {
162+
target.postMessage({
163+
type: BROADCAST_DESTROY_KEY,
164+
payload: JSON.parse(
165+
JSON.stringify({
166+
timestamp: id,
167+
})
168+
),
169+
});
170+
}
171+
172+
export type LiveControlReadyEventData = {
173+
type: 'composition-live-controls:ready';
174+
payload: {
175+
controls: Array<Control>;
176+
values: Record<string, any>;
177+
timestamp: number;
178+
};
179+
};
180+
181+
export type LiveControlUpdateEventData = {
182+
type: 'composition-live-controls:update';
183+
payload: {
184+
key: string;
185+
value: any;
186+
timestamp: number;
187+
};
188+
};
189+
190+
export type LiveControlDestroyEventData = {
191+
type: 'composition-live-controls:destroy';
192+
payload: {
193+
timestamp: number;
194+
};
195+
};
196+
197+
export type LiveControlEventData = LiveControlUpdateEventData | LiveControlReadyEventData | LiveControlDestroyEventData;
198+
199+
export function getReadyListener(
200+
event: MessageEvent<LiveControlReadyEventData>,
201+
callback: (data: { controls: Control[]; values: Record<string, any>; timestamp: number }) => void
202+
) {
203+
if (!event.data || event.data.type !== BROADCAST_READY_KEY) return;
204+
callback(JSON.parse(JSON.stringify(event.data.payload)));
205+
}
206+
207+
export function getUpdateListener(
208+
event: MessageEvent<LiveControlUpdateEventData>,
209+
callback: (data: { key: string; value: any; timestamp: number }) => void
210+
) {
211+
if (!event.data || event.data.type !== BROADCAST_UPDATE_KEY) return;
212+
callback(JSON.parse(JSON.stringify(event.data.payload)));
213+
}
214+
215+
export function getDestroyListener(
216+
event: MessageEvent<LiveControlDestroyEventData>,
217+
callback: (data: { timestamp: number }) => void
218+
) {
219+
if (!event.data || event.data.type !== BROADCAST_DESTROY_KEY) return;
220+
callback(JSON.parse(JSON.stringify(event.data.payload)));
221+
}
222+
223+
export type LiveComposition<ComponentType = any, RenderingResult = any> = {
224+
live: boolean;
225+
Comp: ComponentType;
226+
props: Record<string, any>;
227+
controls?: Array<Control> | Record<string, Omit<Control, 'id'>>;
228+
render?: (args: any, component: ComponentType) => RenderingResult;
229+
};

0 commit comments

Comments
 (0)