@salutejs/plasma-new-hope 0.118.0-dev.0 → 0.118.1-canary.1345.10282607319.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. package/cjs/components/Modal/Modal.js +3 -1
  2. package/cjs/components/Modal/Modal.js.map +1 -1
  3. package/cjs/hooks/useFocusTrap.js +97 -0
  4. package/cjs/hooks/useFocusTrap.js.map +1 -0
  5. package/cjs/index.js +2 -0
  6. package/cjs/index.js.map +1 -1
  7. package/cjs/utils/focusManager.js +56 -0
  8. package/cjs/utils/focusManager.js.map +1 -0
  9. package/cjs/utils/scopeTab.js +37 -0
  10. package/cjs/utils/scopeTab.js.map +1 -0
  11. package/cjs/utils/tabbable.js +51 -0
  12. package/cjs/utils/tabbable.js.map +1 -0
  13. package/emotion/cjs/components/Modal/Modal.js +4 -3
  14. package/emotion/cjs/examples/plasma_b2c/components/Modal/Modal.stories.tsx +113 -1
  15. package/emotion/cjs/examples/plasma_web/components/Modal/Modal.stories.tsx +113 -1
  16. package/emotion/cjs/hooks/index.js +7 -0
  17. package/emotion/cjs/hooks/useFocusTrap.js +95 -0
  18. package/emotion/cjs/utils/focusManager.js +60 -0
  19. package/emotion/cjs/utils/scopeTab.js +35 -0
  20. package/emotion/cjs/utils/tabbable.js +46 -0
  21. package/emotion/cjs/utils/useFocusTrap.js +95 -0
  22. package/emotion/es/components/Modal/Modal.js +3 -2
  23. package/emotion/es/examples/plasma_b2c/components/Modal/Modal.stories.tsx +113 -1
  24. package/emotion/es/examples/plasma_web/components/Modal/Modal.stories.tsx +113 -1
  25. package/emotion/es/hooks/index.js +1 -0
  26. package/emotion/es/hooks/useFocusTrap.js +90 -0
  27. package/emotion/es/utils/focusManager.js +55 -0
  28. package/emotion/es/utils/scopeTab.js +30 -0
  29. package/emotion/es/utils/tabbable.js +40 -0
  30. package/emotion/es/utils/useFocusTrap.js +90 -0
  31. package/es/components/Modal/Modal.js +4 -2
  32. package/es/components/Modal/Modal.js.map +1 -1
  33. package/es/hooks/useFocusTrap.js +93 -0
  34. package/es/hooks/useFocusTrap.js.map +1 -0
  35. package/es/index.js +1 -0
  36. package/es/index.js.map +1 -1
  37. package/es/utils/focusManager.js +52 -0
  38. package/es/utils/focusManager.js.map +1 -0
  39. package/es/utils/scopeTab.js +33 -0
  40. package/es/utils/scopeTab.js.map +1 -0
  41. package/es/utils/tabbable.js +43 -0
  42. package/es/utils/tabbable.js.map +1 -0
  43. package/package.json +4 -4
  44. package/styled-components/cjs/components/Modal/Modal.js +4 -3
  45. package/styled-components/cjs/examples/plasma_b2c/components/Modal/Modal.stories.tsx +113 -1
  46. package/styled-components/cjs/examples/plasma_web/components/Modal/Modal.stories.tsx +113 -1
  47. package/styled-components/cjs/hooks/index.js +7 -0
  48. package/styled-components/cjs/hooks/useFocusTrap.js +95 -0
  49. package/styled-components/cjs/utils/focusManager.js +60 -0
  50. package/styled-components/cjs/utils/scopeTab.js +35 -0
  51. package/styled-components/cjs/utils/tabbable.js +46 -0
  52. package/styled-components/cjs/utils/useFocusTrap.js +95 -0
  53. package/styled-components/es/components/Modal/Modal.js +3 -2
  54. package/styled-components/es/examples/plasma_b2c/components/Modal/Modal.stories.tsx +113 -1
  55. package/styled-components/es/examples/plasma_web/components/Modal/Modal.stories.tsx +113 -1
  56. package/styled-components/es/hooks/index.js +1 -0
  57. package/styled-components/es/hooks/useFocusTrap.js +90 -0
  58. package/styled-components/es/utils/focusManager.js +55 -0
  59. package/styled-components/es/utils/scopeTab.js +30 -0
  60. package/styled-components/es/utils/tabbable.js +40 -0
  61. package/styled-components/es/utils/useFocusTrap.js +90 -0
  62. package/types/components/Modal/Modal.d.ts.map +1 -1
  63. package/types/hooks/index.d.ts +1 -0
  64. package/types/hooks/index.d.ts.map +1 -1
  65. package/types/hooks/useFocusTrap.d.ts +6 -0
  66. package/types/hooks/useFocusTrap.d.ts.map +1 -0
  67. package/types/utils/focusManager.d.ts +15 -0
  68. package/types/utils/focusManager.d.ts.map +1 -0
  69. package/types/utils/scopeTab.d.ts +7 -0
  70. package/types/utils/scopeTab.d.ts.map +1 -0
  71. package/types/utils/tabbable.d.ts +6 -0
  72. package/types/utils/tabbable.d.ts.map +1 -0
  73. package/types/utils/useFocusTrap.d.ts +6 -0
  74. package/types/utils/useFocusTrap.d.ts.map +1 -0
