@storybook/addon-interactions 6.4.0-beta.32 → 6.4.0-rc.10

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.
Files changed (59) hide show
  1. package/dist/cjs/Panel.js +83 -110
  2. package/dist/cjs/Panel.stories.js +23 -9
  3. package/dist/cjs/components/AccountForm/addon-interactions.stories.js +207 -155
  4. package/dist/cjs/components/Interaction/Interaction.js +16 -15
  5. package/dist/cjs/components/Interaction/Interaction.stories.js +9 -3
  6. package/dist/cjs/components/Subnav/Subnav.js +15 -20
  7. package/dist/cjs/components/Subnav/Subnav.stories.js +54 -16
  8. package/dist/cjs/mocks/index.js +4 -3
  9. package/dist/esm/Panel.js +84 -109
  10. package/dist/esm/Panel.stories.js +20 -9
  11. package/dist/esm/components/AccountForm/addon-interactions.stories.js +203 -154
  12. package/dist/esm/components/Interaction/Interaction.js +16 -15
  13. package/dist/esm/components/Interaction/Interaction.stories.js +6 -3
  14. package/dist/esm/components/Subnav/Subnav.js +15 -20
  15. package/dist/esm/components/Subnav/Subnav.stories.js +49 -13
  16. package/dist/esm/mocks/index.js +4 -3
  17. package/dist/modern/Panel.js +58 -80
  18. package/dist/modern/Panel.stories.js +19 -9
  19. package/dist/modern/components/AccountForm/addon-interactions.stories.js +19 -0
  20. package/dist/modern/components/Interaction/Interaction.js +14 -15
  21. package/dist/modern/components/Interaction/Interaction.stories.js +6 -3
  22. package/dist/modern/components/Subnav/Subnav.js +15 -20
  23. package/dist/modern/components/Subnav/Subnav.stories.js +49 -13
  24. package/dist/modern/mocks/index.js +4 -3
  25. package/dist/ts3.4/Panel.d.ts +29 -0
  26. package/dist/ts3.4/Tool.d.ts +2 -0
  27. package/dist/ts3.4/components/AccountForm/AccountForm.d.ts +15 -0
  28. package/dist/ts3.4/components/Interaction/Interaction.d.ts +9 -0
  29. package/dist/ts3.4/components/List.d.ts +14 -0
  30. package/dist/ts3.4/components/MatcherResult.d.ts +12 -0
  31. package/dist/ts3.4/components/MethodCall.d.ts +55 -0
  32. package/dist/ts3.4/components/StatusBadge/StatusBadge.d.ts +6 -0
  33. package/dist/ts3.4/components/StatusIcon/StatusIcon.d.ts +7 -0
  34. package/dist/ts3.4/components/Subnav/Subnav.d.ts +12 -0
  35. package/dist/ts3.4/constants.d.ts +3 -0
  36. package/dist/ts3.4/index.d.ts +2 -0
  37. package/dist/ts3.4/mocks/index.d.ts +2 -0
  38. package/dist/ts3.4/preset/argsEnhancers.d.ts +3 -0
  39. package/dist/ts3.4/preset/checkActionsLoaded.d.ts +1 -0
  40. package/dist/ts3.4/register.d.ts +1 -0
  41. package/dist/ts3.4/theme.d.ts +14 -0
  42. package/dist/ts3.9/Panel.d.ts +29 -0
  43. package/dist/ts3.9/Tool.d.ts +2 -0
  44. package/dist/ts3.9/components/AccountForm/AccountForm.d.ts +15 -0
  45. package/dist/ts3.9/components/Interaction/Interaction.d.ts +9 -0
  46. package/dist/ts3.9/components/List.d.ts +14 -0
  47. package/dist/ts3.9/components/MatcherResult.d.ts +12 -0
  48. package/dist/ts3.9/components/MethodCall.d.ts +55 -0
  49. package/dist/ts3.9/components/StatusBadge/StatusBadge.d.ts +6 -0
  50. package/dist/ts3.9/components/StatusIcon/StatusIcon.d.ts +7 -0
  51. package/dist/ts3.9/components/Subnav/Subnav.d.ts +12 -0
  52. package/dist/ts3.9/constants.d.ts +3 -0
  53. package/dist/ts3.9/index.d.ts +2 -0
  54. package/dist/ts3.9/mocks/index.d.ts +2 -0
  55. package/dist/ts3.9/preset/argsEnhancers.d.ts +3 -0
  56. package/dist/ts3.9/preset/checkActionsLoaded.d.ts +1 -0
  57. package/dist/ts3.9/register.d.ts +1 -0
  58. package/dist/ts3.9/theme.d.ts +14 -0
  59. package/package.json +11 -11
