@player-ui/storybook 0.4.0-next.7 → 0.4.0-next.9

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 CHANGED
@@ -13,12 +13,14 @@ var makeClass = require('clsx');
13
13
  var components = require('@storybook/components');
14
14
  var api = require('@storybook/api');
15
15
  var coreEvents = require('@storybook/core-events');
16
+ var beaconPluginReact = require('@player-ui/beacon-plugin-react');
16
17
  var react$1 = require('@player-ui/react');
17
18
  var react = require('@chakra-ui/react');
18
19
  var makeFlow = require('@player-ui/make-flow');
19
20
  var addonDocs = require('@storybook/addon-docs');
20
21
  var lzString = require('lz-string');
21
22
  var metricsPluginReact = require('@player-ui/metrics-plugin-react');
23
+ var player = require('@player-ui/player');
22
24
 
23
25
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
24
26
 
@@ -177,6 +179,9 @@ const EditorPanel = (props) => {
177
179
  theme: darkMode ? "vs-dark" : "light",
178
180
  value: editorValue,
179
181
  language: "json",
182
+ options: {
183
+ formatOnPaste: true
184
+ },
180
185
  onChange
181
186
  }));
182
187
  };
@@ -469,14 +474,29 @@ class StorybookPlayerPlugin {
469
474
  }
470
475
 