@@ -0,0 +1,52 @@
1
+ import { createClass as _createClass, classCallCheck as _classCallCheck, defineProperty as _defineProperty } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { findTabbableDescendants } from './tabbable.js';
3
+
4
+ /**
5
+ * Менеджер фокуса при открытии и закрытии нод при использовании focus-trap.
6
+ * Также необходим, чтобы фокус всегда должен находиться внутри необходимой ноды.
7
+ * */
8
+ var FocusManager = /*#__PURE__*/_createClass(function FocusManager() {
9
+ var _this = this;
10
+ _classCallCheck(this, FocusManager);
11
+ // массив с элементами, которые нужно зафокусить после анмаунта
12
+ _defineProperty(this, "focusAfterElements", []);
13
+ // массив с trap нодами
14
+ _defineProperty(this, "focusNodes", []);
15
+ _defineProperty(this, "handleFocus", function () {
16
+ // Фокус всегда должен находиться внутри необходимой ноды
17
+ var focusNode = _this.focusNodes[_this.focusNodes.length - 1];
18
+ if (!focusNode || focusNode.contains(document.activeElement)) {
19
+ return;
20
+ }
21
+
22
+ // Выделяем первый tabbable элемент
23
+ var el = findTabbableDescendants(focusNode)[0] || focusNode;
24
+ el.focus();
25
+ });
26
+ // добавление на фокус после анмаунта
27
+ _defineProperty(this, "markForFocusAfter", function (focusAfterNode) {
28
+ var node = focusAfterNode && focusAfterNode.current ? focusAfterNode.current : document.activeElement;
29
+ _this.focusAfterElements.push(node);
30
+ });
31
+ // фокус на необходимый элемент
32
+ _defineProperty(this, "returnFocus", function () {
33
+ var _this$focusAfterEleme;
34
+ var toFocus = (_this$focusAfterEleme = _this.focusAfterElements.pop()) !== null && _this$focusAfterEleme !== void 0 ? _this$focusAfterEleme : null;
35
+ if (toFocus) {
36
+ toFocus.focus();
37
+ }
38
+ });
39
+ // при маунте ноды
40
+ _defineProperty(this, "setupScopedFocus", function (element) {
41
+ _this.focusNodes.push(element);
42
+ document.addEventListener('focusin', _this.handleFocus, true);
43
+ });
44
+ // при анмаунте
45
+ _defineProperty(this, "teardownScopedFocus", function () {
46
+ _this.focusNodes.pop();
47
+ document.removeEventListener('focusin', _this.handleFocus);
48
+ });
49
+ });
50
+
51
+ export { FocusManager };
52
+ //# sourceMappingURL=focusManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusManager.js","sources":["../../src/utils/focusManager.ts"],"sourcesContent":["import { findTabbableDescendants } from './tabbable';\n\n/**\n * Менеджер фокуса при открытии и закрытии нод при использовании focus-trap.\n * Также необходим, чтобы фокус всегда должен находиться внутри необходимой ноды.\n * */\nexport class FocusManager {\n // массив с элементами, которые нужно зафокусить после анмаунта\n private focusAfterElements: Array<HTMLElement> = [];\n\n // массив с trap нодами\n private focusNodes: Array<HTMLElement> = [];\n\n private handleFocus = () => {\n // Фокус всегда должен находиться внутри необходимой ноды\n const focusNode = this.focusNodes[this.focusNodes.length - 1];\n\n if (!focusNode || focusNode.contains(document.activeElement)) {\n return;\n }\n\n // Выделяем первый tabbable элемент\n const el = findTabbableDescendants(focusNode)[0] || focusNode;\n el.focus();\n };\n\n // добавление на фокус после анмаунта\n public markForFocusAfter = (focusAfterNode?: React.RefObject<HTMLElement>) => {\n const node =\n focusAfterNode && focusAfterNode.current ? focusAfterNode.current : (document.activeElement as HTMLElement);\n this.focusAfterElements.push(node);\n };\n\n // фокус на необходимый элемент\n public returnFocus = () => {\n const toFocus = this.focusAfterElements.pop() ?? null;\n if (toFocus) {\n toFocus.focus();\n }\n };\n\n // при маунте ноды\n public setupScopedFocus = (element: HTMLElement) => {\n this.focusNodes.push(element);\n document.addEventListener('focusin', this.handleFocus, true);\n };\n\n // при анмаунте\n public teardownScopedFocus = () => {\n this.focusNodes.pop();\n document.removeEventListener('focusin', this.handleFocus);\n };\n}\n"],"names":["FocusManager","_createClass","_this","_classCallCheck","_defineProperty","focusNode","focusNodes","length","contains","document","activeElement","el","findTabbableDescendants","focus","focusAfterNode","node","current","focusAfterElements","push","_this$focusAfterEleme","toFocus","pop","element","addEventListener","handleFocus","removeEventListener"],"mappings":";;;AAEA;AACA;AACA;AACA;AACA,IAAaA,YAAY,gBAAAC,YAAA,CAAA,SAAAD,YAAA,GAAA;AAAA,EAAA,IAAAE,KAAA,GAAA,IAAA,CAAA;AAAAC,EAAAA,eAAA,OAAAH,YAAA,CAAA,CAAA;AACrB;AAAAI,EAAAA,eAAA,6BACiD,EAAE,CAAA,CAAA;AAEnD;AAAAA,EAAAA,eAAA,qBACyC,EAAE,CAAA,CAAA;AAAAA,EAAAA,eAAA,sBAErB,YAAM;AACxB;AACA,IAAA,IAAMC,SAAS,GAAGH,KAAI,CAACI,UAAU,CAACJ,KAAI,CAACI,UAAU,CAACC,MAAM,GAAG,CAAC,CAAC,CAAA;IAE7D,IAAI,CAACF,SAAS,IAAIA,SAAS,CAACG,QAAQ,CAACC,QAAQ,CAACC,aAAa,CAAC,EAAE;AAC1D,MAAA,OAAA;AACJ,KAAA;;AAEA;IACA,IAAMC,EAAE,GAAGC,uBAAuB,CAACP,SAAS,CAAC,CAAC,CAAC,CAAC,IAAIA,SAAS,CAAA;IAC7DM,EAAE,CAACE,KAAK,EAAE,CAAA;GACb,CAAA,CAAA;AAED;EAAAT,eAAA,CAAA,IAAA,EAAA,mBAAA,EAC2B,UAACU,cAA6C,EAAK;AAC1E,IAAA,IAAMC,IAAI,GACND,cAAc,IAAIA,cAAc,CAACE,OAAO,GAAGF,cAAc,CAACE,OAAO,GAAIP,QAAQ,CAACC,aAA6B,CAAA;AAC/GR,IAAAA,KAAI,CAACe,kBAAkB,CAACC,IAAI,CAACH,IAAI,CAAC,CAAA;GACrC,CAAA,CAAA;AAED;AAAAX,EAAAA,eAAA,sBACqB,YAAM;AAAA,IAAA,IAAAe,qBAAA,CAAA;AACvB,IAAA,IAAMC,OAAO,GAAAD,CAAAA,qBAAA,GAAGjB,KAAI,CAACe,kBAAkB,CAACI,GAAG,EAAE,MAAAF,IAAAA,IAAAA,qBAAA,KAAAA,KAAAA,CAAAA,GAAAA,qBAAA,GAAI,IAAI,CAAA;AACrD,IAAA,IAAIC,OAAO,EAAE;MACTA,OAAO,CAACP,KAAK,EAAE,CAAA;AACnB,KAAA;GACH,CAAA,CAAA;AAED;EAAAT,eAAA,CAAA,IAAA,EAAA,kBAAA,EAC0B,UAACkB,OAAoB,EAAK;AAChDpB,IAAAA,KAAI,CAACI,UAAU,CAACY,IAAI,CAACI,OAAO,CAAC,CAAA;IAC7Bb,QAAQ,CAACc,gBAAgB,CAAC,SAAS,EAAErB,KAAI,CAACsB,WAAW,EAAE,IAAI,CAAC,CAAA;GAC/D,CAAA,CAAA;AAED;AAAApB,EAAAA,eAAA,8BAC6B,YAAM;AAC/BF,IAAAA,KAAI,CAACI,UAAU,CAACe,GAAG,EAAE,CAAA;IACrBZ,QAAQ,CAACgB,mBAAmB,CAAC,SAAS,EAAEvB,KAAI,CAACsB,WAAW,CAAC,CAAA;GAC5D,CAAA,CAAA;AAAA,CAAA;;;;"}
@@ -0,0 +1,33 @@
1
+ import { findTabbableDescendants } from './tabbable.js';
2
+
3
+ /**
4
+ * Управлление фокусом лишь внутри ноды через tab
5
+ * @param node
6
+ * @param event
7
+ */
8
+ var scopeTab = function scopeTab(node, event) {
9
+ var tabbable = findTabbableDescendants(node);
10
+ if (!tabbable.length) {
11
+ event.preventDefault();
12
+ return;
13
+ }
14
+
15
+ // смотрим, является ли элемент крайним - первый или последним
16
+ var finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];
17
+ var leavingFinalTabbable = finalTabbable === document.activeElement || node === document.activeElement;
18
+
19
+ // если не является, то передаем обработку таба самому браузеру
20
+ if (!leavingFinalTabbable) {
21
+ return;
22
+ }
23
+
24
+ // иначе зацкливаемся
25
+ event.preventDefault();
26
+ var target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];
27
+ if (target) {
28
+ target.focus();
29
+ }
30
+ };
31
+
32
+ export { scopeTab };
33
+ //# sourceMappingURL=scopeTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopeTab.js","sources":["../../src/utils/scopeTab.ts"],"sourcesContent":["import { findTabbableDescendants } from './tabbable';\n\n/**\n * Управлление фокусом лишь внутри ноды через tab\n * @param node\n * @param event\n */\nexport const scopeTab = (node: HTMLElement, event: KeyboardEvent) => {\n const tabbable = findTabbableDescendants(node);\n if (!tabbable.length) {\n event.preventDefault();\n return;\n }\n\n // смотрим, является ли элемент крайним - первый или последним\n const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];\n const leavingFinalTabbable = finalTabbable === document.activeElement || node === document.activeElement;\n\n // если не является, то передаем обработку таба самому браузеру\n if (!leavingFinalTabbable) {\n return;\n }\n\n // иначе зацкливаемся\n event.preventDefault();\n const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];\n if (target) {\n target.focus();\n }\n};\n"],"names":["scopeTab","node","event","tabbable","findTabbableDescendants","length","preventDefault","finalTabbable","shiftKey","leavingFinalTabbable","document","activeElement","target","focus"],"mappings":";;AAEA;AACA;AACA;AACA;AACA;AACO,IAAMA,QAAQ,GAAG,SAAXA,QAAQA,CAAIC,IAAiB,EAAEC,KAAoB,EAAK;AACjE,EAAA,IAAMC,QAAQ,GAAGC,uBAAuB,CAACH,IAAI,CAAC,CAAA;AAC9C,EAAA,IAAI,CAACE,QAAQ,CAACE,MAAM,EAAE;IAClBH,KAAK,CAACI,cAAc,EAAE,CAAA;AACtB,IAAA,OAAA;AACJ,GAAA;;AAEA;AACA,EAAA,IAAMC,aAAa,GAAGJ,QAAQ,CAACD,KAAK,CAACM,QAAQ,GAAG,CAAC,GAAGL,QAAQ,CAACE,MAAM,GAAG,CAAC,CAAC,CAAA;AACxE,EAAA,IAAMI,oBAAoB,GAAGF,aAAa,KAAKG,QAAQ,CAACC,aAAa,IAAIV,IAAI,KAAKS,QAAQ,CAACC,aAAa,CAAA;;AAExG;EACA,IAAI,CAACF,oBAAoB,EAAE;AACvB,IAAA,OAAA;AACJ,GAAA;;AAEA;EACAP,KAAK,CAACI,cAAc,EAAE,CAAA;AACtB,EAAA,IAAMM,MAAM,GAAGT,QAAQ,CAACD,KAAK,CAACM,QAAQ,GAAGL,QAAQ,CAACE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AACjE,EAAA,IAAIO,MAAM,EAAE;IACRA,MAAM,CAACC,KAAK,EAAE,CAAA;AAClB,GAAA;AACJ;;;;"}
@@ -0,0 +1,43 @@
1
+ var tabbableNode = /input|select|textarea|button|object/;
2
+ var focusSelector = /*#__PURE__*/['input', 'select', 'textarea', 'a', 'button', 'object', '[tabindex]', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])'].join(',');
3
+ var isHidden = function isHidden(el) {
4
+ return el.offsetWidth <= 0 && el.offsetHeight <= 0 || el.style.display === 'none' || el.style.visibility === 'hidden' || el.style.opacity === '0';
5
+ };
6
+ var isVisible = function isVisible(element, parentContainer) {
7
+ var parentElement = element;
8
+ while (parentElement) {
9
+ if (parentElement === parentContainer || parentElement === document.body) {
10
+ break;
11
+ }
12
+ if (isHidden(parentElement)) {
13
+ return false;
14
+ }
15
+ parentElement = parentElement.parentNode;
16
+ }
17
+ return true;
18
+ };
19
+ var getElementTabIndex = function getElementTabIndex(element) {
20
+ var tabIndex = element.getAttribute('tabindex');
21
+ return tabIndex === null ? NaN : parseInt(tabIndex, 10);
22
+ };
23
+ var isFocusable = function isFocusable(element, parentContainer) {
24
+ var nodeName = element.nodeName.toLowerCase();
25
+ var isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));
26
+ var res = tabbableNode.test(nodeName) && !element.disabled || (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN);
27
+ return Boolean(res) && isVisible(element, parentContainer);
28
+ };
29
+ var isTabble = function isTabble(element, parentContainer) {
30
+ var tabIndex = getElementTabIndex(element);
31
+ var isTabIndexNaN = Number.isNaN(tabIndex);
32
+ return (isTabIndexNaN || tabIndex >= 0) && isFocusable(element, parentContainer);
33
+ };
34
+
35
+ // Все элементы внутри данной ноды, до которых можно добраться табом
36
+ var findTabbableDescendants = function findTabbableDescendants(element) {
37
+ return Array.from(element.querySelectorAll(focusSelector)).filter(function (el) {
38
+ return isTabble(el, element);
39
+ });
40
+ };
41
+
42
+ export { findTabbableDescendants, focusSelector, isFocusable, isTabble, isVisible };
43
+ //# sourceMappingURL=tabbable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabbable.js","sources":["../../src/utils/tabbable.ts"],"sourcesContent":["const tabbableNode = /input|select|textarea|button|object/;\n\nexport const focusSelector = [\n 'input',\n 'select',\n 'textarea',\n 'a',\n 'button',\n 'object',\n '[tabindex]',\n 'audio[controls]',\n 'video[controls]',\n '[contenteditable]:not([contenteditable=\"false\"])',\n].join(',');\n\nconst isHidden = (el: HTMLElement) => {\n return (\n (el.offsetWidth <= 0 && el.offsetHeight <= 0) ||\n el.style.display === 'none' ||\n el.style.visibility === 'hidden' ||\n el.style.opacity === '0'\n );\n};\n\nexport const isVisible = (element: HTMLElement, parentContainer?: HTMLElement): boolean => {\n let parentElement: HTMLElement = element;\n\n while (parentElement) {\n if (parentElement === parentContainer || parentElement === document.body) {\n break;\n }\n\n if (isHidden(parentElement)) {\n return false;\n }\n\n parentElement = parentElement.parentNode as HTMLElement;\n }\n\n return true;\n};\n\nconst getElementTabIndex = (element: HTMLElement): number => {\n const tabIndex = element.getAttribute('tabindex');\n\n return tabIndex === null ? NaN : parseInt(tabIndex as string, 10);\n};\n\nexport const isFocusable = (element: HTMLElement, parentContainer?: HTMLElement): boolean => {\n const nodeName = element.nodeName.toLowerCase();\n const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));\n const res =\n (tabbableNode.test(nodeName) && !(element as HTMLSelectElement).disabled) ||\n (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN);\n\n return Boolean(res) && isVisible(element, parentContainer);\n};\n\nexport const isTabble = (element: HTMLElement, parentContainer?: HTMLElement): boolean => {\n const tabIndex = getElementTabIndex(element);\n const isTabIndexNaN = Number.isNaN(tabIndex);\n return (isTabIndexNaN || tabIndex >= 0) && isFocusable(element, parentContainer);\n};\n\n// Все элементы внутри данной ноды, до которых можно добраться табом\nexport const findTabbableDescendants = (element: HTMLElement): Array<HTMLElement> => {\n return Array.from(element.querySelectorAll<HTMLElement>(focusSelector)).filter((el) => isTabble(el, element));\n};\n"],"names":["tabbableNode","focusSelector","join","isHidden","el","offsetWidth","offsetHeight","style","display","visibility","opacity","isVisible","element","parentContainer","parentElement","document","body","parentNode","getElementTabIndex","tabIndex","getAttribute","NaN","parseInt","isFocusable","nodeName","toLowerCase","isTabIndexNotNaN","Number","isNaN","res","test","disabled","HTMLAnchorElement","href","Boolean","isTabble","isTabIndexNaN","findTabbableDescendants","Array","from","querySelectorAll","filter"],"mappings":"AAAA,IAAMA,YAAY,GAAG,qCAAqC,CAAA;AAE7CC,IAAAA,aAAa,gBAAG,CACzB,OAAO,EACP,QAAQ,EACR,UAAU,EACV,GAAG,EACH,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,kDAAkD,CACrD,CAACC,IAAI,CAAC,GAAG,EAAC;AAEX,IAAMC,QAAQ,GAAG,SAAXA,QAAQA,CAAIC,EAAe,EAAK;AAClC,EAAA,OACKA,EAAE,CAACC,WAAW,IAAI,CAAC,IAAID,EAAE,CAACE,YAAY,IAAI,CAAC,IAC5CF,EAAE,CAACG,KAAK,CAACC,OAAO,KAAK,MAAM,IAC3BJ,EAAE,CAACG,KAAK,CAACE,UAAU,KAAK,QAAQ,IAChCL,EAAE,CAACG,KAAK,CAACG,OAAO,KAAK,GAAG,CAAA;AAEhC,CAAC,CAAA;AAEM,IAAMC,SAAS,GAAG,SAAZA,SAASA,CAAIC,OAAoB,EAAEC,eAA6B,EAAc;EACvF,IAAIC,aAA0B,GAAGF,OAAO,CAAA;AAExC,EAAA,OAAOE,aAAa,EAAE;IAClB,IAAIA,aAAa,KAAKD,eAAe,IAAIC,aAAa,KAAKC,QAAQ,CAACC,IAAI,EAAE;AACtE,MAAA,MAAA;AACJ,KAAA;AAEA,IAAA,IAAIb,QAAQ,CAACW,aAAa,CAAC,EAAE;AACzB,MAAA,OAAO,KAAK,CAAA;AAChB,KAAA;IAEAA,aAAa,GAAGA,aAAa,CAACG,UAAyB,CAAA;AAC3D,GAAA;AAEA,EAAA,OAAO,IAAI,CAAA;AACf,EAAC;AAED,IAAMC,kBAAkB,GAAG,SAArBA,kBAAkBA,CAAIN,OAAoB,EAAa;AACzD,EAAA,IAAMO,QAAQ,GAAGP,OAAO,CAACQ,YAAY,CAAC,UAAU,CAAC,CAAA;EAEjD,OAAOD,QAAQ,KAAK,IAAI,GAAGE,GAAG,GAAGC,QAAQ,CAACH,QAAQ,EAAY,EAAE,CAAC,CAAA;AACrE,CAAC,CAAA;AAEM,IAAMI,WAAW,GAAG,SAAdA,WAAWA,CAAIX,OAAoB,EAAEC,eAA6B,EAAc;EACzF,IAAMW,QAAQ,GAAGZ,OAAO,CAACY,QAAQ,CAACC,WAAW,EAAE,CAAA;EAC/C,IAAMC,gBAAgB,GAAG,CAACC,MAAM,CAACC,KAAK,CAACV,kBAAkB,CAACN,OAAO,CAAC,CAAC,CAAA;EACnE,IAAMiB,GAAG,GACJ7B,YAAY,CAAC8B,IAAI,CAACN,QAAQ,CAAC,IAAI,CAAEZ,OAAO,CAAuBmB,QAAQ,KACvEnB,OAAO,YAAYoB,iBAAiB,GAAGpB,OAAO,CAACqB,IAAI,IAAIP,gBAAgB,GAAGA,gBAAgB,CAAC,CAAA;EAEhG,OAAOQ,OAAO,CAACL,GAAG,CAAC,IAAIlB,SAAS,CAACC,OAAO,EAAEC,eAAe,CAAC,CAAA;AAC9D,EAAC;AAEM,IAAMsB,QAAQ,GAAG,SAAXA,QAAQA,CAAIvB,OAAoB,EAAEC,eAA6B,EAAc;AACtF,EAAA,IAAMM,QAAQ,GAAGD,kBAAkB,CAACN,OAAO,CAAC,CAAA;AAC5C,EAAA,IAAMwB,aAAa,GAAGT,MAAM,CAACC,KAAK,CAACT,QAAQ,CAAC,CAAA;AAC5C,EAAA,OAAO,CAACiB,aAAa,IAAIjB,QAAQ,IAAI,CAAC,KAAKI,WAAW,CAACX,OAAO,EAAEC,eAAe,CAAC,CAAA;AACpF,EAAC;;AAED;IACawB,uBAAuB,GAAG,SAA1BA,uBAAuBA,CAAIzB,OAAoB,EAAyB;AACjF,EAAA,OAAO0B,KAAK,CAACC,IAAI,CAAC3B,OAAO,CAAC4B,gBAAgB,CAAcvC,aAAa,CAAC,CAAC,CAACwC,MAAM,CAAC,UAACrC,EAAE,EAAA;AAAA,IAAA,OAAK+B,QAAQ,CAAC/B,EAAE,EAAEQ,OAAO,CAAC,CAAA;GAAC,CAAA,CAAA;AACjH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salutejs/plasma-new-hope",
3
- "version": "0.118.0-dev.0",
3
+ "version": "0.118.1-canary.1345.10282607319.0",
4
4
  "description": "Salute Design System blueprint",
