@player-ui/storybook 1.1.0-next.2 → 1.1.0-next.4

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.js CHANGED
@@ -275,6 +275,7 @@ var StorybookControlsContext = React5__namespace.default.createContext({
275
275
  controls: {}
276
276
  });
277
277
  var PlayerOptionsContext = React5__namespace.default.createContext({ options: {} });
278
+ var StartFormatContext = React5__namespace.default.createContext({});
278
279
  var SuspenseSpinner = (props) => {
279
280
  return /* @__PURE__ */ React5__namespace.default.createElement(React5__namespace.default.Suspense, { fallback: /* @__PURE__ */ React5__namespace.default.createElement("div", { className: "sb-loader" }) }, props.children);
280
281
  };
@@ -282,6 +283,7 @@ var PlayerJsonEditorStory = () => {
282
283
  const jsonEditorValue = useJSONEditorValue();
283
284
  useFlowSetListener(previewApi.addons.getChannel());
284
285
  const { plugins } = React5__namespace.default.useContext(ReactPlayerPluginContext);
286
+ const { format } = React5__namespace.default.useContext(StartFormatContext);
285
287
  const dispatch = reactRedux.useDispatch();
286
288
  const [playerState, setPlayerState] = React5__namespace.default.useState("not-started");
287
289
  const [trackedBeacons, setTrackedBeacons] = React5__namespace.default.useState([]);
@@ -302,8 +304,10 @@ var PlayerJsonEditorStory = () => {
302
304
  }
303
305
  setPlayerState("in-progress");
304
306
  setTrackedBeacons([]);
305
- setKey(jsonEditorValue.value.id);
306
- wp.start(jsonEditorValue.value).then(() => {
307
+ setKey(
308
+ jsonEditorValue.value.id ?? jsonEditorValue.value.surfaceId
309
+ );
310
+ wp.start(jsonEditorValue.value, format ? { format } : void 0).then(() => {
307
311
  setPlayerState("completed");
308
312
  }).catch((e) => {
309
313
  console.error("Error starting flow", e);
@@ -365,14 +369,12 @@ var LocalPlayerStory = (props) => {
365
369
  }
366
370
  return /* @__PURE__ */ React5__namespace.default.createElement(components.Placeholder, null, "Unable to render flow");
367
371
  };
368
- function wrapInLazy(Component, mockFactory, other) {
372
+ function wrapInLazy(Component, mockFactory, other, skipMakeFlow) {
369
373
  const asPlayer = async () => {
370
374
  const mock = typeof mockFactory === "function" ? await mockFactory() : mockFactory;
371
375
  const Comp = () => {
372
- const flow = {
373
- ...makeFlow.makeFlow("default" in mock ? mock.default : mock),
374
- ...other ?? {}
375
- };
376
+ const raw = "default" in mock ? mock.default : mock;
377
+ const flow = skipMakeFlow ? { ...raw, ...other ?? {} } : { ...makeFlow.makeFlow(raw), ...other ?? {} };
376
378
  return /* @__PURE__ */ React5__namespace.default.createElement(Component, { mock: flow });
377
379
  };
378
380
  return {
@@ -382,10 +384,10 @@ function wrapInLazy(Component, mockFactory, other) {
382
384
  return React5__namespace.default.lazy(asPlayer);
383
385
  }
384
386
  var PlayerStory = (props) => {
385
- const { flow, storybookControls, options: options2, ...other } = props;
387
+ const { flow, storybookControls, options: options2, format, ...other } = props;
386
388
  useContentKind("json");
387
389
  const MockComp = React5__namespace.default.useMemo(
388
- () => wrapInLazy(LocalPlayerStory, flow, other),
390
+ () => wrapInLazy(LocalPlayerStory, flow, other, format === "a2ui"),
389
391
  []
390
392
  );
391
393
  return /* @__PURE__ */ React5__namespace.default.createElement("div", null, /* @__PURE__ */ React5__namespace.default.createElement(SuspenseSpinner, null, /* @__PURE__ */ React5__namespace.default.createElement(
@@ -402,7 +404,7 @@ var PlayerStory = (props) => {
402
404
  options: options2
403
405
  }
404
406
  },
405
- /* @__PURE__ */ React5__namespace.default.createElement(MockComp, null)
407
+ /* @__PURE__ */ React5__namespace.default.createElement(StartFormatContext.Provider, { value: { format } }, /* @__PURE__ */ React5__namespace.default.createElement(MockComp, null))
406
408
  )
407
409
  )));
408
410
  };
@@ -710,6 +712,23 @@ var PlayerDecorator = (Story, ctx) => {
710
712
  /* @__PURE__ */ React5__namespace.default.createElement(DSLPluginContext.Provider, { value: playerParams.dslEditor ?? {} }, Story())
711
713
  )));
712
714
  };
715
+ function createA2UIStory(loader, options2) {
716
+ const Comp = () => /* @__PURE__ */ React5__namespace.default.createElement(
717
+ PlayerStory,
718
+ {
719
+ flow: async () => {
720
+ const mod2 = await loader();
721
+ const snap = "default" in mod2 ? mod2.default : mod2;
722
+ return { default: snap };
723
+ },
724
+ format: "a2ui",
725
+ options: options2
726
+ }
727
+ );
728
+ if (options2 == null ? void 0 : options2.args)
729
+ Comp.args = options2.args;
730
+ return { render: Comp };
731
+ }
713
732
 
714
733
  // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/tools/storybook/src/preview.tsx
715
734
  var preview = {
@@ -1526,8 +1545,10 @@ exports.PlayerRenderContext = PlayerRenderContext;
1526
1545
  exports.PlayerRenderContextWrapper = PlayerRenderContextWrapper;
1527
1546
  exports.PlayerStory = PlayerStory;
1528
1547
  exports.ReactPlayerPluginContext = ReactPlayerPluginContext;
1548
+ exports.StartFormatContext = StartFormatContext;
1529
1549
  exports.StorybookControlsContext = StorybookControlsContext;
1530
1550
  exports.SuspenseSpinner = SuspenseSpinner;
1551
+ exports.createA2UIStory = createA2UIStory;
1531
1552
  exports.createDSLStory = createDSLStory;
1532
1553
  exports.execute = execute;
1533
1554
  exports.preview = preview;
package/dist/index.mjs CHANGED
@@ -250,6 +250,7 @@ var StorybookControlsContext = React5__default.createContext({
250
250
  controls: {}
251
251
  });
252
252
  var PlayerOptionsContext = React5__default.createContext({ options: {} });
253
+ var StartFormatContext = React5__default.createContext({});
253
254
  var SuspenseSpinner = (props) => {
254
255
  return /* @__PURE__ */ React5__default.createElement(React5__default.Suspense, { fallback: /* @__PURE__ */ React5__default.createElement("div", { className: "sb-loader" }) }, props.children);
255
256
  };
@@ -257,6 +258,7 @@ var PlayerJsonEditorStory = () => {
257
258
  const jsonEditorValue = useJSONEditorValue();
258
259
  useFlowSetListener(addons$1.getChannel());
259
260
  const { plugins } = React5__default.useContext(ReactPlayerPluginContext);
261
+ const { format } = React5__default.useContext(StartFormatContext);
260
262
  const dispatch = useDispatch();
261
263
  const [playerState, setPlayerState] = React5__default.useState("not-started");
262
264
  const [trackedBeacons, setTrackedBeacons] = React5__default.useState([]);
@@ -277,8 +279,10 @@ var PlayerJsonEditorStory = () => {
277
279
  }
278
280
  setPlayerState("in-progress");
279
281
  setTrackedBeacons([]);
280
- setKey(jsonEditorValue.value.id);
281
- wp.start(jsonEditorValue.value).then(() => {
282
+ setKey(
283
+ jsonEditorValue.value.id ?? jsonEditorValue.value.surfaceId
284
+ );
285
+ wp.start(jsonEditorValue.value, format ? { format } : void 0).then(() => {
282
286
  setPlayerState("completed");
283
287
  }).catch((e) => {
284
288
  console.error("Error starting flow", e);
@@ -340,14 +344,12 @@ var LocalPlayerStory = (props) => {
340
344
  }
341
345
  return /* @__PURE__ */ React5__default.createElement(Placeholder, null, "Unable to render flow");
342
346
  };
343
- function wrapInLazy(Component, mockFactory, other) {
347
+ function wrapInLazy(Component, mockFactory, other, skipMakeFlow) {
344
348
  const asPlayer = async () => {
345
349
  const mock = typeof mockFactory === "function" ? await mockFactory() : mockFactory;
346
350
  const Comp = () => {
347
- const flow = {
348
- ...makeFlow("default" in mock ? mock.default : mock),
349
- ...other ?? {}
350
- };
351
+ const raw = "default" in mock ? mock.default : mock;
352
+ const flow = skipMakeFlow ? { ...raw, ...other ?? {} } : { ...makeFlow(raw), ...other ?? {} };
351
353
  return /* @__PURE__ */ React5__default.createElement(Component, { mock: flow });
352
354
  };
353
355
  return {
@@ -357,10 +359,10 @@ function wrapInLazy(Component, mockFactory, other) {
357
359
  return React5__default.lazy(asPlayer);
358
360
  }
359
361
  var PlayerStory = (props) => {
360
- const { flow, storybookControls, options: options2, ...other } = props;
362
+ const { flow, storybookControls, options: options2, format, ...other } = props;
361
363
  useContentKind("json");
362
364
  const MockComp = React5__default.useMemo(
363
- () => wrapInLazy(LocalPlayerStory, flow, other),
365
+ () => wrapInLazy(LocalPlayerStory, flow, other, format === "a2ui"),
364
366
  []
365
367
  );
366
368
  return /* @__PURE__ */ React5__default.createElement("div", null, /* @__PURE__ */ React5__default.createElement(SuspenseSpinner, null, /* @__PURE__ */ React5__default.createElement(
@@ -377,7 +379,7 @@ var PlayerStory = (props) => {
377
379
  options: options2
378
380
  }
379
381
  },
380
- /* @__PURE__ */ React5__default.createElement(MockComp, null)
382
+ /* @__PURE__ */ React5__default.createElement(StartFormatContext.Provider, { value: { format } }, /* @__PURE__ */ React5__default.createElement(MockComp, null))
381
383
  )
382
384
  )));
383
385
  };
@@ -685,6 +687,23 @@ var PlayerDecorator = (Story, ctx) => {
685
687
  /* @__PURE__ */ React5__default.createElement(DSLPluginContext.Provider, { value: playerParams.dslEditor ?? {} }, Story())
686
688
  )));
687
689
  };
690
+ function createA2UIStory(loader, options2) {
691
+ const Comp = () => /* @__PURE__ */ React5__default.createElement(
692
+ PlayerStory,
693
+ {
694
+ flow: async () => {
695
+ const mod2 = await loader();
696
+ const snap = "default" in mod2 ? mod2.default : mod2;
697
+ return { default: snap };
698
+ },
699
+ format: "a2ui",
700
+ options: options2
701
+ }
702
+ );
703
+ if (options2 == null ? void 0 : options2.args)
704
+ Comp.args = options2.args;
705
+ return { render: Comp };
706
+ }
688
707
 
689
708
  // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/tools/storybook/src/preview.tsx
690
709
  var preview = {
@@ -1492,6 +1511,6 @@ var register = () => {
1492
1511
  });
1493
1512
  };
1494
1513
 
1495
- export { DSLLocalPlayerStory, DSLPlayerStory, DSLPluginContext, PlayerDecorator, PlayerOptionsContext, PlayerRenderContext, PlayerRenderContextWrapper, PlayerStory, ReactPlayerPluginContext, StorybookControlsContext, SuspenseSpinner, createDSLStory, execute, preview, register, toLazyStory };
1514
+ export { DSLLocalPlayerStory, DSLPlayerStory, DSLPluginContext, PlayerDecorator, PlayerOptionsContext, PlayerRenderContext, PlayerRenderContextWrapper, PlayerStory, ReactPlayerPluginContext, StartFormatContext, StorybookControlsContext, SuspenseSpinner, createA2UIStory, createDSLStory, execute, preview, register, toLazyStory };
1496
1515
  //# sourceMappingURL=index.mjs.map
1497
1516
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "manager.mjs"
9
9
  ],
10
10
  "name": "@player-ui/storybook",
11
- "version": "1.1.0-next.2",
11
+ "version": "1.1.0-next.4",
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./src/index.ts",
@@ -24,10 +24,12 @@
24
24
  },
25
25
  "main": "./dist/index.js",
26
26
  "dependencies": {
27
- "@player-ui/beacon-plugin-react": "1.1.0-next.2",
28
- "@player-ui/make-flow": "1.1.0-next.2",
29
- "@player-ui/react": "1.1.0-next.2",
30
- "@player-ui/metrics-plugin-react": "1.1.0-next.2",
27
+ "@player-ui/a2ui-plugin": "1.1.0-next.4",
28
+ "@player-ui/beacon-plugin-react": "1.1.0-next.4",
29
+ "@player-ui/make-flow": "1.1.0-next.4",
30
+ "@player-ui/player": "1.1.0-next.4",
31
+ "@player-ui/react": "1.1.0-next.4",
32
+ "@player-ui/metrics-plugin-react": "1.1.0-next.4",
31
33
  "@vueless/storybook-dark-mode": "^10.0.4",
32
34
  "storybook": "^10.1.4",
33
35
  "@storybook/icons": "^2.0.1",
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import type { A2UISnapshot } from "@player-ui/a2ui-plugin";
3
+ import { PlayerStory } from "../player";
4
+
5
+ export type A2UIStoryLoader = () => Promise<
6
+ A2UISnapshot | { default: A2UISnapshot }
7
+ >;
8
+
9
+ /**
10
+ * Story factory for A2UI snapshots. Hands the snapshot directly to
11
+ * `ReactPlayer.start(..., { format: "a2ui" })`, letting Player adapt it on
12
+ * every start. The editor surfaces the raw snapshot JSON, so live edits or
13
+ * arbitrary user-pasted A2UI content re-render through the adapter without
14
+ * a separate build step.
15
+ */
16
+ export function createA2UIStory(loader: A2UIStoryLoader, options?: any) {
17
+ const Comp = () => (
18
+ <PlayerStory
19
+ flow={async () => {
20
+ const mod = await loader();
21
+ const snap = "default" in mod ? mod.default : mod;
22
+ return { default: snap };
23
+ }}
24
+ format="a2ui"
25
+ options={options}
26
+ />
27
+ );
28
+ if (options?.args) (Comp as any).args = options.args;
29
+ return { render: Comp };
30
+ }
@@ -0,0 +1 @@
1
+ export * from "./createA2UIStory";
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./decorator";
2
2
  export * from "./player";
3
3
  export * from "./dsl";
4
+ export * from "./a2ui";
4
5
  export * from "./preview";
5
6
  export * from "./manager";
@@ -8,6 +8,7 @@ import type {
8
8
  import { ReactPlayer } from "@player-ui/react";
9
9
  import { BeaconPlugin } from "@player-ui/beacon-plugin-react";
10
10
  import { makeFlow } from "@player-ui/make-flow";
11
+ import type { StartOptions } from "@player-ui/player";
11
12
  import { Placeholder } from "storybook/internal/components";
12
13
  import { useDispatch, useSelector } from "react-redux";
13
14
  import { addons } from "storybook/preview-api";
@@ -61,6 +62,15 @@ export const PlayerOptionsContext = React.createContext<{
61
62
  options?: ReactPlayerOptions;
62
63
  }>({ options: {} });
63
64
 
65
+ /**
66
+ * Content format passed to `ReactPlayer.start`. When `"a2ui"`, the editor
67
+ * value is treated as an A2UI snapshot and Player will adapt it on every
68
+ * start — so users can edit the snapshot live in the JSON editor.
69
+ */
70
+ export const StartFormatContext = React.createContext<{
71
+ format?: StartOptions["format"];
72
+ }>({});
73
+
64
74
  export const SuspenseSpinner = (props: PropsWithChildren) => {
65
75
  return (
66
76
  <React.Suspense fallback={<div className="sb-loader" />}>
@@ -74,6 +84,7 @@ const PlayerJsonEditorStory = () => {
74
84
  useFlowSetListener(addons.getChannel());
75
85
 
76
86
  const { plugins } = React.useContext(ReactPlayerPluginContext);
87
+ const { format } = React.useContext(StartFormatContext);
77
88
 
78
89
  const dispatch = useDispatch();
79
90
 
@@ -103,9 +114,12 @@ const PlayerJsonEditorStory = () => {
103
114
  setPlayerState("in-progress");
104
115
  setTrackedBeacons([]);
105
116
 
106
- setKey(jsonEditorValue.value.id);
117
+ setKey(
118
+ (jsonEditorValue.value as { id?: string; surfaceId?: string }).id ??
119
+ (jsonEditorValue.value as { surfaceId?: string }).surfaceId,
120
+ );
107
121
 
108
- wp.start(jsonEditorValue.value)
122
+ wp.start(jsonEditorValue.value, format ? { format } : undefined)
109
123
  .then(() => {
110
124
  setPlayerState("completed");
111
125
  })
@@ -190,7 +204,7 @@ const LocalPlayerStory = (props: LocalPlayerStory) => {
190
204
  return <Placeholder>Unable to render flow</Placeholder>;
191
205
  };
192
206
 
193
- type Mock = Record<string, unknown>;
207
+ type Mock = object;
194
208
  type MockFactory = () => Mock;
195
209
  type MockFactoryOrPromise = MockFactory | Mock;
196
210
 
@@ -207,6 +221,8 @@ function wrapInLazy(
207
221
 
208
222
  /** Any other props to pass */
209
223
  other?: any,
224
+ /** Skip makeFlow wrapping — used for raw content like A2UI snapshots. */
225
+ skipMakeFlow?: boolean,
210
226
  ) {
211
227
  /** an async loader to wrap the mock as a player component */
212
228
  const asPlayer = async () => {
@@ -215,10 +231,13 @@ function wrapInLazy(
215
231
 
216
232
  /** The component to load */
217
233
  const Comp = () => {
218
- const flow = {
219
- ...makeFlow("default" in mock ? mock.default : mock),
220
- ...(other ?? {}),
221
- };
234
+ const raw = ("default" in mock ? mock.default : mock) as Record<
235
+ string,
236
+ unknown
237
+ >;
238
+ const flow = skipMakeFlow
239
+ ? ({ ...raw, ...(other ?? {}) } as Flow)
240
+ : ({ ...makeFlow(raw), ...(other ?? {}) } as Flow);
222
241
 
223
242
  return <Component mock={flow} />;
224
243
  };
@@ -240,6 +259,12 @@ export interface PlayerStoryProps {
240
259
  storybookControls?: Flow["data"];
241
260
  /** options, like suspend and plugins */
242
261
  options?: ReactPlayerOptions;
262
+ /**
263
+ * Content format passed to Player.start. Default `"player"` (Flow JSON).
264
+ * Use `"a2ui"` to feed an A2UI snapshot — Player adapts on every start so
265
+ * users can edit the snapshot live.
266
+ */
267
+ format?: StartOptions["format"];
243
268
  }
244
269
 
245
270
  /**
@@ -247,11 +272,11 @@ export interface PlayerStoryProps {
247
272
  * This handles all of the wiring of the mock into the flow editor, events, etc
248
273
  */
249
274
  export const PlayerStory = (props: PlayerStoryProps) => {
250
- const { flow, storybookControls, options, ...other } = props;
275
+ const { flow, storybookControls, options, format, ...other } = props;
251
276
  useContentKind("json");
252
277
 
253
278
  const MockComp = React.useMemo(
254
- () => wrapInLazy(LocalPlayerStory, flow, other),
279
+ () => wrapInLazy(LocalPlayerStory, flow, other, format === "a2ui"),
255
280
  [],
256
281
  );
257
282
 
@@ -268,7 +293,9 @@ export const PlayerStory = (props: PlayerStoryProps) => {
268
293
  options,
269
294
  }}
270
295
  >
271
- <MockComp />
296
+ <StartFormatContext.Provider value={{ format }}>
297
+ <MockComp />
298
+ </StartFormatContext.Provider>
272
299
  </PlayerOptionsContext.Provider>
273
300
  </StorybookControlsContext.Provider>
274
301
  </SuspenseSpinner>