@@ -49,7 +49,7 @@ var RowContainer = styled('div', {
49
49
  borderBottom: "1px solid ".concat(theme.appBorderColor),
50
50
  fontFamily: typography.fonts.base,
51
51
  fontSize: 13
52
- }, call.state === CallStates.ERROR && {
52
+ }, call.status === CallStates.ERROR && {
53
53
  backgroundColor: theme.base === 'dark' ? transparentize(0.93, theme.color.negative) : theme.background.warning
54
54
  });
55
55
  });
@@ -71,17 +71,17 @@ var RowLabel = styled('button', {
71
71
  margin: 0,
72
72
  padding: '8px 15px',
73
73
  textAlign: 'start',
74
- cursor: disabled || call.state === CallStates.ERROR ? 'default' : 'pointer',
75
- '&:hover': {
74
+ cursor: disabled || call.status === CallStates.ERROR ? 'default' : 'pointer',
75
+ '&:hover': disabled ? {} : {
76
76
  background: theme.background.hoverable
77
77
  },
78
78
  '&:focus-visible': {
79
79
  outline: 0,
80
- boxShadow: "inset 3px 0 0 0 ".concat(call.state === CallStates.ERROR ? theme.color.warning : theme.color.secondary),
81
- background: call.state === CallStates.ERROR ? 'transparent' : theme.background.hoverable
80
+ boxShadow: "inset 3px 0 0 0 ".concat(call.status === CallStates.ERROR ? theme.color.warning : theme.color.secondary),
81
+ background: call.status === CallStates.ERROR ? 'transparent' : theme.background.hoverable
82
82
  },
83
83
  '& > div': {
84
- opacity: call.state === CallStates.WAITING ? 0.5 : 1
84
+ opacity: call.status === CallStates.WAITING ? 0.5 : 1
85
85
  }
86
86
  };
87
87
  });
@@ -93,9 +93,8 @@ var RowMessage = styled('pre')({
93
93
  export var Interaction = function Interaction(_ref3) {
94
94
  var call = _ref3.call,
95
95
  callsById = _ref3.callsById,
96
- onClick = _ref3.onClick,
97
- isDisabled = _ref3.isDisabled,
98
- isDebuggingEnabled = _ref3.isDebuggingEnabled;
96
+ controls = _ref3.controls,
97
+ controlStates = _ref3.controlStates;
99
98
 
100
99
  var _React$useState = React.useState(false),
101
100
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -106,16 +105,18 @@ export var Interaction = function Interaction(_ref3) {
106
105
  call: call
107
106
  }, /*#__PURE__*/React.createElement(RowLabel, {
108
107
  call: call,
109
- onClick: onClick,
110
- disabled: isDebuggingEnabled ? isDisabled : true,
108
+ onClick: function onClick() {
109
+ return controls.goto(call.id);
110
+ },
111
+ disabled: !controlStates.goto,
111
112
  onMouseEnter: function onMouseEnter() {
112
- return isDebuggingEnabled && setIsHovered(true);
113
+ return controlStates.goto && setIsHovered(true);
113
114
  },
114
115
  onMouseLeave: function onMouseLeave() {
115
- return isDebuggingEnabled && setIsHovered(false);
116
+ return controlStates.goto && setIsHovered(false);
116
117
  }
117
118
  }, /*#__PURE__*/React.createElement(StatusIcon, {
118
- status: isHovered ? CallStates.ACTIVE : call.state
119
+ status: isHovered ? CallStates.ACTIVE : call.status
119
120
  }), /*#__PURE__*/React.createElement(MethodCallWrapper, {
120
121
  style: {
121
122
  marginLeft: 6,
@@ -124,5 +125,5 @@ export var Interaction = function Interaction(_ref3) {
124
125
  }, /*#__PURE__*/React.createElement(MethodCall, {
125
126
  call: call,
126
127
  callsById: callsById
127
- }))), call.state === CallStates.ERROR && call.exception && (call.exception.message.startsWith('expect(') ? /*#__PURE__*/React.createElement(MatcherResult, call.exception) : /*#__PURE__*/React.createElement(RowMessage, null, call.exception.message)));
128
+ }))), call.status === CallStates.ERROR && call.exception && (call.exception.message.startsWith('expect(') ? /*#__PURE__*/React.createElement(MatcherResult, call.exception) : /*#__PURE__*/React.createElement(RowMessage, null, call.exception.message)));
128
129
  };
@@ -16,13 +16,14 @@ import { CallStates } from '@storybook/instrumenter';
16
16
  import { userEvent, within } from '@storybook/testing-library';