5
5
  "main": "cjs/index.js",
6
6
  "module": "es/index.js",
@@ -80,7 +80,7 @@
80
80
  "@rollup/plugin-babel": "^6.0.4",
81
81
  "@rollup/plugin-commonjs": "^25.0.4",
82
82
  "@rollup/plugin-node-resolve": "^15.1.0",
83
- "@salutejs/plasma-sb-utils": "0.163.0-dev.0",
83
+ "@salutejs/plasma-sb-utils": "0.163.1-canary.1345.10282607319.0",
84
84
  "@storybook/addon-docs": "^7.6.17",
85
85
  "@storybook/addon-essentials": "^7.6.17",
86
86
  "@storybook/addons": "^7.6.17",
@@ -110,7 +110,7 @@
110
110
  "@linaria/core": "5.0.2",
111
111
  "@linaria/react": "5.0.3",
112
112
  "@popperjs/core": "2.11.8",
113
- "@salutejs/plasma-core": "1.165.0-dev.0",
113
+ "@salutejs/plasma-core": "1.165.1-canary.1345.10282607319.0",
114
114
  "dayjs": "1.11.11",
115
115
  "focus-visible": "5.2.0",
116
116
  "lodash.throttle": "4.1.1",
@@ -118,5 +118,5 @@
118
118
  "react-popper": "2.3.0",
