@micromag/viewer 0.2.409 → 0.3.0

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/es/index.js CHANGED
@@ -1,49 +1,314 @@
1
1
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
2
2
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
3
- import React, { useRef, useCallback, useMemo, useState, useEffect } from 'react';
4
3
  import PropTypes from 'prop-types';
4
+ import React, { useEffect, useState, useCallback, useRef, useMemo } from 'react';
5
5
  import { Switch, Route, MemoryRouter } from 'react-router';
6
6
  import { BrowserRouter } from 'react-router-dom';
7
- import { ScreensProvider } from '@micromag/screens';
8
- import { IntlProvider } from '@micromag/intl';
9
- import fieldsManager from '@micromag/fields/manager';
10
7
  import { PropTypes as PropTypes$1 } from '@micromag/core';
11
- import { ScreenSizeProvider, ViewerProvider, useRoutes, useRoutePush, GoogleKeysProvider, GoogleMapsClientProvider, FieldsProvider, UserInteractionProvider, TrackingProvider, RoutesProvider } from '@micromag/core/contexts';
8
+ import { ScreenSizeProvider, ViewerProvider, useRoutes, useRoutePush, GoogleKeysProvider, GoogleMapsClientProvider, FieldsProvider, ComponentsProvider, SCREENS_NAMESPACE, UserInteractionProvider, TrackingProvider, RoutesProvider } from '@micromag/core/contexts';
9
+ import fieldsManager from '@micromag/fields/manager';
10
+ import { IntlProvider } from '@micromag/intl';
11
+ import { ScreensProvider } from '@micromag/screens';
12
12
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
13
13
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
14
14
  import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
15
+ import classNames from 'classnames';
16
+ import { Helmet } from 'react-helmet';
17
+ import { useIntl, FormattedMessage } from 'react-intl';
15
18
  import { Button, ScreenPreview, Screen, Meta, FontFaces } from '@micromag/core/components';
16
- import { useDocumentEvent, useParsedStory, useLoadedFonts, useTrackScreenView, useTrackEvent, useScreenSizeFromElement, useResizeObserver, useFullscreen } from '@micromag/core/hooks';
19
+ import { useDocumentEvent, useResizeObserver, useTrackEvent, useParsedStory, useLoadedFonts, useTrackScreenView, useScreenSizeFromElement, useFullscreen } from '@micromag/core/hooks';
17
20
  import { getStyleFromColor, getStyleFromText, getDeviceScreens } from '@micromag/core/utils';
18
21
  import { useSpring, config } from '@react-spring/core';
19
22
  import { animated } from '@react-spring/web';
20
23
  import { useDrag } from '@use-gesture/react';
21
- import classNames from 'classnames';
22
- import { Helmet } from 'react-helmet';
23
- import { useIntl, FormattedMessage } from 'react-intl';
24
24
  import { faTimes, faShare, faCompress, faExpand } from '@fortawesome/free-solid-svg-icons';
25
25
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
26
26
  import Scroll from '@micromag/element-scroll';
27
27
  import { FacebookShareButton, FacebookIcon, TwitterShareButton, TwitterIcon, EmailShareButton, EmailIcon } from 'react-share';
28
+ import EventEmitter from 'wolfy87-eventemitter';
29
+
30
+ var home = "/";
31
+ var screen = "/:screen";
32
+ var defaultRoutes = {
33
+ home: home,
34
+ screen: screen
35
+ };
28
36
 
29
37
  var routes = PropTypes.shape({
30
38
  home: PropTypes.string.isRequired,
31
39
  screen: PropTypes.string.isRequired
32
40
  });
33
41
 
34
- var styles$6 = {"container":"micromag-viewer-container","menuPreview":"micromag-viewer-menuPreview","menuPreviewContainer":"micromag-viewer-menuPreviewContainer","screen":"micromag-viewer-screen","screenInner":"micromag-viewer-screenInner","content":"micromag-viewer-content","menuDotsContainer":"micromag-viewer-menuDotsContainer","menuDots":"micromag-viewer-menuDots","current":"micromag-viewer-current","landscape":"micromag-viewer-landscape","hideMenu":"micromag-viewer-hideMenu","ready":"micromag-viewer-ready"};
42
+ function useKeyboardShortcuts() {
43
+ var shortcuts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
44
+
45
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
46
+ _ref$disabled = _ref.disabled,
47
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
48
+
49
+ useEffect(function () {
50
+ var onKey = function onKey(e) {
51
+ if (['input', 'textarea'].reduce(function (foundMatch, match) {
52
+ return foundMatch || e.target.matches(match);
53
+ }, false)) {
54
+ return;
55
+ }
56
+
57
+ var key = e.key;
58
+ var lowercaseKey = key.toLowerCase();
59
+
60
+ if (typeof shortcuts[lowercaseKey] !== 'undefined') {
61
+ shortcuts[lowercaseKey]();
62
+ }
63
+ };
64
+
65
+ if (!disabled) {
66
+ window.addEventListener('keydown', onKey);
67
+ }
68
+
69
+ return function () {
70
+ if (!disabled) {
71
+ window.removeEventListener('keydown', onKey);
72
+ }
73
+ };
74
+ }, [disabled]);
75
+ }
76
+
77
+ function checkClickable(el) {
78
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
79
+ var distance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
80
+
81
+ var _ref = options || {},
82
+ _ref$maxDistance = _ref.maxDistance,
83
+ maxDistance = _ref$maxDistance === void 0 ? 5 : _ref$maxDistance,
84
+ _ref$tags = _ref.tags,
85
+ tags = _ref$tags === void 0 ? ['BUTTON', 'A', 'INPUT', 'TEXTAREA'] : _ref$tags;
86
+
87
+ var _ref2 = el || {},
88
+ _ref2$tagName = _ref2.tagName,
89
+ tagName = _ref2$tagName === void 0 ? null : _ref2$tagName,
90
+ _ref2$parentNode = _ref2.parentNode,
91
+ parentNode = _ref2$parentNode === void 0 ? null : _ref2$parentNode;
92
+
93
+ if (tagName === 'BODY') {
94
+ return false;
95
+ }
96
+
97
+ if (tags.map(function (it) {
98
+ return it.toLowerCase();
99
+ }).indexOf(tagName.toLowerCase()) > -1) {
100
+ return true;
101
+ }
102
+
103
+ if (distance < maxDistance) {
104
+ return checkClickable(parentNode, options, distance + 1);
105
+ }
106
+
107
+ return false;
108
+ }
109
+
110
+ function useScreenInteraction() {
111
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
112
+ screens = _ref.screens,
113
+ screenId = _ref.screenId,
114
+ screenWidth = _ref.screenWidth,
115
+ _ref$isView = _ref.isView,
116
+ isView = _ref$isView === void 0 ? false : _ref$isView,
117
+ _ref$clickOnSiblings = _ref.clickOnSiblings,
118
+ clickOnSiblings = _ref$clickOnSiblings === void 0 ? false : _ref$clickOnSiblings,
119
+ _ref$nextScreenWidthP = _ref.nextScreenWidthPercent,
120
+ nextScreenWidthPercent = _ref$nextScreenWidthP === void 0 ? 0.5 : _ref$nextScreenWidthP,
121
+ _ref$eventsManager = _ref.eventsManager,
122
+ eventsManager = _ref$eventsManager === void 0 ? null : _ref$eventsManager,
123
+ _ref$onClick = _ref.onClick,
124
+ onClick = _ref$onClick === void 0 ? null : _ref$onClick,
125
+ _ref$onEnd = _ref.onEnd,
126
+ onEnd = _ref$onEnd === void 0 ? null : _ref$onEnd,
127
+ _ref$onChangeScreen = _ref.onChangeScreen,
128
+ onChangeScreen = _ref$onChangeScreen === void 0 ? null : _ref$onChangeScreen;
129
+
130
+ var _useState = useState(screens.reduce(function (map, _ref2) {
131
+ var id = _ref2.id;
132
+ return _objectSpread(_objectSpread({}, map), {}, _defineProperty({}, id, true));
133
+ }, {})),
134
+ _useState2 = _slicedToArray(_useState, 2),
135
+ screensInteractionEnabled = _useState2[0],
136
+ setScreensInteractionEnabled = _useState2[1];
137
+
138
+ var screenIndex = screens.findIndex(function (_ref3) {
139
+ var id = _ref3.id;
140
+ return id === screenId;
141
+ });
142
+ var _screensInteractionEn = screensInteractionEnabled[screenId],
143
+ currentScreenInteractionEnabled = _screensInteractionEn === void 0 ? true : _screensInteractionEn;
144
+ var updateInteraction = useCallback(function (newValue) {
145
+ var _screensInteractionEn2 = screensInteractionEnabled[screenId],
146
+ currentValue = _screensInteractionEn2 === void 0 ? true : _screensInteractionEn2;
147
+
148
+ if (currentValue !== newValue) {
149
+ setScreensInteractionEnabled(screens.reduce(function (map, _ref4) {
150
+ var id = _ref4.id;
151
+ return screenId === id ? _objectSpread(_objectSpread({}, map), {}, _defineProperty({}, id, newValue)) : _objectSpread(_objectSpread({}, map), {}, _defineProperty({}, id, typeof screensInteractionEnabled[id] === 'undefined' || screensInteractionEnabled[id] === true));
152
+ }, {}));
153
+ }
154
+ }, [screens, screenId, screensInteractionEnabled, setScreensInteractionEnabled]);
155
+ var enableInteraction = useCallback(function () {
156
+ return updateInteraction(true);
157
+ }, [updateInteraction]);
158
+ var disableInteraction = useCallback(function () {
159
+ return updateInteraction(false);
160
+ }, [updateInteraction]);
161
+ var onScreenClick = useCallback(function (e, index) {
162
+ if (onClick !== null) {
163
+ onClick(e, index);
164
+ }
165
+
166
+ var screensCount = screens.length;
167
+ var tappedCurrent = screenIndex === index;
168
+ eventsManager.emit('tap', e, index);
169
+
170
+ if (!isView && tappedCurrent || checkClickable(e.target) || tappedCurrent && !currentScreenInteractionEnabled) {
171
+ return;
172
+ }
173
+
174
+ var nextIndex = screenIndex;
175
+
176
+ var _e$currentTarget$getB = e.currentTarget.getBoundingClientRect(),
177
+ _e$currentTarget$getB2 = _e$currentTarget$getB.left,
178
+ contentX = _e$currentTarget$getB2 === void 0 ? 0 : _e$currentTarget$getB2;
179
+
180
+ var tapX = e.clientX;
181
+ var hasTappedLeft = tappedCurrent ? tapX - contentX < screenWidth * (1 - nextScreenWidthPercent) : screenIndex > index;
182
+
183
+ if (hasTappedLeft) {
184
+ nextIndex = clickOnSiblings ? index : Math.max(0, screenIndex - 1);
185
+ eventsManager.emit('tap_previous', nextIndex);
186
+ } else {
187
+ nextIndex = clickOnSiblings ? index : Math.min(screensCount - 1, screenIndex + 1);
188
+ var isLastScreen = screenIndex === screensCount - 1;
189
+
190
+ if (isLastScreen && onEnd !== null) {
191
+ eventsManager.emit('tap_end');
192
+ onEnd();
193
+ } else {
194
+ eventsManager.emit('tap_next', nextIndex);
195
+ }
196
+ }
197
+
198
+ eventsManager.emit('change_screen', nextIndex);
199
+ onChangeScreen(nextIndex);
200
+ }, [screenWidth, screens, screenIndex, eventsManager, onClick, onEnd, onChangeScreen, screenIndex, screensInteractionEnabled, currentScreenInteractionEnabled, nextScreenWidthPercent, isView, clickOnSiblings]);
201
+ return {
202
+ onClick: onScreenClick,
203
+ currentScreenInteractionEnabled: currentScreenInteractionEnabled,
204
+ enableInteraction: enableInteraction,
205
+ disableInteraction: disableInteraction
206
+ };
207
+ }
208
+
209
+ var styles$7 = {"container":"micromag-viewer-container","menuPreview":"micromag-viewer-menuPreview","menuPreviewContainer":"micromag-viewer-menuPreviewContainer","screen":"micromag-viewer-screen","screenInner":"micromag-viewer-screenInner","content":"micromag-viewer-content","menuDotsContainer":"micromag-viewer-menuDotsContainer","menuDots":"micromag-viewer-menuDots","current":"micromag-viewer-current","landscape":"micromag-viewer-landscape","visible":"micromag-viewer-visible","withSibblings":"micromag-viewer-withSibblings","hideMenu":"micromag-viewer-hideMenu","ready":"micromag-viewer-ready"};
210
+
211
+ var styles$6 = {"container":"micromag-viewer-menus-menu-dots-container","closeButton":"micromag-viewer-menus-menu-dots-closeButton","menuButton":"micromag-viewer-menus-menu-dots-menuButton","item":"micromag-viewer-menus-menu-dots-item","items":"micromag-viewer-menus-menu-dots-items","menu":"micromag-viewer-menus-menu-dots-menu","menuIcon":"micromag-viewer-menus-menu-dots-menuIcon","vertical":"micromag-viewer-menus-menu-dots-vertical","withShadow":"micromag-viewer-menus-menu-dots-withShadow"};
212
+
213
+ var styles$5 = {"container":"micromag-viewer-menus-menu-dot-container","button":"micromag-viewer-menus-menu-dot-button","dot":"micromag-viewer-menus-menu-dot-dot","vertical":"micromag-viewer-menus-menu-dot-vertical"};
214
+
215
+ var propTypes$a = {
216
+ current: PropTypes.bool,
217
+ active: PropTypes.bool,
218
+ colors: PropTypes.shape({
219
+ primary: PropTypes.string,
220
+ secondary: PropTypes.string
221
+ }),
222
+ vertical: PropTypes.bool,
223
+ onClick: PropTypes.func,
224
+ className: PropTypes.string
225
+ };
226
+ var defaultProps$a = {
227
+ current: false,
228
+ active: false,
229
+ colors: null,
230
+ vertical: false,
231
+ onClick: null,
232
+ className: null
233
+ };
234
+
235
+ var ViewerMenuDot = function ViewerMenuDot(_ref) {
236
+ var _ref3;
237
+
238
+ var current = _ref.current,
239
+ active = _ref.active,
240
+ colors = _ref.colors,
241
+ vertical = _ref.vertical,
242
+ onClick = _ref.onClick,
243
+ className = _ref.className;
244
+ var currentTime = 0;
245
+ var duration = 1;
246
+ var playing = true;
247
+
248
+ var _ref2 = colors || {},
249
+ _ref2$primary = _ref2.primary,
250
+ primary = _ref2$primary === void 0 ? 'rgba(255, 255, 255, 1)' : _ref2$primary,
251
+ _ref2$secondary = _ref2.secondary,
252
+ secondary = _ref2$secondary === void 0 ? 'rgba(200, 200, 200, 0.5)' : _ref2$secondary; // TODO: if approved animate progress
253
+
254
+
255
+ var _useSpring = useSpring(function () {
256
+ return {
257
+ x: 0,
258
+ config: {
259
+ duration: 0
260
+ }
261
+ };
262
+ }),
263
+ _useSpring2 = _slicedToArray(_useSpring, 2);
264
+ _useSpring2[0];
265
+ var setSpringProps = _useSpring2[1];
266
+
267
+ useEffect(function () {
268
+
269
+ var progress = currentTime / duration;
270
+ setSpringProps.start({
271
+ reset: true,
272
+ immediate: !playing,
273
+ from: {
274
+ x: progress
275
+ },
276
+ to: {
277
+ x: 1
278
+ },
279
+ config: {
280
+ duration: (duration - currentTime) * 1000
281
+ }
282
+ });
283
+ }, [playing, duration, currentTime, setSpringProps]);
284
+ return /*#__PURE__*/React.createElement("li", {
285
+ className: classNames([styles$5.container, (_ref3 = {}, _defineProperty(_ref3, styles$5.active, current), _defineProperty(_ref3, styles$5.vertical, vertical), _defineProperty(_ref3, className, className !== null), _ref3)]),
286
+ "aria-hidden": "true"
287
+ }, /*#__PURE__*/React.createElement("button", {
288
+ type: "button",
289
+ className: styles$5.button,
290
+ onClick: onClick,
291
+ tabIndex: "-1"
292
+ }, /*#__PURE__*/React.createElement("span", {
293
+ className: styles$5.dot,
294
+ style: {
295
+ backgroundColor: active ? primary : secondary
296
+ }
297
+ })));
298
+ };
35
299
 