17
17
  import { getCall } from '../../mocks';
18
18
  import { Interaction } from './Interaction';
19
+ import SubnavStories from '../Subnav/Subnav.stories';
19
20
  export default {
20
21
  title: 'Addons/Interactions/Interaction',
21
22
  component: Interaction,
22
23
  args: {
23
24
  callsById: new Map(),
24
- isDisabled: false,
25
- isDebuggingEnabled: true
25
+ controls: SubnavStories.args.controls,
26
+ controlStates: SubnavStories.args.controlStates
26
27
  }
27
28
  };
28
29
  export var Active = {
@@ -47,7 +48,9 @@ export var Done = {
47
48
  };
48
49
  export var Disabled = {
49
50
  args: Object.assign({}, Done.args, {
50
- isDisabled: true
51
+ controlStates: Object.assign({}, SubnavStories.args.controlStates, {
52
+ goto: false
53
+ })
51
54
  })
52
55
  };
53
56
  export var Hovered = Object.assign({}, Done, {
@@ -84,15 +84,10 @@ var withTooltipModifiers = [{
84
84
  }
85
85
  }];
86
86
  export var Subnav = function Subnav(_ref6) {
87
- var isDisabled = _ref6.isDisabled,
88
- hasNext = _ref6.hasNext,
89
- hasPrevious = _ref6.hasPrevious,
90
- storyFileName = _ref6.storyFileName,
87
+ var controls = _ref6.controls,
88
+ controlStates = _ref6.controlStates,
91
89
  status = _ref6.status,
92
- onStart = _ref6.onStart,
93
- onPrevious = _ref6.onPrevious,
94
- onNext = _ref6.onNext,
95
- onEnd = _ref6.onEnd,
90
+ storyFileName = _ref6.storyFileName,
96
91
  onScrollToEnd = _ref6.onScrollToEnd;
97
92
  var buttonText = status === CallStates.ERROR ? 'Scroll to error' : 'Scroll to end';
98
93
  return /*#__PURE__*/React.createElement(Bar, null, /*#__PURE__*/React.createElement(StyledSubnav, null, /*#__PURE__*/React.createElement(Group, null, /*#__PURE__*/React.createElement(StatusBadge, {
@@ -103,49 +98,49 @@ export var Subnav = function Subnav(_ref6) {
103
98
  }, buttonText), /*#__PURE__*/React.createElement(StyledSeparator, null), /*#__PURE__*/React.createElement(WithTooltip, {
104
99
  modifiers: withTooltipModifiers,
105
100
  hasChrome: false,
106
- trigger: hasPrevious ? 'hover' : 'none',
101
+ trigger: controlStates.start ? 'hover' : 'none',
107
102
  tooltip: /*#__PURE__*/React.createElement(Note, {
108
103
  note: "Go to start"
109
104
  })
110
105
  }, /*#__PURE__*/React.createElement(RewindButton, {
111
- onClick: onStart,
112
- disabled: isDisabled || !hasPrevious
106
+ onClick: controls.start,
107
+ disabled: !controlStates.start
113
108
  }, /*#__PURE__*/React.createElement(Icons, {
114
109
  icon: "rewind"
115
110
  }))), /*#__PURE__*/React.createElement(WithTooltip, {
116
111
  modifiers: withTooltipModifiers,
117
112
  hasChrome: false,
118
- trigger: hasPrevious ? 'hover' : 'none',
113
+ trigger: controlStates.back ? 'hover' : 'none',
119
114
  tooltip: /*#__PURE__*/React.createElement(Note, {
120
115
  note: "Go back"
121
116
  })
122
117
  }, /*#__PURE__*/React.createElement(StyledIconButton, {
123
- onClick: onPrevious,
124
- disabled: isDisabled || !hasPrevious
118
+ onClick: controls.back,
119
+ disabled: !controlStates.back
125
120
  }, /*#__PURE__*/React.createElement(Icons, {
126
121
  icon: "playback"
127
122
  }))), /*#__PURE__*/React.createElement(WithTooltip, {
128
123
  modifiers: withTooltipModifiers,
129
124
  hasChrome: false,
130
- trigger: hasNext ? 'hover' : 'none',
125
+ trigger: controlStates.next ? 'hover' : 'none',
131
126
  tooltip: /*#__PURE__*/React.createElement(Note, {
132
127
  note: "Go forward"
133
128
  })
134
129
  }, /*#__PURE__*/React.createElement(StyledIconButton, {
135
- onClick: onNext,
136
- disabled: isDisabled || !hasNext
130
+ onClick: controls.next,
131
+ disabled: !controlStates.next
137
132
  }, /*#__PURE__*/React.createElement(Icons, {
138
133
  icon: "playnext"
139
134
  }))), /*#__PURE__*/React.createElement(WithTooltip, {
140
135
  modifiers: withTooltipModifiers,
141
- trigger: hasNext ? 'hover' : 'none',
136
+ trigger: controlStates.end ? 'hover' : 'none',
142
137
  hasChrome: false,
143
138
  tooltip: /*#__PURE__*/React.createElement(Note, {
144
139
  note: "Go to end"
145
140
  })
146
141
  }, /*#__PURE__*/React.createElement(StyledIconButton, {
147
- onClick: onEnd,
148
- disabled: isDisabled || !hasNext
142
+ onClick: controls.end,
143
+ disabled: !controlStates.end
149
144
  }, /*#__PURE__*/React.createElement(Icons, {
150
145
  icon: "fastforward"
151
146
  })))), storyFileName && /*#__PURE__*/React.createElement(Group, null, /*#__PURE__*/React.createElement(StyledLocation, null, storyFileName))));
@@ -1,14 +1,25 @@
1
+ import { action } from '@storybook/addon-actions';
1
2
  import { CallStates } from '@storybook/instrumenter';
2
3
  import { Subnav } from './Subnav';
3
4
  export default {
4
5
  title: 'Addons/Interactions/Subnav',
5
6
  component: Subnav,
6
7
  args: {
7
- onPrevious: function onPrevious() {},
8
- onNext: function onNext() {},
9
- onReplay: function onReplay() {},
10
- goToStart: function goToStart() {},
11
- goToEnd: function goToEnd() {},
8
+ controls: {
9
+ start: action('start'),
10
+ back: action('back'),
11
+ goto: action('goto'),
12
+ next: action('next'),
13
+ end: action('end')
14
+ },
15
+ controlStates: {
16
+ debugger: true,
17
+ start: true,
18
+ back: true,
19
+ goto: true,
20
+ next: false,
21
+ end: false
22
+ },
12
23
  storyFileName: 'Subnav.stories.tsx',
13
24
  hasNext: true,
14
25
  hasPrevious: true
@@ -29,17 +40,42 @@ export var Runs = {
29
40
  status: CallStates.WAITING
30
41
  }
31
42
  };
32
- export var AtTheBeginning = {
33
- name: 'at the beginning',
43
+ export var AtStart = {
34
44
  args: {
35
- status: CallStates.DONE,
36
- hasPrevious: false
45
+ status: CallStates.WAITING,
46
+ controlStates: {
47
+ debugger: true,
48
+ start: false,
49
+ back: false,
50
+ goto: true,
51
+ next: true,
52
+ end: true
53
+ }
37
54
  }
38
55
  };
39
- export var AtTheEnd = {
40
- name: 'at the end',
56
+ export var Midway = {
41
57
  args: {
42
- status: CallStates.DONE,
43
- hasNext: false
58
+ status: CallStates.WAITING,
59
+ controlStates: {
60
+ debugger: true,
61
+ start: true,
62
+ back: true,
63
+ goto: true,
64
+ next: true,
65
+ end: true
66
+ }
67
+ }
68
+ };
69
+ export var Locked = {
70
+ args: {
71
+ status: CallStates.ACTIVE,
72
+ controlStates: {
73
+ debugger: true,
74
+ start: false,
75
+ back: false,
76
+ goto: false,
77
+ next: false,
78
+ end: false
79
+ }
44
80
  }
45
81
  };
@@ -1,8 +1,9 @@
1
1
  import "core-js/modules/es.object.assign.js";
2
2
  import { CallStates } from '@storybook/instrumenter';
3
- export var getCall = function getCall(state) {
3
+ export var getCall = function getCall(status) {
4
4
  var defaultData = {
5
5
  id: 'addons-interactions-accountform--standard-email-filled [3] change',
6
+ cursor: 0,
6
7
  path: ['fireEvent'],
7
8
  method: 'change',
8
9
  storyId: 'addons-interactions-accountform--standard-email-filled',
@@ -16,11 +17,11 @@ export var getCall = function getCall(state) {
16
17
  }],
17
18
  interceptable: true,
18
19
  retain: false,
19
- state: state
20
+ status: status
20
21
  };
21
22
  var overrides = CallStates.ERROR ? {
22
23
  exception: {
23
- callId: '',
24
+ name: 'Error',
24
25
  stack: '',
25
26
  message: "Things didn't work!"
26
27
  }
@@ -5,7 +5,7 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
5
5
  import global from 'global';
6
6
  import * as React from 'react';
7
7
  import ReactDOM from 'react-dom';
8
- import { useChannel, useParameter, useStorybookState } from '@storybook/api';
8
+ import { useChannel, useParameter } from '@storybook/api';
9
9
  import { STORY_RENDER_PHASE_CHANGED } from '@storybook/core-events';
10
10
  import { AddonPanel, Link, Placeholder } from '@storybook/components';
11
11
  import { EVENTS, CallStates } from '@storybook/instrumenter';
@@ -13,11 +13,14 @@ import { styled } from '@storybook/theming';
13
13
  import { StatusIcon } from './components/StatusIcon/StatusIcon';
14
14
  import { Subnav } from './components/Subnav/Subnav';
15
15
  import { Interaction } from './components/Interaction/Interaction';
16
- const {
17
- FEATURES
18
- } = global;
19
- const pendingStates = [CallStates.ACTIVE, CallStates.WAITING];
20
- const completedStates = [CallStates.DONE, CallStates.ERROR];
16
+ const INITIAL_CONTROL_STATES = {
17
+ debugger: false,
18
+ start: false,
19
+ back: false,
20
+ goto: false,
21
+ next: false,
22
+ end: false
23
+ };
21
24
  const TabIcon = styled(StatusIcon)({
22
25
  marginLeft: 5
23
26
  });
@@ -31,44 +34,31 @@ const TabStatus = ({
31
34
 
32
35
  export const AddonPanelPure = /*#__PURE__*/React.memo((_ref) => {
33
36
  let {
37
+ calls,
38
+ controls,
39
+ controlStates,
34
40
  interactions,
35
- isDisabled,
36
- hasPrevious,
37
- hasNext,
38
41
  fileName,
39
42
  hasException,
40
43
  isPlaying,
41
- onStart,
42
- onPrevious,
43
- onNext,
44
- onEnd,
45
44
  onScrollToEnd,
46
- calls,
47
- onInteractionClick,
48
- endRef,
49
- isDebuggingEnabled
45
+ endRef
50
46
  } = _ref,
51
- panelProps = _objectWithoutPropertiesLoose(_ref, ["interactions", "isDisabled", "hasPrevious", "hasNext", "fileName", "hasException", "isPlaying", "onStart", "onPrevious", "onNext", "onEnd", "onScrollToEnd", "calls", "onInteractionClick", "endRef", "isDebuggingEnabled"]);
47
+ panelProps = _objectWithoutPropertiesLoose(_ref, ["calls", "controls", "controlStates", "interactions", "fileName", "hasException", "isPlaying", "onScrollToEnd", "endRef"]);
52
48
 
53
- return /*#__PURE__*/React.createElement(AddonPanel, panelProps, isDebuggingEnabled && interactions.length > 0 && /*#__PURE__*/React.createElement(Subnav, {
54
- isDisabled: isDisabled,
55
- hasPrevious: hasPrevious,
56
- hasNext: hasNext,
57
- storyFileName: fileName,
49
+ return /*#__PURE__*/React.createElement(AddonPanel, panelProps, controlStates.debugger && interactions.length > 0 && /*#__PURE__*/React.createElement(Subnav, {
50
+ controls: controls,
51
+ controlStates: controlStates,
58
52
  status: // eslint-disable-next-line no-nested-ternary
59
53
  isPlaying ? CallStates.ACTIVE : hasException ? CallStates.ERROR : CallStates.DONE,
60
- onStart: onStart,
61
- onPrevious: onPrevious,
62
- onNext: onNext,
63
- onEnd: onEnd,
54
+ storyFileName: fileName,
64
55
  onScrollToEnd: onScrollToEnd
65
56
  }), interactions.map(call => /*#__PURE__*/React.createElement(Interaction, {
66
57
  key: call.id,
67
58
  call: call,
68
59
  callsById: calls,
69
- isDebuggingEnabled: isDebuggingEnabled,
70
- isDisabled: isDisabled,
71
- onClick: () => onInteractionClick(call.id)
60
+ controls: controls,
61
+ controlStates: controlStates
72
62
  })), /*#__PURE__*/React.createElement("div", {
73
63
  ref: endRef
74
64
  }), !isPlaying && interactions.length === 0 && /*#__PURE__*/React.createElement(Placeholder, null, "No interactions found", /*#__PURE__*/React.createElement(Link, {
@@ -78,13 +68,15 @@ export const AddonPanelPure = /*#__PURE__*/React.memo((_ref) => {
78
68
  }, "Learn how to add interactions to your story")));
79
69
  });
80
70
  export const Panel = props => {
81
- const [isLocked, setLock] = React.useState(false);
82
- const [isPlaying, setPlaying] = React.useState(true);
83
- const [scrollTarget, setScrollTarget] = React.useState();
71
+ const [storyId, setStoryId] = React.useState();
72
+ const [controlStates, setControlStates] = React.useState(INITIAL_CONTROL_STATES);
73
+ const [isPlaying, setPlaying] = React.useState(false);
74
+ const [scrollTarget, setScrollTarget] = React.useState(); // Calls are tracked in a ref so we don't needlessly rerender.
75
+
84
76
  const calls = React.useRef(new Map());
85
77
 
86
78
  const setCall = (_ref2) => {
87
- let call = _objectWithoutPropertiesLoose(_ref2, ["state"]);
79
+ let call = _objectWithoutPropertiesLoose(_ref2, ["status"]);
88
80
 
89
81
  return calls.current.set(call.id, call);
90
82
  };
@@ -92,9 +84,9 @@ export const Panel = props => {
92
84
  const [log, setLog] = React.useState([]);
93
85
  const interactions = log.map(({
94
86
  callId,
95
- state
87
+ status
96
88
  }) => Object.assign({}, calls.current.get(callId), {
97
- state
89
+ status
98
90
  }));
99
91
  const endRef = React.useRef();
100
92
  React.useEffect(() => {
@@ -106,18 +98,33 @@ export const Panel = props => {
106
98
  }, []);
107
99
  const emit = useChannel({
108
100
  [EVENTS.CALL]: setCall,
109
- [EVENTS.SYNC]: setLog,
110
- [EVENTS.LOCK]: setLock,
111
- [STORY_RENDER_PHASE_CHANGED]: ({
112
- newPhase
113
- }) => {
114
- setLock(false);
115
- setPlaying(newPhase === 'playing');
101
+ [EVENTS.SYNC]: payload => {
102
+ setControlStates(payload.controlStates);
103
+ setLog(payload.logItems);
104
+ },
105
+ [STORY_RENDER_PHASE_CHANGED]: event => {
106
+ setStoryId(event.storyId);
107
+ setPlaying(event.newPhase === 'playing');
116
108
  }
117
- });
118
- const {
119
- storyId
120
- } = useStorybookState();
109
+ }, []);
110
+ const controls = React.useMemo(() => ({
111
+ start: () => emit(EVENTS.START, {
112
+ storyId
113
+ }),
114
+ back: () => emit(EVENTS.BACK, {
115
+ storyId
116
+ }),
117
+ goto: callId => emit(EVENTS.GOTO, {
118
+ storyId,
119
+ callId
120
+ }),
121
+ next: () => emit(EVENTS.NEXT, {
122
+ storyId
123
+ }),
124
+ end: () => emit(EVENTS.END, {
125
+ storyId
126
+ })
127
+ }), [storyId]);
121
128
  const storyFilePath = useParameter('fileName', '');
122
129
  const [fileName] = storyFilePath.toString().split('/').slice(-1);
123
130
 
@@ -126,50 +133,21 @@ export const Panel = props => {
126
133
  block: 'end'
127
134
  });
128
135
 
129
- const isDebuggingEnabled = FEATURES.interactionsDebugger === true;
130
136
  const showStatus = log.length > 0 && !isPlaying;
131
- const isDebugging = log.some(item => pendingStates.includes(item.state));
132
- const hasPrevious = log.some(item => completedStates.includes(item.state));
133
- const hasNext = log.some(item => item.state === CallStates.WAITING);
134
- const hasActive = log.some(item => item.state === CallStates.ACTIVE);
135
- const hasException = log.some(item => item.state === CallStates.ERROR);
136
- const isDisabled = isDebuggingEnabled ? hasActive || isLocked || isPlaying && !isDebugging : true;
137
- const onStart = React.useCallback(() => emit(EVENTS.START, {
138
- storyId
139
- }), [storyId]);
140
- const onPrevious = React.useCallback(() => emit(EVENTS.BACK, {
141
- storyId
142
- }), [storyId]);
143
- const onNext = React.useCallback(() => emit(EVENTS.NEXT, {
144
- storyId
145
- }), [storyId]);
146
- const onEnd = React.useCallback(() => emit(EVENTS.END, {
147
- storyId
148
- }), [storyId]);
149
- const onInteractionClick = React.useCallback(callId => emit(EVENTS.GOTO, {
150
- storyId,
151
- callId
152
- }), [storyId]);
137
+ const hasException = log.some(item => item.status === CallStates.ERROR);
153
138
  return /*#__PURE__*/React.createElement(React.Fragment, {
154
139
  key: "interactions"
155
140
  }, /*#__PURE__*/React.createElement(TabStatus, null, showStatus && (hasException ? /*#__PURE__*/React.createElement(TabIcon, {
156
141
  status: CallStates.ERROR
157
142
  }) : ` (${interactions.length})`)), /*#__PURE__*/React.createElement(AddonPanelPure, _extends({
143
+ calls: calls.current,
144
+ controls: controls,
145
+ controlStates: controlStates,
158
146
  interactions: interactions,
159
- isDisabled: isDisabled,
160
- hasPrevious: hasPrevious,
161
- hasNext: hasNext,
162
147
  fileName: fileName,
163
148
  hasException: hasException,
164
149
  isPlaying: isPlaying,
165
- calls: calls.current,
166
150
  endRef: endRef,
167
- isDebuggingEnabled: isDebuggingEnabled,
168
- onStart: onStart,
169
- onPrevious: onPrevious,
170
- onNext: onNext,
171
- onEnd: onEnd,
172
- onInteractionClick: onInteractionClick,
173
151
  onScrollToEnd: scrollTarget && scrollToTarget
174
152
  }, props)));
175
153
  };
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
+ import { action } from '@storybook/addon-actions';
2
3
  import { CallStates } from '@storybook/instrumenter';
3
4
  import { styled } from '@storybook/theming';
4
5
  import { getCall } from './mocks';
5
6
  import { AddonPanelPure } from './Panel';
7
+ import SubnavStories from './components/Subnav/Subnav.stories';
6
8
  const StyledWrapper = styled.div(({
7
9
  theme
8
10
  }) => ({
@@ -27,16 +29,14 @@ export default {
27
29
  },
28
30
  args: {
29
31
  calls: new Map(),
30
- endRef: null,
32
+ controls: SubnavStories.args.controls,
33
+ controlStates: SubnavStories.args.controlStates,
34
+ interactions: [getCall(CallStates.DONE)],
31
35
  fileName: 'addon-interactions.stories.tsx',
32
36
  hasException: false,
33
- hasNext: false,
34
- hasPrevious: true,
35
- interactions: [getCall(CallStates.DONE)],
36
- isDisabled: false,
37
37
  isPlaying: false,
38
- showTabIcon: false,
39
- isDebuggingEnabled: true,
38
+ onScrollToEnd: action('onScrollToEnd'),
39
+ endRef: null,
40
40
  // prop for the AddonPanel used as wrapper of Panel
41
41
  active: true
42
42
  }
@@ -49,7 +49,15 @@ export const Passing = {
49
49
  export const Paused = {
50
50
  args: {
51
51
  isPlaying: true,
52
- interactions: [getCall(CallStates.WAITING)]
52
+ interactions: [getCall(CallStates.WAITING)],
53
+ controlStates: {
54
+ debugger: true,
55
+ start: false,
56
+ back: false,
57
+ goto: true,
58
+ next: true,
59
+ end: true
60
+ }
53
61
  }
54
62
  };
55
63
  export const Playing = {
@@ -66,7 +74,9 @@ export const Failed = {
66
74
  };
67
75
  export const WithDebuggingDisabled = {
68
76
  args: {
69
- isDebuggingEnabled: false
77
+ controlStates: Object.assign({}, SubnavStories.args.controlStates, {
78
+ debugger: false
79
+ })
70
80
  }
71
81
  };
72
82
  export const NoInteractions = {
@@ -31,6 +31,24 @@ Demo.play = async ({
31
31
  await expect(args.onSubmit).toHaveBeenCalledWith(expect.stringMatching(/([A-Z])\w+/gi));
32
32
  };
33
33
 
34
+ export const FindBy = args => {
35
+ const [isLoading, setIsLoading] = React.useState(true);
36
+ React.useEffect(() => {
37
+ setTimeout(() => setIsLoading(false), 500);
38
+ }, []);
39
+ return isLoading ? /*#__PURE__*/React.createElement("div", null, "Loading...") : /*#__PURE__*/React.createElement("button", {
40
+ type: "button"
41
+ }, "Loaded!");
42
+ };
43
+
44
+ FindBy.play = async ({
45
+ canvasElement
46
+ }) => {
47
+ const canvas = within(canvasElement);
48
+ await canvas.findByRole('button');
49
+ await expect(true).toBe(true);
50
+ };
51
+
34
52
  export const WaitFor = args => /*#__PURE__*/React.createElement("button", {
35
53
  type: "button",
36
54
  onClick: () => setTimeout(() => args.onSubmit('clicked'), 100)
@@ -43,6 +61,7 @@ WaitFor.play = async ({
43
61
  await userEvent.click(await within(canvasElement).findByText('Click'));
44
62
  await waitFor(async () => {
45
63
  await expect(args.onSubmit).toHaveBeenCalledWith(expect.stringMatching(/([A-Z])\w+/gi));
64
+ await expect(true).toBe(true);
46
65
  });
47
66
  };
48
67
 
@@ -20,7 +20,7 @@ const RowContainer = styled('div', {
20
20
  borderBottom: `1px solid ${theme.appBorderColor}`,
21
21
  fontFamily: typography.fonts.base,
22
22
  fontSize: 13
23
- }, call.state === CallStates.ERROR && {
23
+ }, call.status === CallStates.ERROR && {
24
24
  backgroundColor: theme.base === 'dark' ? transparentize(0.93, theme.color.negative) : theme.background.warning
25
25
  }));
26
26
  const RowLabel = styled('button', {
@@ -39,17 +39,17 @@ const RowLabel = styled('button', {
39
39
  margin: 0,
40
40
  padding: '8px 15px',
41
41
  textAlign: 'start',
42
- cursor: disabled || call.state === CallStates.ERROR ? 'default' : 'pointer',
43
- '&:hover': {
42
+ cursor: disabled || call.status === CallStates.ERROR ? 'default' : 'pointer',
43
+ '&:hover': disabled ? {} : {
44
44
  background: theme.background.hoverable
45
45
  },
46
46
  '&:focus-visible': {
47
47
  outline: 0,
48
- boxShadow: `inset 3px 0 0 0 ${call.state === CallStates.ERROR ? theme.color.warning : theme.color.secondary}`,
49
- background: call.state === CallStates.ERROR ? 'transparent' : theme.background.hoverable
48
+ boxShadow: `inset 3px 0 0 0 ${call.status === CallStates.ERROR ? theme.color.warning : theme.color.secondary}`,
49
+ background: call.status === CallStates.ERROR ? 'transparent' : theme.background.hoverable
50
50
  },
51
51
  '& > div': {
52
- opacity: call.state === CallStates.WAITING ? 0.5 : 1
52
+ opacity: call.status === CallStates.WAITING ? 0.5 : 1
53
53
  }
54
54
  }));
55
55
  const RowMessage = styled('pre')({
@@ -60,21 +60,20 @@ const RowMessage = styled('pre')({
60
60
  export const Interaction = ({
61
61
  call,
62
62
  callsById,
63
- onClick,
64
- isDisabled,
65
- isDebuggingEnabled
63
+ controls,
64
+ controlStates
66
65
  }) => {
67
66
  const [isHovered, setIsHovered] = React.useState(false);
68
67
  return /*#__PURE__*/React.createElement(RowContainer, {
69
68
  call: call
70
69
  }, /*#__PURE__*/React.createElement(RowLabel, {
71
70
  call: call,
72
- onClick: onClick,
73
- disabled: isDebuggingEnabled ? isDisabled : true,
74
- onMouseEnter: () => isDebuggingEnabled && setIsHovered(true),
75
- onMouseLeave: () => isDebuggingEnabled && setIsHovered(false)
71
+ onClick: () => controls.goto(call.id),
72
+ disabled: !controlStates.goto,
73
+ onMouseEnter: () => controlStates.goto && setIsHovered(true),
74
+ onMouseLeave: () => controlStates.goto && setIsHovered(false)
76
75
  }, /*#__PURE__*/React.createElement(StatusIcon, {
77
- status: isHovered ? CallStates.ACTIVE : call.state
76
+ status: isHovered ? CallStates.ACTIVE : call.status
78
77
  }), /*#__PURE__*/React.createElement(MethodCallWrapper, {
79
78
  style: {
80
79
  marginLeft: 6,
@@ -83,5 +82,5 @@ export const Interaction = ({
83
82
  }, /*#__PURE__*/React.createElement(MethodCall, {
84
83
  call: call,
85
84
  callsById: callsById
86
- }))), call.state === CallStates.ERROR && call.exception && (call.exception.message.startsWith('expect(') ? /*#__PURE__*/React.createElement(MatcherResult, call.exception) : /*#__PURE__*/React.createElement(RowMessage, null, call.exception.message)));
85
+ }))), call.status === CallStates.ERROR && call.exception && (call.exception.message.startsWith('expect(') ? /*#__PURE__*/React.createElement(MatcherResult, call.exception) : /*#__PURE__*/React.createElement(RowMessage, null, call.exception.message)));
87
86
  };