119
119
  "storeon": "3.1.5"
120
120
  },
121
- "gitHead": "4d14239f0c11c8dc5f85020fe7c98e956419895e"
121
+ "gitHead": "ec124a34ebff82bfeca411fca9cf7961df4af595"
122
122
  }
@@ -11,8 +11,9 @@ var _engines = /*#__PURE__*/require("../../engines");
11
11
  var _Popup = /*#__PURE__*/require("../Popup");
12
12
  var _Overlay = /*#__PURE__*/require("../Overlay");
13
13
  var _utils = /*#__PURE__*/require("../Popup/utils");
14
+ var _hooks = /*#__PURE__*/require("../../hooks");
14
15
  var _Modal = /*#__PURE__*/require("./Modal.tokens");
15
- var _hooks = /*#__PURE__*/require("./hooks");
16
+ var _hooks2 = /*#__PURE__*/require("./hooks");
16
17
  var _base = /*#__PURE__*/require("./variations/_view/base");
17
18
  var _ModalContext = /*#__PURE__*/require("./ModalContext");
18
19
  var _excluded = ["id", "withAnimation", "onClose", "onOverlayClick", "onEscKeyDown", "closeOnEsc", "closeOnOverlayClick", "withBlur", "initialFocusRef", "focusAfterRef", "zIndex", "popupInfo", "children", "view", "isOpen"];
