@vkontakte/vkui 6.2.1 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/cjs/components/Checkbox/Checkbox.d.ts.map +1 -1
  2. package/dist/cjs/components/Checkbox/Checkbox.js +10 -8
  3. package/dist/cjs/components/Checkbox/Checkbox.js.map +1 -1
  4. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  5. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js +1 -3
  6. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  7. package/dist/cjs/components/FocusTrap/FocusTrap.d.ts.map +1 -1
  8. package/dist/cjs/components/FocusTrap/FocusTrap.js +10 -1
  9. package/dist/cjs/components/FocusTrap/FocusTrap.js.map +1 -1
  10. package/dist/cjs/components/PanelHeaderContext/PanelHeaderContext.d.ts.map +1 -1
  11. package/dist/cjs/components/PanelHeaderContext/PanelHeaderContext.js +1 -1
  12. package/dist/cjs/components/PanelHeaderContext/PanelHeaderContext.js.map +1 -1
  13. package/dist/cjs/components/Snackbar/Snackbar.d.ts +6 -0
  14. package/dist/cjs/components/Snackbar/Snackbar.d.ts.map +1 -1
  15. package/dist/cjs/components/Snackbar/Snackbar.js +3 -1
  16. package/dist/cjs/components/Snackbar/Snackbar.js.map +1 -1
  17. package/dist/cjs/components/Snackbar/types.d.ts +1 -0
  18. package/dist/cjs/components/Snackbar/types.d.ts.map +1 -1
  19. package/dist/cjs/components/Snackbar/utils.d.ts +4 -8
  20. package/dist/cjs/components/Snackbar/utils.d.ts.map +1 -1
  21. package/dist/cjs/components/Snackbar/utils.js +31 -41
  22. package/dist/cjs/components/Snackbar/utils.js.map +1 -1
  23. package/dist/cjs/helpers/array.d.ts +5 -0
  24. package/dist/cjs/helpers/array.d.ts.map +1 -0
  25. package/dist/cjs/helpers/array.js +20 -0
  26. package/dist/cjs/helpers/array.js.map +1 -0
  27. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  28. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +9 -5
  29. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  30. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  31. package/dist/components/Checkbox/Checkbox.js +10 -8
  32. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  33. package/dist/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  34. package/dist/components/ChipsInputBase/ChipsInputBase.js +1 -3
  35. package/dist/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  36. package/dist/components/FocusTrap/FocusTrap.d.ts.map +1 -1
  37. package/dist/components/FocusTrap/FocusTrap.js +10 -1
  38. package/dist/components/FocusTrap/FocusTrap.js.map +1 -1
  39. package/dist/components/PanelHeaderContext/PanelHeaderContext.d.ts.map +1 -1
  40. package/dist/components/PanelHeaderContext/PanelHeaderContext.js +1 -1
  41. package/dist/components/PanelHeaderContext/PanelHeaderContext.js.map +1 -1
  42. package/dist/components/Snackbar/Snackbar.d.ts +6 -0
  43. package/dist/components/Snackbar/Snackbar.d.ts.map +1 -1
  44. package/dist/components/Snackbar/Snackbar.js +3 -1
  45. package/dist/components/Snackbar/Snackbar.js.map +1 -1
  46. package/dist/components/Snackbar/types.d.ts +1 -0
  47. package/dist/components/Snackbar/types.d.ts.map +1 -1
  48. package/dist/components/Snackbar/types.js.map +1 -1
  49. package/dist/components/Snackbar/utils.d.ts +4 -8
  50. package/dist/components/Snackbar/utils.d.ts.map +1 -1
  51. package/dist/components/Snackbar/utils.js +30 -41
  52. package/dist/components/Snackbar/utils.js.map +1 -1
  53. package/dist/components.css +2 -2
  54. package/dist/components.css.map +1 -1
  55. package/dist/components.js.tmp +101 -75
  56. package/dist/cssm/components/Checkbox/Checkbox.d.ts.map +1 -1
  57. package/dist/cssm/components/Checkbox/Checkbox.js +10 -8
  58. package/dist/cssm/components/Checkbox/Checkbox.js.map +1 -1
  59. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  60. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js +1 -3
  61. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  62. package/dist/cssm/components/FocusTrap/FocusTrap.d.ts.map +1 -1
  63. package/dist/cssm/components/FocusTrap/FocusTrap.js +10 -1
  64. package/dist/cssm/components/FocusTrap/FocusTrap.js.map +1 -1
  65. package/dist/cssm/components/PanelHeaderContext/PanelHeaderContext.d.ts.map +1 -1
  66. package/dist/cssm/components/PanelHeaderContext/PanelHeaderContext.js +1 -1
  67. package/dist/cssm/components/PanelHeaderContext/PanelHeaderContext.js.map +1 -1
  68. package/dist/cssm/components/Search/Search.module.css +4 -5
  69. package/dist/cssm/components/Snackbar/Snackbar.d.ts +6 -0
  70. package/dist/cssm/components/Snackbar/Snackbar.d.ts.map +1 -1
  71. package/dist/cssm/components/Snackbar/Snackbar.js +3 -1
  72. package/dist/cssm/components/Snackbar/Snackbar.js.map +1 -1
  73. package/dist/cssm/components/Snackbar/Snackbar.module.css +47 -33
  74. package/dist/cssm/components/Snackbar/types.d.ts +1 -0
  75. package/dist/cssm/components/Snackbar/types.d.ts.map +1 -1
  76. package/dist/cssm/components/Snackbar/types.js.map +1 -1
  77. package/dist/cssm/components/Snackbar/utils.d.ts +4 -8
  78. package/dist/cssm/components/Snackbar/utils.d.ts.map +1 -1
  79. package/dist/cssm/components/Snackbar/utils.js +30 -41
  80. package/dist/cssm/components/Snackbar/utils.js.map +1 -1
  81. package/dist/cssm/helpers/array.d.ts +5 -0
  82. package/dist/cssm/helpers/array.d.ts.map +1 -0
  83. package/dist/cssm/helpers/array.js +10 -0
  84. package/dist/cssm/helpers/array.js.map +1 -0
  85. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  86. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +9 -5
  87. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  88. package/dist/helpers/array.d.ts +5 -0
  89. package/dist/helpers/array.d.ts.map +1 -0
  90. package/dist/helpers/array.js +10 -0
  91. package/dist/helpers/array.js.map +1 -0
  92. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  93. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +9 -5
  94. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  95. package/dist/vkui.css +2 -2
  96. package/dist/vkui.css.map +1 -1
  97. package/dist/vkui.js.tmp +101 -75
  98. package/package.json +1 -1
  99. package/src/components/Checkbox/Checkbox.tsx +11 -8
  100. package/src/components/ChipsInputBase/ChipsInputBase.tsx +1 -3
  101. package/src/components/FocusTrap/FocusTrap.tsx +10 -1
  102. package/src/components/PanelHeaderContext/PanelHeaderContext.tsx +2 -0
  103. package/src/components/Search/Search.module.css +4 -5
  104. package/src/components/Snackbar/Snackbar.module.css +47 -33
  105. package/src/components/Snackbar/Snackbar.tsx +9 -0
  106. package/src/components/Snackbar/types.ts +8 -1
  107. package/src/components/Snackbar/utils.ts +46 -42
  108. package/src/helpers/array.ts +9 -0
  109. package/src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts +18 -10
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/FocusTrap/FocusTrap.tsx"],"sourcesContent":["import { AllHTMLAttributes, useCallback, useRef, useState } from 'react';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { FOCUSABLE_ELEMENTS_LIST, Keys, pressedKey } from '../../lib/accessibility';\nimport {\n contains,\n getActiveElementByAnotherElement,\n getWindow,\n isHTMLElement,\n useDOM,\n} from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nconst FOCUSABLE_ELEMENTS: string = FOCUSABLE_ELEMENTS_LIST.join();\nexport interface FocusTrapProps<T extends HTMLElement = HTMLElement>\n extends AllHTMLAttributes<T>,\n HasRootRef<T>,\n HasComponent {\n autoFocus?: boolean;\n restoreFocus?: boolean | (() => boolean);\n mount?: boolean;\n timeout?: number;\n onClose?: () => void;\n /**\n * Форсированное отключение захвата фокуса\n */\n disabled?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/FocusTrap\n */\nexport const FocusTrap = <T extends HTMLElement = HTMLElement>({\n Component = 'div',\n onClose,\n autoFocus = true,\n restoreFocus = true,\n disabled = false,\n mount = true,\n timeout = 0,\n getRootRef,\n children,\n ...restProps\n}: FocusTrapProps<T>) => {\n const ref = useExternRef<T>(getRootRef);\n const { document } = useDOM();\n\n const focusableNodesRef = useRef<HTMLElement[]>([]);\n\n const [restoreFocusTo, setRestoreFocusTo] = useState<Element | null>(null);\n\n const focusNodeByIndex = (nodeIndex: number) => {\n const element = focusableNodesRef.current[nodeIndex];\n\n if (element) {\n element.focus();\n }\n };\n\n const recalculateFocusableNodesRef = (parentNode: HTMLElement) => {\n // eslint-disable-next-line no-restricted-properties\n const newFocusableElements = parentNode.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENTS);\n\n const nodes: HTMLElement[] = [];\n newFocusableElements.forEach((focusableEl) => {\n const { display, visibility } = getComputedStyle(focusableEl);\n if (display !== 'none' && visibility !== 'hidden') {\n nodes.push(focusableEl);\n }\n });\n\n if (nodes.length === 0) {\n // Чтобы фокус был хотя бы на родителе\n nodes.push(parentNode);\n }\n focusableNodesRef.current = nodes;\n };\n\n const onMutateParentHandler = (parentNode: HTMLElement) => {\n recalculateFocusableNodesRef(parentNode);\n\n if (document) {\n const activeElement = document.activeElement as HTMLElement;\n const currentElementIndex = Math.max(\n document.activeElement ? focusableNodesRef.current.indexOf(activeElement) : -1,\n 0,\n );\n focusNodeByIndex(currentElementIndex);\n }\n };\n\n useIsomorphicLayoutEffect(\n function collectFocusableNodesRef() {\n if (!ref.current) {\n return;\n }\n const parentNode = ref.current;\n const observer = new MutationObserver(() => onMutateParentHandler(parentNode));\n observer.observe(ref.current, {\n subtree: true,\n childList: true,\n });\n recalculateFocusableNodesRef(parentNode);\n return () => observer.disconnect();\n },\n [ref],\n );\n\n useIsomorphicLayoutEffect(\n function tryToAutoFocusToFirstNode() {\n if (!ref.current || !autoFocus || disabled) {\n return;\n }\n\n const autoFocusToFirstNode = () => {\n if (!ref.current || !focusableNodesRef.current.length) {\n return;\n }\n const activeElement = getActiveElementByAnotherElement(ref.current);\n if (!contains(ref.current, activeElement)) {\n focusableNodesRef.current[0].focus();\n }\n };\n const timeoutId = setTimeout(autoFocusToFirstNode, timeout);\n return () => {\n clearTimeout(timeoutId);\n };\n },\n [autoFocus, timeout, disabled],\n );\n\n const restoreFocusImpl = useCallback(() => {\n const shouldRestoreFocus = typeof restoreFocus === 'function' ? restoreFocus() : restoreFocus;\n\n if (!restoreFocusTo || !isHTMLElement(restoreFocusTo) || !shouldRestoreFocus) {\n return;\n }\n\n setTimeout(() => {\n if (restoreFocusTo) {\n restoreFocusTo.focus();\n setRestoreFocusTo(null);\n }\n }, timeout);\n }, [restoreFocus, restoreFocusTo, timeout]);\n\n useIsomorphicLayoutEffect(\n function calculateRestoreFocusTo() {\n if (!ref.current || !restoreFocus || !mount) {\n setRestoreFocusTo(null);\n return;\n }\n setRestoreFocusTo(getActiveElementByAnotherElement(ref.current));\n },\n [ref, mount, restoreFocus],\n );\n\n useIsomorphicLayoutEffect(\n function tryToRestoreFocusOnUnmount() {\n return () => restoreFocusImpl();\n },\n [restoreFocusImpl],\n );\n\n useIsomorphicLayoutEffect(\n function tryToRestoreFocusWhenFakeUnmount() {\n if (!mount) {\n restoreFocusImpl();\n }\n },\n [mount, restoreFocusImpl],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!ref.current) {\n return;\n }\n\n const onDocumentKeydown = (event: KeyboardEvent) => {\n if (disabled) {\n return;\n }\n\n const pressedKeyResult = pressedKey(event);\n\n switch (pressedKeyResult) {\n case Keys.TAB: {\n if (!focusableNodesRef.current.length) {\n return false;\n }\n\n const lastIdx = focusableNodesRef.current.length - 1;\n const targetIdx = focusableNodesRef.current.findIndex((node) => node === event.target);\n\n const shouldFocusFirstNode =\n targetIdx === -1 || (targetIdx === lastIdx && !event.shiftKey);\n\n if (shouldFocusFirstNode || (targetIdx === 0 && event.shiftKey)) {\n event.preventDefault();\n\n const node = focusableNodesRef.current[shouldFocusFirstNode ? 0 : lastIdx];\n\n if (node !== getActiveElementByAnotherElement(node)) {\n node.focus();\n }\n\n return false;\n }\n\n break;\n }\n case Keys.ESCAPE: {\n if (onClose) {\n event.preventDefault();\n onClose();\n }\n }\n }\n\n return true;\n };\n\n const doc = getWindow(ref.current).document;\n doc.addEventListener('keydown', onDocumentKeydown, {\n capture: true,\n });\n return () => {\n doc.removeEventListener('keydown', onDocumentKeydown, true);\n };\n }, [onClose, ref, disabled]);\n\n return (\n <Component tabIndex={-1} ref={ref} {...restProps}>\n {children}\n </Component>\n );\n};\n"],"names":["useCallback","useRef","useState","useExternRef","FOCUSABLE_ELEMENTS_LIST","Keys","pressedKey","contains","getActiveElementByAnotherElement","getWindow","isHTMLElement","useDOM","useIsomorphicLayoutEffect","FOCUSABLE_ELEMENTS","join","FocusTrap","Component","onClose","autoFocus","restoreFocus","disabled","mount","timeout","getRootRef","children","restProps","ref","document","focusableNodesRef","restoreFocusTo","setRestoreFocusTo","focusNodeByIndex","nodeIndex","element","current","focus","recalculateFocusableNodesRef","parentNode","newFocusableElements","querySelectorAll","nodes","forEach","focusableEl","display","visibility","getComputedStyle","push","length","onMutateParentHandler","activeElement","currentElementIndex","Math","max","indexOf","collectFocusableNodesRef","observer","MutationObserver","observe","subtree","childList","disconnect","tryToAutoFocusToFirstNode","autoFocusToFirstNode","timeoutId","setTimeout","clearTimeout","restoreFocusImpl","shouldRestoreFocus","calculateRestoreFocusTo","tryToRestoreFocusOnUnmount","tryToRestoreFocusWhenFakeUnmount","onDocumentKeydown","event","pressedKeyResult","TAB","lastIdx","targetIdx","findIndex","node","target","shouldFocusFirstNode","shiftKey","preventDefault","ESCAPE","doc","addEventListener","capture","removeEventListener","tabIndex"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/FocusTrap/FocusTrap.tsx"],"sourcesContent":["import { AllHTMLAttributes, useCallback, useRef, useState } from 'react';\nimport { arraysEquals } from '../../helpers/array';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { FOCUSABLE_ELEMENTS_LIST, Keys, pressedKey } from '../../lib/accessibility';\nimport {\n contains,\n getActiveElementByAnotherElement,\n getWindow,\n isHTMLElement,\n useDOM,\n} from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nconst FOCUSABLE_ELEMENTS: string = FOCUSABLE_ELEMENTS_LIST.join();\nexport interface FocusTrapProps<T extends HTMLElement = HTMLElement>\n extends AllHTMLAttributes<T>,\n HasRootRef<T>,\n HasComponent {\n autoFocus?: boolean;\n restoreFocus?: boolean | (() => boolean);\n mount?: boolean;\n timeout?: number;\n onClose?: () => void;\n /**\n * Форсированное отключение захвата фокуса\n */\n disabled?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/FocusTrap\n */\nexport const FocusTrap = <T extends HTMLElement = HTMLElement>({\n Component = 'div',\n onClose,\n autoFocus = true,\n restoreFocus = true,\n disabled = false,\n mount = true,\n timeout = 0,\n getRootRef,\n children,\n ...restProps\n}: FocusTrapProps<T>) => {\n const ref = useExternRef<T>(getRootRef);\n const { document } = useDOM();\n\n const focusableNodesRef = useRef<HTMLElement[]>([]);\n\n const [restoreFocusTo, setRestoreFocusTo] = useState<Element | null>(null);\n\n const focusNodeByIndex = (nodeIndex: number) => {\n const element = focusableNodesRef.current[nodeIndex];\n\n if (element) {\n element.focus({\n preventScroll: true,\n });\n }\n };\n\n const recalculateFocusableNodesRef = (parentNode: HTMLElement) => {\n // eslint-disable-next-line no-restricted-properties\n const newFocusableElements = parentNode.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENTS);\n\n const nodes: HTMLElement[] = [];\n newFocusableElements.forEach((focusableEl) => {\n const { display, visibility } = getComputedStyle(focusableEl);\n if (display !== 'none' && visibility !== 'hidden') {\n nodes.push(focusableEl);\n }\n });\n\n if (nodes.length === 0) {\n // Чтобы фокус был хотя бы на родителе\n nodes.push(parentNode);\n }\n focusableNodesRef.current = nodes;\n };\n\n const onMutateParentHandler = (parentNode: HTMLElement) => {\n const oldFocusableNodes = [...focusableNodesRef.current];\n\n recalculateFocusableNodesRef(parentNode);\n\n if (arraysEquals(oldFocusableNodes, focusableNodesRef.current)) {\n return;\n }\n\n if (document) {\n const activeElement = document.activeElement as HTMLElement;\n const currentElementIndex = Math.max(\n document.activeElement ? focusableNodesRef.current.indexOf(activeElement) : -1,\n 0,\n );\n focusNodeByIndex(currentElementIndex);\n }\n };\n\n useIsomorphicLayoutEffect(\n function collectFocusableNodesRef() {\n if (!ref.current) {\n return;\n }\n const parentNode = ref.current;\n const observer = new MutationObserver(() => onMutateParentHandler(parentNode));\n observer.observe(ref.current, {\n subtree: true,\n childList: true,\n });\n recalculateFocusableNodesRef(parentNode);\n return () => observer.disconnect();\n },\n [ref],\n );\n\n useIsomorphicLayoutEffect(\n function tryToAutoFocusToFirstNode() {\n if (!ref.current || !autoFocus || disabled) {\n return;\n }\n\n const autoFocusToFirstNode = () => {\n if (!ref.current || !focusableNodesRef.current.length) {\n return;\n }\n const activeElement = getActiveElementByAnotherElement(ref.current);\n if (!contains(ref.current, activeElement)) {\n focusableNodesRef.current[0].focus();\n }\n };\n const timeoutId = setTimeout(autoFocusToFirstNode, timeout);\n return () => {\n clearTimeout(timeoutId);\n };\n },\n [autoFocus, timeout, disabled],\n );\n\n const restoreFocusImpl = useCallback(() => {\n const shouldRestoreFocus = typeof restoreFocus === 'function' ? restoreFocus() : restoreFocus;\n\n if (!restoreFocusTo || !isHTMLElement(restoreFocusTo) || !shouldRestoreFocus) {\n return;\n }\n\n setTimeout(() => {\n if (restoreFocusTo) {\n restoreFocusTo.focus();\n setRestoreFocusTo(null);\n }\n }, timeout);\n }, [restoreFocus, restoreFocusTo, timeout]);\n\n useIsomorphicLayoutEffect(\n function calculateRestoreFocusTo() {\n if (!ref.current || !restoreFocus || !mount) {\n setRestoreFocusTo(null);\n return;\n }\n setRestoreFocusTo(getActiveElementByAnotherElement(ref.current));\n },\n [ref, mount, restoreFocus],\n );\n\n useIsomorphicLayoutEffect(\n function tryToRestoreFocusOnUnmount() {\n return () => restoreFocusImpl();\n },\n [restoreFocusImpl],\n );\n\n useIsomorphicLayoutEffect(\n function tryToRestoreFocusWhenFakeUnmount() {\n if (!mount) {\n restoreFocusImpl();\n }\n },\n [mount, restoreFocusImpl],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!ref.current) {\n return;\n }\n\n const onDocumentKeydown = (event: KeyboardEvent) => {\n if (disabled) {\n return;\n }\n\n const pressedKeyResult = pressedKey(event);\n\n switch (pressedKeyResult) {\n case Keys.TAB: {\n if (!focusableNodesRef.current.length) {\n return false;\n }\n\n const lastIdx = focusableNodesRef.current.length - 1;\n const targetIdx = focusableNodesRef.current.findIndex((node) => node === event.target);\n\n const shouldFocusFirstNode =\n targetIdx === -1 || (targetIdx === lastIdx && !event.shiftKey);\n\n if (shouldFocusFirstNode || (targetIdx === 0 && event.shiftKey)) {\n event.preventDefault();\n\n const node = focusableNodesRef.current[shouldFocusFirstNode ? 0 : lastIdx];\n\n if (node !== getActiveElementByAnotherElement(node)) {\n node.focus();\n }\n\n return false;\n }\n\n break;\n }\n case Keys.ESCAPE: {\n if (onClose) {\n event.preventDefault();\n onClose();\n }\n }\n }\n\n return true;\n };\n\n const doc = getWindow(ref.current).document;\n doc.addEventListener('keydown', onDocumentKeydown, {\n capture: true,\n });\n return () => {\n doc.removeEventListener('keydown', onDocumentKeydown, true);\n };\n }, [onClose, ref, disabled]);\n\n return (\n <Component tabIndex={-1} ref={ref} {...restProps}>\n {children}\n </Component>\n );\n};\n"],"names":["useCallback","useRef","useState","arraysEquals","useExternRef","FOCUSABLE_ELEMENTS_LIST","Keys","pressedKey","contains","getActiveElementByAnotherElement","getWindow","isHTMLElement","useDOM","useIsomorphicLayoutEffect","FOCUSABLE_ELEMENTS","join","FocusTrap","Component","onClose","autoFocus","restoreFocus","disabled","mount","timeout","getRootRef","children","restProps","ref","document","focusableNodesRef","restoreFocusTo","setRestoreFocusTo","focusNodeByIndex","nodeIndex","element","current","focus","preventScroll","recalculateFocusableNodesRef","parentNode","newFocusableElements","querySelectorAll","nodes","forEach","focusableEl","display","visibility","getComputedStyle","push","length","onMutateParentHandler","oldFocusableNodes","activeElement","currentElementIndex","Math","max","indexOf","collectFocusableNodesRef","observer","MutationObserver","observe","subtree","childList","disconnect","tryToAutoFocusToFirstNode","autoFocusToFirstNode","timeoutId","setTimeout","clearTimeout","restoreFocusImpl","shouldRestoreFocus","calculateRestoreFocusTo","tryToRestoreFocusOnUnmount","tryToRestoreFocusWhenFakeUnmount","onDocumentKeydown","event","pressedKeyResult","TAB","lastIdx","targetIdx","findIndex","node","target","shouldFocusFirstNode","shiftKey","preventDefault","ESCAPE","doc","addEventListener","capture","removeEventListener","tabIndex"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelHeaderContext.d.ts","sourceRoot":"","sources":["../../../src/components/PanelHeaderContext/PanelHeaderContext.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAW7D,MAAM,WAAW,uBAAwB,SAAQ,yBAAyB,CAAC,cAAc,CAAC;IACxF,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,2DAM5B,uBAAuB,mDAwDzB,CAAC"}
1
+ {"version":3,"file":"PanelHeaderContext.d.ts","sourceRoot":"","sources":["../../../src/components/PanelHeaderContext/PanelHeaderContext.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAW7D,MAAM,WAAW,uBAAwB,SAAQ,yBAAyB,CAAC,cAAc,CAAC;IACxF,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,2DAM5B,uBAAuB,mDA0DzB,CAAC"}
@@ -27,7 +27,7 @@ const sizeXClassNames = {
27
27
  const platform = usePlatform();
28
28
  const { sizeX = 'none' } = useAdaptivity();
29
29
  const elementRef = React.useRef(null);
30
- const [animationState, animationHandlers] = useCSSKeyframesAnimationController(opened ? 'enter' : 'exit');
30
+ const [animationState, animationHandlers] = useCSSKeyframesAnimationController(opened ? 'enter' : 'exit', undefined, true);
31
31
  const visible = animationState !== 'exited';
32
32
  useScrollLock(platform !== 'vkcom' && visible);
33
33
  const handleGlobalOnClickOutside = React.useCallback((event)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PanelHeaderContext/PanelHeaderContext.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useGlobalOnClickOutside } from '../../hooks/useGlobalOnClickOutside';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { FixedLayout } from '../FixedLayout/FixedLayout';\nimport styles from './PanelHeaderContext.module.css';\n\nconst sizeXClassNames = {\n none: styles['PanelHeaderContext--sizeX-none'],\n compact: styles['PanelHeaderContext--sizeX-compact'],\n regular: styles['PanelHeaderContext--sizeX-regular'],\n};\n\nexport interface PanelHeaderContextProps extends HTMLAttributesWithRootRef<HTMLDivElement> {\n opened: boolean;\n onClose: VoidFunction;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/PanelHeaderContext\n */\nexport const PanelHeaderContext = ({\n children,\n opened = false,\n className,\n onClose,\n ...restProps\n}: PanelHeaderContextProps) => {\n const platform = usePlatform();\n const { sizeX = 'none' } = useAdaptivity();\n const elementRef = React.useRef<HTMLDivElement>(null);\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n opened ? 'enter' : 'exit',\n );\n const visible = animationState !== 'exited';\n\n useScrollLock(platform !== 'vkcom' && visible);\n\n const handleGlobalOnClickOutside = React.useCallback(\n (event: MouseEvent) => {\n if (opened) {\n event.stopPropagation();\n onClose();\n }\n },\n [opened, onClose],\n );\n\n useGlobalOnClickOutside(handleGlobalOnClickOutside, visible ? elementRef : null);\n\n if (!visible) {\n return null;\n }\n\n return (\n <FixedLayout\n {...restProps}\n className={classNames(\n styles['PanelHeaderContext'],\n platform === 'ios' && styles['PanelHeaderContext--ios'],\n opened ? styles['PanelHeaderContext--opened'] : styles['PanelHeaderContext--closing'],\n sizeXClassNames[sizeX],\n className,\n )}\n vertical=\"top\"\n >\n <div\n onClick={(event) => {\n event.stopPropagation();\n onClose();\n }}\n className={styles['PanelHeaderContext__fade']}\n />\n <div\n data-testid={process.env.NODE_ENV === 'test' ? 'content' : undefined}\n className={styles['PanelHeaderContext__in']}\n ref={elementRef}\n {...animationHandlers}\n >\n <div className={styles['PanelHeaderContext__content']}>{children}</div>\n </div>\n </FixedLayout>\n );\n};\n"],"names":["React","classNames","useAdaptivity","useGlobalOnClickOutside","usePlatform","useCSSKeyframesAnimationController","useScrollLock","FixedLayout","sizeXClassNames","none","compact","regular","PanelHeaderContext","children","opened","className","onClose","restProps","platform","sizeX","elementRef","useRef","animationState","animationHandlers","visible","handleGlobalOnClickOutside","useCallback","event","stopPropagation","vertical","div","onClick","data-testid","process","env","NODE_ENV","undefined","ref"],"mappings":";;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,uBAAuB,QAAQ,sCAAsC;AAC9E,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,kCAAkC,QAAQ,sBAAsB;AAEzE,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AAGzD,MAAMC,kBAAkB;IACtBC,IAAI;IACJC,OAAO;IACPC,OAAO;AACT;AAOA;;CAEC,GACD,OAAO,MAAMC,qBAAqB;QAAC,EACjCC,QAAQ,EACRC,SAAS,KAAK,EACdC,SAAS,EACTC,OAAO,EAEiB,WADrBC;QAJHJ;QACAC;QACAC;QACAC;;IAGA,MAAME,WAAWd;IACjB,MAAM,EAAEe,QAAQ,MAAM,EAAE,GAAGjB;IAC3B,MAAMkB,aAAapB,MAAMqB,MAAM,CAAiB;IAChD,MAAM,CAACC,gBAAgBC,kBAAkB,GAAGlB,mCAC1CS,SAAS,UAAU;IAErB,MAAMU,UAAUF,mBAAmB;IAEnChB,cAAcY,aAAa,WAAWM;IAEtC,MAAMC,6BAA6BzB,MAAM0B,WAAW,CAClD,CAACC;QACC,IAAIb,QAAQ;YACVa,MAAMC,eAAe;YACrBZ;QACF;IACF,GACA;QAACF;QAAQE;KAAQ;IAGnBb,wBAAwBsB,4BAA4BD,UAAUJ,aAAa;IAE3E,IAAI,CAACI,SAAS;QACZ,OAAO;IACT;IAEA,qBACE,MAACjB,qDACKU;QACJF,WAAWd,qCAETiB,aAAa,wCACbJ,+EACAN,eAAe,CAACW,MAAM,EACtBJ;QAEFc,UAAS;;0BAET,KAACC;gBACCC,SAAS,CAACJ;oBACRA,MAAMC,eAAe;oBACrBZ;gBACF;gBACAD,SAAS;;0BAEX,KAACe;gBACCE,eAAaC,QAAQC,GAAG,CAACC,QAAQ,KAAK,SAAS,YAAYC;gBAC3DrB,SAAS;gBACTsB,KAAKjB;eACDG;0BAEJ,cAAA,KAACO;oBAAIf,SAAS;8BAA0CF;;;;;AAIhE,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/PanelHeaderContext/PanelHeaderContext.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useGlobalOnClickOutside } from '../../hooks/useGlobalOnClickOutside';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { FixedLayout } from '../FixedLayout/FixedLayout';\nimport styles from './PanelHeaderContext.module.css';\n\nconst sizeXClassNames = {\n none: styles['PanelHeaderContext--sizeX-none'],\n compact: styles['PanelHeaderContext--sizeX-compact'],\n regular: styles['PanelHeaderContext--sizeX-regular'],\n};\n\nexport interface PanelHeaderContextProps extends HTMLAttributesWithRootRef<HTMLDivElement> {\n opened: boolean;\n onClose: VoidFunction;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/PanelHeaderContext\n */\nexport const PanelHeaderContext = ({\n children,\n opened = false,\n className,\n onClose,\n ...restProps\n}: PanelHeaderContextProps) => {\n const platform = usePlatform();\n const { sizeX = 'none' } = useAdaptivity();\n const elementRef = React.useRef<HTMLDivElement>(null);\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n opened ? 'enter' : 'exit',\n undefined,\n true,\n );\n const visible = animationState !== 'exited';\n\n useScrollLock(platform !== 'vkcom' && visible);\n\n const handleGlobalOnClickOutside = React.useCallback(\n (event: MouseEvent) => {\n if (opened) {\n event.stopPropagation();\n onClose();\n }\n },\n [opened, onClose],\n );\n\n useGlobalOnClickOutside(handleGlobalOnClickOutside, visible ? elementRef : null);\n\n if (!visible) {\n return null;\n }\n\n return (\n <FixedLayout\n {...restProps}\n className={classNames(\n styles['PanelHeaderContext'],\n platform === 'ios' && styles['PanelHeaderContext--ios'],\n opened ? styles['PanelHeaderContext--opened'] : styles['PanelHeaderContext--closing'],\n sizeXClassNames[sizeX],\n className,\n )}\n vertical=\"top\"\n >\n <div\n onClick={(event) => {\n event.stopPropagation();\n onClose();\n }}\n className={styles['PanelHeaderContext__fade']}\n />\n <div\n data-testid={process.env.NODE_ENV === 'test' ? 'content' : undefined}\n className={styles['PanelHeaderContext__in']}\n ref={elementRef}\n {...animationHandlers}\n >\n <div className={styles['PanelHeaderContext__content']}>{children}</div>\n </div>\n </FixedLayout>\n );\n};\n"],"names":["React","classNames","useAdaptivity","useGlobalOnClickOutside","usePlatform","useCSSKeyframesAnimationController","useScrollLock","FixedLayout","sizeXClassNames","none","compact","regular","PanelHeaderContext","children","opened","className","onClose","restProps","platform","sizeX","elementRef","useRef","animationState","animationHandlers","undefined","visible","handleGlobalOnClickOutside","useCallback","event","stopPropagation","vertical","div","onClick","data-testid","process","env","NODE_ENV","ref"],"mappings":";;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,uBAAuB,QAAQ,sCAAsC;AAC9E,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,kCAAkC,QAAQ,sBAAsB;AAEzE,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AAGzD,MAAMC,kBAAkB;IACtBC,IAAI;IACJC,OAAO;IACPC,OAAO;AACT;AAOA;;CAEC,GACD,OAAO,MAAMC,qBAAqB;QAAC,EACjCC,QAAQ,EACRC,SAAS,KAAK,EACdC,SAAS,EACTC,OAAO,EAEiB,WADrBC;QAJHJ;QACAC;QACAC;QACAC;;IAGA,MAAME,WAAWd;IACjB,MAAM,EAAEe,QAAQ,MAAM,EAAE,GAAGjB;IAC3B,MAAMkB,aAAapB,MAAMqB,MAAM,CAAiB;IAChD,MAAM,CAACC,gBAAgBC,kBAAkB,GAAGlB,mCAC1CS,SAAS,UAAU,QACnBU,WACA;IAEF,MAAMC,UAAUH,mBAAmB;IAEnChB,cAAcY,aAAa,WAAWO;IAEtC,MAAMC,6BAA6B1B,MAAM2B,WAAW,CAClD,CAACC;QACC,IAAId,QAAQ;YACVc,MAAMC,eAAe;YACrBb;QACF;IACF,GACA;QAACF;QAAQE;KAAQ;IAGnBb,wBAAwBuB,4BAA4BD,UAAUL,aAAa;IAE3E,IAAI,CAACK,SAAS;QACZ,OAAO;IACT;IAEA,qBACE,MAAClB,qDACKU;QACJF,WAAWd,qCAETiB,aAAa,wCACbJ,+EACAN,eAAe,CAACW,MAAM,EACtBJ;QAEFe,UAAS;;0BAET,KAACC;gBACCC,SAAS,CAACJ;oBACRA,MAAMC,eAAe;oBACrBb;gBACF;gBACAD,SAAS;;0BAEX,KAACgB;gBACCE,eAAaC,QAAQC,GAAG,CAACC,QAAQ,KAAK,SAAS,YAAYZ;gBAC3DT,SAAS;gBACTsB,KAAKjB;eACDG;0BAEJ,cAAA,KAACQ;oBAAIhB,SAAS;8BAA0CF;;;;;AAIhE,EAAE"}
@@ -5,6 +5,12 @@ import type { SnackbarPlacement } from './types';
5
5
  export interface SnackbarProps extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'role'>, BasicProps {
6
6
  /**
7
7
  * Задаёт расположение компонента.
8
+ *
9
+ * > Note: в мобильном режиме:
10
+ * > - `"top-start"`/`"top-end"` перебивается на `"top"`, чтобы поведение было схожим с нативными
11
+ * > уведомлениями;
12
+ * > - `"bottom"`/`"bottom-end"` перебивается на "bottom-start", чтобы избежать вызова системных
13
+ * > функций, таких как **Pull To Refresh** и **Режим управления одной рукой**.
8
14
  */
9
15
  placement?: SnackbarPlacement;
10
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA2B5D,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,EAC7D,UAAU;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAClD;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;yJAgBlB,aAAa;;CAmMf,CAAC"}
1
+ {"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA2B5D,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,EAC7D,UAAU;IACZ;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAClD;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;yJAgBlB,aAAa;;CAqMf,CAAC"}
@@ -7,6 +7,7 @@ import { classNames, noop } from '@vkontakte/vkjs';
7
7
  import { useExternRef } from '../../hooks/useExternRef';
8
8
  import { useFocusWithin } from '../../hooks/useFocusWithin';
9
9
  import { useGlobalEscKeyDown } from '../../hooks/useGlobalEscKeyDown';
10
+ import { useMediaQueries } from '../../hooks/useMediaQueries';
10
11
  import { usePlatform } from '../../hooks/usePlatform';
11
12
  import { useCSSKeyframesAnimationController } from '../../lib/animation';
12
13
  import { getRelativeBoundingClientRect } from '../../lib/dom';
@@ -61,6 +62,7 @@ const animationStateClassNames = {
61
62
  const shiftDataRef = React.useRef(null);
62
63
  const rafRef = React.useRef(null);
63
64
  const closeTimeoutIdRef = React.useRef();
65
+ const mediaQueries = useMediaQueries();
64
66
  const [animationState, animationHandlers] = useCSSKeyframesAnimationController(open ? 'enter' : 'exit', {
65
67
  onExited: onClose
66
68
  });
@@ -92,7 +94,7 @@ const animationStateClassNames = {
92
94
  const handleTouchStart = (event)=>{
93
95
  panGestureRecognizer.current = new UIPanGestureRecognizer();
94
96
  panGestureRecognizer.current.setStartCoords(event.nativeEvent);
95
- shiftDataRef.current = getInitialShiftData(rootRef.current.offsetWidth, rootRef.current.offsetHeight);
97
+ shiftDataRef.current = getInitialShiftData(rootRef.current.offsetWidth, rootRef.current.offsetHeight, mediaQueries);
96
98
  setTouched(true);
97
99
  };
98
100
  const handleTouchMove = (event)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Snackbar/Snackbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { useGlobalEscKeyDown } from '../../hooks/useGlobalEscKeyDown';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport { getRelativeBoundingClientRect } from '../../lib/dom';\nimport { UIPanGestureRecognizer } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HTMLAttributesWithRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Basic, BasicProps } from './subcomponents/Basic/Basic';\nimport type { ShiftData, SnackbarPlacement } from './types';\nimport {\n getInitialShiftData,\n getMovedShiftData,\n resolveOffsetYCssStyle,\n shouldBeClosedByShiftData,\n} from './utils';\nimport styles from './Snackbar.module.css';\n\nconst placementClassNames = {\n 'top-start': styles['Snackbar--placement-top-start'],\n 'top': styles['Snackbar--placement-top'],\n 'top-end': styles['Snackbar--placement-top-end'],\n 'bottom-start': styles['Snackbar--placement-bottom-start'],\n 'bottom': styles['Snackbar--placement-bottom'],\n 'bottom-end': styles['Snackbar--placement-bottom-end'],\n};\n\nconst animationStateClassNames = {\n enter: styles['Snackbar--state-enter'],\n entering: styles['Snackbar--state-entering'],\n entered: styles['Snackbar--state-entered'],\n exit: styles['Snackbar--state-exit'],\n exiting: styles['Snackbar--state-exiting'],\n exited: undefined,\n};\n\nexport interface SnackbarProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'role'>,\n BasicProps {\n /**\n * Задаёт расположение компонента.\n */\n placement?: SnackbarPlacement;\n /**\n * Название кнопки действия в уведомлении\n * Не может использоваться одновременно с `subtitle`\n */\n action?: React.ReactNode;\n /**\n * Будет вызвано при клике на кнопку действия\n */\n onActionClick?: (event: React.MouseEvent) => void;\n /**\n * Время в миллисекундах, через которое плашка скроется\n */\n duration?: number;\n /**\n * Обработчик закрытия уведомления\n */\n onClose: () => void;\n /**\n * Величина отступа снизу. Используется для позиционирования элемента в случае, когда нежелательно, чтобы Snackbar при появлении перекрывал важные элементы интерфейса.\n */\n offsetY?: React.CSSProperties['bottom'];\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Snackbar\n */\nexport const Snackbar = ({\n placement = 'bottom-start',\n children,\n layout,\n action,\n before,\n after,\n duration = 4000,\n onActionClick = noop,\n onClose,\n mode = 'default',\n subtitle,\n offsetY,\n style,\n getRootRef,\n ...restProps\n}: SnackbarProps) => {\n const platform = usePlatform();\n\n const [open, setOpen] = React.useState(true);\n const [touched, setTouched] = React.useState(false);\n\n const rootRef = useExternRef(getRootRef);\n const focused = useFocusWithin(rootRef);\n const inRef = React.useRef<HTMLDivElement>(null);\n const panGestureRecognizer = React.useRef<UIPanGestureRecognizer | null>(null);\n\n const shiftDataRef = React.useRef<ShiftData | null>(null);\n\n const rafRef = React.useRef<ReturnType<typeof requestAnimationFrame> | null>(null);\n const closeTimeoutIdRef = React.useRef<ReturnType<typeof setTimeout>>();\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n open ? 'enter' : 'exit',\n {\n onExited: onClose,\n },\n );\n\n const clearRAF = React.useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n }, []);\n\n const updateShiftAxisCSSProperties = React.useCallback(\n (x: number | null, y: number | null) => {\n rafRef.current = requestAnimationFrame(() => {\n if (rootRef.current) {\n x === null\n ? rootRef.current.style.removeProperty('--vkui_internal--snackbar_shift_x')\n : rootRef.current.style.setProperty('--vkui_internal--snackbar_shift_x', `${x}px`);\n y === null\n ? rootRef.current.style.removeProperty('--vkui_internal--snackbar_shift_y')\n : rootRef.current.style.setProperty('--vkui_internal--snackbar_shift_y', `${y}px`);\n }\n });\n },\n [rootRef],\n );\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleActionClick = (event: React.MouseEvent) => {\n close();\n if (action) {\n onActionClick(event);\n }\n };\n\n const handleTouchStart = (event: React.UIEvent<HTMLDivElement>) => {\n panGestureRecognizer.current = new UIPanGestureRecognizer();\n panGestureRecognizer.current.setStartCoords(event.nativeEvent);\n shiftDataRef.current = getInitialShiftData(\n rootRef.current!.offsetWidth,\n rootRef.current!.offsetHeight,\n );\n setTouched(true);\n };\n\n const handleTouchMove = (event: React.UIEvent<HTMLDivElement>) => {\n if (shiftDataRef.current && panGestureRecognizer.current) {\n panGestureRecognizer.current.setInitialTimeOnce();\n panGestureRecognizer.current.setEndCoords(event.nativeEvent);\n shiftDataRef.current = getMovedShiftData(\n placement,\n shiftDataRef.current,\n panGestureRecognizer.current.delta(),\n );\n\n if (shiftDataRef.current.shifted) {\n updateShiftAxisCSSProperties(shiftDataRef.current.x, shiftDataRef.current.y);\n }\n }\n };\n\n const handleTouchEnd = () => {\n if (\n touched &&\n shiftDataRef.current &&\n panGestureRecognizer.current &&\n shouldBeClosedByShiftData(\n placement,\n shiftDataRef.current,\n getRelativeBoundingClientRect(rootRef.current!, inRef.current!),\n panGestureRecognizer.current.velocity(),\n )\n ) {\n close();\n }\n\n setTouched(false);\n };\n\n useIsomorphicLayoutEffect(\n function closeAfterDelay() {\n if (!open || focused || touched || animationState !== 'entered') {\n return;\n }\n closeTimeoutIdRef.current = setTimeout(close, duration);\n return function preventCloseAfterDelayOnUnmount() {\n clearTimeout(closeTimeoutIdRef.current);\n };\n },\n [open, focused, touched, animationState, close, duration],\n );\n\n useIsomorphicLayoutEffect(\n function clearUserInteractionDataAfterTouchEnd() {\n if (!touched) {\n clearRAF();\n shiftDataRef.current = null;\n panGestureRecognizer.current = null;\n\n if (open) {\n updateShiftAxisCSSProperties(null, null);\n }\n }\n },\n [touched, open, updateShiftAxisCSSProperties, clearRAF],\n );\n\n React.useEffect(() => clearRAF, [clearRAF]);\n\n useGlobalEscKeyDown(open, close);\n\n if (animationState === 'exited') {\n return null;\n }\n\n return (\n <RootComponent\n {...restProps}\n role=\"presentation\"\n baseClassName={classNames(\n styles['Snackbar'],\n platform === 'ios' && styles['Snackbar--ios'],\n touched && styles['Snackbar--touched'],\n placementClassNames[placement],\n animationStateClassNames[animationState],\n )}\n style={resolveOffsetYCssStyle(placement, style, offsetY)}\n getRootRef={rootRef}\n >\n <div\n role=\"alert\"\n className={styles['Snackbar__in']}\n ref={inRef}\n // mobile\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n // desktop\n onMouseDown={handleTouchStart}\n onMouseMove={handleTouchMove}\n onMouseUp={handleTouchEnd}\n onMouseLeave={handleTouchEnd}\n {...animationHandlers}\n >\n <Basic\n mode={mode}\n layout={layout}\n before={before}\n after={after}\n subtitle={subtitle}\n action={\n action && (\n <Button\n align=\"left\"\n mode=\"link\"\n appearance={\n mode === 'dark'\n ? /* istanbul ignore next: проверяется в e2e */\n 'overlay'\n : 'accent'\n }\n size=\"s\"\n onClick={handleActionClick}\n >\n {action}\n </Button>\n )\n }\n >\n {children}\n </Basic>\n </div>\n </RootComponent>\n );\n};\n\nSnackbar.Basic = Basic;\n"],"names":["React","classNames","noop","useExternRef","useFocusWithin","useGlobalEscKeyDown","usePlatform","useCSSKeyframesAnimationController","getRelativeBoundingClientRect","UIPanGestureRecognizer","useIsomorphicLayoutEffect","Button","RootComponent","Basic","getInitialShiftData","getMovedShiftData","resolveOffsetYCssStyle","shouldBeClosedByShiftData","placementClassNames","animationStateClassNames","enter","entering","entered","exit","exiting","exited","undefined","Snackbar","placement","children","layout","action","before","after","duration","onActionClick","onClose","mode","subtitle","offsetY","style","getRootRef","restProps","platform","open","setOpen","useState","touched","setTouched","rootRef","focused","inRef","useRef","panGestureRecognizer","shiftDataRef","rafRef","closeTimeoutIdRef","animationState","animationHandlers","onExited","clearRAF","useCallback","current","cancelAnimationFrame","updateShiftAxisCSSProperties","x","y","requestAnimationFrame","removeProperty","setProperty","close","handleActionClick","event","handleTouchStart","setStartCoords","nativeEvent","offsetWidth","offsetHeight","handleTouchMove","setInitialTimeOnce","setEndCoords","delta","shifted","handleTouchEnd","velocity","closeAfterDelay","setTimeout","preventCloseAfterDelayOnUnmount","clearTimeout","clearUserInteractionDataAfterTouchEnd","useEffect","role","baseClassName","div","className","ref","onTouchStart","onTouchMove","onTouchEnd","onMouseDown","onMouseMove","onMouseUp","onMouseLeave","align","appearance","size","onClick"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Snackbar/Snackbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { useGlobalEscKeyDown } from '../../hooks/useGlobalEscKeyDown';\nimport { useMediaQueries } from '../../hooks/useMediaQueries';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport { getRelativeBoundingClientRect } from '../../lib/dom';\nimport { UIPanGestureRecognizer } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HTMLAttributesWithRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Basic, BasicProps } from './subcomponents/Basic/Basic';\nimport type { ShiftData, SnackbarPlacement } from './types';\nimport {\n getInitialShiftData,\n getMovedShiftData,\n resolveOffsetYCssStyle,\n shouldBeClosedByShiftData,\n} from './utils';\nimport styles from './Snackbar.module.css';\n\nconst placementClassNames = {\n 'top-start': styles['Snackbar--placement-top-start'],\n 'top': styles['Snackbar--placement-top'],\n 'top-end': styles['Snackbar--placement-top-end'],\n 'bottom-start': styles['Snackbar--placement-bottom-start'],\n 'bottom': styles['Snackbar--placement-bottom'],\n 'bottom-end': styles['Snackbar--placement-bottom-end'],\n};\n\nconst animationStateClassNames = {\n enter: styles['Snackbar--state-enter'],\n entering: styles['Snackbar--state-entering'],\n entered: styles['Snackbar--state-entered'],\n exit: styles['Snackbar--state-exit'],\n exiting: styles['Snackbar--state-exiting'],\n exited: undefined,\n};\n\nexport interface SnackbarProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'role'>,\n BasicProps {\n /**\n * Задаёт расположение компонента.\n *\n * > Note: в мобильном режиме:\n * > - `\"top-start\"`/`\"top-end\"` перебивается на `\"top\"`, чтобы поведение было схожим с нативными\n * > уведомлениями;\n * > - `\"bottom\"`/`\"bottom-end\"` перебивается на \"bottom-start\", чтобы избежать вызова системных\n * > функций, таких как **Pull To Refresh** и **Режим управления одной рукой**.\n */\n placement?: SnackbarPlacement;\n /**\n * Название кнопки действия в уведомлении\n * Не может использоваться одновременно с `subtitle`\n */\n action?: React.ReactNode;\n /**\n * Будет вызвано при клике на кнопку действия\n */\n onActionClick?: (event: React.MouseEvent) => void;\n /**\n * Время в миллисекундах, через которое плашка скроется\n */\n duration?: number;\n /**\n * Обработчик закрытия уведомления\n */\n onClose: () => void;\n /**\n * Величина отступа снизу. Используется для позиционирования элемента в случае, когда нежелательно, чтобы Snackbar при появлении перекрывал важные элементы интерфейса.\n */\n offsetY?: React.CSSProperties['bottom'];\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Snackbar\n */\nexport const Snackbar = ({\n placement = 'bottom-start',\n children,\n layout,\n action,\n before,\n after,\n duration = 4000,\n onActionClick = noop,\n onClose,\n mode = 'default',\n subtitle,\n offsetY,\n style,\n getRootRef,\n ...restProps\n}: SnackbarProps) => {\n const platform = usePlatform();\n\n const [open, setOpen] = React.useState(true);\n const [touched, setTouched] = React.useState(false);\n\n const rootRef = useExternRef(getRootRef);\n const focused = useFocusWithin(rootRef);\n const inRef = React.useRef<HTMLDivElement>(null);\n const panGestureRecognizer = React.useRef<UIPanGestureRecognizer | null>(null);\n\n const shiftDataRef = React.useRef<ShiftData | null>(null);\n\n const rafRef = React.useRef<ReturnType<typeof requestAnimationFrame> | null>(null);\n const closeTimeoutIdRef = React.useRef<ReturnType<typeof setTimeout>>();\n const mediaQueries = useMediaQueries();\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n open ? 'enter' : 'exit',\n {\n onExited: onClose,\n },\n );\n\n const clearRAF = React.useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n }, []);\n\n const updateShiftAxisCSSProperties = React.useCallback(\n (x: number | null, y: number | null) => {\n rafRef.current = requestAnimationFrame(() => {\n if (rootRef.current) {\n x === null\n ? rootRef.current.style.removeProperty('--vkui_internal--snackbar_shift_x')\n : rootRef.current.style.setProperty('--vkui_internal--snackbar_shift_x', `${x}px`);\n y === null\n ? rootRef.current.style.removeProperty('--vkui_internal--snackbar_shift_y')\n : rootRef.current.style.setProperty('--vkui_internal--snackbar_shift_y', `${y}px`);\n }\n });\n },\n [rootRef],\n );\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleActionClick = (event: React.MouseEvent) => {\n close();\n if (action) {\n onActionClick(event);\n }\n };\n\n const handleTouchStart = (event: React.UIEvent<HTMLDivElement>) => {\n panGestureRecognizer.current = new UIPanGestureRecognizer();\n panGestureRecognizer.current.setStartCoords(event.nativeEvent);\n shiftDataRef.current = getInitialShiftData(\n rootRef.current!.offsetWidth,\n rootRef.current!.offsetHeight,\n mediaQueries,\n );\n setTouched(true);\n };\n\n const handleTouchMove = (event: React.UIEvent<HTMLDivElement>) => {\n if (shiftDataRef.current && panGestureRecognizer.current) {\n panGestureRecognizer.current.setInitialTimeOnce();\n panGestureRecognizer.current.setEndCoords(event.nativeEvent);\n shiftDataRef.current = getMovedShiftData(\n placement,\n shiftDataRef.current,\n panGestureRecognizer.current.delta(),\n );\n\n if (shiftDataRef.current.shifted) {\n updateShiftAxisCSSProperties(shiftDataRef.current.x, shiftDataRef.current.y);\n }\n }\n };\n\n const handleTouchEnd = () => {\n if (\n touched &&\n shiftDataRef.current &&\n panGestureRecognizer.current &&\n shouldBeClosedByShiftData(\n placement,\n shiftDataRef.current,\n getRelativeBoundingClientRect(rootRef.current!, inRef.current!),\n panGestureRecognizer.current.velocity(),\n )\n ) {\n close();\n }\n\n setTouched(false);\n };\n\n useIsomorphicLayoutEffect(\n function closeAfterDelay() {\n if (!open || focused || touched || animationState !== 'entered') {\n return;\n }\n closeTimeoutIdRef.current = setTimeout(close, duration);\n return function preventCloseAfterDelayOnUnmount() {\n clearTimeout(closeTimeoutIdRef.current);\n };\n },\n [open, focused, touched, animationState, close, duration],\n );\n\n useIsomorphicLayoutEffect(\n function clearUserInteractionDataAfterTouchEnd() {\n if (!touched) {\n clearRAF();\n shiftDataRef.current = null;\n panGestureRecognizer.current = null;\n\n if (open) {\n updateShiftAxisCSSProperties(null, null);\n }\n }\n },\n [touched, open, updateShiftAxisCSSProperties, clearRAF],\n );\n\n React.useEffect(() => clearRAF, [clearRAF]);\n\n useGlobalEscKeyDown(open, close);\n\n if (animationState === 'exited') {\n return null;\n }\n\n return (\n <RootComponent\n {...restProps}\n role=\"presentation\"\n baseClassName={classNames(\n styles['Snackbar'],\n platform === 'ios' && styles['Snackbar--ios'],\n touched && styles['Snackbar--touched'],\n placementClassNames[placement],\n animationStateClassNames[animationState],\n )}\n style={resolveOffsetYCssStyle(placement, style, offsetY)}\n getRootRef={rootRef}\n >\n <div\n role=\"alert\"\n className={styles['Snackbar__in']}\n ref={inRef}\n // mobile\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n // desktop\n onMouseDown={handleTouchStart}\n onMouseMove={handleTouchMove}\n onMouseUp={handleTouchEnd}\n onMouseLeave={handleTouchEnd}\n {...animationHandlers}\n >\n <Basic\n mode={mode}\n layout={layout}\n before={before}\n after={after}\n subtitle={subtitle}\n action={\n action && (\n <Button\n align=\"left\"\n mode=\"link\"\n appearance={\n mode === 'dark'\n ? /* istanbul ignore next: проверяется в e2e */\n 'overlay'\n : 'accent'\n }\n size=\"s\"\n onClick={handleActionClick}\n >\n {action}\n </Button>\n )\n }\n >\n {children}\n </Basic>\n </div>\n </RootComponent>\n );\n};\n\nSnackbar.Basic = Basic;\n"],"names":["React","classNames","noop","useExternRef","useFocusWithin","useGlobalEscKeyDown","useMediaQueries","usePlatform","useCSSKeyframesAnimationController","getRelativeBoundingClientRect","UIPanGestureRecognizer","useIsomorphicLayoutEffect","Button","RootComponent","Basic","getInitialShiftData","getMovedShiftData","resolveOffsetYCssStyle","shouldBeClosedByShiftData","placementClassNames","animationStateClassNames","enter","entering","entered","exit","exiting","exited","undefined","Snackbar","placement","children","layout","action","before","after","duration","onActionClick","onClose","mode","subtitle","offsetY","style","getRootRef","restProps","platform","open","setOpen","useState","touched","setTouched","rootRef","focused","inRef","useRef","panGestureRecognizer","shiftDataRef","rafRef","closeTimeoutIdRef","mediaQueries","animationState","animationHandlers","onExited","clearRAF","useCallback","current","cancelAnimationFrame","updateShiftAxisCSSProperties","x","y","requestAnimationFrame","removeProperty","setProperty","close","handleActionClick","event","handleTouchStart","setStartCoords","nativeEvent","offsetWidth","offsetHeight","handleTouchMove","setInitialTimeOnce","setEndCoords","delta","shifted","handleTouchEnd","velocity","closeAfterDelay","setTimeout","preventCloseAfterDelayOnUnmount","clearTimeout","clearUserInteractionDataAfterTouchEnd","useEffect","role","baseClassName","div","className","ref","onTouchStart","onTouchMove","onTouchEnd","onMouseDown","onMouseMove","onMouseUp","onMouseLeave","align","appearance","size","onClick"],"mappings":"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"}
@@ -5,5 +5,6 @@ export type ShiftData = {
5
5
  width: number;
6
6
  height: number;
7
7
  shifted: boolean;
8
+ isDesktop: boolean;
8
9
  };
9
10
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,KAAK,GACL,SAAS,GACT,cAAc,GACd,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,KAAK,GACL,SAAS,GACT,cAAc,GACd,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Snackbar/types.ts"],"sourcesContent":["export type SnackbarPlacement =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'bottom-start'\n | 'bottom'\n | 'bottom-end';\n\nexport type ShiftData = { x: number; y: number; width: number; height: number; shifted: boolean };\n"],"names":[],"mappings":"AAQA,WAAkG"}
1
+ {"version":3,"sources":["../../../src/components/Snackbar/types.ts"],"sourcesContent":["export type SnackbarPlacement =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'bottom-start'\n | 'bottom'\n | 'bottom-end';\n\nexport type ShiftData = {\n x: number;\n y: number;\n width: number;\n height: number;\n shifted: boolean;\n isDesktop: boolean;\n};\n"],"names":[],"mappings":"AAQA,WAOE"}
@@ -1,12 +1,8 @@
1
+ import * as React from 'react';
2
+ import type { MediaQueries } from '../../lib/adaptivity';
1
3
  import type { ShiftData, SnackbarPlacement } from './types';
2
- export declare function resolveOffsetYCssStyle(placement: SnackbarPlacement, style?: React.CSSProperties, offsetY?: React.CSSProperties['inset']): import("react").CSSProperties | undefined;
3
- export declare function getInitialShiftData(width: number, height: number): {
4
- shifted: boolean;
5
- x: number;
6
- y: number;
7
- width: number;
8
- height: number;
9
- };
4
+ export declare function resolveOffsetYCssStyle(placement: SnackbarPlacement, style?: React.CSSProperties, offsetY?: React.CSSProperties['inset']): React.CSSProperties | undefined;
5
+ export declare function getInitialShiftData(width: number, height: number, mediaQueries: MediaQueries): ShiftData;
10
6
  export declare function getMovedShiftData(placement: SnackbarPlacement, shiftData: ShiftData, nextShift: {
11
7
  x: number;
12
8
  y: number;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5D,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,iBAAiB,EAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,EAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,6CAevC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;EAQhE;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,aA6BpC;AAID,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,OAAO,EAC3B,QAAQ,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,WA2CnC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5D,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,iBAAiB,EAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,EAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,mCAevC;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,SAAS,CASX;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,SAAS,CAuBX;AAID,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,OAAO,EAC3B,QAAQ,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,WA6CnC"}
@@ -1,5 +1,6 @@
1
1
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
2
  import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import * as React from 'react';
3
4
  import { rubberbandIfOutOfBounds } from '../../lib/animation';
4
5
  export function resolveOffsetYCssStyle(placement, style, offsetY) {
5
6
  if (offsetY === undefined) {
@@ -20,9 +21,10 @@ export function resolveOffsetYCssStyle(placement, style, offsetY) {
20
21
  });
21
22
  }
22
23
  }
23
- export function getInitialShiftData(width, height) {
24
+ export function getInitialShiftData(width, height, mediaQueries) {
24
25
  return {
25
26
  shifted: false,
27
+ isDesktop: mediaQueries.smallTabletPlus.matches,
26
28
  x: 0,
27
29
  y: 0,
28
30
  width,
@@ -30,27 +32,20 @@ export function getInitialShiftData(width, height) {
30
32
  };
31
33
  }
32
34
  export function getMovedShiftData(placement, shiftData, nextShift) {
33
- switch(placement){
34
- case 'top-start':
35
- case 'bottom-start':
35
+ /* istanbul ignore else: TODO чтобы протестировать кейс в блоке else, нужно мокать useMediaQueries(), чтобы перебивать mediaQueries.smallTabletPlus.matches */ if (shiftData.isDesktop) {
36
+ if (placement.endsWith('start')) {
36
37
  shiftData.x = rubberbandIfOutOfBounds(nextShift.x, -shiftData.width, 0);
37
- break;
38
- case 'top-end':
39
- case 'bottom-end':
38
+ } else if (placement.endsWith('end')) {
40
39
  shiftData.x = rubberbandIfOutOfBounds(nextShift.x, 0, shiftData.width);
41
- break;
42
- }
43
- switch(placement){
44
- case 'top-start':
45
- case 'top':
46
- case 'top-end':
47
- shiftData.y = rubberbandIfOutOfBounds(nextShift.y, -shiftData.height, 0);
48
- break;
49
- case 'bottom-start':
50
- case 'bottom':
51
- case 'bottom-end':
40
+ }
41
+ if (placement.startsWith('bottom')) {
52
42
  shiftData.y = rubberbandIfOutOfBounds(nextShift.y, 0, shiftData.height);
53
- break;
43
+ }
44
+ } else if (placement.startsWith('bottom')) {
45
+ shiftData.x = rubberbandIfOutOfBounds(nextShift.x, -shiftData.width, 0);
46
+ }
47
+ if (placement.startsWith('top')) {
48
+ shiftData.y = rubberbandIfOutOfBounds(nextShift.y, -shiftData.height, 0);
54
49
  }
55
50
  shiftData.shifted = true;
56
51
  return shiftData;
@@ -68,31 +63,25 @@ export function shouldBeClosedByShiftData(placement, shiftData, relativeClientRe
68
63
  x: false,
69
64
  y: false
70
65
  };
71
- switch(placement){
72
- case 'top-start':
73
- case 'bottom-start':
66
+ /* istanbul ignore else: TODO чтобы протестировать кейс в блоке else, нужно мокать useMediaQueries(), чтобы перебивать mediaQueries.smallTabletPlus.matches */ if (shiftData.isDesktop) {
67
+ if (placement.endsWith('start')) {
74
68
  shouldBeClosedThreshold.x = relativeClientRect.x < -relativeClientRect.width / 2;
75
- shouldBeClosedByVelocity.x = velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;
76
- break;
77
- case 'top-end':
78
- case 'bottom-end':
69
+ shouldBeClosedByVelocity.x = relativeClientRect.x < 0 ? velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;
70
+ } else if (placement.endsWith('end')) {
79
71
  shouldBeClosedThreshold.x = relativeClientRect.x > relativeClientRect.width / 2;
80
- shouldBeClosedByVelocity.x = velocity.x > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;
81
- break;
82
- }
83
- switch(placement){
84
- case 'top-start':
85
- case 'top':
86
- case 'top-end':
87
- shouldBeClosedThreshold.y = relativeClientRect.y < -relativeClientRect.height / 2;
88
- shouldBeClosedByVelocity.y = velocity.y < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;
89
- break;
90
- case 'bottom-start':
91
- case 'bottom':
92
- case 'bottom-end':
72
+ shouldBeClosedByVelocity.x = relativeClientRect.x > 0 ? velocity.x > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;
73
+ }
74
+ if (placement.startsWith('bottom')) {
93
75
  shouldBeClosedThreshold.y = relativeClientRect.y > relativeClientRect.height / 2;
94
- shouldBeClosedByVelocity.y = velocity.y > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;
95
- break;
76
+ shouldBeClosedByVelocity.y = relativeClientRect.y > 0 ? velocity.y > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;
77
+ }
78
+ } else if (placement.startsWith('bottom')) {
79
+ shouldBeClosedThreshold.x = relativeClientRect.x < -relativeClientRect.width / 2;
80
+ shouldBeClosedByVelocity.x = relativeClientRect.x < 0 ? velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;
81
+ }
82
+ if (placement.startsWith('top')) {
83
+ shouldBeClosedThreshold.y = relativeClientRect.y < -relativeClientRect.height / 2;
84
+ shouldBeClosedByVelocity.y = relativeClientRect.y < 0 ? velocity.y < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;
96
85
  }
97
86
  return shouldBeClosedThreshold.x || shouldBeClosedByVelocity.x || shouldBeClosedThreshold.y || /* istanbul ignore next: подсвечивает жёлтым и пишет "branch not covered" */ shouldBeClosedByVelocity.y;
98
87
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Snackbar/utils.ts"],"sourcesContent":["import { rubberbandIfOutOfBounds } from '../../lib/animation';\nimport type { ShiftData, SnackbarPlacement } from './types';\n\nexport function resolveOffsetYCssStyle(\n placement: SnackbarPlacement,\n style?: React.CSSProperties,\n offsetY?: React.CSSProperties['inset'],\n) {\n if (offsetY === undefined) {\n return style;\n }\n switch (placement) {\n case 'top-start':\n case 'top':\n case 'top-end':\n return { ...style, top: offsetY };\n case 'bottom-start':\n case 'bottom':\n case 'bottom-end':\n return { ...style, bottom: offsetY };\n }\n}\n\nexport function getInitialShiftData(width: number, height: number) {\n return {\n shifted: false,\n x: 0,\n y: 0,\n width,\n height,\n };\n}\n\nexport function getMovedShiftData(\n placement: SnackbarPlacement,\n shiftData: ShiftData,\n nextShift: { x: number; y: number },\n) {\n switch (placement) {\n case 'top-start':\n case 'bottom-start':\n shiftData.x = rubberbandIfOutOfBounds(nextShift.x, -shiftData.width, 0);\n break;\n case 'top-end':\n case 'bottom-end':\n shiftData.x = rubberbandIfOutOfBounds(nextShift.x, 0, shiftData.width);\n break;\n }\n\n switch (placement) {\n case 'top-start':\n case 'top':\n case 'top-end':\n shiftData.y = rubberbandIfOutOfBounds(nextShift.y, -shiftData.height, 0);\n break;\n case 'bottom-start':\n case 'bottom':\n case 'bottom-end':\n shiftData.y = rubberbandIfOutOfBounds(nextShift.y, 0, shiftData.height);\n break;\n }\n\n shiftData.shifted = true;\n\n return shiftData;\n}\n\nconst MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE = 200;\n\nexport function shouldBeClosedByShiftData(\n placement: SnackbarPlacement,\n shiftData: ShiftData,\n relativeClientRect: DOMRect,\n velocity: { x: number; y: number },\n) {\n if (!shiftData.shifted) {\n return false;\n }\n const shouldBeClosedThreshold = { x: false, y: false };\n const shouldBeClosedByVelocity = { x: false, y: false };\n\n switch (placement) {\n case 'top-start':\n case 'bottom-start':\n shouldBeClosedThreshold.x = relativeClientRect.x < -relativeClientRect.width / 2;\n shouldBeClosedByVelocity.x = velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;\n break;\n case 'top-end':\n case 'bottom-end':\n shouldBeClosedThreshold.x = relativeClientRect.x > relativeClientRect.width / 2;\n shouldBeClosedByVelocity.x = velocity.x > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;\n break;\n }\n\n switch (placement) {\n case 'top-start':\n case 'top':\n case 'top-end':\n shouldBeClosedThreshold.y = relativeClientRect.y < -relativeClientRect.height / 2;\n shouldBeClosedByVelocity.y = velocity.y < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;\n break;\n case 'bottom-start':\n case 'bottom':\n case 'bottom-end':\n shouldBeClosedThreshold.y = relativeClientRect.y > relativeClientRect.height / 2;\n shouldBeClosedByVelocity.y = velocity.y > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE;\n break;\n }\n\n return (\n shouldBeClosedThreshold.x ||\n shouldBeClosedByVelocity.x ||\n shouldBeClosedThreshold.y ||\n /* istanbul ignore next: подсвечивает жёлтым и пишет \"branch not covered\" */\n shouldBeClosedByVelocity.y\n );\n}\n"],"names":["rubberbandIfOutOfBounds","resolveOffsetYCssStyle","placement","style","offsetY","undefined","top","bottom","getInitialShiftData","width","height","shifted","x","y","getMovedShiftData","shiftData","nextShift","MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE","shouldBeClosedByShiftData","relativeClientRect","velocity","shouldBeClosedThreshold","shouldBeClosedByVelocity"],"mappings":";;AAAA,SAASA,uBAAuB,QAAQ,sBAAsB;AAG9D,OAAO,SAASC,uBACdC,SAA4B,EAC5BC,KAA2B,EAC3BC,OAAsC;IAEtC,IAAIA,YAAYC,WAAW;QACzB,OAAOF;IACT;IACA,OAAQD;QACN,KAAK;QACL,KAAK;QACL,KAAK;YACH,OAAO,wCAAKC;gBAAOG,KAAKF;;QAC1B,KAAK;QACL,KAAK;QACL,KAAK;YACH,OAAO,wCAAKD;gBAAOI,QAAQH;;IAC/B;AACF;AAEA,OAAO,SAASI,oBAAoBC,KAAa,EAAEC,MAAc;IAC/D,OAAO;QACLC,SAAS;QACTC,GAAG;QACHC,GAAG;QACHJ;QACAC;IACF;AACF;AAEA,OAAO,SAASI,kBACdZ,SAA4B,EAC5Ba,SAAoB,EACpBC,SAAmC;IAEnC,OAAQd;QACN,KAAK;QACL,KAAK;YACHa,UAAUH,CAAC,GAAGZ,wBAAwBgB,UAAUJ,CAAC,EAAE,CAACG,UAAUN,KAAK,EAAE;YACrE;QACF,KAAK;QACL,KAAK;YACHM,UAAUH,CAAC,GAAGZ,wBAAwBgB,UAAUJ,CAAC,EAAE,GAAGG,UAAUN,KAAK;YACrE;IACJ;IAEA,OAAQP;QACN,KAAK;QACL,KAAK;QACL,KAAK;YACHa,UAAUF,CAAC,GAAGb,wBAAwBgB,UAAUH,CAAC,EAAE,CAACE,UAAUL,MAAM,EAAE;YACtE;QACF,KAAK;QACL,KAAK;QACL,KAAK;YACHK,UAAUF,CAAC,GAAGb,wBAAwBgB,UAAUH,CAAC,EAAE,GAAGE,UAAUL,MAAM;YACtE;IACJ;IAEAK,UAAUJ,OAAO,GAAG;IAEpB,OAAOI;AACT;AAEA,MAAME,wCAAwC;AAE9C,OAAO,SAASC,0BACdhB,SAA4B,EAC5Ba,SAAoB,EACpBI,kBAA2B,EAC3BC,QAAkC;IAElC,IAAI,CAACL,UAAUJ,OAAO,EAAE;QACtB,OAAO;IACT;IACA,MAAMU,0BAA0B;QAAET,GAAG;QAAOC,GAAG;IAAM;IACrD,MAAMS,2BAA2B;QAAEV,GAAG;QAAOC,GAAG;IAAM;IAEtD,OAAQX;QACN,KAAK;QACL,KAAK;YACHmB,wBAAwBT,CAAC,GAAGO,mBAAmBP,CAAC,GAAG,CAACO,mBAAmBV,KAAK,GAAG;YAC/Ea,yBAAyBV,CAAC,GAAGQ,SAASR,CAAC,GAAG,CAACK;YAC3C;QACF,KAAK;QACL,KAAK;YACHI,wBAAwBT,CAAC,GAAGO,mBAAmBP,CAAC,GAAGO,mBAAmBV,KAAK,GAAG;YAC9Ea,yBAAyBV,CAAC,GAAGQ,SAASR,CAAC,GAAGK;YAC1C;IACJ;IAEA,OAAQf;QACN,KAAK;QACL,KAAK;QACL,KAAK;YACHmB,wBAAwBR,CAAC,GAAGM,mBAAmBN,CAAC,GAAG,CAACM,mBAAmBT,MAAM,GAAG;YAChFY,yBAAyBT,CAAC,GAAGO,SAASP,CAAC,GAAG,CAACI;YAC3C;QACF,KAAK;QACL,KAAK;QACL,KAAK;YACHI,wBAAwBR,CAAC,GAAGM,mBAAmBN,CAAC,GAAGM,mBAAmBT,MAAM,GAAG;YAC/EY,yBAAyBT,CAAC,GAAGO,SAASP,CAAC,GAAGI;YAC1C;IACJ;IAEA,OACEI,wBAAwBT,CAAC,IACzBU,yBAAyBV,CAAC,IAC1BS,wBAAwBR,CAAC,IACzB,0EAA0E,GAC1ES,yBAAyBT,CAAC;AAE9B"}
1
+ {"version":3,"sources":["../../../src/components/Snackbar/utils.ts"],"sourcesContent":["import * as React from 'react';\nimport type { MediaQueries } from '../../lib/adaptivity';\nimport { rubberbandIfOutOfBounds } from '../../lib/animation';\nimport type { ShiftData, SnackbarPlacement } from './types';\n\nexport function resolveOffsetYCssStyle(\n placement: SnackbarPlacement,\n style?: React.CSSProperties,\n offsetY?: React.CSSProperties['inset'],\n) {\n if (offsetY === undefined) {\n return style;\n }\n switch (placement) {\n case 'top-start':\n case 'top':\n case 'top-end':\n return { ...style, top: offsetY };\n case 'bottom-start':\n case 'bottom':\n case 'bottom-end':\n return { ...style, bottom: offsetY };\n }\n}\n\nexport function getInitialShiftData(\n width: number,\n height: number,\n mediaQueries: MediaQueries,\n): ShiftData {\n return {\n shifted: false,\n isDesktop: mediaQueries.smallTabletPlus.matches, // eslint-disable-line no-restricted-properties\n x: 0,\n y: 0,\n width,\n height,\n };\n}\n\nexport function getMovedShiftData(\n placement: SnackbarPlacement,\n shiftData: ShiftData,\n nextShift: { x: number; y: number },\n): ShiftData {\n /* istanbul ignore else: TODO чтобы протестировать кейс в блоке else, нужно мокать useMediaQueries(), чтобы перебивать mediaQueries.smallTabletPlus.matches */\n if (shiftData.isDesktop) {\n if (placement.endsWith('start')) {\n shiftData.x = rubberbandIfOutOfBounds(nextShift.x, -shiftData.width, 0);\n } else if (placement.endsWith('end')) {\n shiftData.x = rubberbandIfOutOfBounds(nextShift.x, 0, shiftData.width);\n }\n\n if (placement.startsWith('bottom')) {\n shiftData.y = rubberbandIfOutOfBounds(nextShift.y, 0, shiftData.height);\n }\n } else if (placement.startsWith('bottom')) {\n shiftData.x = rubberbandIfOutOfBounds(nextShift.x, -shiftData.width, 0);\n }\n\n if (placement.startsWith('top')) {\n shiftData.y = rubberbandIfOutOfBounds(nextShift.y, -shiftData.height, 0);\n }\n\n shiftData.shifted = true;\n\n return shiftData;\n}\n\nconst MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE = 200;\n\nexport function shouldBeClosedByShiftData(\n placement: SnackbarPlacement,\n shiftData: ShiftData,\n relativeClientRect: DOMRect,\n velocity: { x: number; y: number },\n) {\n if (!shiftData.shifted) {\n return false;\n }\n\n const shouldBeClosedThreshold = { x: false, y: false };\n const shouldBeClosedByVelocity = { x: false, y: false };\n\n /* istanbul ignore else: TODO чтобы протестировать кейс в блоке else, нужно мокать useMediaQueries(), чтобы перебивать mediaQueries.smallTabletPlus.matches */\n if (shiftData.isDesktop) {\n if (placement.endsWith('start')) {\n shouldBeClosedThreshold.x = relativeClientRect.x < -relativeClientRect.width / 2;\n shouldBeClosedByVelocity.x =\n relativeClientRect.x < 0 ? velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;\n } else if (placement.endsWith('end')) {\n shouldBeClosedThreshold.x = relativeClientRect.x > relativeClientRect.width / 2;\n shouldBeClosedByVelocity.x =\n relativeClientRect.x > 0 ? velocity.x > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;\n }\n\n if (placement.startsWith('bottom')) {\n shouldBeClosedThreshold.y = relativeClientRect.y > relativeClientRect.height / 2;\n shouldBeClosedByVelocity.y =\n relativeClientRect.y > 0 ? velocity.y > MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;\n }\n } else if (placement.startsWith('bottom')) {\n shouldBeClosedThreshold.x = relativeClientRect.x < -relativeClientRect.width / 2;\n shouldBeClosedByVelocity.x =\n relativeClientRect.x < 0 ? velocity.x < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;\n }\n\n if (placement.startsWith('top')) {\n shouldBeClosedThreshold.y = relativeClientRect.y < -relativeClientRect.height / 2;\n shouldBeClosedByVelocity.y =\n relativeClientRect.y < 0 ? velocity.y < -MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE : false;\n }\n\n return (\n shouldBeClosedThreshold.x ||\n shouldBeClosedByVelocity.x ||\n shouldBeClosedThreshold.y ||\n /* istanbul ignore next: подсвечивает жёлтым и пишет \"branch not covered\" */\n shouldBeClosedByVelocity.y\n );\n}\n"],"names":["React","rubberbandIfOutOfBounds","resolveOffsetYCssStyle","placement","style","offsetY","undefined","top","bottom","getInitialShiftData","width","height","mediaQueries","shifted","isDesktop","smallTabletPlus","matches","x","y","getMovedShiftData","shiftData","nextShift","endsWith","startsWith","MINIMUM_PAN_GESTURE_FOR_TRIGGER_CLOSE","shouldBeClosedByShiftData","relativeClientRect","velocity","shouldBeClosedThreshold","shouldBeClosedByVelocity"],"mappings":"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"}