471
476
  const PlayerFlowSummary = (props) => {
472
- var _a;
477
+ var _a, _b, _c;
478
+ React.useEffect(() => {
479
+ var _a2, _b2;
480
+ const model = new player.LocalModel((_a2 = props.completedState) == null ? void 0 : _a2.data);
481
+ const parser = new player.BindingParser({
482
+ get: (binding) => model.get(binding)
483
+ });
484
+ window.__PLAYER_COMPLETED_DATA__ = {
485
+ completedState: props.completedState,
486
+ get: (path) => model.get(parser.parse(path)),
487
+ beacons: (_b2 = props.beacons) != null ? _b2 : []
488
+ };
489
+ return () => {
490
+ delete window.__PLAYER_COMPLETED_DATA__;
491
+ };
492
+ }, [props.completedState, props.beacons]);
473
493
  return /* @__PURE__ */ React__default["default"].createElement(react.VStack, {
474
494
  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, {
495
+ }, /* @__PURE__ */ React__default["default"].createElement(react.Heading, null, "Flow Completed ", props.error ? "with Error" : ""), ((_a = props.completedState) == null ? void 0 : _a.endState.outcome) && /* @__PURE__ */ React__default["default"].createElement(react.Code, null, "Outcome:", " ", /* @__PURE__ */ React__default["default"].createElement(react.Text, {
476
496
  as: "strong"
477
- }, props.outcome)), props.error && /* @__PURE__ */ React__default["default"].createElement(react.Code, {
497
+ }, (_b = props.completedState) == null ? void 0 : _b.endState.outcome)), props.error && /* @__PURE__ */ React__default["default"].createElement(react.Code, {
478
498
  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, {
499
+ }, /* @__PURE__ */ React__default["default"].createElement("pre", null, (_c = props.error) == null ? void 0 : _c.message)), /* @__PURE__ */ React__default["default"].createElement(react.Button, {
480
500
  variant: "solid",
481
501
  onClick: props.reset
482
502
  }, "Reset"));
@@ -552,18 +572,26 @@ const LocalPlayerStory = (props) => {
552
572
  const stateActions = useStateActions(addons__default["default"].getChannel());
553
573
  const plugins = (_b = (_a = props.webPlugins) != null ? _a : pluginContext == null ? void 0 : pluginContext.plugins) != null ? _b : [];
554
574
  const [playerState, setPlayerState] = React__default["default"].useState("not-started");
575
+ const [trackedBeacons, setTrackedBeacons] = React__default["default"].useState([]);
555
576
  const rp = React__default["default"].useMemo(() => {
556
577
  var _a2;
578
+ const beaconPlugin = new beaconPluginReact.BeaconPlugin({
579
+ callback: (beacon) => {
580
+ setTrackedBeacons((t) => [...t, beacon]);
581
+ }
582
+ });
557
583
  return new react$1.ReactPlayer(__spreadProps(__spreadValues({}, options), {
558
584
  plugins: [
559
585
  new StorybookPlayerPlugin(stateActions),
586
+ beaconPlugin,
560
587
  ...plugins,
561
588
  ...(_a2 = options == null ? void 0 : options.plugins) != null ? _a2 : []
562
589
  ]
563
590
  }));
564
- }, [plugins]);
591
+ }, [plugins, flow]);
565
592
  const startFlow = () => {
566
593
  setPlayerState("in-progress");
594
+ setTrackedBeacons([]);
567
595
  rp.start(flow).then(() => {
568
596
  setPlayerState("completed");
569
597
  }).catch((e) => {
@@ -573,7 +601,7 @@ const LocalPlayerStory = (props) => {
573
601
  };
574
602
  React__default["default"].useEffect(() => {
575
603
  startFlow();
576
- }, [rp, flow]);
604
+ }, [rp]);
577
605
  React__default["default"].useEffect(() => {
578
606
  var _a2;
579
607
  if (controlsContext) {
@@ -587,7 +615,7 @@ const LocalPlayerStory = (props) => {
587
615
  return subscribe(addons__default["default"].getChannel(), "@@player/flow/reset", () => {
588
616
  startFlow();
589
617
  });
590
- }, [rp, flow]);
618
+ }, [rp]);
591
619
  if (renderContext.platform !== "web" && renderContext.token) {
592
620
  return /* @__PURE__ */ React__default["default"].createElement(Appetize, {
593
621
  flow,
@@ -601,7 +629,8 @@ const LocalPlayerStory = (props) => {
601
629
  if (playerState === "completed" && currentState.status === "completed") {
602
630
  return /* @__PURE__ */ React__default["default"].createElement(PlayerFlowSummary, {
603
631
  reset: startFlow,
604
- outcome: currentState.endState.outcome
632
+ completedState: currentState,
633
+ beacons: trackedBeacons
605
634
  });
606
635
  }
607
636
  if (playerState === "error" && currentState.status === "error") {
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import addons, { types } from '@storybook/addons';
3
3
  import { useDarkMode } from 'storybook-dark-mode';
4
4
  import { dequal } from 'dequal';
@@ -9,12 +9,14 @@ import makeClass from 'clsx';
9
9
  import { Separator, IconButton, Icons, WithTooltip, TooltipLinkList } from '@storybook/components';
10
10
  import { useParameter } from '@storybook/api';
11
11
  import { STORY_CHANGED } from '@storybook/core-events';
12
+ import { BeaconPlugin } from '@player-ui/beacon-plugin-react';
12
13
  import { ReactPlayer } from '@player-ui/react';
13
14
  import { VStack, Heading, Code, Text, Button, ChakraProvider, Spinner } from '@chakra-ui/react';
14
15
  import { makeFlow } from '@player-ui/make-flow';
15
16
  import { DocsContext } from '@storybook/addon-docs';
16
17
  import { compressToEncodedURIComponent } from 'lz-string';
17
18
  import { MetricsPlugin } from '@player-ui/metrics-plugin-react';
19
+ import { LocalModel, BindingParser } from '@player-ui/player';
18
20
 
19
21
  const ADDON_ID = "web-player/addon";
20
22
  const FLOW_PANEL_ID = `${ADDON_ID}/flow-editor-panel`;
@@ -166,6 +168,9 @@ const EditorPanel = (props) => {
166
168
  theme: darkMode ? "vs-dark" : "light",
167
169
  value: editorValue,
168
170
  language: "json",
171
+ options: {
172
+ formatOnPaste: true
173
+ },
169
174
  onChange
170
175
  }));
171
176
  };
@@ -458,14 +463,29 @@ class StorybookPlayerPlugin {
458
463
  }
459
464
 
460
465
  const PlayerFlowSummary = (props) => {
461
- var _a;
466
+ var _a, _b, _c;
467
+ useEffect(() => {
468
+ var _a2, _b2;
469
+ const model = new LocalModel((_a2 = props.completedState) == null ? void 0 : _a2.data);
470
+ const parser = new BindingParser({
471
+ get: (binding) => model.get(binding)
472
+ });
473
+ window.__PLAYER_COMPLETED_DATA__ = {
474
+ completedState: props.completedState,
475
+ get: (path) => model.get(parser.parse(path)),
476
+ beacons: (_b2 = props.beacons) != null ? _b2 : []
477
+ };
478
+ return () => {
479
+ delete window.__PLAYER_COMPLETED_DATA__;
480
+ };
481
+ }, [props.completedState, props.beacons]);
462
482
  return /* @__PURE__ */ React.createElement(VStack, {
463
483
  gap: "10"
464
- }, /* @__PURE__ */ React.createElement(Heading, null, "Flow Completed ", props.error ? "with Error" : ""), props.outcome && /* @__PURE__ */ React.createElement(Code, null, "Outcome: ", /* @__PURE__ */ React.createElement(Text, {
484
+ }, /* @__PURE__ */ React.createElement(Heading, null, "Flow Completed ", props.error ? "with Error" : ""), ((_a = props.completedState) == null ? void 0 : _a.endState.outcome) && /* @__PURE__ */ React.createElement(Code, null, "Outcome:", " ", /* @__PURE__ */ React.createElement(Text, {
465
485
  as: "strong"
466
- }, props.outcome)), props.error && /* @__PURE__ */ React.createElement(Code, {
486
+ }, (_b = props.completedState) == null ? void 0 : _b.endState.outcome)), props.error && /* @__PURE__ */ React.createElement(Code, {
467
487
  colorScheme: "red"
468
- }, /* @__PURE__ */ React.createElement("pre", null, (_a = props.error) == null ? void 0 : _a.message)), /* @__PURE__ */ React.createElement(Button, {
488
+ }, /* @__PURE__ */ React.createElement("pre", null, (_c = props.error) == null ? void 0 : _c.message)), /* @__PURE__ */ React.createElement(Button, {
469
489
  variant: "solid",
470
490
  onClick: props.reset
471
491
  }, "Reset"));
@@ -541,18 +561,26 @@ const LocalPlayerStory = (props) => {
541
561
  const stateActions = useStateActions(addons.getChannel());
542
562
  const plugins = (_b = (_a = props.webPlugins) != null ? _a : pluginContext == null ? void 0 : pluginContext.plugins) != null ? _b : [];
543
563
  const [playerState, setPlayerState] = React.useState("not-started");
564
+ const [trackedBeacons, setTrackedBeacons] = React.useState([]);
544
565
  const rp = React.useMemo(() => {
545
566
  var _a2;
567
+ const beaconPlugin = new BeaconPlugin({
568
+ callback: (beacon) => {
569
+ setTrackedBeacons((t) => [...t, beacon]);
570
+ }
571
+ });
546
572
  return new ReactPlayer(__spreadProps(__spreadValues({}, options), {
547
573
  plugins: [
548
574
  new StorybookPlayerPlugin(stateActions),
575
+ beaconPlugin,
549
576
  ...plugins,
550
577
  ...(_a2 = options == null ? void 0 : options.plugins) != null ? _a2 : []
551
578
  ]
552
579
  }));
553
- }, [plugins]);
580
+ }, [plugins, flow]);
554
581
  const startFlow = () => {
555
582
  setPlayerState("in-progress");
583
+ setTrackedBeacons([]);
556
584
  rp.start(flow).then(() => {
557
585
  setPlayerState("completed");
558
586
  }).catch((e) => {
@@ -562,7 +590,7 @@ const LocalPlayerStory = (props) => {
562
590
  };
563
591
  React.useEffect(() => {
564
592
  startFlow();
565
- }, [rp, flow]);
593
+ }, [rp]);
566
594
  React.useEffect(() => {
567
595
  var _a2;
568
596
  if (controlsContext) {
@@ -576,7 +604,7 @@ const LocalPlayerStory = (props) => {
576
604
  return subscribe(addons.getChannel(), "@@player/flow/reset", () => {
577
605
  startFlow();
578
606
  });
579
- }, [rp, flow]);
607
+ }, [rp]);
580
608
  if (renderContext.platform !== "web" && renderContext.token) {
581
609
  return /* @__PURE__ */ React.createElement(Appetize, {
582
610
  flow,
@@ -590,7 +618,8 @@ const LocalPlayerStory = (props) => {
590
618
  if (playerState === "completed" && currentState.status === "completed") {
591
619
  return /* @__PURE__ */ React.createElement(PlayerFlowSummary, {
592
620
  reset: startFlow,
593
- outcome: currentState.endState.outcome
621
+ completedState: currentState,
622
+ beacons: trackedBeacons
594
623
  });
595
624
  }
596
625
  if (playerState === "error" && currentState.status === "error") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@player-ui/storybook",
3
- "version": "0.4.0-next.7",
3
+ "version": "0.4.0-next.9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org"
@@ -11,8 +11,8 @@
11
11
  "@storybook/addon-docs": "^6.4.15",
12
12
  "react": "^17.0.2",
13
13
  "@types/react": "^17.0.25",
14
- "@player-ui/react": "0.4.0-next.7",
15
- "@player-ui/make-flow": "0.4.0-next.7"
14
+ "@player-ui/react": "0.4.0-next.9",
15
+ "@player-ui/make-flow": "0.4.0-next.9"
16
16
  },
17
17
  "dependencies": {
18
18
  "@monaco-editor/react": "^4.3.1",
@@ -28,7 +28,8 @@
28
28
  "dequal": "^2.0.2",
29
29
  "ts-debounce": "^4.0.0",
30
30
  "uuid": "^8.3.2",
31
- "@player-ui/metrics-plugin-react": "0.4.0-next.7",
31
+ "@player-ui/metrics-plugin-react": "0.4.0-next.9",
32
+ "@player-ui/beacon-plugin-react": "0.4.0-next.9",
32
33
  "@babel/runtime": "7.15.4"
33
34
  },
34
35
  "main": "dist/index.cjs.js",
@@ -72,6 +73,14 @@
72
73
  {
73
74
  "name": "Kelly Harrop",
74
75
  "url": "https://github.com/kharrop"
76
+ },
77
+ {
78
+ "name": "Alejandro Fimbres",
79
+ "url": "https://github.com/lexfm"
80
+ },
81
+ {
82
+ "name": "Rafael Campos",
83
+ "url": "https://github.com/rafbcampos"
75
84
  }
76
85
  ]
77
86
  }
@@ -78,6 +78,9 @@ export const EditorPanel = (props: EditorPanelProps) => {
78
78
  theme={darkMode ? 'vs-dark' : 'light'}
79
79
  value={editorValue}
80
80
  language="json"
81
+ options={{
82
+ formatOnPaste: true,
83
+ }}
81
84
  onChange={onChange}
82
85
  />
83
86
  </div>
@@ -1,4 +1,6 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
+ import type { CompletedState } from '@player-ui/player';
3
+ import { BindingParser, LocalModel } from '@player-ui/player';
2
4
  import { VStack, Code, Heading, Button, Text } from '@chakra-ui/react';
3
5
 
4
6
  export type PlayerFlowSummaryProps = {
@@ -6,19 +8,57 @@ export type PlayerFlowSummaryProps = {
6
8
  reset: () => void;
7
9
  /** The outcome of the flow */
8
10
  outcome?: string;
11
+ /** The completed state of the flow */
12
+ completedState?: CompletedState;
13
+ /** Beacons sent in the flow */
14
+ beacons?: unknown[];
9
15
  /** any error */
10
16
  error?: Error;
11
17
  };
12
18
 
19
+ interface CompletedStorybookFlowData {
20
+ /** The CompletedState of the flow */
21
+ completedState?: CompletedState;
22
+
23
+ get(path: string): unknown;
24
+
25
+ /** Beacons that were fired during the flow */
26
+ beacons: any[];
27
+ }
28
+
29
+ declare global {
30
+ interface Window {
31
+ /** Completed data from the player flow if it was successful */
32
+ __PLAYER_COMPLETED_DATA__?: CompletedStorybookFlowData;
33
+ }
34
+ }
35
+
13
36
  /** A component to show at the end of a flow */
14
37
  export const PlayerFlowSummary = (props: PlayerFlowSummaryProps) => {
38
+ useEffect(() => {
39
+ const model = new LocalModel(props.completedState?.data);
40
+ // Point back to local model for data lookups when
41
+ // parsing a path
42
+ const parser = new BindingParser({
43
+ get: (binding) => model.get(binding),
44
+ });
45
+ window.__PLAYER_COMPLETED_DATA__ = {
46
+ completedState: props.completedState,
47
+ get: (path) => model.get(parser.parse(path)),
48
+ beacons: props.beacons ?? [],
49
+ };
50
+ return () => {
51
+ delete window.__PLAYER_COMPLETED_DATA__;
52
+ };
53
+ }, [props.completedState, props.beacons]);
54
+
15
55
  return (
16
56
  <VStack gap="10">
17
57
  <Heading>Flow Completed {props.error ? 'with Error' : ''}</Heading>
18
-
19
- {props.outcome && (
58
+ {props.completedState?.endState.outcome && (
20
59
  <Code>
21
- Outcome: <Text as="strong">{props.outcome}</Text>
60
+ Outcome:{' '}
61
+ <Text as="strong">{props.completedState?.endState.outcome}</Text>
22
62
  </Code>
23
63
  )}
24
64
 
@@ -5,6 +5,7 @@ import type {
5
5
  Flow,
6
6
  ReactPlayerOptions,
7
7
  } from '@player-ui/react';
8
+ import { BeaconPlugin } from '@player-ui/beacon-plugin-react';
8
9
  import { ReactPlayer } from '@player-ui/react';
9
10
  import { ChakraProvider, Spinner } from '@chakra-ui/react';
10
11
  import { makeFlow } from '@player-ui/make-flow';
@@ -59,20 +60,30 @@ const LocalPlayerStory = (props: LocalPlayerStory) => {
59
60
  const [playerState, setPlayerState] =
60
61
  React.useState<PlayerFlowStatus>('not-started');
61
62
 
63
+ const [trackedBeacons, setTrackedBeacons] = React.useState<any[]>([]);
64
+
62
65
  const rp = React.useMemo(() => {
66
+ const beaconPlugin = new BeaconPlugin({
67
+ callback: (beacon) => {
68
+ setTrackedBeacons((t) => [...t, beacon]);
69
+ },
70
+ });
71
+
63
72
  return new ReactPlayer({
64
73
  ...options,
65
74
  plugins: [
66
75
  new StorybookPlayerPlugin(stateActions),
76
+ beaconPlugin,
67
77
  ...plugins,
68
78
  ...(options?.plugins ?? []),
69
79
  ],
70
80
  });
71
- }, [plugins]);
81
+ }, [plugins, flow]);
72
82
 
73
83
  /** A callback to start the flow */
74
84
  const startFlow = () => {
75
85
  setPlayerState('in-progress');
86
+ setTrackedBeacons([]);
76
87
  rp.start(flow)
77
88
  .then(() => {
78
89
  setPlayerState('completed');
@@ -85,7 +96,7 @@ const LocalPlayerStory = (props: LocalPlayerStory) => {
85
96
 
86
97
  React.useEffect(() => {
87
98
  startFlow();
88
- }, [rp, flow]);
99
+ }, [rp]);
89
100
 
90
101
  React.useEffect(() => {
91
102
  // merge new data from storybook controls
@@ -105,7 +116,7 @@ const LocalPlayerStory = (props: LocalPlayerStory) => {
105
116
  return subscribe(addons.getChannel(), '@@player/flow/reset', () => {
106
117
  startFlow();
107
118
  });
108
- }, [rp, flow]);
119
+ }, [rp]);
109
120
 
110
121
  if (renderContext.platform !== 'web' && renderContext.token) {
111
122
  return (
@@ -125,7 +136,8 @@ const LocalPlayerStory = (props: LocalPlayerStory) => {
125
136
  return (
126
137
  <PlayerFlowSummary
127
138
  reset={startFlow}
128
- outcome={currentState.endState.outcome}
139
+ completedState={currentState}
140
+ beacons={trackedBeacons}
129
141
  />
130
142
  );
131
143
  }