36
- var styles$5 = {"container":"micromag-viewer-menus-menu-dots-container","closeButton":"micromag-viewer-menus-menu-dots-closeButton","item":"micromag-viewer-menus-menu-dots-item","button":"micromag-viewer-menus-menu-dots-button","menuButton":"micromag-viewer-menus-menu-dots-menuButton","items":"micromag-viewer-menus-menu-dots-items","dot":"micromag-viewer-menus-menu-dots-dot","menu":"micromag-viewer-menus-menu-dots-menu","menuIcon":"micromag-viewer-menus-menu-dots-menuIcon","vertical":"micromag-viewer-menus-menu-dots-vertical","withShadow":"micromag-viewer-menus-menu-dots-withShadow"};
300
+ ViewerMenuDot.propTypes = propTypes$a;
301
+ ViewerMenuDot.defaultProps = defaultProps$a;
37
302
 
38
303
  var styles$4 = {};
39
304
 
40
- var propTypes$8 = {
305
+ var propTypes$9 = {
41
306
  size: PropTypes.number,
42
307
  spacing: PropTypes.number,
43
308
  color: PropTypes.string,
44
309
  className: PropTypes.string
45
310
  };
46
- var defaultProps$8 = {
311
+ var defaultProps$9 = {
47
312
  size: 100,
48
313
  spacing: 8,
49
314
  color: 'white',
@@ -75,57 +340,66 @@ var MenuIcon = function MenuIcon(_ref) {
75
340
  }));
76
341
  };
77
342
 
78
- MenuIcon.propTypes = propTypes$8;
79
- MenuIcon.defaultProps = defaultProps$8;
343
+ MenuIcon.propTypes = propTypes$9;
344
+ MenuIcon.defaultProps = defaultProps$9;
80
345
 
81
- var propTypes$7 = {
346
+ var propTypes$8 = {
82
347
  direction: PropTypes.oneOf(['horizontal', 'vertical']),
83
348
  withShadow: PropTypes.bool,
84
349
  items: PropTypes$1.menuItems,
85
- current: PropTypes.number,
86
350
  onClickItem: PropTypes.func,
351
+ onClickMenu: PropTypes.func,
87
352
  colors: PropTypes.shape({
88
353
  primary: PropTypes.string,
89
354
  secondary: PropTypes.string
90
355
  }),
91
356
  closeable: PropTypes.bool,
357
+ withItemClick: PropTypes.bool,
358
+ withoutScreensMenu: PropTypes.bool,
92
359
  onClose: PropTypes.func,
93
360
  className: PropTypes.string
94
361
  };
95
- var defaultProps$7 = {
362
+ var defaultProps$8 = {
96
363
  direction: 'horizontal',
97
364
  withShadow: false,
98
365
  items: [],
99
- current: 0,
100
366
  onClickItem: null,
367
+ onClickMenu: null,
101
368
  colors: null,
102
369
  closeable: false,
370
+ withItemClick: false,
371
+ withoutScreensMenu: false,
103
372
  onClose: null,
104
373
  className: null
105
374
  };
106
375
 
107
376
  var ViewerMenuDots = function ViewerMenuDots(_ref) {
108
- var _ref3;
377
+ var _ref4;
109
378
 
110
379
  var direction = _ref.direction,
111
380
  withShadow = _ref.withShadow,
112
381
  items = _ref.items,
113
- current = _ref.current,
114
382
  onClickItem = _ref.onClickItem,
383
+ onClickMenu = _ref.onClickMenu,
115
384
  colors = _ref.colors,
116
385
  closeable = _ref.closeable,
386
+ withItemClick = _ref.withItemClick,
387
+ withoutScreensMenu = _ref.withoutScreensMenu,
117
388
  onClose = _ref.onClose,
118
389
  className = _ref.className;
119
390
 
120
391
  var _ref2 = colors || {},
121
392
  _ref2$primary = _ref2.primary,
122
- primary = _ref2$primary === void 0 ? 'rgba(255, 255, 255, 1)' : _ref2$primary,
123
- _ref2$secondary = _ref2.secondary,
124
- secondary = _ref2$secondary === void 0 ? 'rgba(200, 200, 200, 0.5)' : _ref2$secondary;
393
+ primary = _ref2$primary === void 0 ? 'rgba(255, 255, 255, 1)' : _ref2$primary;
125
394
 
126
395
  var intl = useIntl();
396
+ var currentIndex = items.findIndex(function (_ref3) {
397
+ var _ref3$current = _ref3.current,
398
+ current = _ref3$current === void 0 ? false : _ref3$current;
399
+ return current;
400
+ });
127
401
  return /*#__PURE__*/React.createElement("nav", {
128
- className: classNames([styles$5.container, (_ref3 = {}, _defineProperty(_ref3, className, className !== null), _defineProperty(_ref3, styles$5.vertical, direction === 'vertical'), _defineProperty(_ref3, styles$5.withShadow, withShadow), _ref3)]),
402
+ className: classNames([styles$6.container, (_ref4 = {}, _defineProperty(_ref4, className, className !== null), _defineProperty(_ref4, styles$6.vertical, direction === 'vertical'), _defineProperty(_ref4, styles$6.withShadow, withShadow), _ref4)]),
129
403
  "aria-label": intl.formatMessage({
130
404
  id: "bLYuuN",
131
405
  defaultMessage: [{
@@ -145,35 +419,32 @@ var ViewerMenuDots = function ViewerMenuDots(_ref) {
145
419
  "value": "."
146
420
  }]
147
421
  }, {
148
- current: current + 1,
422
+ current: currentIndex + 1,
149
423
  total: items.length
150
424
  })
151
425
  }, /*#__PURE__*/React.createElement("ul", {
152
- className: styles$5.items
426
+ className: styles$6.items
153
427
  }, items.map(function (item, index) {
154
- return /*#__PURE__*/React.createElement("li", {
155
- className: classNames([styles$5.item, _defineProperty({}, styles$5.active, current === index)]),
156
- key: "item-".concat(index),
157
- "aria-hidden": "true"
158
- }, /*#__PURE__*/React.createElement("button", {
159
- type: "button",
160
- className: styles$5.button,
428
+ var _item$current = item.current,
429
+ current = _item$current === void 0 ? false : _item$current;
430
+ return /*#__PURE__*/React.createElement(ViewerMenuDot, {
431
+ key: "item-".concat(index + 1),
432
+ current: current,
433
+ active: index <= currentIndex,
434
+ colors: colors,
161
435
  onClick: function onClick() {
162
- if (onClickItem !== null) {
163
- onClickItem(index);
436
+ if ((withItemClick || withoutScreensMenu) && onClickItem !== null) {
437
+ onClickItem(item);
438
+ } else if (!withItemClick && onClickMenu !== null) {
439
+ onClickMenu();
164
440
  }
165
441
  },
166
- tabIndex: "-1"
167
- }, /*#__PURE__*/React.createElement("span", {
168
- className: styles$5.dot,
169
- style: {
170
- backgroundColor: index <= current ? primary : secondary
171
- }
172
- })));
173
- }), /*#__PURE__*/React.createElement("li", {
174
- className: styles$5.menu
442
+ vertical: direction === 'vertical'
443
+ });
444
+ }), !withoutScreensMenu ? /*#__PURE__*/React.createElement("li", {
445
+ className: styles$6.menu
175
446
  }, /*#__PURE__*/React.createElement(MenuIcon, {
176
- className: styles$5.menuIcon,
447
+ className: styles$6.menuIcon,
177
448
  color: primary
178
449
  }), /*#__PURE__*/React.createElement("button", {
179
450
  type: "button",
@@ -191,20 +462,16 @@ var ViewerMenuDots = function ViewerMenuDots(_ref) {
191
462
  "value": "Menu"
192
463
  }]
193
464
  }),
194
- className: styles$5.menuButton,
195
- onClick: function onClick() {
196
- if (onClickItem !== null) {
197
- onClickItem(null);
198
- }
199
- }
200
- })), closeable ? /*#__PURE__*/React.createElement("li", {
201
- className: styles$5.closeButton,
465
+ className: styles$6.menuButton,
466
+ onClick: onClickMenu
467
+ })) : null, closeable ? /*#__PURE__*/React.createElement("li", {
468
+ className: styles$6.closeButton,
202
469
  style: {
203
470
  color: primary
204
471
  }
205
472
  }, /*#__PURE__*/React.createElement("button", {
206
473
  type: "button",
207
- className: styles$5.closeButton,
474
+ className: styles$6.closeButton,
208
475
  onClick: onClose,
209
476
  title: intl.formatMessage({
210
477
  id: "dj/p/q",
@@ -225,14 +492,14 @@ var ViewerMenuDots = function ViewerMenuDots(_ref) {
225
492
  }))) : null));
226
493
  };
227
494
 
228
- ViewerMenuDots.propTypes = propTypes$7;
229
- ViewerMenuDots.defaultProps = defaultProps$7;
495
+ ViewerMenuDots.propTypes = propTypes$8;
496
+ ViewerMenuDots.defaultProps = defaultProps$8;
230
497
 
231
- var styles$3 = {"container":"micromag-viewer-menus-menu-preview-container","screenButton":"micromag-viewer-menus-menu-preview-screenButton","activeScreenBorder":"micromag-viewer-menus-menu-preview-activeScreenBorder","itemContent":"micromag-viewer-menus-menu-preview-itemContent","scroll":"micromag-viewer-menus-menu-preview-scroll","header":"micromag-viewer-menus-menu-preview-header","button":"micromag-viewer-menus-menu-preview-button","shareButton":"micromag-viewer-menus-menu-preview-shareButton","disabled":"micromag-viewer-menus-menu-preview-disabled","icon":"micromag-viewer-menus-menu-preview-icon","buttons":"micromag-viewer-menus-menu-preview-buttons","organisation":"micromag-viewer-menus-menu-preview-organisation","title":"micromag-viewer-menus-menu-preview-title","content":"micromag-viewer-menus-menu-preview-content","nav":"micromag-viewer-menus-menu-preview-nav","item":"micromag-viewer-menus-menu-preview-item","items":"micromag-viewer-menus-menu-preview-items","active":"micromag-viewer-menus-menu-preview-active","screenContainer":"micromag-viewer-menus-menu-preview-screenContainer","screenContent":"micromag-viewer-menus-menu-preview-screenContent"};
498
+ var styles$3 = {"container":"micromag-viewer-menus-menu-preview-container","screenButton":"micromag-viewer-menus-menu-preview-screenButton","activeScreenBorder":"micromag-viewer-menus-menu-preview-activeScreenBorder","scroll":"micromag-viewer-menus-menu-preview-scroll","header":"micromag-viewer-menus-menu-preview-header","button":"micromag-viewer-menus-menu-preview-button","shareButton":"micromag-viewer-menus-menu-preview-shareButton","disabled":"micromag-viewer-menus-menu-preview-disabled","icon":"micromag-viewer-menus-menu-preview-icon","buttons":"micromag-viewer-menus-menu-preview-buttons","organisation":"micromag-viewer-menus-menu-preview-organisation","title":"micromag-viewer-menus-menu-preview-title","content":"micromag-viewer-menus-menu-preview-content","nav":"micromag-viewer-menus-menu-preview-nav","item":"micromag-viewer-menus-menu-preview-item","items":"micromag-viewer-menus-menu-preview-items","active":"micromag-viewer-menus-menu-preview-active","itemContent":"micromag-viewer-menus-menu-preview-itemContent","screenContainer":"micromag-viewer-menus-menu-preview-screenContainer","screenContent":"micromag-viewer-menus-menu-preview-screenContent"};
232
499
 
233
500
  var styles$2 = {"container":"micromag-viewer-partials-share-modal-container","content":"micromag-viewer-partials-share-modal-content","opened":"micromag-viewer-partials-share-modal-opened"};
234
501
 
235
- var propTypes$6 = {
502
+ var propTypes$7 = {
236
503
  url: PropTypes.string,
237
504
  title: PropTypes.string,
238
505
  opened: PropTypes.bool,
@@ -240,7 +507,7 @@ var propTypes$6 = {
240
507
  onShare: PropTypes.func,
241
508
  onCancel: PropTypes.func
242
509
  };
243
- var defaultProps$6 = {
510
+ var defaultProps$7 = {
244
511
  url: null,
245
512
  title: null,
246
513
  opened: false,
@@ -324,12 +591,12 @@ var ShareModal = function ShareModal(_ref) {
324
591
  }), /*#__PURE__*/React.createElement(EmailIcon, shareIconProps)))));
325
592
  };
