@player-ui/storybook 0.0.1-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +659 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.esm.js +643 -0
- package/package.json +37 -0
- package/register.js +1 -0
- package/src/addons/appetize/index.tsx +72 -0
- package/src/addons/constants.ts +10 -0
- package/src/addons/editor/index.tsx +85 -0
- package/src/addons/events/events.css +7 -0
- package/src/addons/events/index.tsx +100 -0
- package/src/addons/index.tsx +46 -0
- package/src/addons/refresh/index.tsx +28 -0
- package/src/decorator/index.tsx +46 -0
- package/src/index.ts +3 -0
- package/src/player/Appetize.tsx +121 -0
- package/src/player/PlayerFlowSummary.tsx +36 -0
- package/src/player/PlayerStory.tsx +198 -0
- package/src/player/hooks.ts +29 -0
- package/src/player/index.ts +1 -0
- package/src/player/storybookWebPlayerPlugin.ts +113 -0
- package/src/state/events.ts +62 -0
- package/src/state/hooks.ts +152 -0
- package/src/state/index.ts +2 -0
- package/src/types.ts +41 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var addons = require('@storybook/addons');
|
|
7
|
+
var storybookDarkMode = require('storybook-dark-mode');
|
|
8
|
+
var dequal = require('dequal');
|
|
9
|
+
var Editor = require('@monaco-editor/react');
|
|
10
|
+
var uuid = require('uuid');
|
|
11
|
+
var table = require('@devtools-ds/table');
|
|
12
|
+
var makeClass = require('clsx');
|
|
13
|
+
var components = require('@storybook/components');
|
|
14
|
+
var api = require('@storybook/api');
|
|
15
|
+
var coreEvents = require('@storybook/core-events');
|
|
16
|
+
var react$1 = require('@player-ui/react');
|
|
17
|
+
var react = require('@chakra-ui/react');
|
|
18
|
+
var makeFlow = require('@player-ui/make-flow');
|
|
19
|
+
var addonDocs = require('@storybook/addon-docs');
|
|
20
|
+
var lzString = require('lz-string');
|
|
21
|
+
var metricsPluginReact = require('@player-ui/metrics-plugin-react');
|
|
22
|
+
|
|
23
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
24
|
+
|
|
25
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
26
|
+
var addons__default = /*#__PURE__*/_interopDefaultLegacy(addons);
|
|
27
|
+
var Editor__default = /*#__PURE__*/_interopDefaultLegacy(Editor);
|
|
28
|
+
var makeClass__default = /*#__PURE__*/_interopDefaultLegacy(makeClass);
|
|
29
|
+
|
|
30
|
+
const ADDON_ID = "web-player/addon";
|
|
31
|
+
const FLOW_PANEL_ID = `${ADDON_ID}/flow-editor-panel`;
|
|
32
|
+
const EVENT_PANEL_ID = `${ADDON_ID}/events-panel`;
|
|
33
|
+
const FLOW_REFRESH_TOOL_ID = `${ADDON_ID}/flow-refresh-tool`;
|
|
34
|
+
const RENDER_SELECT_TOOL_ID = `${ADDON_ID}/render-select-tool`;
|
|
35
|
+
|
|
36
|
+
var __defProp$2 = Object.defineProperty;
|
|
37
|
+
var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
|
|
38
|
+
var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
|
|
39
|
+
var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
|
|
40
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
41
|
+
var __spreadValues$2 = (a, b) => {
|
|
42
|
+
for (var prop in b || (b = {}))
|
|
43
|
+
if (__hasOwnProp$2.call(b, prop))
|
|
44
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
45
|
+
if (__getOwnPropSymbols$2)
|
|
46
|
+
for (var prop of __getOwnPropSymbols$2(b)) {
|
|
47
|
+
if (__propIsEnum$2.call(b, prop))
|
|
48
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
49
|
+
}
|
|
50
|
+
return a;
|
|
51
|
+
};
|
|
52
|
+
function createEvent(base) {
|
|
53
|
+
return __spreadValues$2({
|
|
54
|
+
id: uuid.v4(),
|
|
55
|
+
time: Date.now()
|
|
56
|
+
}, base);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function subscribe(chan, eventName, callback) {
|
|
60
|
+
const handler = (payload) => {
|
|
61
|
+
callback(JSON.parse(payload));
|
|
62
|
+
};
|
|
63
|
+
chan.addListener(eventName, handler);
|
|
64
|
+
return () => {
|
|
65
|
+
chan.removeListener(eventName, handler);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function publish(chan, event) {
|
|
69
|
+
chan.emit(event.type, JSON.stringify(event));
|
|
70
|
+
}
|
|
71
|
+
function useStateActions(chan) {
|
|
72
|
+
return React__default["default"].useMemo(() => ({
|
|
73
|
+
addEvents: (events) => {
|
|
74
|
+
publish(chan, {
|
|
75
|
+
type: "@@player/event/add",
|
|
76
|
+
events
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
setMetrics: (metrics) => {
|
|
80
|
+
publish(chan, {
|
|
81
|
+
type: "@@player/metrics/set",
|
|
82
|
+
metrics
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
clearEvents: () => {
|
|
86
|
+
publish(chan, {
|
|
87
|
+
type: "@@player/event/clear"
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
setFlow: (flow) => {
|
|
91
|
+
publish(chan, {
|
|
92
|
+
type: "@@player/flow/set",
|
|
93
|
+
flow
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
resetFlow: () => {
|
|
97
|
+
publish(chan, { type: "@@player/flow/reset" });
|
|
98
|
+
},
|
|
99
|
+
setPlatform: (platform) => {
|
|
100
|
+
publish(chan, { type: "@@player/platform/set", platform });
|
|
101
|
+
}
|
|
102
|
+
}), [chan]);
|
|
103
|
+
}
|
|
104
|
+
function useEventState(chan) {
|
|
105
|
+
const [events, setEvents] = React__default["default"].useState([]);
|
|
106
|
+
React__default["default"].useEffect(() => {
|
|
107
|
+
const unsubAdd = subscribe(chan, "@@player/event/add", (evt) => setEvents((old) => [...old, ...evt.events]));
|
|
108
|
+
const unsubClear = subscribe(chan, "@@player/event/clear", () => {
|
|
109
|
+
setEvents([]);
|
|
110
|
+
});
|
|
111
|
+
return () => {
|
|
112
|
+
unsubAdd();
|
|
113
|
+
unsubClear();
|
|
114
|
+
};
|
|
115
|
+
}, [chan]);
|
|
116
|
+
return events;
|
|
117
|
+
}
|
|
118
|
+
function useFlowState(chan) {
|
|
119
|
+
const [flow, setFlow] = React__default["default"].useState();
|
|
120
|
+
React__default["default"].useEffect(() => {
|
|
121
|
+
return subscribe(chan, "@@player/flow/set", (evt) => {
|
|
122
|
+
setFlow(evt.flow);
|
|
123
|
+
});
|
|
124
|
+
}, [chan]);
|
|
125
|
+
return flow;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const EditorPanel = (props) => {
|
|
129
|
+
const { active } = props;
|
|
130
|
+
const darkMode = storybookDarkMode.useDarkMode();
|
|
131
|
+
const flow = useFlowState(props.api.getChannel());
|
|
132
|
+
const actions = useStateActions(props.api.getChannel());
|
|
133
|
+
const [editorValue, setEditorValue] = React__default["default"].useState(flow ? JSON.stringify(flow, null, 2) : "{}");
|
|
134
|
+
const updateTimerRef = React__default["default"].useRef(void 0);
|
|
135
|
+
function clearPending() {
|
|
136
|
+
if (updateTimerRef.current) {
|
|
137
|
+
clearTimeout(updateTimerRef.current);
|
|
138
|
+
updateTimerRef.current = void 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
React__default["default"].useEffect(() => {
|
|
142
|
+
if (!active) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
if (editorValue) {
|
|
147
|
+
const parsed = JSON.parse(editorValue);
|
|
148
|
+
if (dequal.dequal(flow, parsed)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} catch (e) {
|
|
153
|
+
}
|
|
154
|
+
setEditorValue(JSON.stringify(flow, null, 2));
|
|
155
|
+
}, [flow, active]);
|
|
156
|
+
if (!active) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const onChange = (val) => {
|
|
160
|
+
clearPending();
|
|
161
|
+
setEditorValue(val != null ? val : "");
|
|
162
|
+
try {
|
|
163
|
+
if (val) {
|
|
164
|
+
const parsed = JSON.parse(val);
|
|
165
|
+
if (!dequal.dequal(parsed, flow)) {
|
|
166
|
+
updateTimerRef.current = setTimeout(() => {
|
|
167
|
+
if (active) {
|
|
168
|
+
actions.setFlow(parsed);
|
|
169
|
+
}
|
|
170
|
+
}, 1e3);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
} catch (e) {
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(Editor__default["default"], {
|
|
177
|
+
theme: darkMode ? "vs-dark" : "light",
|
|
178
|
+
value: editorValue,
|
|
179
|
+
language: "json",
|
|
180
|
+
onChange
|
|
181
|
+
}));
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}
|
|
185
|
+
|
|
186
|
+
var css = "\n.events_header__1bcc1085 td {\n width: 200px;\n}\n\n.events_body__1bcc1085 td {\n}\n";
|
|
187
|
+
var modules_2563542d = {"header":"events_header__1bcc1085","body":"events_body__1bcc1085"};
|
|
188
|
+
n(css,{});
|
|
189
|
+
|
|
190
|
+
var __defProp$1 = Object.defineProperty;
|
|
191
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
192
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
193
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
194
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
195
|
+
var __spreadValues$1 = (a, b) => {
|
|
196
|
+
for (var prop in b || (b = {}))
|
|
197
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
198
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
199
|
+
if (__getOwnPropSymbols$1)
|
|
200
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
201
|
+
if (__propIsEnum$1.call(b, prop))
|
|
202
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
203
|
+
}
|
|
204
|
+
return a;
|
|
205
|
+
};
|
|
206
|
+
const ExtraCells = (event) => {
|
|
207
|
+
var _a, _b;
|
|
208
|
+
if (event.type === "log") {
|
|
209
|
+
return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.severity), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message.map((a) => JSON.stringify(a)).join(" ")));
|
|
210
|
+
}
|
|
211
|
+
if (event.type === "dataChange") {
|
|
212
|
+
return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.binding), /* @__PURE__ */ React__default["default"].createElement("td", null, `${JSON.stringify(event.from)} \u279C ${JSON.stringify(event.to)}`));
|
|
213
|
+
}
|
|
214
|
+
if (event.type === "stateChange") {
|
|
215
|
+
let name = event.state;
|
|
216
|
+
if (event.state === "completed") {
|
|
217
|
+
name = `${name} (${event.error ? "error" : "success"})`;
|
|
218
|
+
}
|
|
219
|
+
return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, name), /* @__PURE__ */ React__default["default"].createElement("td", null, (_b = (_a = event.outcome) != null ? _a : event.error) != null ? _b : ""));
|
|
220
|
+
}
|
|
221
|
+
if (event.type === "metric") {
|
|
222
|
+
return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.metricType), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message));
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
};
|
|
226
|
+
const EventsPanel = (props) => {
|
|
227
|
+
const events = useEventState(props.api.getChannel());
|
|
228
|
+
const darkMode = storybookDarkMode.useDarkMode();
|
|
229
|
+
if (!props.active) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
return /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
233
|
+
className: makeClass__default["default"](modules_2563542d.wrapper, {
|
|
234
|
+
[modules_2563542d.dark]: darkMode
|
|
235
|
+
})
|
|
236
|
+
}, /* @__PURE__ */ React__default["default"].createElement(table.Table, {
|
|
237
|
+
colorScheme: darkMode ? "dark" : "light"
|
|
238
|
+
}, /* @__PURE__ */ React__default["default"].createElement(table.Head, {
|
|
239
|
+
className: modules_2563542d.header
|
|
240
|
+
}, /* @__PURE__ */ React__default["default"].createElement(table.Row, null, /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Time"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Type"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null))), /* @__PURE__ */ React__default["default"].createElement(table.Body, {
|
|
241
|
+
className: modules_2563542d.body
|
|
242
|
+
}, events.map((evt) => /* @__PURE__ */ React__default["default"].createElement(table.Row, {
|
|
243
|
+
key: evt.id
|
|
244
|
+
}, /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.time), /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.type), /* @__PURE__ */ React__default["default"].createElement(ExtraCells, __spreadValues$1({}, evt)))))));
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const FlowRefresh = ({ api }) => {
|
|
248
|
+
const actions = useStateActions(api.getChannel());
|
|
249
|
+
return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement(components.Separator, null), /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
|
|
250
|
+
title: "Reset the current flow",
|
|
251
|
+
onClick: () => {
|
|
252
|
+
actions.resetFlow();
|
|
253
|
+
}
|
|
254
|
+
}, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
|
|
255
|
+
icon: "sync"
|
|
256
|
+
})));
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const RenderSelection = ({ api: api$1 }) => {
|
|
260
|
+
const params = api.useParameter("appetizeTokens", {});
|
|
261
|
+
const actions = useStateActions(api$1.getChannel());
|
|
262
|
+
const [selectedPlatform, setPlatform] = React__default["default"].useState("web");
|
|
263
|
+
React__default["default"].useEffect(() => {
|
|
264
|
+
const listener = () => {
|
|
265
|
+
setPlatform("web");
|
|
266
|
+
};
|
|
267
|
+
api$1.getChannel().addListener(coreEvents.STORY_CHANGED, listener);
|
|
268
|
+
return () => {
|
|
269
|
+
api$1.getChannel().removeListener(coreEvents.STORY_CHANGED, listener);
|
|
270
|
+
};
|
|
271
|
+
}, [api$1]);
|
|
272
|
+
const mobilePlatforms = Object.keys(params);
|
|
273
|
+
if (mobilePlatforms.length === 0) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
return /* @__PURE__ */ React__default["default"].createElement(components.WithTooltip, {
|
|
277
|
+
closeOnClick: true,
|
|
278
|
+
placement: "top",
|
|
279
|
+
trigger: "click",
|
|
280
|
+
tooltip: ({ onHide }) => /* @__PURE__ */ React__default["default"].createElement(components.TooltipLinkList, {
|
|
281
|
+
links: ["web", ...mobilePlatforms].map((platform) => ({
|
|
282
|
+
id: platform,
|
|
283
|
+
title: platform,
|
|
284
|
+
onClick: () => {
|
|
285
|
+
setPlatform(platform);
|
|
286
|
+
actions.setPlatform(platform);
|
|
287
|
+
onHide();
|
|
288
|
+
},
|
|
289
|
+
value: platform,
|
|
290
|
+
active: platform === selectedPlatform
|
|
291
|
+
}))
|
|
292
|
+
})
|
|
293
|
+
}, /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
|
|
294
|
+
title: "Change the render target"
|
|
295
|
+
}, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
|
|
296
|
+
icon: selectedPlatform === "web" ? "browser" : "mobile"
|
|
297
|
+
})));
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
function register() {
|
|
301
|
+
addons__default["default"].register(ADDON_ID, (api) => {
|
|
302
|
+
addons__default["default"].addPanel(EVENT_PANEL_ID, {
|
|
303
|
+
title: "Events",
|
|
304
|
+
render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(EventsPanel, {
|
|
305
|
+
key,
|
|
306
|
+
api,
|
|
307
|
+
active: Boolean(active)
|
|
308
|
+
})
|
|
309
|
+
});
|
|
310
|
+
addons__default["default"].addPanel(FLOW_PANEL_ID, {
|
|
311
|
+
title: "Flow",
|
|
312
|
+
render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(EditorPanel, {
|
|
313
|
+
key,
|
|
314
|
+
api,
|
|
315
|
+
active: Boolean(active)
|
|
316
|
+
})
|
|
317
|
+
});
|
|
318
|
+
addons__default["default"].add(FLOW_REFRESH_TOOL_ID, {
|
|
319
|
+
title: "Refresh Flow",
|
|
320
|
+
type: addons.types.TOOL,
|
|
321
|
+
render: () => /* @__PURE__ */ React__default["default"].createElement(FlowRefresh, {
|
|
322
|
+
api
|
|
323
|
+
})
|
|
324
|
+
});
|
|
325
|
+
addons__default["default"].add(RENDER_SELECT_TOOL_ID, {
|
|
326
|
+
title: "Render Selection",
|
|
327
|
+
type: addons.types.TOOL,
|
|
328
|
+
render: () => /* @__PURE__ */ React__default["default"].createElement(RenderSelection, {
|
|
329
|
+
api
|
|
330
|
+
})
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function useEditorFlow(initialFlow) {
|
|
336
|
+
const stateActions = useStateActions(addons__default["default"].getChannel());
|
|
337
|
+
const flow = useFlowState(addons__default["default"].getChannel());
|
|
338
|
+
const docsContext = React__default["default"].useContext(addonDocs.DocsContext);
|
|
339
|
+
React__default["default"].useEffect(() => {
|
|
340
|
+
stateActions.setFlow(initialFlow);
|
|
341
|
+
}, [initialFlow]);
|
|
342
|
+
React__default["default"].useEffect(() => {
|
|
343
|
+
if (!flow) {
|
|
344
|
+
stateActions.setFlow(initialFlow);
|
|
345
|
+
}
|
|
346
|
+
}, [flow]);
|
|
347
|
+
if (docsContext.id) {
|
|
348
|
+
return initialFlow;
|
|
349
|
+
}
|
|
350
|
+
return flow != null ? flow : initialFlow;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const DEVICE_HEIGHT = {
|
|
354
|
+
iphonexs: 845
|
|
355
|
+
};
|
|
356
|
+
const toAppetizeUrl = (baseUrl, key, params) => `https://${baseUrl}/embed/${key}?${Object.entries(params).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
|
|
357
|
+
const Appetize = (props) => {
|
|
358
|
+
const device = "iphonexs";
|
|
359
|
+
const height = DEVICE_HEIGHT[device];
|
|
360
|
+
const defaultVersions = {
|
|
361
|
+
ios: "13.7",
|
|
362
|
+
android: "8.1"
|
|
363
|
+
};
|
|
364
|
+
const {
|
|
365
|
+
baseUrl = "appetize.io",
|
|
366
|
+
token,
|
|
367
|
+
flow,
|
|
368
|
+
osVersions = defaultVersions,
|
|
369
|
+
platform
|
|
370
|
+
} = props;
|
|
371
|
+
const osVersion = osVersions[platform];
|
|
372
|
+
return /* @__PURE__ */ React__default["default"].createElement("iframe", {
|
|
373
|
+
title: "native app",
|
|
374
|
+
style: { height: `${height}px`, border: "none", width: "100%" },
|
|
375
|
+
src: toAppetizeUrl(baseUrl, token, {
|
|
376
|
+
autoplay: true,
|
|
377
|
+
device: "iphonexs",
|
|
378
|
+
deviceColor: "black",
|
|
379
|
+
scale: 100,
|
|
380
|
+
osVersion,
|
|
381
|
+
params: encodeURIComponent(JSON.stringify({
|
|
382
|
+
json: lzString.compressToEncodedURIComponent(JSON.stringify(flow))
|
|
383
|
+
}))
|
|
384
|
+
})
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
class StorybookPlayerPlugin {
|
|
389
|
+
constructor(actions) {
|
|
390
|
+
this.name = "Storybook";
|
|
391
|
+
this.actions = actions;
|
|
392
|
+
this.metricsPlugin = new metricsPluginReact.MetricsPlugin({
|
|
393
|
+
onUpdate: (metrics) => {
|
|
394
|
+
actions.setMetrics(metrics);
|
|
395
|
+
},
|
|
396
|
+
onRenderEnd: (timing) => {
|
|
397
|
+
this.onMetricChange(timing, "render");
|
|
398
|
+
},
|
|
399
|
+
onUpdateEnd: (timing) => {
|
|
400
|
+
this.onMetricChange(timing, "update");
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
apply(player) {
|
|
405
|
+
player.registerPlugin(this.metricsPlugin);
|
|
406
|
+
}
|
|
407
|
+
applyWeb(wp) {
|
|
408
|
+
wp.registerPlugin(this.metricsPlugin);
|
|
409
|
+
wp.player.hooks.dataController.tap(this.name, (dc) => {
|
|
410
|
+
this.actions.clearEvents();
|
|
411
|
+
dc.hooks.onUpdate.tap(this.name, (dataUpdates) => {
|
|
412
|
+
const events = dataUpdates.map((dataUpdate) => createEvent({
|
|
413
|
+
type: "dataChange",
|
|
414
|
+
binding: dataUpdate.binding.asString(),
|
|
415
|
+
from: dataUpdate.oldValue,
|
|
416
|
+
to: dataUpdate.newValue
|
|
417
|
+
}));
|
|
418
|
+
this.actions.addEvents(events);
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
wp.player.logger.hooks.log.tap(this.name, (severity, data) => {
|
|
422
|
+
this.actions.addEvents([
|
|
423
|
+
createEvent({
|
|
424
|
+
type: "log",
|
|
425
|
+
message: data,
|
|
426
|
+
severity
|
|
427
|
+
})
|
|
428
|
+
]);
|
|
429
|
+
});
|
|
430
|
+
wp.player.hooks.state.tap(this.name, (newState) => {
|
|
431
|
+
if ("error" in newState) {
|
|
432
|
+
this.actions.addEvents([
|
|
433
|
+
createEvent({
|
|
434
|
+
type: "stateChange",
|
|
435
|
+
state: newState.status,
|
|
436
|
+
error: newState.error.message
|
|
437
|
+
})
|
|
438
|
+
]);
|
|
439
|
+
} else if (newState.status === "completed") {
|
|
440
|
+
this.actions.addEvents([
|
|
441
|
+
createEvent({
|
|
442
|
+
type: "stateChange",
|
|
443
|
+
state: newState.status,
|
|
444
|
+
outcome: newState.endState.outcome
|
|
445
|
+
})
|
|
446
|
+
]);
|
|
447
|
+
} else {
|
|
448
|
+
this.actions.addEvents([
|
|
449
|
+
createEvent({
|
|
450
|
+
type: "stateChange",
|
|
451
|
+
state: newState.status
|
|
452
|
+
})
|
|
453
|
+
]);
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
onMetricChange(timing, metricType) {
|
|
458
|
+
if (!timing.completed) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
this.actions.addEvents([
|
|
462
|
+
createEvent({
|
|
463
|
+
type: "metric",
|
|
464
|
+
metricType,
|
|
465
|
+
message: `Duration: ${timing.duration.toFixed(0)} ms`
|
|
466
|
+
})
|
|
467
|
+
]);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const PlayerFlowSummary = (props) => {
|
|
472
|
+
var _a;
|
|
473
|
+
return /* @__PURE__ */ React__default["default"].createElement(react.VStack, {
|
|
474
|
+
gap: "10"
|
|
475
|
+
}, /* @__PURE__ */ React__default["default"].createElement(react.Heading, null, "Flow Completed ", props.error ? "with Error" : ""), props.outcome && /* @__PURE__ */ React__default["default"].createElement(react.Code, null, "Outcome: ", /* @__PURE__ */ React__default["default"].createElement(react.Text, {
|
|
476
|
+
as: "strong"
|
|
477
|
+
}, props.outcome)), props.error && /* @__PURE__ */ React__default["default"].createElement(react.Code, {
|
|
478
|
+
colorScheme: "red"
|
|
479
|
+
}, /* @__PURE__ */ React__default["default"].createElement("pre", null, (_a = props.error) == null ? void 0 : _a.message)), /* @__PURE__ */ React__default["default"].createElement(react.Button, {
|
|
480
|
+
variant: "solid",
|
|
481
|
+
onClick: props.reset
|
|
482
|
+
}, "Reset"));
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
var __defProp = Object.defineProperty;
|
|
486
|
+
var __defProps = Object.defineProperties;
|
|
487
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
488
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
489
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
490
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
491
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
492
|
+
var __spreadValues = (a, b) => {
|
|
493
|
+
for (var prop in b || (b = {}))
|
|
494
|
+
if (__hasOwnProp.call(b, prop))
|
|
495
|
+
__defNormalProp(a, prop, b[prop]);
|
|
496
|
+
if (__getOwnPropSymbols)
|
|
497
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
498
|
+
if (__propIsEnum.call(b, prop))
|
|
499
|
+
__defNormalProp(a, prop, b[prop]);
|
|
500
|
+
}
|
|
501
|
+
return a;
|
|
502
|
+
};
|
|
503
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
504
|
+
var __objRest = (source, exclude) => {
|
|
505
|
+
var target = {};
|
|
506
|
+
for (var prop in source)
|
|
507
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
508
|
+
target[prop] = source[prop];
|
|
509
|
+
if (source != null && __getOwnPropSymbols)
|
|
510
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
511
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
512
|
+
target[prop] = source[prop];
|
|
513
|
+
}
|
|
514
|
+
return target;
|
|
515
|
+
};
|
|
516
|
+
var __async = (__this, __arguments, generator) => {
|
|
517
|
+
return new Promise((resolve, reject) => {
|
|
518
|
+
var fulfilled = (value) => {
|
|
519
|
+
try {
|
|
520
|
+
step(generator.next(value));
|
|
521
|
+
} catch (e) {
|
|
522
|
+
reject(e);
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
var rejected = (value) => {
|
|
526
|
+
try {
|
|
527
|
+
step(generator.throw(value));
|
|
528
|
+
} catch (e) {
|
|
529
|
+
reject(e);
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
533
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
const WebPlayerPluginContext = React__default["default"].createContext({ plugins: [] });
|
|
537
|
+
const PlayerRenderContext = React__default["default"].createContext({
|
|
538
|
+
platform: "web"
|
|
539
|
+
});
|
|
540
|
+
const StorybookControlsContext = React__default["default"].createContext({
|
|
541
|
+
controls: {}
|
|
542
|
+
});
|
|
543
|
+
const LocalPlayerStory = (props) => {
|
|
544
|
+
var _a, _b;
|
|
545
|
+
let flow = useEditorFlow(props.flow);
|
|
546
|
+
const renderContext = React__default["default"].useContext(PlayerRenderContext);
|
|
547
|
+
const pluginContext = React__default["default"].useContext(WebPlayerPluginContext);
|
|
548
|
+
const controlsContext = React__default["default"].useContext(StorybookControlsContext);
|
|
549
|
+
const stateActions = useStateActions(addons__default["default"].getChannel());
|
|
550
|
+
const plugins = (_b = (_a = props.webPlugins) != null ? _a : pluginContext == null ? void 0 : pluginContext.plugins) != null ? _b : [];
|
|
551
|
+
const [playerState, setPlayerState] = React__default["default"].useState("not-started");
|
|
552
|
+
const wp = React__default["default"].useMemo(() => {
|
|
553
|
+
return new react$1.WebPlayer({
|
|
554
|
+
plugins: [new StorybookPlayerPlugin(stateActions), ...plugins]
|
|
555
|
+
});
|
|
556
|
+
}, [plugins]);
|
|
557
|
+
const startFlow = () => {
|
|
558
|
+
setPlayerState("in-progress");
|
|
559
|
+
wp.start(flow).then(() => {
|
|
560
|
+
setPlayerState("completed");
|
|
561
|
+
}).catch((e) => {
|
|
562
|
+
console.error("Error starting flow", e);
|
|
563
|
+
setPlayerState("error");
|
|
564
|
+
});
|
|
565
|
+
};
|
|
566
|
+
React__default["default"].useEffect(() => {
|
|
567
|
+
startFlow();
|
|
568
|
+
}, [wp, flow]);
|
|
569
|
+
React__default["default"].useEffect(() => {
|
|
570
|
+
var _a2;
|
|
571
|
+
if (controlsContext) {
|
|
572
|
+
flow = __spreadProps(__spreadValues({}, flow), {
|
|
573
|
+
data: __spreadValues(__spreadValues({}, (_a2 = flow.data) != null ? _a2 : {}), controlsContext)
|
|
574
|
+
});
|
|
575
|
+
stateActions.setFlow(flow);
|
|
576
|
+
}
|
|
577
|
+
}, [controlsContext]);
|
|
578
|
+
React__default["default"].useEffect(() => {
|
|
579
|
+
return subscribe(addons__default["default"].getChannel(), "@@player/flow/reset", () => {
|
|
580
|
+
startFlow();
|
|
581
|
+
});
|
|
582
|
+
}, [wp, flow]);
|
|
583
|
+
if (renderContext.platform !== "web" && renderContext.token) {
|
|
584
|
+
return /* @__PURE__ */ React__default["default"].createElement(Appetize, {
|
|
585
|
+
flow,
|
|
586
|
+
platform: renderContext.platform,
|
|
587
|
+
token: renderContext.token,
|
|
588
|
+
baseUrl: renderContext.baseUrl,
|
|
589
|
+
osVersions: renderContext.appetizeVersions
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
const currentState = wp.player.getState();
|
|
593
|
+
if (playerState === "completed" && currentState.status === "completed") {
|
|
594
|
+
return /* @__PURE__ */ React__default["default"].createElement(PlayerFlowSummary, {
|
|
595
|
+
reset: startFlow,
|
|
596
|
+
outcome: currentState.endState.outcome
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
if (playerState === "error" && currentState.status === "error") {
|
|
600
|
+
return /* @__PURE__ */ React__default["default"].createElement(PlayerFlowSummary, {
|
|
601
|
+
reset: startFlow,
|
|
602
|
+
error: currentState.error
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
return /* @__PURE__ */ React__default["default"].createElement(wp.Component, null);
|
|
606
|
+
};
|
|
607
|
+
function wrapInLazy(Component, flowFactory, other) {
|
|
608
|
+
const asPlayer = () => __async(this, null, function* () {
|
|
609
|
+
const mock = typeof flowFactory === "function" ? yield flowFactory() : flowFactory;
|
|
610
|
+
const Comp = () => {
|
|
611
|
+
const flow = __spreadValues(__spreadValues({}, makeFlow.makeFlow("default" in mock ? mock.default : mock)), other != null ? other : {});
|
|
612
|
+
return /* @__PURE__ */ React__default["default"].createElement(Component, {
|
|
613
|
+
flow
|
|
614
|
+
});
|
|
615
|
+
};
|
|
616
|
+
return {
|
|
617
|
+
default: Comp
|
|
618
|
+
};
|
|
619
|
+
});
|
|
620
|
+
return React__default["default"].lazy(asPlayer);
|
|
621
|
+
}
|
|
622
|
+
const PlayerStory = (props) => {
|
|
623
|
+
const _a = props, { flow, storybookControls } = _a, other = __objRest(_a, ["flow", "storybookControls"]);
|
|
624
|
+
const MockComp = React__default["default"].useMemo(() => wrapInLazy(LocalPlayerStory, flow, other), []);
|
|
625
|
+
return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(react.ChakraProvider, null, /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Suspense, {
|
|
626
|
+
fallback: /* @__PURE__ */ React__default["default"].createElement(react.Spinner, null)
|
|
627
|
+
}, /* @__PURE__ */ React__default["default"].createElement(StorybookControlsContext.Provider, {
|
|
628
|
+
value: __spreadValues({}, storybookControls)
|
|
629
|
+
}, /* @__PURE__ */ React__default["default"].createElement(MockComp, null)))));
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
const PlayerDecorator = (story, ctx) => {
|
|
633
|
+
var _a;
|
|
634
|
+
const playerParams = ctx.parameters;
|
|
635
|
+
const [selectedPlatform, setPlatform] = React__default["default"].useState("web");
|
|
636
|
+
React__default["default"].useEffect(() => {
|
|
637
|
+
return subscribe(addons__default["default"].getChannel(), "@@player/platform/set", (evt) => {
|
|
638
|
+
setPlatform(evt.platform);
|
|
639
|
+
});
|
|
640
|
+
}, []);
|
|
641
|
+
return /* @__PURE__ */ React__default["default"].createElement(PlayerRenderContext.Provider, {
|
|
642
|
+
value: {
|
|
643
|
+
platform: selectedPlatform,
|
|
644
|
+
token: selectedPlatform === "web" ? void 0 : (_a = playerParams == null ? void 0 : playerParams.appetizeTokens) == null ? void 0 : _a[selectedPlatform],
|
|
645
|
+
baseUrl: playerParams.appetizeBaseUrl,
|
|
646
|
+
appetizeVersions: playerParams.appetizeVersions
|
|
647
|
+
}
|
|
648
|
+
}, /* @__PURE__ */ React__default["default"].createElement(WebPlayerPluginContext.Provider, {
|
|
649
|
+
value: { plugins: playerParams.webplayerPlugins }
|
|
650
|
+
}, story()));
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
exports.PlayerDecorator = PlayerDecorator;
|
|
654
|
+
exports.PlayerRenderContext = PlayerRenderContext;
|
|
655
|
+
exports.PlayerStory = PlayerStory;
|
|
656
|
+
exports.StorybookControlsContext = StorybookControlsContext;
|
|
657
|
+
exports.WebPlayerPluginContext = WebPlayerPluginContext;
|
|
658
|
+
exports.register = register;
|
|
659
|
+
//# sourceMappingURL=index.cjs.js.map
|