UNPKG

15.5 kBJavaScriptView Raw
1function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
3import "regenerator-runtime/runtime.js";
4
5function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
6
7function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
8
9function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
10
11function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12
13function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
14
15function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
16
17function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
18
19function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
20
21import "core-js/modules/es.regexp.exec.js";
22import "core-js/modules/es.string.match.js";
23import "core-js/modules/es.object.keys.js";
24import "core-js/modules/es.object.freeze.js";
25import "core-js/modules/es.object.assign.js";
26import "core-js/modules/es.object.to-string.js";
27import "core-js/modules/web.dom-collections.for-each.js";
28import "core-js/modules/es.object.entries.js";
29import "core-js/modules/es.array.concat.js";
30import "core-js/modules/es.array.find.js";
31import "core-js/modules/es.symbol.js";
32import "core-js/modules/es.symbol.description.js";
33import "core-js/modules/es.symbol.iterator.js";
34import "core-js/modules/es.array.iterator.js";
35import "core-js/modules/es.string.iterator.js";
36import "core-js/modules/web.dom-collections.iterator.js";
37import "core-js/modules/es.array.slice.js";
38import "core-js/modules/es.function.name.js";
39import "core-js/modules/es.array.from.js";
40import "core-js/modules/es.promise.js";
41import global from 'global';
42import { PREVIEW_KEYDOWN } from '@storybook/core-events';
43import { shortcutMatchesShortcut, eventToShortcut } from '../lib/shortcut';
44import { focusableUIElements } from './layout';
45var navigator = global.navigator,
46 document = global.document;
47export var isMacLike = function isMacLike() {
48 return navigator && navigator.platform ? !!navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) : false;
49};
50export var controlOrMetaKey = function controlOrMetaKey() {
51 return isMacLike() ? 'meta' : 'control';
52};
53export function keys(o) {
54 return Object.keys(o);
55}
56export var defaultShortcuts = Object.freeze({
57 fullScreen: ['F'],
58 togglePanel: ['A'],
59 panelPosition: ['D'],
60 toggleNav: ['S'],
61 toolbar: ['T'],
62 search: ['/'],
63 focusNav: ['1'],
64 focusIframe: ['2'],
65 focusPanel: ['3'],
66 prevComponent: ['alt', 'ArrowUp'],
67 nextComponent: ['alt', 'ArrowDown'],
68 prevStory: ['alt', 'ArrowLeft'],
69 nextStory: ['alt', 'ArrowRight'],
70 shortcutsPage: [controlOrMetaKey(), 'shift', ','],
71 aboutPage: [','],
72 escape: ['escape'],
73 // This one is not customizable
74 collapseAll: [controlOrMetaKey(), 'shift', 'ArrowUp'],
75 expandAll: [controlOrMetaKey(), 'shift', 'ArrowDown']
76});
77var addonsShortcuts = {};
78
79function focusInInput(event) {
80 return /input|textarea/i.test(event.target.tagName) || event.target.getAttribute('contenteditable') !== null;
81}
82
83export var init = function init(_ref) {
84 var store = _ref.store,
85 fullAPI = _ref.fullAPI;
86 var api = {
87 // Getting and setting shortcuts
88 getShortcutKeys: function getShortcutKeys() {
89 return store.getState().shortcuts;
90 },
91 getDefaultShortcuts: function getDefaultShortcuts() {
92 return Object.assign({}, defaultShortcuts, api.getAddonsShortcutDefaults());
93 },
94 getAddonsShortcuts: function getAddonsShortcuts() {
95 return addonsShortcuts;
96 },
97 getAddonsShortcutLabels: function getAddonsShortcutLabels() {
98 var labels = {};
99 Object.entries(api.getAddonsShortcuts()).forEach(function (_ref2) {
100 var _ref3 = _slicedToArray(_ref2, 2),
101 actionName = _ref3[0],
102 label = _ref3[1].label;
103
104 labels[actionName] = label;
105 });
106 return labels;
107 },
108 getAddonsShortcutDefaults: function getAddonsShortcutDefaults() {
109 var defaults = {};
110 Object.entries(api.getAddonsShortcuts()).forEach(function (_ref4) {
111 var _ref5 = _slicedToArray(_ref4, 2),
112 actionName = _ref5[0],
113 defaultShortcut = _ref5[1].defaultShortcut;
114
115 defaults[actionName] = defaultShortcut;
116 });
117 return defaults;
118 },
119 setShortcuts: function setShortcuts(shortcuts) {
120 return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
121 return regeneratorRuntime.wrap(function _callee$(_context) {
122 while (1) {
123 switch (_context.prev = _context.next) {
124 case 0:
125 _context.next = 2;
126 return store.setState({
127 shortcuts: shortcuts
128 }, {
129 persistence: 'permanent'
130 });
131
132 case 2:
133 return _context.abrupt("return", shortcuts);
134
135 case 3:
136 case "end":
137 return _context.stop();
138 }
139 }
140 }, _callee);
141 }))();
142 },
143 restoreAllDefaultShortcuts: function restoreAllDefaultShortcuts() {
144 return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
145 return regeneratorRuntime.wrap(function _callee2$(_context2) {
146 while (1) {
147 switch (_context2.prev = _context2.next) {
148 case 0:
149 return _context2.abrupt("return", api.setShortcuts(api.getDefaultShortcuts()));
150
151 case 1:
152 case "end":
153 return _context2.stop();
154 }
155 }
156 }, _callee2);
157 }))();
158 },
159 setShortcut: function setShortcut(action, value) {
160 return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
161 var shortcuts;
162 return regeneratorRuntime.wrap(function _callee3$(_context3) {
163 while (1) {
164 switch (_context3.prev = _context3.next) {
165 case 0:
166 shortcuts = api.getShortcutKeys();
167 _context3.next = 3;
168 return api.setShortcuts(Object.assign({}, shortcuts, _defineProperty({}, action, value)));
169
170 case 3:
171 return _context3.abrupt("return", value);
172
173 case 4:
174 case "end":
175 return _context3.stop();
176 }
177 }
178 }, _callee3);
179 }))();
180 },
181 setAddonShortcut: function setAddonShortcut(addon, shortcut) {
182 return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
183 var shortcuts;
184 return regeneratorRuntime.wrap(function _callee4$(_context4) {
185 while (1) {
186 switch (_context4.prev = _context4.next) {
187 case 0:
188 shortcuts = api.getShortcutKeys();
189 _context4.next = 3;
190 return api.setShortcuts(Object.assign({}, shortcuts, _defineProperty({}, "".concat(addon, "-").concat(shortcut.actionName), shortcut.defaultShortcut)));
191
192 case 3:
193 addonsShortcuts["".concat(addon, "-").concat(shortcut.actionName)] = shortcut;
194 return _context4.abrupt("return", shortcut);
195
196 case 5:
197 case "end":
198 return _context4.stop();
199 }
200 }
201 }, _callee4);
202 }))();
203 },
204 restoreDefaultShortcut: function restoreDefaultShortcut(action) {
205 return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
206 var defaultShortcut;
207 return regeneratorRuntime.wrap(function _callee5$(_context5) {
208 while (1) {
209 switch (_context5.prev = _context5.next) {
210 case 0:
211 defaultShortcut = api.getDefaultShortcuts()[action];
212 return _context5.abrupt("return", api.setShortcut(action, defaultShortcut));
213
214 case 2:
215 case "end":
216 return _context5.stop();
217 }
218 }
219 }, _callee5);
220 }))();
221 },
222 // Listening to shortcut events
223 handleKeydownEvent: function handleKeydownEvent(event) {
224 var shortcut = eventToShortcut(event);
225 var shortcuts = api.getShortcutKeys();
226 var actions = keys(shortcuts);
227 var matchedFeature = actions.find(function (feature) {
228 return shortcutMatchesShortcut(shortcut, shortcuts[feature]);
229 });
230
231 if (matchedFeature) {
232 // Event.prototype.preventDefault is missing when received from the MessageChannel.
233 if (event !== null && event !== void 0 && event.preventDefault) event.preventDefault();
234 api.handleShortcutFeature(matchedFeature);
235 }
236 },
237 // warning: event might not have a full prototype chain because it may originate from the channel
238 handleShortcutFeature: function handleShortcutFeature(feature) {
239 var _store$getState = store.getState(),
240 _store$getState$layou = _store$getState.layout,
241 isFullscreen = _store$getState$layou.isFullscreen,
242 showNav = _store$getState$layou.showNav,
243 showPanel = _store$getState$layou.showPanel,
244 enableShortcuts = _store$getState.ui.enableShortcuts;
245
246 if (!enableShortcuts) {
247 return;
248 }
249
250 switch (feature) {
251 case 'escape':
252 {
253 if (isFullscreen) {
254 fullAPI.toggleFullscreen();
255 } else if (!showNav) {
256 fullAPI.toggleNav();
257 }
258
259 break;
260 }
261
262 case 'focusNav':
263 {
264 if (isFullscreen) {
265 fullAPI.toggleFullscreen();
266 }
267
268 if (!showNav) {
269 fullAPI.toggleNav();
270 }
271
272 fullAPI.focusOnUIElement(focusableUIElements.storyListMenu);
273 break;
274 }
275
276 case 'search':
277 {
278 if (isFullscreen) {
279 fullAPI.toggleFullscreen();
280 }
281
282 if (!showNav) {
283 fullAPI.toggleNav();
284 }
285
286 setTimeout(function () {
287 fullAPI.focusOnUIElement(focusableUIElements.storySearchField, true);
288 }, 0);
289 break;
290 }
291
292 case 'focusIframe':
293 {
294 var element = document.getElementById('storybook-preview-iframe');
295
296 if (element) {
297 try {
298 // should be like a channel message and all that, but yolo for now
299 element.contentWindow.focus();
300 } catch (e) {//
301 }
302 }
303
304 break;
305 }
306
307 case 'focusPanel':
308 {
309 if (isFullscreen) {
310 fullAPI.toggleFullscreen();
311 }
312
313 if (!showPanel) {
314 fullAPI.togglePanel();
315 }
316
317 fullAPI.focusOnUIElement(focusableUIElements.storyPanelRoot);
318 break;
319 }
320
321 case 'nextStory':
322 {
323 fullAPI.jumpToStory(1);
324 break;
325 }
326
327 case 'prevStory':
328 {
329 fullAPI.jumpToStory(-1);
330 break;
331 }
332
333 case 'nextComponent':
334 {
335 fullAPI.jumpToComponent(1);
336 break;
337 }
338
339 case 'prevComponent':
340 {
341 fullAPI.jumpToComponent(-1);
342 break;
343 }
344
345 case 'fullScreen':
346 {
347 fullAPI.toggleFullscreen();
348 break;
349 }
350
351 case 'togglePanel':
352 {
353 if (isFullscreen) {
354 fullAPI.toggleFullscreen();
355 fullAPI.resetLayout();
356 }
357
358 fullAPI.togglePanel();
359 break;
360 }
361
362 case 'toggleNav':
363 {
364 if (isFullscreen) {
365 fullAPI.toggleFullscreen();
366 fullAPI.resetLayout();
367 }
368
369 fullAPI.toggleNav();
370 break;
371 }
372
373 case 'toolbar':
374 {
375 fullAPI.toggleToolbar();
376 break;
377 }
378
379 case 'panelPosition':
380 {
381 if (isFullscreen) {
382 fullAPI.toggleFullscreen();
383 }
384
385 if (!showPanel) {
386 fullAPI.togglePanel();
387 }
388
389 fullAPI.togglePanelPosition();
390 break;
391 }
392
393 case 'aboutPage':
394 {
395 fullAPI.navigate('/settings/about');
396 break;
397 }
398
399 case 'shortcutsPage':
400 {
401 fullAPI.navigate('/settings/shortcuts');
402 break;
403 }
404
405 case 'collapseAll':
406 {
407 fullAPI.collapseAll();
408 break;
409 }
410
411 case 'expandAll':
412 {
413 fullAPI.expandAll();
414 break;
415 }
416
417 default:
418 addonsShortcuts[feature].action();
419 break;
420 }
421 }
422 };
423
424 var _store$getState2 = store.getState(),
425 _store$getState2$shor = _store$getState2.shortcuts,
426 persistedShortcuts = _store$getState2$shor === void 0 ? defaultShortcuts : _store$getState2$shor;
427
428 var state = {
429 // Any saved shortcuts that are still in our set of defaults
430 shortcuts: keys(defaultShortcuts).reduce(function (acc, key) {
431 return Object.assign({}, acc, _defineProperty({}, key, persistedShortcuts[key] || defaultShortcuts[key]));
432 }, defaultShortcuts)
433 };
434
435 var initModule = function initModule() {
436 // Listen for keydown events in the manager
437 document.addEventListener('keydown', function (event) {
438 if (!focusInInput(event)) {
439 fullAPI.handleKeydownEvent(event);
440 }
441 }); // Also listen to keydown events sent over the channel
442
443 fullAPI.on(PREVIEW_KEYDOWN, function (data) {
444 fullAPI.handleKeydownEvent(data.event);
445 });
446 };
447
448 return {
449 api: api,
450 state: state,
451 init: initModule
452 };
453};
\No newline at end of file