326
593
 
327
- ShareModal.propTypes = propTypes$6;
328
- ShareModal.defaultProps = defaultProps$6;
594
+ ShareModal.propTypes = propTypes$7;
595
+ ShareModal.defaultProps = defaultProps$7;
329
596
 
330
597
  var styles$1 = {"container":"micromag-viewer-partials-share-button-container","shareModal":"micromag-viewer-partials-share-button-shareModal"};
331
598
 
332
- var propTypes$5 = {
599
+ var propTypes$6 = {
333
600
  title: PropTypes.string,
334
601
  url: PropTypes.string,
335
602
  className: PropTypes.string,
@@ -338,7 +605,7 @@ var propTypes$5 = {
338
605
  children: PropTypes.node,
339
606
  focusable: PropTypes.bool
340
607
  };
341
- var defaultProps$5 = {
608
+ var defaultProps$6 = {
342
609
  title: null,
343
610
  url: null,
344
611
  className: null,
@@ -408,16 +675,16 @@ var ShareButton = function ShareButton(_ref) {
408
675
  }));
409
676
  };
410
677
 
411
- ShareButton.propTypes = propTypes$5;
412
- ShareButton.defaultProps = defaultProps$5;
678
+ ShareButton.propTypes = propTypes$6;
679
+ ShareButton.defaultProps = defaultProps$6;
413
680
 
414
- var propTypes$4 = {
681
+ var propTypes$5 = {
415
682
  viewerTheme: PropTypes$1.viewerTheme,
416
- screenWidth: PropTypes.number,
683
+ screenSize: PropTypes$1.screenSize,
684
+ menuWidth: PropTypes.number,
417
685
  title: PropTypes.string,
418
686
  shareUrl: PropTypes.string,
419
687
  items: PropTypes$1.menuItems,
420
- current: PropTypes.number,
421
688
  focusable: PropTypes.bool,
422
689
  onClickItem: PropTypes.func,
423
690
  onClose: PropTypes.func,
@@ -428,13 +695,13 @@ var propTypes$4 = {
428
695
  fullscreenEnabled: PropTypes.bool,
429
696
  className: PropTypes.string
430
697
  };
431
- var defaultProps$4 = {
698
+ var defaultProps$5 = {
432
699
  viewerTheme: null,
433
- screenWidth: null,
700
+ screenSize: null,
701
+ menuWidth: null,
434
702
  title: null,
435
703
  shareUrl: null,
436
704
  items: [],
437
- current: 0,
438
705
  focusable: true,
439
706
  onClickItem: null,
440
707
  onClose: null,
@@ -446,13 +713,13 @@ var defaultProps$4 = {
446
713
  className: null
447
714
  };
448
715
 
449
- function ViewerMenuPreview(_ref) {
716
+ var ViewerMenuPreview = function ViewerMenuPreview(_ref) {
450
717
  var viewerTheme = _ref.viewerTheme,
451
- screenWidth = _ref.screenWidth,
718
+ screenSize = _ref.screenSize,
719
+ menuWidth = _ref.menuWidth,
452
720
  title = _ref.title,
453
721
  shareUrl = _ref.shareUrl,
454
722
  items = _ref.items,
455
- current = _ref.current,
456
723
  focusable = _ref.focusable,
457
724
  onClickItem = _ref.onClickItem,
458
725
  onClose = _ref.onClose,
@@ -463,82 +730,74 @@ function ViewerMenuPreview(_ref) {
463
730
  fullscreenEnabled = _ref.fullscreenEnabled,
464
731
  className = _ref.className;
465
732
  var intl = useIntl();
466
- var screenSizeRatio = "".concat(3 / 2 / thumbsPerLine * 100, "%");
467
- var screenRatioHeight = screenWidth * 3 / 2;
468
- var hasSize = screenWidth > 0;
469
- var hasItems = items !== null && items.length > 0;
470
-
471
- var _useState = useState(null),
472
- _useState2 = _slicedToArray(_useState, 2),
473
- thumbSize = _useState2[0],
474
- setThumbSize = _useState2[1];
475
-
476
- var firstScreenContainerRef = useRef(null);
477
- useEffect(function () {
478
- if (hasItems && hasSize && firstScreenContainerRef.current !== null) {
479
- var _firstScreenContainer = firstScreenContainerRef.current,
480
- offsetWidth = _firstScreenContainer.offsetWidth,
481
- offsetHeight = _firstScreenContainer.offsetHeight;
482
- setThumbSize({
483
- width: offsetWidth,
484
- height: offsetHeight
485
- });
486
- }
487
- }, [screenWidth, hasItems, hasSize]); // Viewer theme
488
-
489
- var _ref2 = viewerTheme || {},
490
- _ref2$colors = _ref2.colors,
491
- colors = _ref2$colors === void 0 ? null : _ref2$colors,
492
- _ref2$background = _ref2.background,
493
- background = _ref2$background === void 0 ? null : _ref2$background,
494
- _ref2$textStyles = _ref2.textStyles,
495
- textStyles = _ref2$textStyles === void 0 ? null : _ref2$textStyles,
496
- _ref2$logo = _ref2.logo,
497
- brandLogo = _ref2$logo === void 0 ? null : _ref2$logo;
498
-
499
- var _ref3 = textStyles || {},
500
- _ref3$title = _ref3.title,
501
- brandTextStyle = _ref3$title === void 0 ? null : _ref3$title;
502
-
503
- var _ref4 = colors || {},
504
- _ref4$primary = _ref4.primary,
505
- brandPrimaryColor = _ref4$primary === void 0 ? null : _ref4$primary,
506
- _ref4$secondary = _ref4.secondary,
507
- brandSecondaryColor = _ref4$secondary === void 0 ? null : _ref4$secondary;
508
733
 
509
- var _ref5 = background || {},
510
- _ref5$color = _ref5.color,
511
- brandBackgroundColor = _ref5$color === void 0 ? null : _ref5$color,
512
- _ref5$image = _ref5.image,
513
- image = _ref5$image === void 0 ? null : _ref5$image;
734
+ var _ref2 = screenSize || {},
735
+ screenWidth = _ref2.width,
736
+ screenHeight = _ref2.height;
514
737
 
515
- var _ref6 = image || {},
516
- _ref6$url = _ref6.url,
517
- brandImageUrl = _ref6$url === void 0 ? null : _ref6$url;
738
+ var _useResizeObserver = useResizeObserver(),
739
+ firstScreenContainerRef = _useResizeObserver.ref,
740
+ firstScreenContentRect = _useResizeObserver.entry.contentRect;
741
+
742
+ var _ref3 = firstScreenContentRect || {},
743
+ _ref3$width = _ref3.width,
744
+ thumbWidth = _ref3$width === void 0 ? 0 : _ref3$width;
745
+
746
+ var screenScale = thumbWidth / screenWidth; // Viewer theme
747
+
748
+ var _ref4 = viewerTheme || {},
749
+ _ref4$colors = _ref4.colors,
750
+ colors = _ref4$colors === void 0 ? null : _ref4$colors,
751
+ _ref4$background = _ref4.background,
752
+ background = _ref4$background === void 0 ? null : _ref4$background,
753
+ _ref4$textStyles = _ref4.textStyles,
754
+ textStyles = _ref4$textStyles === void 0 ? null : _ref4$textStyles,
755
+ _ref4$logo = _ref4.logo,
756
+ brandLogo = _ref4$logo === void 0 ? null : _ref4$logo;
757
+
758
+ var _ref5 = textStyles || {},
759
+ _ref5$title = _ref5.title,
760
+ brandTextStyle = _ref5$title === void 0 ? null : _ref5$title;
761
+
762
+ var _ref6 = colors || {},
763
+ _ref6$primary = _ref6.primary,
764
+ brandPrimaryColor = _ref6$primary === void 0 ? null : _ref6$primary,
765
+ _ref6$secondary = _ref6.secondary,
766
+ brandSecondaryColor = _ref6$secondary === void 0 ? null : _ref6$secondary;
767
+
768
+ var _ref7 = background || {},
769
+ _ref7$color = _ref7.color,
770
+ brandBackgroundColor = _ref7$color === void 0 ? null : _ref7$color,
771
+ _ref7$image = _ref7.image,
772
+ image = _ref7$image === void 0 ? null : _ref7$image;
773
+
774
+ var _ref8 = image || {},
775
+ _ref8$url = _ref8.url,
776
+ brandImageUrl = _ref8$url === void 0 ? null : _ref8$url;
518
777
 
519
778
  var borderPrimaryColorStyle = getStyleFromColor(brandPrimaryColor, 'borderColor');
520
779
  var colorSecondaryColorStyle = getStyleFromColor(brandSecondaryColor, 'color');
521
780
  var backgroundColorStyle = getStyleFromColor(brandBackgroundColor, 'backgroundColor');
522
781
 
523
- var _ref7 = brandLogo || {},
524
- _ref7$url = _ref7.url,
525
- brandLogoUrl = _ref7$url === void 0 ? null : _ref7$url;
782
+ var _ref9 = brandLogo || {},
783
+ _ref9$url = _ref9.url,
784
+ brandLogoUrl = _ref9$url === void 0 ? null : _ref9$url;
526
785
 
527
786
  var brandImageStyle = brandImageUrl !== null ? {
528
787
  backgroundImage: "url(".concat(brandImageUrl, ")")
529
788
  } : null;
530
789
  var titleStyle = brandTextStyle !== null ? getStyleFromText(brandTextStyle) : null;
531
790
 
532
- var _useState3 = useState(false),
533
- _useState4 = _slicedToArray(_useState3, 2),
534
- scrolledBottom = _useState4[0],
535
- setScrolledBottom = _useState4[1];
791
+ var _useState = useState(false),
792
+ _useState2 = _slicedToArray(_useState, 2),
793
+ scrolledBottom = _useState2[0],
794
+ setScrolledBottom = _useState2[1];
536
795
 
537
- var dragBind = useDrag(function (_ref8) {
538
- var _ref8$direction = _slicedToArray(_ref8.direction, 2),
539
- dy = _ref8$direction[1],
540
- last = _ref8.last,
541
- tap = _ref8.tap;
796
+ var dragBind = useDrag(function (_ref10) {
797
+ var _ref10$direction = _slicedToArray(_ref10.direction, 2),
798
+ dy = _ref10$direction[1],
799
+ last = _ref10.last,
800
+ tap = _ref10.tap;
542
801
 
543
802
  if (!tap && last && scrolledBottom && dy < 0 && onClose !== null) {
544
803
  onClose();
@@ -555,10 +814,10 @@ function ViewerMenuPreview(_ref) {
555
814
  var onScrolledNotBottom = useCallback(function () {
556
815
  setScrolledBottom(false);
557
816
  }, [setScrolledBottom]);
558
- return hasSize ? /*#__PURE__*/React.createElement("div", Object.assign({
817
+ return /*#__PURE__*/React.createElement("div", Object.assign({
559
818
  className: classNames([styles$3.container, _defineProperty({}, className, className !== null)]),
560
819
  style: _objectSpread(_objectSpread(_objectSpread({}, backgroundColorStyle), brandImageStyle), {}, {
561
- width: screenWidth
820
+ width: menuWidth
562
821
  }),
563
822
  "aria-hidden": focusable ? null : 'true'
564
823
  }, dragBind()), /*#__PURE__*/React.createElement("div", {
@@ -637,7 +896,10 @@ function ViewerMenuPreview(_ref) {
637
896
  }, /*#__PURE__*/React.createElement("ul", {
638
897
  className: styles$3.items
639
898
  }, items.map(function (item, index) {
640
- var screenIndexLabel = intl.formatMessage({
899
+ var _item$current = item.current,
900
+ current = _item$current === void 0 ? false : _item$current,
901
+ screen = item.screen;
902
+ var screenAriaLabel = "".concat(intl.formatMessage({
641
903
  id: "LkVfwW",
642
904
  defaultMessage: [{
643
905
  "type": 0,
@@ -648,106 +910,385 @@ function ViewerMenuPreview(_ref) {
648
910
  }]
649
911
  }, {
650
912
  index: index + 1
651
- });
652
- var isCurrentScreenLabel = current === index ? " ".concat(intl.formatMessage({
913
+ })).concat(current ? " ".concat(intl.formatMessage({
653
914
  id: "vmrJ8U",
654
915
  defaultMessage: [{
655
916
  "type": 0,
656
917
  "value": "(current screen)"
657
918
  }]
658
- })) : '';
659
- var screenAriaLabel = screenIndexLabel + isCurrentScreenLabel;
919
+ })) : '');
660
920
  return /*#__PURE__*/React.createElement("li", {
661
- className: classNames([styles$3.item, _defineProperty({}, styles$3.active, current === index)]),
921
+ className: classNames([styles$3.item, _defineProperty({}, styles$3.active, current)]),
662
922
  key: "item-".concat(index),
663
923
  style: {
664
- paddingBottom: screenSizeRatio,
665
924
  width: "".concat(100 / thumbsPerLine, "%")
666
925
  }
667
926
  }, /*#__PURE__*/React.createElement("div", {
668
927
  className: styles$3.itemContent
669
928
  }, /*#__PURE__*/React.createElement("div", {
670
929
  className: styles$3.screenContainer,
671
- ref: index === 0 ? firstScreenContainerRef : null
672
- }, /*#__PURE__*/React.createElement("div", {
930
+ ref: index === 0 ? firstScreenContainerRef : null,
931
+ style: {
932
+ height: screenHeight * screenScale
933
+ }
934
+ }, screenWidth > 0 && screenHeight > 0 ? /*#__PURE__*/React.createElement("div", {
673
935
  className: styles$3.screenContent,
674
- style: thumbSize !== null ? {
936
+ style: {
675
937
  width: screenWidth,
676
- height: screenRatioHeight,
677
- transform: "scale(".concat(thumbSize.width / screenWidth)
678
- } : null,
938
+ height: screenHeight,
939
+ transform: "scale(".concat(screenScale)
940
+ },
679
941
  "aria-hidden": "true"
680
942
  }, /*#__PURE__*/React.createElement(ScreenPreview, {
681
943
  width: screenWidth,
682
- height: screenRatioHeight,
683
- screen: item,
944
+ height: screenHeight,
945
+ screen: screen,
684
946
  focusable: false
685
- })), current === index ? /*#__PURE__*/React.createElement("div", {
947
+ })) : null, current ? /*#__PURE__*/React.createElement("div", {
686
948
  className: styles$3.activeScreenBorder,
687
949
  style: borderPrimaryColorStyle
688
950
  }) : null)), /*#__PURE__*/React.createElement("button", {
689
951
  type: "button",
690
952
  className: styles$3.screenButton,
691
953
  onClick: function onClick() {
692
- onClickItem(index);
954
+ if (onClickItem !== null) {
955
+ onClickItem(item);
956
+ }
693
957
  },
694
958
  "aria-label": screenAriaLabel,
695
959
  onKeyUp: function onKeyUp(e) {
696
- if (e.key === 'Enter') {
697
- onClickItem(index);
960
+ if (e.key === 'Enter' && onClickItem !== null) {
961
+ onClickItem(item);
698
962
  }
699
963
  },
700
964
  tabIndex: focusable ? '0' : '-1'
701
965
  }));
702
- })))))) : null;
703
- }
966
+ }))))));
967
+ };
704
968
 
705
- ViewerMenuPreview.propTypes = propTypes$4;
706
- ViewerMenuPreview.defaultProps = defaultProps$4;
969
+ ViewerMenuPreview.propTypes = propTypes$5;
970
+ ViewerMenuPreview.defaultProps = defaultProps$5;
707
971
 
708
- var styles = {"container":"micromag-viewer-screen-container","current":"micromag-viewer-screen-current"};
972
+ var propTypes$4 = {
973
+ story: PropTypes$1.story.isRequired,
974
+ currentScreenIndex: PropTypes.number,
975
+ opened: PropTypes.bool,
976
+ toggleFullscreen: PropTypes.func,
977
+ fullscreenActive: PropTypes.bool,
978
+ fullscreenEnabled: PropTypes.bool,
979
+ closeable: PropTypes.bool,
980
+ withShadow: PropTypes.bool,
981
+ trackingEnabled: PropTypes.bool,
982
+ shareBasePath: PropTypes.string,
983
+ theme: PropTypes$1.viewerTheme,
984
+ screenSize: PropTypes$1.screenSize,
985
+ menuWidth: PropTypes.number,
986
+ withDotItemClick: PropTypes.bool,
987
+ withoutScreensMenu: PropTypes.bool,
988
+ onRequestOpen: PropTypes.func,
989
+ onRequestClose: PropTypes.func,
990
+ onClickItem: PropTypes.func,
991
+ onClickMenu: PropTypes.func,
992
+ onClickCloseViewer: PropTypes.func,
993
+ refDots: PropTypes.shape({
994
+ current: PropTypes.any // eslint-disable-line
709
995
 
710
- var propTypes$3 = {
711
- screen: PropTypes$1.screenComponent,
712
- renderContext: PropTypes$1.renderContext,
713
- current: PropTypes.bool,
714
- active: PropTypes.bool,
715
- onPrevious: PropTypes.func,
716
- onNext: PropTypes.func,
717
- onEnableInteraction: PropTypes.func,
718
- onDisableInteraction: PropTypes.func,
719
- getMediaRef: PropTypes.func
996
+ })
720
997
  };
721
- var defaultProps$3 = {
722
- screen: null,
723
- renderContext: null,
724
- current: false,
725
- active: true,
726
- onPrevious: null,
727
- onNext: null,
728
- onEnableInteraction: null,
729
- onDisableInteraction: null,
730
- getMediaRef: null
998
+ var defaultProps$4 = {
999
+ currentScreenIndex: 0,
1000
+ opened: false,
1001
+ toggleFullscreen: null,
1002
+ fullscreenActive: false,
1003
+ fullscreenEnabled: false,
1004
+ closeable: false,
1005
+ withShadow: false,
1006
+ trackingEnabled: false,
1007
+ shareBasePath: null,
1008
+ theme: null,
1009
+ screenSize: null,
1010
+ menuWidth: null,
1011
+ withDotItemClick: false,
1012
+ withoutScreensMenu: false,
1013
+ onRequestOpen: null,
1014
+ onRequestClose: null,
1015
+ onClickItem: null,
1016
+ onClickMenu: null,
1017
+ onClickCloseViewer: null,
1018
+ refDots: null
731
1019
  };
732
1020
 
733
- var ViewerScreen = function ViewerScreen(_ref) {
734
- var _ref2;
735
-
736
- var screen = _ref.screen,
737
- renderContext = _ref.renderContext,
738
- active = _ref.active,
739
- current = _ref.current,
740
- onPrevious = _ref.onPrevious,
741
- onNext = _ref.onNext,
742
- onEnableInteraction = _ref.onEnableInteraction,
743
- onDisableInteraction = _ref.onDisableInteraction,
744
- getMediaRef = _ref.getMediaRef;
745
- return screen !== null ? /*#__PURE__*/React.createElement("div", {
746
- className: classNames([styles.container, (_ref2 = {}, _defineProperty(_ref2, styles.active, active), _defineProperty(_ref2, styles.current, current), _ref2)]),
747
- "aria-hidden": current ? null : 'true'
748
- }, /*#__PURE__*/React.createElement(Screen, {
1021
+ var ViewerMenu = function ViewerMenu(_ref) {
1022
+ var story = _ref.story,
1023
+ currentScreenIndex = _ref.currentScreenIndex,
1024
+ opened = _ref.opened,
1025
+ toggleFullscreen = _ref.toggleFullscreen,
1026
+ fullscreenActive = _ref.fullscreenActive,
1027
+ fullscreenEnabled = _ref.fullscreenEnabled,
1028
+ closeable = _ref.closeable,
1029
+ withShadow = _ref.withShadow,
1030
+ shareBasePath = _ref.shareBasePath,
1031
+ trackingEnabled = _ref.trackingEnabled,
1032
+ viewerTheme = _ref.theme,
1033
+ screenSize = _ref.screenSize,
1034
+ menuWidth = _ref.menuWidth,
1035
+ withDotItemClick = _ref.withDotItemClick,
1036
+ withoutScreensMenu = _ref.withoutScreensMenu,
1037
+ onRequestOpen = _ref.onRequestOpen,
1038
+ onRequestClose = _ref.onRequestClose,
1039
+ customOnClickItem = _ref.onClickItem,
1040
+ customOnClickMenu = _ref.onClickMenu,
1041
+ onClickCloseViewer = _ref.onClickCloseViewer,
1042
+ refDots = _ref.refDots;
1043
+ var _story$components = story.components,
1044
+ screens = _story$components === void 0 ? [] : _story$components,
1045
+ _story$title = story.title,
1046
+ title = _story$title === void 0 ? null : _story$title;
1047
+ var currentScreen = screens !== null ? screens[currentScreenIndex] || null : null;
1048
+
1049
+ var _ref2 = currentScreen || {},
1050
+ _ref2$id = _ref2.id,
1051
+ screenId = _ref2$id === void 0 ? null : _ref2$id,
1052
+ _ref2$type = _ref2.type,
1053
+ screenType = _ref2$type === void 0 ? null : _ref2$type;
1054
+
1055
+ var items = useMemo(function () {
1056
+ return screens.filter(function (_ref3) {
1057
+ var _ref3$parentId = _ref3.parentId,
1058
+ parentId = _ref3$parentId === void 0 ? null : _ref3$parentId;
1059
+ return parentId === null;
1060
+ }).map(function (it) {
1061
+ return {
1062
+ screen: it,
1063
+ screenId: it.id,
1064
+ current: screenId === it.id
1065
+ };
1066
+ });
1067
+ }, [screens, screenId]);
1068
+ var trackEvent = useTrackEvent();
1069
+ var trackScreenEvent = useCallback(function (cat, action, label) {
1070
+ if (trackingEnabled) {
1071
+ trackEvent(cat, action, label, {
1072
+ screenId: screenId,
1073
+ screenIndex: currentScreenIndex,
1074
+ screenType: screenType
1075
+ });
1076
+ }
1077
+ }, [trackEvent, screenId, currentScreenIndex, screenType]);
1078
+ var shareUrl = useMemo(function () {
1079
+ var origin = typeof window !== 'undefined' ? window.location.origin.replace(/\/+$/, '') : '';
1080
+ var path = shareBasePath !== null ? "".concat(origin).concat(shareBasePath) : origin;
1081
+ return path;
1082
+ }, [shareBasePath]);
1083
+
1084
+ var _useSpring = useSpring(function () {
1085
+ return {
1086
+ y: 0,
1087
+ config: _objectSpread(_objectSpread({}, config.stiff), {}, {
1088
+ clamp: true
1089
+ })
1090
+ };
1091
+ }),
1092
+ _useSpring2 = _slicedToArray(_useSpring, 2),
1093
+ menuY = _useSpring2[0].y,
1094
+ setMenuSpring = _useSpring2[1];
1095
+
1096
+ var refOpened = useRef(opened);
1097
+
1098
+ if (refOpened.current !== opened) {
1099
+ refOpened.current = opened;
1100
+ }
1101
+
1102
+ useEffect(function () {
1103
+ setMenuSpring.start({
1104
+ y: opened ? 1 : 0
1105
+ });
1106
+ }, [opened]);
1107
+
1108
+ var _useResizeObserver = useResizeObserver(),
1109
+ menuPreviewContainerRef = _useResizeObserver.ref,
1110
+ menuPreviewContainerRect = _useResizeObserver.entry.contentRect;
1111
+
1112
+ var _ref4 = menuPreviewContainerRect || {},
1113
+ _ref4$height = _ref4.height,
1114
+ menuPreviewContainerHeight = _ref4$height === void 0 ? 0 : _ref4$height;
1115
+
1116
+ var menuPreviewStyle = {
1117
+ transform: menuY.to(function (y) {
1118
+ return "translateY(".concat(y * menuPreviewContainerHeight, "px)");
1119
+ })
1120
+ };
1121
+ var menuDragBind = useDrag(function (_ref5) {
1122
+ var _ref5$movement = _slicedToArray(_ref5.movement, 2),
1123
+ my = _ref5$movement[1],
1124
+ first = _ref5.first,
1125
+ last = _ref5.last,
1126
+ _ref5$direction = _slicedToArray(_ref5.direction, 2),
1127
+ dy = _ref5$direction[1],
1128
+ cancel = _ref5.cancel,
1129
+ canceled = _ref5.canceled,
1130
+ tap = _ref5.tap;
1131
+
1132
+ if (canceled || tap) {
1133
+ return;
1134
+ }
1135
+
1136
+ var isMenuOpened = refOpened.current;
1137
+
1138
+ if (first) {
1139
+ if (isMenuOpened) {
1140
+ cancel();
1141
+ return;
1142
+ }
1143
+ }
1144
+
1145
+ var yProgress = Math.max(0, Math.min(1, my / menuPreviewContainerHeight + (isMenuOpened ? 1 : 0)));
1146
+
1147
+ if (last) {
1148
+ var menuNowOpened = dy > 0 && yProgress > 0.1;
1149
+ refOpened.current = menuNowOpened;
1150
+ setMenuSpring.start({
1151
+ y: menuNowOpened ? 1 : 0
1152
+ });
1153
+
1154
+ if (menuNowOpened && onRequestOpen !== null) {
1155
+ onRequestOpen();
1156
+ } else if (!menuNowOpened && onRequestClose !== null) {
1157
+ onRequestClose();
1158
+ }
1159
+ } else {
1160
+ setMenuSpring.start({
1161
+ y: yProgress
1162
+ });
1163
+ }
1164
+ }, {
1165
+ axis: 'y',
1166
+ filterTaps: true
1167
+ }); // handle preview menu item click
1168
+
1169
+ var onClickMenu = useCallback(function (index) {
1170
+ if (customOnClickMenu !== null) {
1171
+ customOnClickMenu(index);
1172
+ }
1173
+
1174
+ trackScreenEvent('viewer_menu', 'click_open', 'Menu icon');
1175
+ }, [customOnClickMenu, trackScreenEvent]);
1176
+ var onClickItem = useCallback(function (item) {
1177
+ if (customOnClickItem !== null) {
1178
+ customOnClickItem(item);
1179
+ }
1180
+
1181
+ var index = items.findIndex(function (_ref6) {
1182
+ var id = _ref6.id;
1183
+ return id === screenId;
1184
+ });
1185
+ trackScreenEvent('viewer_menu', 'click_screen_change', "Screen ".concat(index + 1));
1186
+ }, [customOnClickItem, items, screenId, trackScreenEvent]);
1187
+ var onClickClose = useCallback(function () {
1188
+ if (onRequestClose !== null) {
1189
+ onRequestClose();
1190
+ }
1191
+
1192
+ trackScreenEvent('viewer_menu', 'click_close', 'Close icon');
1193
+ }, [onRequestClose, trackScreenEvent]); // Handle preview menu share click
1194
+
1195
+ var onClickShare = useCallback(function (type) {
1196
+ return trackScreenEvent('viewer_menu', 'click_share', type);
1197
+ }, [trackScreenEvent]);
1198
+
1199
+ var _ref7 = viewerTheme || {},
1200
+ _ref7$menuTheme = _ref7.menuTheme,
1201
+ menuTheme = _ref7$menuTheme === void 0 ? null : _ref7$menuTheme;
1202
+
1203
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", Object.assign({
1204
+ className: styles$7.menuDotsContainer,
1205
+ ref: refDots,
1206
+ style: {
1207
+ width: menuWidth
1208
+ }
1209
+ }, menuDragBind()), /*#__PURE__*/React.createElement(ViewerMenuDots, Object.assign({}, menuTheme, {
1210
+ direction: "horizontal",
1211
+ withShadow: withShadow,
1212
+ items: items,
1213
+ onClickItem: onClickItem,
1214
+ onClickMenu: onClickMenu,
1215
+ closeable: closeable,
1216
+ withItemClick: withDotItemClick,
1217
+ withoutScreensMenu: withoutScreensMenu,
1218
+ onClose: onClickCloseViewer,
1219
+ className: styles$7.menuDots
1220
+ }))), /*#__PURE__*/React.createElement(animated.div, {
1221
+ className: styles$7.menuPreviewContainer,
1222
+ style: menuPreviewStyle,
1223
+ ref: menuPreviewContainerRef
1224
+ }, /*#__PURE__*/React.createElement(ViewerMenuPreview, {
1225
+ viewerTheme: viewerTheme,
1226
+ title: title,
1227
+ shareUrl: shareUrl,
1228
+ className: styles$7.menuPreview,
1229
+ screenSize: screenSize,
1230
+ menuWidth: menuWidth,
1231
+ focusable: opened,
1232
+ items: items,
1233
+ onClickItem: onClickItem,
1234
+ onClose: onClickClose,
1235
+ onShare: onClickShare,
1236
+ toggleFullscreen: toggleFullscreen,
1237
+ fullscreenActive: fullscreenActive,
1238
+ fullscreenEnabled: fullscreenEnabled
1239
+ })));
1240
+ };
1241
+
1242
+ ViewerMenu.propTypes = propTypes$4;
1243
+ ViewerMenu.defaultProps = defaultProps$4;
1244
+
1245
+ var styles = {"container":"micromag-viewer-screen-container","current":"micromag-viewer-screen-current"};
1246
+
1247
+ var propTypes$3 = {
1248
+ screen: PropTypes$1.screenComponent,
1249
+ renderContext: PropTypes$1.renderContext,
1250
+ screenState: PropTypes.string,
1251
+ current: PropTypes.bool,
1252
+ active: PropTypes.bool,
1253
+ onPrevious: PropTypes.func,
1254
+ onNext: PropTypes.func,
1255
+ onEnableInteraction: PropTypes.func,
1256
+ onDisableInteraction: PropTypes.func,
1257
+ getMediaRef: PropTypes.func
1258
+ };
1259
+ var defaultProps$3 = {
1260
+ screen: null,
1261
+ renderContext: null,
1262
+ screenState: null,
1263
+ current: false,
1264
+ active: true,
1265
+ onPrevious: null,
1266
+ onNext: null,
1267
+ onEnableInteraction: null,
1268
+ onDisableInteraction: null,
1269
+ getMediaRef: null
1270
+ };
1271
+
1272
+ var ViewerScreen = function ViewerScreen(_ref) {
1273
+ var _ref2;
1274
+
1275
+ var screen = _ref.screen,
1276
+ renderContext = _ref.renderContext,
1277
+ screenState = _ref.screenState,
1278
+ active = _ref.active,
1279
+ current = _ref.current,
1280
+ onPrevious = _ref.onPrevious,
1281
+ onNext = _ref.onNext,
1282
+ onEnableInteraction = _ref.onEnableInteraction,
1283
+ onDisableInteraction = _ref.onDisableInteraction,
1284
+ getMediaRef = _ref.getMediaRef;
1285
+ return screen !== null ? /*#__PURE__*/React.createElement("div", {
1286
+ className: classNames([styles.container, (_ref2 = {}, _defineProperty(_ref2, styles.active, active), _defineProperty(_ref2, styles.current, current), _ref2)]),
1287
+ "aria-hidden": current ? null : 'true'
1288
+ }, /*#__PURE__*/React.createElement(Screen, {
749
1289
  screen: screen,
750
1290
  renderContext: renderContext,
1291
+ screenState: screenState,
751
1292
  active: active,
752
1293
  current: current,
753
1294
  onPrevious: onPrevious,
@@ -769,6 +1310,7 @@ var propTypes$2 = {
769
1310
  width: PropTypes.number,
770
1311
  height: PropTypes.number,
771
1312
  screen: PropTypes.string,
1313
+ screenState: PropTypes.string,
772
1314
  deviceScreens: PropTypes$1.deviceScreens,
773
1315
  renderContext: PropTypes$1.renderContext,
774
1316
  onScreenChange: PropTypes.func,
@@ -778,7 +1320,9 @@ var propTypes$2 = {
778
1320
  landscapeScreenMargin: PropTypes.number,
779
1321
  withMetadata: PropTypes.bool,
780
1322
  withoutMenu: PropTypes.bool,
1323
+ withoutScreensMenu: PropTypes.bool,
781
1324
  withoutFullscreen: PropTypes.bool,
1325
+ withLandscapeSiblingsScreens: PropTypes.bool,
782
1326
  closeable: PropTypes.bool,
783
1327
  onClose: PropTypes.func,
784
1328
  onInteraction: PropTypes.func,
@@ -800,16 +1344,19 @@ var defaultProps$2 = {
800
1344
  width: null,
801
1345
  height: null,
802
1346
  screen: null,
1347
+ screenState: null,
803
1348
  deviceScreens: getDeviceScreens(),
804
1349
  renderContext: 'view',
805
1350
  onScreenChange: null,
806
- tapNextScreenWidthPercent: 0.5,
1351
+ tapNextScreenWidthPercent: 0.8,
807
1352
  neighborScreensActive: 2,
808
1353
  storyIsParsed: false,
809
- landscapeScreenMargin: 50,
1354
+ landscapeScreenMargin: 20,
810
1355
  withMetadata: false,
811
1356
  withoutMenu: false,
1357
+ withoutScreensMenu: false,
812
1358
  withoutFullscreen: false,
1359
+ withLandscapeSiblingsScreens: false,
813
1360
  closeable: false,
814
1361
  onClose: null,
815
1362
  onInteraction: null,
@@ -821,8 +1368,8 @@ var defaultProps$2 = {
821
1368
  className: null
822
1369
  };
823
1370
 
824
- function Viewer(_ref) {
825
- var _ref15;
1371
+ var Viewer = function Viewer(_ref) {
1372
+ var _ref12;
826
1373
 
827
1374
  var story = _ref.story,
828
1375
  basePath = _ref.basePath,
@@ -830,6 +1377,7 @@ function Viewer(_ref) {
830
1377
  width = _ref.width,
831
1378
  height = _ref.height,
832
1379
  screenId = _ref.screen,
1380
+ screenState = _ref.screenState,
833
1381
  deviceScreens = _ref.deviceScreens,
834
1382
  renderContext = _ref.renderContext,
835
1383
  onScreenChange = _ref.onScreenChange,
@@ -838,10 +1386,12 @@ function Viewer(_ref) {
838
1386
  storyIsParsed = _ref.storyIsParsed,
839
1387
  landscapeScreenMargin = _ref.landscapeScreenMargin,
840
1388
  withMetadata = _ref.withMetadata,
841
- withoutMenu = _ref.withoutMenu;
1389
+ withoutMenu = _ref.withoutMenu,
1390
+ withoutScreensMenu = _ref.withoutScreensMenu;
842
1391
  _ref.withoutFullscreen;
843
- var closeable = _ref.closeable,
844
- onClose = _ref.onClose,
1392
+ var withLandscapeSiblingsScreens = _ref.withLandscapeSiblingsScreens,
1393
+ closeable = _ref.closeable,
1394
+ onCloseViewer = _ref.onClose,
845
1395
  onInteraction = _ref.onInteraction,
846
1396
  onEnd = _ref.onEnd,
847
1397
  onViewModeChange = _ref.onViewModeChange,
@@ -860,7 +1410,10 @@ function Viewer(_ref) {
860
1410
  _parsedStory$metadata = parsedStory.metadata,
861
1411
  metadata = _parsedStory$metadata === void 0 ? null : _parsedStory$metadata,
862
1412
  _parsedStory$fonts = parsedStory.fonts,
863
- fonts = _parsedStory$fonts === void 0 ? null : _parsedStory$fonts; // Viewer Theme
1413
+ fonts = _parsedStory$fonts === void 0 ? null : _parsedStory$fonts;
1414
+ var eventsManager = useMemo(function () {
1415
+ return new EventEmitter();
1416
+ }, [parsedStory]); // Viewer Theme
864
1417
 
865
1418
  var _ref2 = viewerTheme || {},
866
1419
  textStyles = _ref2.textStyles;
@@ -884,17 +1437,11 @@ function Viewer(_ref) {
884
1437
  _useLoadedFonts.loaded; // eslint-disable-line
885
1438
 
886
1439
 
887
- var shareUrl = useMemo(function () {
888
- var origin = typeof window !== 'undefined' ? window.location.origin.replace(/\/+$/, '') : '';
889
- var path = basePath !== null ? "".concat(origin).concat(basePath) : origin;
890
- return path;
891
- }, [basePath]);
892
1440
  var isView = renderContext === 'view';
893
1441
  var isStatic = renderContext === 'static';
894
1442
  var isCapture = renderContext === 'capture';
895
1443
  var withoutScreensTransforms = isStatic || isCapture;
896
1444
  var trackScreenView = useTrackScreenView();
897
- var trackEvent = useTrackEvent();
898
1445
  var contentRef = useRef(null); // Get screen size
899
1446
 
900
1447
  var _useScreenSizeFromEle = useScreenSizeFromElement(_objectSpread({
@@ -924,30 +1471,12 @@ function Viewer(_ref) {
924
1471
  landscape: landscape
925
1472
  });
926
1473
  }
927
- }, [ready, landscape, onViewModeChange]); // Get dots menu height
928
-
929
- var _useResizeObserver = useResizeObserver(),
930
- menuDotsContainerRef = _useResizeObserver.ref,
931
- menuDotsContainerRect = _useResizeObserver.entry.contentRect;
932
-
933
- var _ref6 = menuDotsContainerRect || {},
934
- _ref6$height = _ref6.height,
935
- menuDotsContainerHeight = _ref6$height === void 0 ? 0 : _ref6$height; // Get preview menu height
936
-
937
-
938
- var _useResizeObserver2 = useResizeObserver(),
939
- menuPreviewContainerRef = _useResizeObserver2.ref,
940
- menuPreviewContainerRect = _useResizeObserver2.entry.contentRect;
941
-
942
- var _ref7 = menuPreviewContainerRect || {},
943
- _ref7$height = _ref7.height,
944
- menuPreviewContainerHeight = _ref7$height === void 0 ? 0 : _ref7$height;
945
-
1474
+ }, [ready, landscape, onViewModeChange]);
946
1475
  var screensMediasRef = useRef([]); // Screen index
947
1476
 
948
1477
  var screenIndex = useMemo(function () {
949
1478
  return Math.max(0, screens.findIndex(function (it) {
950
- return String(it.id) === String(screenId);
1479
+ return "".concat(it.id) === "".concat(screenId);
951
1480
  }));
952
1481
  }, [screenId, screens]);
953
1482
 
@@ -974,13 +1503,7 @@ function Viewer(_ref) {
974
1503
  }, [screenIndex, screens, onScreenChange]); // Track screen view
975
1504
 
976
1505
  var trackingEnabled = isView;
977
- var validIndex = screens.length > 0 && screenIndex < screens.length;
978
- var currentScreen = validIndex ? screens[screenIndex] : null;
979
-
980
- var _ref8 = currentScreen || {},
981
- _ref8$type = _ref8.type,
982
- screenType = _ref8$type === void 0 ? null : _ref8$type;
983
-
1506
+ var currentScreen = screens[screenIndex] || null;
984
1507
  useEffect(function () {
985
1508
  if (trackingEnabled && currentScreen !== null) {
986
1509
  trackScreenView(currentScreen, screenIndex);
@@ -988,256 +1511,69 @@ function Viewer(_ref) {
988
1511
  }, [currentScreen, trackScreenView, trackingEnabled]); // Handle interaction enable
989
1512
 
990
1513
  var currentScreenRef = useRef(null);
991
- var onScreenPrevious = useCallback(function () {
1514
+ var gotoPreviousScreen = useCallback(function () {
992
1515
  changeIndex(Math.max(0, screenIndex - 1));
993
1516
  currentScreenRef.current.focus();
994
1517
  }, [changeIndex]);
995
- var onScreenNext = useCallback(function () {
1518
+ var gotoNextScreen = useCallback(function () {
996
1519
  changeIndex(Math.min(screens.length - 1, screenIndex + 1));
997
1520
  currentScreenRef.current.focus();
998
1521
  }, [changeIndex]);
999
1522
  var screensCount = screens.length;
1000
-
1001
- var _useState = useState(screens.map(function () {
1002
- return true;
1003
- })),
1004
- _useState2 = _slicedToArray(_useState, 2),
1005
- screensInteractionEnabled = _useState2[0],
1006
- setScreensInteractionEnabled = _useState2[1];
1007
-
1008
- var currentScreenInteractionEnabled = screensInteractionEnabled[screenIndex];
1009
- var menuVisible = screensCount === 0 || currentScreenInteractionEnabled;
1010
- useEffect(function () {
1011
- setScreensInteractionEnabled(_toConsumableArray(Array(screensCount).keys()).map(function () {
1012
- return true;
1013
- }));
1014
- }, [screensCount]);
1015
- var onEnableInteraction = useCallback(function () {
1016
- if (!screensInteractionEnabled[screenIndex]) {
1017
- var newArray = _toConsumableArray(screensInteractionEnabled);
1018
-
1019
- newArray[screenIndex] = true;
1020
- setScreensInteractionEnabled(newArray);
1021
- }
1022
- }, [screenIndex, screensInteractionEnabled, setScreensInteractionEnabled]);
1023
- var onDisableInteraction = useCallback(function () {
1024
- if (screensInteractionEnabled[screenIndex]) {
1025
- var newArray = _toConsumableArray(screensInteractionEnabled);
1026
-
1027
- newArray[screenIndex] = false;
1028
- setScreensInteractionEnabled(newArray);
1029
- }
1030
- }, [screenIndex, screensInteractionEnabled, setScreensInteractionEnabled]); // handle screenClick
1031
-
1032
1523
  var onInteractionPrivate = useCallback(function () {
1033
1524
  if (onInteraction !== null) {
1034
1525
  onInteraction();
1035
1526
  }
1036
1527
  }, [onInteraction]);
1037
- var onScreenClick = useCallback(function (e, index) {
1038
- onInteractionPrivate();
1039
-
1040
- var checkClickable = function checkClickable(el) {
1041
- var maxDistance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5;
1042
- var distance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
1043
-
1044
- var _ref9 = el || {},
1045
- _ref9$tagName = _ref9.tagName,
1046
- tagName = _ref9$tagName === void 0 ? null : _ref9$tagName,
1047
- _ref9$parentNode = _ref9.parentNode,
1048
- parentNode = _ref9$parentNode === void 0 ? null : _ref9$parentNode;
1049
1528
 
1050
- if (tagName === 'BODY') {
1051
- return false;
1052
- }
1053
-
1054
- var tags = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];
1055
-
1056
- if (tags.indexOf(tagName) > -1) {
1057
- return true;
1058
- }
1059
-
1060
- if (distance < maxDistance) {
1061
- return checkClickable(parentNode, maxDistance, distance + 1);
1062
- }
1063
-
1064
- return false;
1065
- };
1066
-
1067
- var tappedCurrent = screenIndex === index;
1068
-
1069
- if (!isView && tappedCurrent || checkClickable(e.target)) {
1070
- return;
1071
- }
1072
-
1073
- var it = screens[screenIndex] || null;
1074
- var interactionEnabled = screensInteractionEnabled[screenIndex];
1075
-
1076
- if (it === null || tappedCurrent && !interactionEnabled) {
1077
- return;
1078
- }
1079
-
1080
- var nextIndex = screenIndex;
1081
-
1082
- var _e$currentTarget$getB = e.currentTarget.getBoundingClientRect(),
1083
- _e$currentTarget$getB2 = _e$currentTarget$getB.left,
1084
- contentX = _e$currentTarget$getB2 === void 0 ? 0 : _e$currentTarget$getB2;
1085
-
1086
- var tapX = e.clientX;
1087
- var hasTappedLeft = tappedCurrent ? tapX - contentX < screenWidth * (1 - tapNextScreenWidthPercent) : screenIndex > index;
1088
-
1089
- if (hasTappedLeft) {
1090
- nextIndex = landscape ? index : Math.max(0, screenIndex - 1);
1091
- } else {
1092
- nextIndex = landscape ? index : Math.min(screens.length - 1, screenIndex + 1);
1093
- var isLastScreen = screenIndex === screens.length - 1;
1094
-
1095
- if (isLastScreen && onEnd !== null) {
1096
- onEnd();
1097
- }
1098
- }
1099
-
1100
- changeIndex(nextIndex);
1101
- }, [onScreenChange, screenWidth, screens, changeIndex, screenIndex, screensInteractionEnabled, isView, onInteractionPrivate, onEnd]); // swipe menu open
1102
-
1103
- var menuOpened = useRef(false);
1104
-
1105
- var _useState3 = useState(false),
1106
- _useState4 = _slicedToArray(_useState3, 2),
1107
- previewMenuOpen = _useState4[0],
1108
- setPreviewMenuOpen = _useState4[1];
1109
-
1110
- var _useSpring = useSpring(function () {
1111
- return {
1112
- y: 0,
1113
- config: _objectSpread(_objectSpread({}, config.stiff), {}, {
1114
- clamp: true
1115
- })
1116
- };
1529
+ var _useScreenInteraction = useScreenInteraction({
1530
+ screens: screens,
1531
+ screenId: screenId,
1532
+ screenWidth: screenWidth,
1533
+ isView: isView,
1534
+ clickOnSiblings: landscape && withLandscapeSiblingsScreens,
1535
+ nextScreenWidthPercent: tapNextScreenWidthPercent,
1536
+ events: eventsManager,
1537
+ onClick: onInteractionPrivate,
1538
+ onEnd: onEnd,
1539
+ onChangeScreen: changeIndex
1117
1540
  }),
1118
- _useSpring2 = _slicedToArray(_useSpring, 2),
1119
- menuY = _useSpring2[0].y,
1120
- setMenuSpring = _useSpring2[1];
1121
-
1122
- var menuPreviewStyle = {
1123
- transform: menuY.to(function (y) {
1124
- return "translateY(".concat(y * menuPreviewContainerHeight, "px)");
1125
- })
1126
- };
1127
- var menuDragBind = useDrag(function (_ref10) {
1128
- var _ref10$movement = _slicedToArray(_ref10.movement, 2),
1129
- my = _ref10$movement[1],
1130
- first = _ref10.first,
1131
- last = _ref10.last,
1132
- _ref10$direction = _slicedToArray(_ref10.direction, 2),
1133
- dy = _ref10$direction[1],
1134
- cancel = _ref10.cancel,
1135
- canceled = _ref10.canceled,
1136
- tap = _ref10.tap;
1137
-
1138
- if (canceled || tap) {
1139
- return;
1140
- }
1141
-
1142
- var isMenuOpened = menuOpened.current;
1143
-
1144
- if (first) {
1145
- if (isMenuOpened) {
1146
- cancel();
1147
- return;
1148
- }
1149
- }
1541
+ onScreenClick = _useScreenInteraction.onClick,
1542
+ currentScreenInteractionEnabled = _useScreenInteraction.currentScreenInteractionEnabled,
1543
+ enableInteraction = _useScreenInteraction.enableInteraction,
1544
+ disableInteraction = _useScreenInteraction.disableInteraction; // swipe menu open
1150
1545
 
1151
- var yProgress = Math.max(0, Math.min(1, my / menuPreviewContainerHeight + (isMenuOpened ? 1 : 0)));
1152
1546
 
1153
- if (last) {
1154
- var menuNowOpened = dy > 0 && yProgress > 0.1;
1155
- menuOpened.current = menuNowOpened;
1156
- setMenuSpring.start({
1157
- y: menuNowOpened ? 1 : 0
1158
- });
1159
- setPreviewMenuOpen(menuNowOpened);
1160
- } else {
1161
- setMenuSpring.start({
1162
- y: yProgress
1163
- });
1164
- }
1165
- }, {
1166
- axis: 'y',
1167
- filterTaps: true
1168
- });
1169
-
1170
- var setPreviewMenu = function setPreviewMenu(opened) {
1171
- setMenuSpring.start({
1172
- y: opened ? 1 : 0
1173
- });
1174
- menuOpened.current = opened;
1175
- setPreviewMenuOpen(opened);
1176
- };
1177
-
1178
- var openPreviewMenu = useCallback(function () {
1179
- setPreviewMenu(true);
1180
- }, [setMenuSpring, setPreviewMenuOpen]);
1181
- var closePreviewMenu = useCallback(function () {
1182
- setPreviewMenu(false);
1183
- }, [setMenuSpring, setPreviewMenuOpen]); // Handle dot menu item click
1547
+ var menuVisible = screensCount === 0 || currentScreenInteractionEnabled;
1184
1548
 
1185
- var onClickDotsMenuItem = useCallback(function (index) {
1549
+ var _useState = useState(false),
1550
+ _useState2 = _slicedToArray(_useState, 2),
1551
+ menuOpened = _useState2[0],
1552
+ setMenuOpened = _useState2[1];
1553
+
1554
+ var onMenuRequestOpen = useCallback(function () {
1555
+ return setMenuOpened(true);
1556
+ }, [setMenuOpened]);
1557
+ var onMenuRequestClose = useCallback(function () {
1558
+ return setMenuOpened(false);
1559
+ }, [setMenuOpened]);
1560
+ var onClickMenu = useCallback(function () {
1186
1561
  onInteractionPrivate();
1187
- var clickedOnDot = index !== null;
1188
- var goToScreen = landscape && clickedOnDot;
1189
-
1190
- if (goToScreen) {
1191
- changeIndex(index);
1192
- } else {
1193
- openPreviewMenu();
1194
- }
1195
-
1196
- if (trackingEnabled) {
1197
- var trackAction = goToScreen ? 'click_screen_change' : 'click_open';
1198
- var trackLabel = clickedOnDot ? "Screen ".concat(index + 1) : 'Menu icon';
1199
- trackEvent('viewer_menu', trackAction, trackLabel, {
1200
- screenId: screenId,
1201
- screenType: screenType,
1202
- screenIndex: index
1203
- });
1204
- }
1205
- }, [changeIndex, landscape, trackingEnabled, trackEvent, screenType, onInteractionPrivate]); // handle preview menu item click
1206
-
1207
- var onClickPreviewMenuItem = useCallback(function (index) {
1562
+ setMenuOpened(true);
1563
+ }, [changeIndex, onInteractionPrivate, setMenuOpened]);
1564
+ var onClickMenuItem = useCallback(function (_ref6) {
1565
+ var itemScreenId = _ref6.screenId;
1566
+ onInteractionPrivate();
1567
+ var index = screens.findIndex(function (_ref7) {
1568
+ var id = _ref7.id;
1569
+ return id === itemScreenId;
1570
+ });
1208
1571
  changeIndex(index);
1209
- closePreviewMenu();
1210
-
1211
- if (trackingEnabled) {
1212
- trackEvent('viewer_menu', 'click_screen_change', "Screen ".concat(index + 1), {
1213
- screenId: screenId,
1214
- screenType: screenType,
1215
- screenIndex: index
1216
- });
1217
- }
1218
- }, [changeIndex, trackingEnabled, trackEvent, screenId, screenType]); // Handle preview menu close click
1219
-
1220
- var onClickPreviewMenuClose = useCallback(function () {
1221
- closePreviewMenu();
1222
-
1223
- if (trackingEnabled) {
1224
- trackEvent('viewer_menu', 'click_close', 'Close icon', {
1225
- screenId: screenId,
1226
- screenIndex: screenIndex,
1227
- screenType: screenType
1228
- });
1229
- }
1230
- }, [closePreviewMenu, trackingEnabled, trackEvent, screenId, screenIndex, screenType]); // Handle preview menu share click
1231
1572
 
1232
- var onClickShare = useCallback(function (type) {
1233
- if (trackingEnabled) {
1234
- trackEvent('viewer_menu', 'click_share', type, {
1235
- screenId: screenId,
1236
- screenIndex: screenIndex,
1237
- screenType: screenType
1238
- });
1573
+ if (menuOpened) {
1574
+ setMenuOpened(false);
1239
1575
  }
1240
- }, [trackingEnabled, trackEvent, screenId, screenIndex, screenType]);
1576
+ }, [onInteractionPrivate, changeIndex, menuOpened, setMenuOpened]);
1241
1577
  var onContextMenu = useCallback(function (e) {
1242
1578
  if (!landscape) {
1243
1579
  e.preventDefault();
@@ -1256,62 +1592,43 @@ function Viewer(_ref) {
1256
1592
  fullscreenEnabled = _useFullscreen.enabled; // Keyboard Events
1257
1593
 
1258
1594
 
1259
- useEffect(function () {
1260
- var onKey = function onKey(e) {
1261
- if (['input', 'textarea'].reduce(function (foundMatch, match) {
1262
- return foundMatch || e.target.matches(match);
1263
- }, false)) {
1264
- return;
1265
- }
1266
-
1267
- var key = e.key;
1268
- var lowercaseKey = key.toLowerCase();
1269
-
1270
- switch (lowercaseKey) {
1271
- case 'f':
1272
- toggleFullscreen();
1273
- break;
1274
-
1275
- case 'm':
1276
- setPreviewMenu(!menuOpened.current);
1277
- break;
1278
-
1279
- case 'escape':
1280
- closePreviewMenu();
1281
- break;
1282
-
1283
- case 'arrowleft':
1284
- onScreenPrevious();
1285
- break;
1286
-
1287
- case 'arrowright':
1288
- case ' ':
1289
- // spacebar
1290
- onScreenNext();
1291
- break;
1595
+ var keyboardShortcuts = useMemo(function () {
1596
+ return {
1597
+ f: function f() {
1598
+ return toggleFullscreen();
1599
+ },
1600
+ m: function m() {
1601
+ return setMenuOpened(!menuOpened);
1602
+ },
1603
+ escape: function escape() {
1604
+ return setMenuOpened(false);
1605
+ },
1606
+ arrowleft: function arrowleft() {
1607
+ return gotoPreviousScreen();
1608
+ },
1609
+ arrowright: function arrowright() {
1610
+ return gotoNextScreen();
1611
+ },
1612
+ ' ': function _() {
1613
+ return gotoNextScreen();
1292
1614
  }
1293
1615
  };
1616
+ }, [menuOpened, setMenuOpened, gotoPreviousScreen, gotoNextScreen]);
1617
+ useKeyboardShortcuts(keyboardShortcuts, {
1618
+ disabled: renderContext !== 'view'
1619
+ });
1294
1620
 
1295
- if (renderContext === 'view') {
1296
- window.addEventListener('keydown', onKey);
1297
- }
1298
-
1299
- return function () {
1300
- window.removeEventListener('keydown', onKey);
1301
- };
1302
- }, [renderContext, closePreviewMenu, onScreenPrevious, onScreenNext]);
1303
-
1304
- var _ref11 = currentScreen || {},
1305
- screenParameters = _ref11.parameters;
1621
+ var _ref8 = currentScreen || {},
1622
+ screenParameters = _ref8.parameters;
1306
1623
 
1307
- var _ref12 = screenParameters || {},
1308
- screenMetadata = _ref12.metadata;
1624
+ var _ref9 = screenParameters || {},
1625
+ screenMetadata = _ref9.metadata;
1309
1626
 
1310
- var _ref13 = screenMetadata || {},
1311
- _ref13$title = _ref13.title,
1312
- screenTitle = _ref13$title === void 0 ? null : _ref13$title,
1313
- _ref13$description = _ref13.description,
1314
- screenDescription = _ref13$description === void 0 ? null : _ref13$description;
1627
+ var _ref10 = screenMetadata || {},
1628
+ _ref10$title = _ref10.title,
1629
+ screenTitle = _ref10$title === void 0 ? null : _ref10$title,
1630
+ _ref10$description = _ref10.description,
1631
+ screenDescription = _ref10$description === void 0 ? null : _ref10$description;
1315
1632
 
1316
1633
  var finalTitle = screenTitle !== null ? screenTitle : title;
1317
1634
  var finalMetadata = useMemo(function () {
@@ -1320,88 +1637,94 @@ function Viewer(_ref) {
1320
1637
  }) : metadata;
1321
1638
  }, [metadata]);
1322
1639
 
1323
- var _ref14 = viewerTheme || {},
1324
- _ref14$menuTheme = _ref14.menuTheme,
1325
- menuTheme = _ref14$menuTheme === void 0 ? null : _ref14$menuTheme;
1640
+ var _useResizeObserver = useResizeObserver(),
1641
+ menuDotsContainerRef = _useResizeObserver.ref,
1642
+ menuDotsContainerRect = _useResizeObserver.entry.contentRect;
1643
+
1644
+ var _ref11 = menuDotsContainerRect || {},
1645
+ _ref11$height = _ref11.height,
1646
+ menuDotsContainerHeight = _ref11$height === void 0 ? 0 : _ref11$height;
1326
1647
 
1327
1648
  return /*#__PURE__*/React.createElement(ScreenSizeProvider, {
1328
1649
  size: screenSize
1329
1650
  }, /*#__PURE__*/React.createElement(ViewerProvider, {
1651
+ events: eventsManager,
1330
1652
  menuVisible: menuVisible,
1331
- menuSize: menuDotsContainerHeight
1653
+ menuSize: menuDotsContainerHeight,
1654
+ gotoPreviousScreen: gotoPreviousScreen,
1655
+ gotoNextScreen: gotoNextScreen,
1656
+ disableInteraction: disableInteraction,
1657
+ enableInteraction: enableInteraction
1332
1658
  }, withMetadata ? /*#__PURE__*/React.createElement(Meta, {
1333
1659
  title: finalTitle,
1334
1660
  metadata: finalMetadata
1335
1661
  }, overscrollStyle) : /*#__PURE__*/React.createElement(Helmet, null, overscrollStyle), /*#__PURE__*/React.createElement(FontFaces, {
1336
1662
  fonts: finalFonts
1337
1663
  }), /*#__PURE__*/React.createElement("div", {
1338
- className: classNames([styles$6.container, screenSize.screens.map(function (screenName) {
1664
+ className: classNames([styles$7.container, screenSize.screens.map(function (screenName) {
1339
1665
  return "story-screen-".concat(screenName);
1340
- }), (_ref15 = {}, _defineProperty(_ref15, styles$6.landscape, landscape), _defineProperty(_ref15, styles$6.hideMenu, !menuVisible), _defineProperty(_ref15, styles$6.ready, ready || withoutScreensTransforms), _defineProperty(_ref15, className, className), _ref15)]),
1666
+ }), (_ref12 = {}, _defineProperty(_ref12, styles$7.landscape, landscape), _defineProperty(_ref12, styles$7.withSibblings, withLandscapeSiblingsScreens), _defineProperty(_ref12, styles$7.hideMenu, !menuVisible), _defineProperty(_ref12, styles$7.ready, ready || withoutScreensTransforms), _defineProperty(_ref12, className, className), _ref12)]),
1341
1667
  ref: containerRef,
1342
1668
  onContextMenu: onContextMenu
1343
- }, !withoutMenu ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", Object.assign({
1344
- className: styles$6.menuDotsContainer,
1345
- ref: menuDotsContainerRef,
1346
- style: {
1347
- width: screenWidth
1348
- }
1349
- }, menuDragBind()), /*#__PURE__*/React.createElement(ViewerMenuDots, Object.assign({}, menuTheme, {
1350
- direction: "horizontal",
1669
+ }, !withoutMenu ? /*#__PURE__*/React.createElement(ViewerMenu, {
1670
+ story: parsedStory,
1671
+ currentScreenIndex: screenIndex,
1672
+ opened: menuOpened,
1351
1673
  withShadow: menuOverScreen,
1352
- items: screens,
1353
- current: screenIndex,
1354
- onClickItem: onClickDotsMenuItem,
1355
- closeable: closeable,
1356
- onClose: onClose,
1357
- className: styles$6.menuDots
1358
- }))), /*#__PURE__*/React.createElement(animated.div, {
1359
- className: styles$6.menuPreviewContainer,
1360
- style: menuPreviewStyle,
1361
- ref: menuPreviewContainerRef
1362
- }, /*#__PURE__*/React.createElement(ViewerMenuPreview, {
1363
- viewerTheme: viewerTheme,
1364
- title: title,
1365
- shareUrl: shareUrl,
1366
- className: styles$6.menuPreview,
1367
- screenWidth: screenWidth,
1368
- focusable: previewMenuOpen,
1369
- items: screens,
1370
- current: screenIndex,
1371
- onClickItem: onClickPreviewMenuItem,
1372
- onClose: onClickPreviewMenuClose,
1373
- onShare: onClickShare,
1374
1674
  toggleFullscreen: toggleFullscreen,
1375
1675
  fullscreenActive: fullscreenActive,
1376
- fullscreenEnabled: fullscreenEnabled
1377
- }))) : null, ready || withoutScreensTransforms ? /*#__PURE__*/React.createElement("div", {
1676
+ fullscreenEnabled: fullscreenEnabled,
1677
+ closeable: closeable,
1678
+ shareBasePath: basePath,
1679
+ screenSize: screenSize,
1680
+ menuWidth: screenWidth,
1681
+ trackingEnabled: trackingEnabled,
1682
+ onClickItem: onClickMenuItem,
1683
+ onClickMenu: onClickMenu,
1684
+ onClickCloseViewer: onCloseViewer,
1685
+ onRequestOpen: onMenuRequestOpen,
1686
+ onRequestClose: onMenuRequestClose,
1687
+ withDotItemClick: screenWidth > 400,
1688
+ withoutScreensMenu: withoutScreensMenu,
1689
+ refDots: menuDotsContainerRef
1690
+ }) : null, ready || withoutScreensTransforms ? /*#__PURE__*/React.createElement("div", {
1378
1691
  ref: contentRef,
1379
- className: styles$6.content
1692
+ className: styles$7.content
1380
1693
  }, screens.map(function (scr, i) {
1694
+ var _ref13;
1695
+
1381
1696
  var current = i === screenIndex;
1382
1697
  var active = i > screenIndex - neighborScreensActive && i < screenIndex + neighborScreensActive;
1383
1698
  var viewerScreen = /*#__PURE__*/React.createElement(ViewerScreen, {
1384
1699
  screen: scr,
1700
+ screenState: current ? screenState : null,
1385
1701
  renderContext: renderContext,
1386
1702
  index: i,
1387
1703
  current: current,
1388
1704
  active: active,
1389
- onPrevious: onScreenPrevious,
1390
- onNext: onScreenNext,
1391
- onEnableInteraction: onEnableInteraction,
1392
- onDisableInteraction: onDisableInteraction,
1705
+ onPrevious: gotoPreviousScreen,
1706
+ onNext: gotoNextScreen,
1707
+ onEnableInteraction: enableInteraction,
1708
+ onDisableInteraction: disableInteraction,
1393
1709
  getMediaRef: function getMediaRef(mediaRef) {
1394
1710
  screensMediasRef.current[i] = mediaRef;
1395
1711
  }
1396
1712
  });
1397
1713
  var key = "screen-viewer-".concat(scr.id || '', "-").concat(i + 1);
1398
- var screenTransform = landscape ? "translateX(calc(".concat((screenWidth + landscapeScreenMargin) * (i - screenIndex), "px - 50%)) scale(").concat(current ? 1 : 0.9, ")") : "translateX(".concat(current ? 0 : '100%', ")");
1714
+ var screenTransform = null;
1715
+
1716
+ if (landscape) {
1717
+ screenTransform = withLandscapeSiblingsScreens ? "translateX(calc(".concat((screenWidth + landscapeScreenMargin) * (i - screenIndex), "px - 50%)) scale(").concat(current ? 1 : 0.9, ")") : null;
1718
+ } else {
1719
+ screenTransform = "translateX(".concat(current ? 0 : '100%', ")");
1720
+ }
1721
+
1399
1722
  return /*#__PURE__*/React.createElement(React.Fragment, {
1400
1723
  key: key
1401
1724
  }, current && screenIndex > 0 ? /*#__PURE__*/React.createElement("button", {
1402
1725
  type: "button",
1403
1726
  className: "sr-only",
1404
- onClick: onScreenPrevious,
1727
+ onClick: gotoPreviousScreen,
1405
1728
  tabIndex: "-1"
1406
1729
  }, /*#__PURE__*/React.createElement(FormattedMessage, {
1407
1730
  id: "zYH/31",
@@ -1416,7 +1739,7 @@ function Viewer(_ref) {
1416
1739
  height: landscape ? screenHeight : null,
1417
1740
  transform: !withoutScreensTransforms ? screenTransform : null
1418
1741
  },
1419
- className: classNames([styles$6.screen, _defineProperty({}, styles$6.current, current)]),
1742
+ className: classNames([styles$7.screen, (_ref13 = {}, _defineProperty(_ref13, styles$7.current, current), _defineProperty(_ref13, styles$7.visible, current || withLandscapeSiblingsScreens), _ref13)]),
1420
1743
  tabIndex: active ? '0' : '-1'
1421
1744
  /* eslint-disable-line */
1422
1745
  ,
@@ -1439,12 +1762,12 @@ function Viewer(_ref) {
1439
1762
  }
1440
1763
  },
1441
1764
  onClick: function onClick(e) {
1442
- onScreenClick(e, i);
1765
+ return onScreenClick(e, i);
1443
1766
  }
1444
1767
  }, viewerScreen), current && screenIndex < screens.length ? /*#__PURE__*/React.createElement("button", {
1445
1768
  type: "button",
1446
1769
  className: "sr-only",
1447
- onClick: onScreenNext,
1770
+ onClick: gotoNextScreen,
1448
1771
  tabIndex: "-1"
1449
1772
  }, /*#__PURE__*/React.createElement(FormattedMessage, {
1450
1773
  id: "v9bqYj",
@@ -1454,7 +1777,7 @@ function Viewer(_ref) {
1454
1777
  }]
1455
1778
  })) : null);
1456
1779
  })) : null)));
1457
- }
1780
+ };
1458
1781
 
1459
1782
  Viewer.propTypes = propTypes$2;
1460
1783
  Viewer.defaultProps = defaultProps$2;
@@ -1508,17 +1831,11 @@ var ViewerRoutes = function ViewerRoutes(_ref) {
1508
1831
  ViewerRoutes.propTypes = propTypes$1;
1509
1832
  ViewerRoutes.defaultProps = defaultProps$1;
1510
1833
 
1511
- var home = "/";
1512
- var screen = "/:screen";
1513
- var defaultRoutes = {
1514
- home: home,
1515
- screen: screen
1516
- };
1517
-
1518
- var _excluded = ["story", "memoryRouter", "basePath", "routes", "withoutRouter", "googleApiKey", "trackingVariables", "locale", "locales", "translations"];
1834
+ var _excluded = ["story", "screenComponents", "memoryRouter", "basePath", "routes", "withoutRouter", "googleApiKey", "trackingVariables", "locale", "locales", "translations"];
1519
1835
  var propTypes = {
1520
1836
  story: PropTypes$1.story,
1521
1837
  screen: PropTypes.string,
1838
+ screenComponents: PropTypes.objectOf(PropTypes.elementType),
1522
1839
  memoryRouter: PropTypes.bool,
1523
1840
  basePath: PropTypes.string,
1524
1841
  routes: routes,
@@ -1533,6 +1850,7 @@ var propTypes = {
1533
1850
  var defaultProps = {
1534
1851
  story: null,
1535
1852
  screen: null,
1853
+ screenComponents: null,
1536
1854
  memoryRouter: false,
1537
1855
  basePath: null,
1538
1856
  routes: defaultRoutes,
@@ -1547,6 +1865,7 @@ var defaultProps = {
1547
1865
 
1548
1866
  var ViewerContainer = function ViewerContainer(_ref) {
1549
1867
  var story = _ref.story,
1868
+ screenComponents = _ref.screenComponents,
1550
1869
  memoryRouter = _ref.memoryRouter,
1551
1870
  basePath = _ref.basePath,
1552
1871
  routes = _ref.routes,
@@ -1597,7 +1916,10 @@ var ViewerContainer = function ViewerContainer(_ref) {
1597
1916
  locale: finalLocale
1598
1917
  }, /*#__PURE__*/React.createElement(FieldsProvider, {
1599
1918
  manager: fieldsManager
1600
- }, /*#__PURE__*/React.createElement(ScreensProvider, null, /*#__PURE__*/React.createElement(UserInteractionProvider, null, /*#__PURE__*/React.createElement(TrackingProvider, {
1919
+ }, /*#__PURE__*/React.createElement(ScreensProvider, null, /*#__PURE__*/React.createElement(ComponentsProvider, {
1920
+ namespace: SCREENS_NAMESPACE,
1921
+ components: screenComponents || {}
1922
+ }, /*#__PURE__*/React.createElement(UserInteractionProvider, null, /*#__PURE__*/React.createElement(TrackingProvider, {
1601
1923
  variables: finalTrackingVariables
1602
1924
  }, withoutRouter ? /*#__PURE__*/React.createElement(Viewer, Object.assign({
1603
1925
  story: story,
@@ -1605,7 +1927,7 @@ var ViewerContainer = function ViewerContainer(_ref) {
1605
1927
  }, otherProps)) : /*#__PURE__*/React.createElement(ViewerRoutes, Object.assign({
1606
1928
  story: story,
1607
1929
  basePath: basePath
1608
- }, otherProps)))))))));
1930
+ }, otherProps))))))))));
1609
1931
  return withoutRouter ? content : /*#__PURE__*/React.createElement(Router, {
1610
1932
  basename: !memoryRouter ? basePath : null
1611
1933
  }, /*#__PURE__*/React.createElement(RoutesProvider, {