@@ -48,13 +49,13 @@ var modalRoot = exports.modalRoot = function modalRoot(Root) {
48
49
  view = _ref.view,
49
50
  isOpen = _ref.isOpen,
50
51
  rest = _objectWithoutProperties(_ref, _excluded);
51
- var trapRef = (0, _plasmaCore.useFocusTrap)(true, initialFocusRef, focusAfterRef);
52
+ var trapRef = (0, _hooks.useFocusTrap)(true, initialFocusRef, focusAfterRef, true);
52
53
  var popupController = (0, _Popup.usePopupContext)();
53
54
  var innerRef = (0, _plasmaCore.useForkRef)(trapRef, outerRootRef);
54
55
  var uniqId = (0, _plasmaCore.safeUseId)();
55
56
  var innerId = id || uniqId;
56
57
  var overlayBackgroundToken = withBlur ? "var(".concat(_Modal.tokens.modalOverlayWithBlurColor, ")") : "var(".concat(_Modal.tokens.modalOverlayColor, ")");
57
- var _useModal = (0, _hooks.useModal)({
58
+ var _useModal = (0, _hooks2.useModal)({
58
59
  id: innerId,
59
60
  isOpen: isOpen,
60
61
  closeOnEsc: closeOnEsc,
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useCallback, useRef, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import type { ComponentProps } from 'react';
4
4
  import type { StoryObj, Meta } from '@storybook/react';
@@ -6,6 +6,7 @@ import { SSRProvider } from '@salutejs/plasma-core';
6
6
 
7
7
  import { PopupProvider, popupClasses } from '../Popup/Popup';
8
8
  import { Button } from '../Button/Button';
9
+ import { TextField } from '../TextField/TextField';
9
10
  import { WithTheme } from '../../../_helpers';
10
11
 
11
12
  import { Modal, modalClasses } from './Modal';
@@ -206,3 +207,114 @@ export const ModalDemo: StoryObj<StoryModalProps> = {
206
207
  },
207
208
  render: (args) => <StoryModalDemo {...args} />,
208
209
  };
210
+
211
+ const StyledModalAnimation = styled(Modal)`
212
+ /* stylelint-disable */
213
+ && .${popupClasses.root} {
214
+ animation: fadeIn 1s forwards;
215
+ }
216
+
217
+ &&.${popupClasses.endAnimation} .${popupClasses.root} {
218
+ animation: fadeOut 1s forwards;
219
+ }
220
+
221
+ && .${modalClasses.overlay} {
222
+ animation: overlayFadeIn 1s forwards;
223
+ }
224
+
225
+ &&.${popupClasses.endAnimation} .${modalClasses.overlay} {
226
+ animation: overlayFadeOut 1s forwards;
227
+ }
228
+ /* stylelint-enable */
229
+
230
+ @keyframes overlayFadeIn {
231
+ from {
232
+ opacity: 0;
233
+ }
234
+
235
+ to {
236
+ opacity: 1;
237
+ }
238
+ }
239
+
240
+ @keyframes overlayFadeOut {
241
+ from {
242
+ opacity: 1;
243
+ }
244
+
245
+ to {
246
+ opacity: 0;
247
+ }
248
+ }
249
+
250
+ @keyframes fadeIn {
251
+ from {
252
+ opacity: 0;
253
+ transform: translate(-50%, 100%);
254
+ }
255
+
256
+ to {
257
+ opacity: 1;
258
+ transform: translate(-50%, -50%);
259
+ }
260
+ }
261
+
262
+ @keyframes fadeOut {
263
+ from {
264
+ opacity: 1;
265
+ transform: translate(-50%, -50%);
266
+ }
267
+
268
+ to {
269
+ opacity: 0;
270
+ transform: translate(-50%, 100%);
271
+ }
272
+ }
273
+ `;
274
+
275
+ const StoryModalAnimationDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProps) => {
276
+ const ref = useRef(null);
277
+ const [isOpen, setIsOpen] = useState(false);
278
+
279
+ const close = useCallback(() => {
280
+ setIsOpen(false);
281
+ }, []);
282
+
283
+ return (
284
+ <SSRProvider>
285
+ <PopupProvider>
286
+ <Button view="default" text="Открыть новое модальное окно" onClick={() => setIsOpen(!isOpen)} />
287
+ <StyledModalAnimation
288
+ id="modal"
289
+ frame="theme-root"
290
+ withAnimation
291
+ onClose={() => setIsOpen(false)}
292
+ isOpen={isOpen}
293
+ placement={placement}
294
+ offset={[offsetX, offsetY]}
295
+ initialFocusRef={ref}
296
+ {...rest}
297
+ >
298
+ <Content>
299
+ <TextField value="Text" onChange={() => {}} />
300
+ <TextField ref={ref} value="Text2" onChange={() => {}} />
301
+ <Button text="Закрыть" onClick={close} />
302
+ </Content>
303
+ </StyledModalAnimation>
304
+ </PopupProvider>
305
+ </SSRProvider>
306
+ );
307
+ };
308
+
309
+ export const ModalBottomAnimation: StoryObj<StoryModalProps> = {
310
+ args: {
311
+ placement: 'bottom',
312
+ withAnimation: true,
313
+ withBlur: false,
314
+ closeOnEsc: true,
315
+ closeOnOverlayClick: true,
316
+ offsetX: 0,
317
+ offsetY: 0,
318
+ },
319
+ render: (args) => <StoryModalAnimationDemo {...args} />,
320
+ };
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useCallback, useRef, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import type { ComponentProps } from 'react';
4
4
  import type { StoryObj, Meta } from '@storybook/react';
@@ -6,6 +6,7 @@ import { SSRProvider } from '@salutejs/plasma-core';
6
6
 
7
7
  import { PopupProvider, popupClasses } from '../Popup/Popup';
8
8
  import { Button } from '../Button/Button';
9
+ import { TextField } from '../TextField/TextField';
9
10
  import { WithTheme } from '../../../_helpers';
10
11
 
11
12
  import { Modal, modalClasses } from './Modal';
@@ -206,3 +207,114 @@ export const ModalDemo: StoryObj<StoryModalProps> = {
206
207
  },
207
208
  render: (args) => <StoryModalDemo {...args} />,
208
209
  };
210
+
211
+ const StyledModalAnimation = styled(Modal)`
212
+ /* stylelint-disable */
213
+ && .${popupClasses.root} {
214
+ animation: fadeIn 1s forwards;
215
+ }
216
+
217
+ &&.${popupClasses.endAnimation} .${popupClasses.root} {
218
+ animation: fadeOut 1s forwards;
219
+ }
220
+
221
+ && .${modalClasses.overlay} {
222
+ animation: overlayFadeIn 1s forwards;
223
+ }
224
+
225
+ &&.${popupClasses.endAnimation} .${modalClasses.overlay} {
226
+ animation: overlayFadeOut 1s forwards;
227
+ }
228
+ /* stylelint-enable */
229
+
230
+ @keyframes overlayFadeIn {
231
+ from {
232
+ opacity: 0;
233
+ }
234
+
235
+ to {
236
+ opacity: 1;
237
+ }
238
+ }
239
+
240
+ @keyframes overlayFadeOut {
241
+ from {
242
+ opacity: 1;
243
+ }
244
+
245
+ to {
246
+ opacity: 0;
247
+ }
248
+ }
249
+
250
+ @keyframes fadeIn {
251
+ from {
252
+ opacity: 0;
253
+ transform: translate(-50%, 100%);
254
+ }
255
+
256
+ to {
257
+ opacity: 1;
258
+ transform: translate(-50%, -50%);
259
+ }
260
+ }
261
+
262
+ @keyframes fadeOut {
263
+ from {
264
+ opacity: 1;
265
+ transform: translate(-50%, -50%);
266
+ }
267
+
268
+ to {
269
+ opacity: 0;
270
+ transform: translate(-50%, 100%);
271
+ }
272
+ }
273
+ `;
274
+
275
+ const StoryModalAnimationDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProps) => {
276
+ const ref = useRef(null);
277
+ const [isOpen, setIsOpen] = useState(false);
278
+
279
+ const close = useCallback(() => {
280
+ setIsOpen(false);
281
+ }, []);
282
+
283
+ return (
284
+ <SSRProvider>
285
+ <PopupProvider>
286
+ <Button view="default" text="Открыть новое модальное окно" onClick={() => setIsOpen(!isOpen)} />
287
+ <StyledModalAnimation
288
+ id="modal"
289
+ frame="theme-root"
290
+ withAnimation
291
+ onClose={() => setIsOpen(false)}
292
+ isOpen={isOpen}
293
+ placement={placement}
294
+ offset={[offsetX, offsetY]}
295
+ initialFocusRef={ref}
296
+ {...rest}
297
+ >
298
+ <Content>
299
+ <TextField value="Text" onChange={() => {}} />
300
+ <TextField ref={ref} value="Text2" onChange={() => {}} />
301
+ <Button text="Закрыть" onClick={close} />
302
+ </Content>
303
+ </StyledModalAnimation>
304
+ </PopupProvider>
305
+ </SSRProvider>
306
+ );
307
+ };
308
+
309
+ export const ModalBottomAnimation: StoryObj<StoryModalProps> = {
310
+ args: {
311
+ placement: 'bottom',
312
+ withAnimation: true,
313
+ withBlur: false,
314
+ closeOnEsc: true,
315
+ closeOnOverlayClick: true,
316
+ offsetX: 0,
317
+ offsetY: 0,
318
+ },
319
+ render: (args) => <StoryModalAnimationDemo {...args} />,
320
+ };
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "useDidMountEffect", {
9
9
  return _useDidMountEffect.useDidMountEffect;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "useFocusTrap", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _useFocusTrap.useFocusTrap;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "useForceUpdate", {
13
19
  enumerable: true,
14
20
  get: function get() {
@@ -40,6 +46,7 @@ Object.defineProperty(exports, "useUniqId", {
40
46
  }
41
47
  });
42
48
  var _useUniqId = /*#__PURE__*/require("./useUniqId");
49
+ var _useFocusTrap = /*#__PURE__*/require("./useFocusTrap");
43
50
  var _usePreviousValue = /*#__PURE__*/require("./usePreviousValue");
44
51
  var _useForceUpdate = /*#__PURE__*/require("./useForceUpdate");
45
52
  var _useDidMountEffect = /*#__PURE__*/require("./useDidMountEffect");
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useFocusTrap = void 0;
7
+ var _react = /*#__PURE__*/require("react");
8
+ var _focusManager = /*#__PURE__*/require("../utils/focusManager");
9
+ var _tabbable = /*#__PURE__*/require("../utils/tabbable");
10
+ var _scopeTab = /*#__PURE__*/require("../utils/scopeTab");
11
+ // Находим элемент для фокуса
12
+ var getFocusElement = function getFocusElement(node, firstFocusSelector) {
13
+ var focusElement = null;
14
+ if (firstFocusSelector) {
15
+ if (typeof firstFocusSelector === 'string') {
16
+ focusElement = node.querySelector(firstFocusSelector);
17
+ } else if (firstFocusSelector.current) {
18
+ focusElement = firstFocusSelector.current;
19
+ }
20
+ }
21
+ if (!focusElement) {
22
+ var children = Array.from(node.querySelectorAll(_tabbable.focusSelector));
23
+ focusElement = children.find(function (el) {
24
+ return (0, _tabbable.isTabble)(el);
25
+ }) || null;
26
+ }
27
+
28
+ // Если ничего не нашлось, то может ли сама нода быть под фокусом
29
+ if (!focusElement && (0, _tabbable.isFocusable)(node)) {
30
+ focusElement = node;
31
+ }
32
+ return focusElement;
33
+ };
34
+ var processNode = function processNode(node, firstFocusSelector, ref) {
35
+ if (ref !== null && ref !== void 0 && ref.current) {
36
+ ref.current.removeEventListener('animationend', function () {
37
+ processNode(node, firstFocusSelector, ref);
38
+ });
39
+ }
40
+ var focusElement = getFocusElement(node, firstFocusSelector);
41
+ if (focusElement) {
42
+ focusElement.focus();
43
+ }
44
+ };
45
+ var focusManager = /*#__PURE__*/new _focusManager.FocusManager();
46
+
47
+ /**
48
+ * Захватывает фокус внутри DOM node.
49
+ * */
50
+ var useFocusTrap = exports.useFocusTrap = function useFocusTrap() {
51
+ var active = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
52
+ var firstFocusSelector = arguments.length > 1 ? arguments[1] : undefined;
53
+ var focusAfterNode = arguments.length > 2 ? arguments[2] : undefined;
54
+ var focusAfterAnimation = arguments.length > 3 ? arguments[3] : undefined;
55
+ var ref = (0, _react.useRef)();
56
+ var setRef = (0, _react.useCallback)(function (node) {
57
+ if (ref.current) {
58
+ focusManager.teardownScopedFocus();
59
+ focusManager.returnFocus();
60
+ }
61
+ if (active && node) {
62
+ focusManager.setupScopedFocus(node);
63
+ focusManager.markForFocusAfter(focusAfterNode);
64
+
65
+ // Delay processing the HTML node by a frame. This ensures focus is assigned correctly.
66
+ setTimeout(function () {
67
+ if (ref !== null && ref !== void 0 && ref.current && node.ownerDocument && focusAfterAnimation) {
68
+ ref.current.addEventListener('animationend', function () {
69
+ processNode(node, firstFocusSelector, ref);
70
+ });
71
+ } else if (node.ownerDocument) {
72
+ processNode(node, firstFocusSelector);
73
+ }
74
+ });
75
+ ref.current = node;
76
+ return;
77
+ }
78
+ ref.current = null;
79
+ }, [active, firstFocusSelector]);
80
+ (0, _react.useEffect)(function () {
81
+ if (!active) {
82
+ return;
83
+ }
84
+ var handleKeyDown = function handleKeyDown(event) {
85
+ if (event.key === 'Tab' && ref.current) {
86
+ (0, _scopeTab.scopeTab)(ref.current, event);
87
+ }
88
+ };
89
+ document.addEventListener('keydown', handleKeyDown);
90
+ return function () {
91
+ document.removeEventListener('keydown', handleKeyDown);
92
+ };
93
+ }, [active]);
94
+ return setRef;
95
+ };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FocusManager = void 0;
7
+ var _tabbable = /*#__PURE__*/require("./tabbable");
8
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
9
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
10
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
11
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
14
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
+ /**
16
+ * Менеджер фокуса при открытии и закрытии нод при использовании focus-trap.
17
+ * Также необходим, чтобы фокус всегда должен находиться внутри необходимой ноды.
18
+ * */
19
+ var FocusManager = exports.FocusManager = /*#__PURE__*/_createClass(function FocusManager() {
20
+ var _this = this;
21
+ _classCallCheck(this, FocusManager);
22
+ // массив с элементами, которые нужно зафокусить после анмаунта
23
+ _defineProperty(this, "focusAfterElements", []);
24
+ // массив с trap нодами
25
+ _defineProperty(this, "focusNodes", []);
26
+ _defineProperty(this, "handleFocus", function () {
27
+ // Фокус всегда должен находиться внутри необходимой ноды
28
+ var focusNode = _this.focusNodes[_this.focusNodes.length - 1];
29
+ if (!focusNode || focusNode.contains(document.activeElement)) {
30
+ return;
31
+ }
32
+
33
+ // Выделяем первый tabbable элемент
34
+ var el = (0, _tabbable.findTabbableDescendants)(focusNode)[0] || focusNode;
35
+ el.focus();
36
+ });
37
+ // добавление на фокус после анмаунта
38
+ _defineProperty(this, "markForFocusAfter", function (focusAfterNode) {
39
+ var node = focusAfterNode && focusAfterNode.current ? focusAfterNode.current : document.activeElement;
40
+ _this.focusAfterElements.push(node);
41
+ });
42
+ // фокус на необходимый элемент
43
+ _defineProperty(this, "returnFocus", function () {
44
+ var _this$focusAfterEleme;
45
+ var toFocus = (_this$focusAfterEleme = _this.focusAfterElements.pop()) !== null && _this$focusAfterEleme !== void 0 ? _this$focusAfterEleme : null;
46
+ if (toFocus) {
47
+ toFocus.focus();
48
+ }
49
+ });
50
+ // при маунте ноды
51
+ _defineProperty(this, "setupScopedFocus", function (element) {
52
+ _this.focusNodes.push(element);
53
+ document.addEventListener('focusin', _this.handleFocus, true);
54
+ });
55
+ // при анмаунте
56
+ _defineProperty(this, "teardownScopedFocus", function () {
57
+ _this.focusNodes.pop();
58
+ document.removeEventListener('focusin', _this.handleFocus);
59
+ });
60
+ });