@atlaskit/modal-dialog 12.0.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 (127) hide show
  1. package/CHANGELOG.md +2111 -0
  2. package/LICENSE +13 -0
  3. package/README.md +13 -0
  4. package/__perf__/default.tsx +42 -0
  5. package/__perf__/interactions.tsx +136 -0
  6. package/__perf__/scroll.tsx +98 -0
  7. package/codemods/12.0.0-lite-mode.ts +51 -0
  8. package/codemods/__tests__/12.0.0-lite-mode.test.ts +493 -0
  9. package/codemods/__tests__/handle-prop-spread.tsx +276 -0
  10. package/codemods/__tests__/inline-WidthNames-declaration.test.ts +260 -0
  11. package/codemods/__tests__/map-actions-prop.tsx +436 -0
  12. package/codemods/__tests__/map-body-from-props.test.ts +645 -0
  13. package/codemods/__tests__/map-container-from-props.test.ts +323 -0
  14. package/codemods/__tests__/map-footer-from-props.test.ts +544 -0
  15. package/codemods/__tests__/map-header-from-props.test.ts +559 -0
  16. package/codemods/__tests__/map-heading-prop.tsx +438 -0
  17. package/codemods/__tests__/remove-appearance-prop.test.ts +79 -0
  18. package/codemods/__tests__/remove-component-override-props.test.ts +153 -0
  19. package/codemods/__tests__/remove-is-chromeless.tsx +182 -0
  20. package/codemods/__tests__/rename-appearance-type.test.ts +52 -0
  21. package/codemods/__tests__/rename-inner-component-prop-types.test.ts +82 -0
  22. package/codemods/__tests__/rename-scrollBehavior-to-shouldScrollInViewport.test.ts +237 -0
  23. package/codemods/internal/constants.tsx +41 -0
  24. package/codemods/internal/utils.tsx +223 -0
  25. package/codemods/migrations/handle-prop-spread.tsx +51 -0
  26. package/codemods/migrations/inline-WidthNames-declaration.ts +92 -0
  27. package/codemods/migrations/map-actions-prop.tsx +430 -0
  28. package/codemods/migrations/map-body-from-props.ts +147 -0
  29. package/codemods/migrations/map-container-from-props.ts +72 -0
  30. package/codemods/migrations/map-footer-from-props.ts +107 -0
  31. package/codemods/migrations/map-header-from-props.ts +101 -0
  32. package/codemods/migrations/map-heading-prop.tsx +193 -0
  33. package/codemods/migrations/remove-appearance-prop.ts +27 -0
  34. package/codemods/migrations/remove-component-override-props.ts +84 -0
  35. package/codemods/migrations/remove-is-chromeless.tsx +42 -0
  36. package/codemods/migrations/rename-appearance-type.ts +9 -0
  37. package/codemods/migrations/rename-inner-component-prop-types.ts +28 -0
  38. package/codemods/migrations/rename-scrollBehavior-to-shouldScrollInViewport.ts +82 -0
  39. package/dist/cjs/hooks.js +22 -0
  40. package/dist/cjs/index.js +63 -0
  41. package/dist/cjs/internal/components/modal-dialog.js +155 -0
  42. package/dist/cjs/internal/components/positioner.js +89 -0
  43. package/dist/cjs/internal/components/scroll-container.js +138 -0
  44. package/dist/cjs/internal/constants.js +48 -0
  45. package/dist/cjs/internal/context.js +13 -0
  46. package/dist/cjs/internal/hooks/use-modal-stack.js +110 -0
  47. package/dist/cjs/internal/hooks/use-on-motion-finish.js +24 -0
  48. package/dist/cjs/internal/hooks/use-prevent-programmatic-scroll.js +55 -0
  49. package/dist/cjs/internal/hooks/use-scroll.js +20 -0
  50. package/dist/cjs/internal/utils.js +35 -0
  51. package/dist/cjs/modal-body.js +66 -0
  52. package/dist/cjs/modal-footer.js +40 -0
  53. package/dist/cjs/modal-header.js +43 -0
  54. package/dist/cjs/modal-title.js +108 -0
  55. package/dist/cjs/modal-transition.js +21 -0
  56. package/dist/cjs/modal-wrapper.js +126 -0
  57. package/dist/cjs/types.js +5 -0
  58. package/dist/cjs/version.json +5 -0
  59. package/dist/es2019/hooks.js +11 -0
  60. package/dist/es2019/index.js +7 -0
  61. package/dist/es2019/internal/components/modal-dialog.js +120 -0
  62. package/dist/es2019/internal/components/positioner.js +78 -0
  63. package/dist/es2019/internal/components/scroll-container.js +97 -0
  64. package/dist/es2019/internal/constants.js +27 -0
  65. package/dist/es2019/internal/context.js +3 -0
  66. package/dist/es2019/internal/hooks/use-modal-stack.js +85 -0
  67. package/dist/es2019/internal/hooks/use-on-motion-finish.js +17 -0
  68. package/dist/es2019/internal/hooks/use-prevent-programmatic-scroll.js +39 -0
  69. package/dist/es2019/internal/hooks/use-scroll.js +11 -0
  70. package/dist/es2019/internal/utils.js +22 -0
  71. package/dist/es2019/modal-body.js +50 -0
  72. package/dist/es2019/modal-footer.js +30 -0
  73. package/dist/es2019/modal-header.js +30 -0
  74. package/dist/es2019/modal-title.js +94 -0
  75. package/dist/es2019/modal-transition.js +10 -0
  76. package/dist/es2019/modal-wrapper.js +88 -0
  77. package/dist/es2019/types.js +1 -0
  78. package/dist/es2019/version.json +5 -0
  79. package/dist/esm/hooks.js +11 -0
  80. package/dist/esm/index.js +7 -0
  81. package/dist/esm/internal/components/modal-dialog.js +131 -0
  82. package/dist/esm/internal/components/positioner.js +76 -0
  83. package/dist/esm/internal/components/scroll-container.js +114 -0
  84. package/dist/esm/internal/constants.js +27 -0
  85. package/dist/esm/internal/context.js +3 -0
  86. package/dist/esm/internal/hooks/use-modal-stack.js +96 -0
  87. package/dist/esm/internal/hooks/use-on-motion-finish.js +16 -0
  88. package/dist/esm/internal/hooks/use-prevent-programmatic-scroll.js +44 -0
  89. package/dist/esm/internal/hooks/use-scroll.js +11 -0
  90. package/dist/esm/internal/utils.js +22 -0
  91. package/dist/esm/modal-body.js +49 -0
  92. package/dist/esm/modal-footer.js +29 -0
  93. package/dist/esm/modal-header.js +29 -0
  94. package/dist/esm/modal-title.js +93 -0
  95. package/dist/esm/modal-transition.js +10 -0
  96. package/dist/esm/modal-wrapper.js +96 -0
  97. package/dist/esm/types.js +1 -0
  98. package/dist/esm/version.json +5 -0
  99. package/dist/types/hooks.d.ts +1 -0
  100. package/dist/types/index.d.ts +8 -0
  101. package/dist/types/internal/components/modal-dialog.d.ts +3 -0
  102. package/dist/types/internal/components/positioner.d.ts +10 -0
  103. package/dist/types/internal/components/scroll-container.d.ts +20 -0
  104. package/dist/types/internal/constants.d.ts +25 -0
  105. package/dist/types/internal/context.d.ts +20 -0
  106. package/dist/types/internal/hooks/use-modal-stack.d.ts +13 -0
  107. package/dist/types/internal/hooks/use-on-motion-finish.d.ts +4 -0
  108. package/dist/types/internal/hooks/use-prevent-programmatic-scroll.d.ts +7 -0
  109. package/dist/types/internal/hooks/use-scroll.d.ts +1 -0
  110. package/dist/types/internal/utils.d.ts +3 -0
  111. package/dist/types/modal-body.d.ts +16 -0
  112. package/dist/types/modal-footer.d.ts +16 -0
  113. package/dist/types/modal-header.d.ts +16 -0
  114. package/dist/types/modal-title.d.ts +26 -0
  115. package/dist/types/modal-transition.d.ts +3 -0
  116. package/dist/types/modal-wrapper.d.ts +5 -0
  117. package/dist/types/types.d.ts +90 -0
  118. package/extract-react-types/modal-attributes.tsx +5 -0
  119. package/hooks/package.json +7 -0
  120. package/modal-body/package.json +7 -0
  121. package/modal-dialog/package.json +7 -0
  122. package/modal-footer/package.json +7 -0
  123. package/modal-header/package.json +7 -0
  124. package/modal-title/package.json +7 -0
  125. package/modal-transition/package.json +7 -0
  126. package/package.json +113 -0
  127. package/types/package.json +7 -0
@@ -0,0 +1,76 @@
1
+ /** @jsx jsx */
2
+ import { css, jsx } from '@emotion/core';
3
+ import { easeInOut } from '@atlaskit/motion/curves';
4
+ import { mediumDurationMs } from '@atlaskit/motion/durations';
5
+ import { layers } from '@atlaskit/theme/constants';
6
+ import { gutter, verticalOffset } from '../constants';
7
+ var maxWidthDimensions = "calc(100vw - ".concat(gutter * 2, "px)");
8
+ var maxHeightDimensions = "calc(100vh - ".concat(gutter * 2 - 1, "px)");
9
+ var positionerStyles = css({
10
+ width: '100%',
11
+ maxWidth: '100%',
12
+ height: '100%',
13
+ position: 'fixed',
14
+ zIndex: layers.modal(),
15
+ top: 0,
16
+ left: 0
17
+ });
18
+ var viewportScrollStyles = css({
19
+ width: 'max-content',
20
+ height: 'auto',
21
+ position: 'relative',
22
+ '@media (min-width: 480px)': {
23
+ margin: "".concat(gutter, "px auto")
24
+ }
25
+ });
26
+ var bodyScrollStyles = css({
27
+ '@media (min-width: 480px)': {
28
+ width: 'max-content',
29
+ maxWidth: maxWidthDimensions,
30
+ maxHeight: maxHeightDimensions,
31
+ marginRight: 'auto',
32
+ marginLeft: 'auto',
33
+ position: 'absolute',
34
+ top: "".concat(gutter, "px"),
35
+ right: 0,
36
+ left: 0,
37
+ pointerEvents: 'none'
38
+ }
39
+ });
40
+ var stackTransitionStyles = css({
41
+ transitionDuration: "".concat(mediumDurationMs, "ms"),
42
+ transitionProperty: 'transform',
43
+ transitionTimingFunction: easeInOut,
44
+
45
+ /** Duplicated from @atlaskit/motion/accessibility
46
+ * because @repo/internal/styles/consistent-style-ordering
47
+ * doesn't work well with object spreading. */
48
+ '@media (prefers-reduced-motion: reduce)': {
49
+ animation: 'none',
50
+ transition: 'none'
51
+ }
52
+ });
53
+ var stackTransformStyles = css({
54
+ transform: 'translateY(var(--modal-dialog-translate-y))'
55
+ });
56
+ var stackIdleStyles = css({
57
+ transform: 'none'
58
+ });
59
+
60
+ var Positioner = function Positioner(props) {
61
+ var children = props.children,
62
+ stackIndex = props.stackIndex,
63
+ shouldScrollInViewport = props.shouldScrollInViewport,
64
+ testId = props.testId;
65
+ return jsx("div", {
66
+ style: {
67
+ '--modal-dialog-translate-y': "".concat(stackIndex * (verticalOffset / 2), "px")
68
+ },
69
+ css: [positionerStyles, stackTransitionStyles,
70
+ /* We only want to apply transform on modals shifting to the back of the stack. */
71
+ stackIndex > 0 ? stackTransformStyles : stackIdleStyles, shouldScrollInViewport ? viewportScrollStyles : bodyScrollStyles],
72
+ "data-testid": testId && "".concat(testId, "--positioner")
73
+ }, children);
74
+ };
75
+
76
+ export default Positioner;
@@ -0,0 +1,114 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+
3
+ /** @jsx jsx */
4
+ import React, { forwardRef, useEffect, useRef, useState } from 'react';
5
+ import { css, jsx } from '@emotion/core';
6
+ import rafSchedule from 'raf-schd';
7
+ import mergeRefs from '@atlaskit/ds-lib/merge-refs';
8
+ import useLazyCallback from '@atlaskit/ds-lib/use-lazy-callback';
9
+ import useStateRef from '@atlaskit/ds-lib/use-state-ref';
10
+ import FocusRing from '@atlaskit/focus-ring';
11
+ import { keylineColor, keylineHeight } from '../constants';
12
+ var baseStyles = css({
13
+ /**
14
+ * We need to inherit flex styles from its parent here
15
+ * in case they're set because we're essentially being a proxy container
16
+ * between the original flex parent and its children (the modal body).
17
+ */
18
+ display: 'inherit',
19
+ margin: 0,
20
+ flex: 'inherit',
21
+ flexDirection: 'inherit',
22
+ overflowX: 'hidden',
23
+ overflowY: 'auto',
24
+ '@media (min-width: 480px)': {
25
+ height: 'unset',
26
+ overflowY: 'auto'
27
+ }
28
+ });
29
+ var topKeylineStyles = css({
30
+ borderTop: "".concat(keylineHeight, "px solid ").concat(keylineColor)
31
+ });
32
+ var bottomKeylineStyles = css({
33
+ borderBottom: "".concat(keylineHeight, "px solid ").concat(keylineColor)
34
+ });
35
+
36
+ /**
37
+ * A container that shows top and bottom keylines when the
38
+ * content overflows into the scrollable element.
39
+ */
40
+ var ScrollContainer = /*#__PURE__*/forwardRef(function (props, ref) {
41
+ var testId = props.testId,
42
+ children = props.children;
43
+
44
+ var _useStateRef = useStateRef({
45
+ previous: false,
46
+ next: false
47
+ }),
48
+ _useStateRef2 = _slicedToArray(_useStateRef, 2),
49
+ hasSiblings = _useStateRef2[0],
50
+ setSiblings = _useStateRef2[1];
51
+
52
+ var _useState = useState(false),
53
+ _useState2 = _slicedToArray(_useState, 2),
54
+ showContentFocus = _useState2[0],
55
+ setContentFocus = _useState2[1];
56
+
57
+ var _useState3 = useState(false),
58
+ _useState4 = _slicedToArray(_useState3, 2),
59
+ showTopKeyline = _useState4[0],
60
+ setTopKeyline = _useState4[1];
61
+
62
+ var _useState5 = useState(false),
63
+ _useState6 = _slicedToArray(_useState5, 2),
64
+ showBottomKeyline = _useState6[0],
65
+ setBottomKeyline = _useState6[1];
66
+
67
+ var scrollableRef = useRef(null);
68
+ var setLazySiblings = useLazyCallback(setSiblings);
69
+ var setLazyContentFocus = useLazyCallback(rafSchedule(function () {
70
+ var target = scrollableRef.current;
71
+ target && setContentFocus(target.scrollHeight > target.clientHeight);
72
+ }));
73
+ var setLazyKeylines = useLazyCallback(rafSchedule(function () {
74
+ var target = scrollableRef.current;
75
+
76
+ if (target) {
77
+ var scrollableDistance = target.scrollHeight - target.clientHeight;
78
+
79
+ if (hasSiblings.current.previous) {
80
+ setTopKeyline(target.scrollTop > keylineHeight);
81
+ }
82
+
83
+ if (hasSiblings.current.next) {
84
+ setBottomKeyline(target.scrollTop <= scrollableDistance - keylineHeight);
85
+ }
86
+ }
87
+ }));
88
+ useEffect(function () {
89
+ var target = scrollableRef.current;
90
+ window.addEventListener('resize', setLazyKeylines, false);
91
+ target === null || target === void 0 ? void 0 : target.addEventListener('scroll', setLazyKeylines, false);
92
+ setLazyContentFocus();
93
+ setLazyKeylines();
94
+ setLazySiblings({
95
+ previous: Boolean(target === null || target === void 0 ? void 0 : target.previousElementSibling),
96
+ next: Boolean(target === null || target === void 0 ? void 0 : target.nextElementSibling)
97
+ });
98
+ return function () {
99
+ window.removeEventListener('resize', setLazyKeylines, false);
100
+ target === null || target === void 0 ? void 0 : target.removeEventListener('scroll', setLazyKeylines, false);
101
+ };
102
+ }, [setLazyContentFocus, setLazyKeylines, setLazySiblings]);
103
+ return jsx(FocusRing, {
104
+ isInset: true
105
+ }, jsx("div", {
106
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
107
+ tabIndex: showContentFocus ? 0 : undefined,
108
+ "data-testid": testId && "".concat(testId, "--scrollable"),
109
+ ref: mergeRefs([ref, scrollableRef]),
110
+ css: [baseStyles, showTopKeyline && topKeylineStyles, showBottomKeyline && bottomKeylineStyles]
111
+ }, children));
112
+ });
113
+ ScrollContainer.displayName = 'ScrollContainer';
114
+ export default ScrollContainer;
@@ -0,0 +1,27 @@
1
+ import { text as getTextColor, N30, N800, R400, Y400 } from '@atlaskit/theme/colors';
2
+ import { borderRadius as getBorderRadius, gridSize as getGridSize } from '@atlaskit/theme/constants';
3
+ export var width = {
4
+ values: ['small', 'medium', 'large', 'x-large'],
5
+ widths: {
6
+ small: 400,
7
+ medium: 600,
8
+ large: 800,
9
+ 'x-large': 968
10
+ },
11
+ defaultValue: 'medium'
12
+ };
13
+ export var gutter = 60;
14
+ var gridSize = getGridSize();
15
+ export var borderRadius = getBorderRadius();
16
+ export var verticalOffset = gridSize * 2;
17
+ export var padding = gridSize * 3;
18
+ export var footerItemGap = gridSize;
19
+ export var titleIconMargin = gridSize;
20
+ export var keylineHeight = 2;
21
+ export var keylineColor = N30;
22
+ export var textColor = getTextColor();
23
+ export var focusOutlineColor = N800;
24
+ export var iconColor = {
25
+ danger: R400,
26
+ warning: Y400
27
+ };
@@ -0,0 +1,3 @@
1
+ import { createContext } from 'react';
2
+ export var ModalContext = /*#__PURE__*/createContext(null);
3
+ export var ScrollContext = /*#__PURE__*/createContext(null);
@@ -0,0 +1,96 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { useEffect } from 'react';
3
+ import useLazyCallback from '@atlaskit/ds-lib/use-lazy-callback';
4
+ import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
5
+ import useStateRef from '@atlaskit/ds-lib/use-state-ref';
6
+ import { useExitingPersistence } from '@atlaskit/motion/exiting-persistence';
7
+ /**
8
+ * ________________________________________________
9
+ * | MAJOR VERSIONS WILL NOT KNOW ABOUT EACH OTHER! |
10
+ * ------------------------------------------------
11
+ *
12
+ * An array which holds references to all currently open modal dialogs.
13
+ * This will only work for modal dialogs of the same major version,
14
+ * as the reference will be different between them.
15
+ *
16
+ * E.g. V11 won't know about any from V12.
17
+ */
18
+
19
+ var modalStackRegister = [];
20
+
21
+ /**
22
+ * Returns the position of the calling modal dialog in the modal dialog stack.
23
+ * Stack index of `0` is the highest position in the stack,
24
+ * with every higher number being behind in the stack.
25
+ */
26
+ export default function useModalStack(_ref) {
27
+ var onStackChange = _ref.onStackChange;
28
+
29
+ var _useExitingPersistenc = useExitingPersistence(),
30
+ isExiting = _useExitingPersistenc.isExiting;
31
+
32
+ var _useStateRef = useStateRef(0),
33
+ _useStateRef2 = _slicedToArray(_useStateRef, 2),
34
+ stackIndexRef = _useStateRef2[0],
35
+ setStackIndex = _useStateRef2[1];
36
+
37
+ var currentStackIndex = stackIndexRef.current;
38
+ var previousStackIndex = usePreviousValue(stackIndexRef.current); // We want to ensure this function **never changes** during the lifecycle of this component.
39
+ // This is why it's assigned to a ref and not in a useMemo/useCallback.
40
+
41
+ var updateStack = useLazyCallback(function () {
42
+ var newStackIndex = modalStackRegister.indexOf(updateStack); // We access the stack index ref instead of state because this closure will always only
43
+ // have the initial state and not any of the later values.
44
+
45
+ if (stackIndexRef.current !== newStackIndex) {
46
+ setStackIndex(newStackIndex);
47
+ stackIndexRef.current = newStackIndex;
48
+ }
49
+ });
50
+ useEffect(function () {
51
+ var currentStackIndex = modalStackRegister.indexOf(updateStack);
52
+
53
+ if (!isExiting && currentStackIndex === -1) {
54
+ // We are opening the modal dialog.
55
+ // Add ourselves to the modal stack register!
56
+ modalStackRegister.unshift(updateStack);
57
+ }
58
+
59
+ if (isExiting && currentStackIndex !== -1) {
60
+ // We are closing the modal dialog using a wrapping modal transition component.
61
+ // Remove ourselves from the modal stack register!
62
+ // NOTE: Modal dialogs that don't have a wrapping modal transition component won't flow through here!
63
+ // For that scenario we cleanup when the component unmounts.
64
+ modalStackRegister.splice(currentStackIndex, 1);
65
+ } // Fire all registered modal dialogs to update their position in the stack.
66
+
67
+
68
+ modalStackRegister.forEach(function (cb) {
69
+ return cb();
70
+ });
71
+ }, [updateStack, isExiting]);
72
+ useEffect(function () {
73
+ return function () {
74
+ // Final cleanup just in case this modal dialog did not have a wrapping modal transition.
75
+ var currentStackIndex = modalStackRegister.indexOf(updateStack);
76
+
77
+ if (currentStackIndex !== -1) {
78
+ modalStackRegister.splice(currentStackIndex, 1);
79
+ modalStackRegister.forEach(function (cb) {
80
+ return cb();
81
+ });
82
+ }
83
+ };
84
+ }, [updateStack]);
85
+ useEffect(function () {
86
+ if (previousStackIndex === undefined) {
87
+ // Initial case that we don't need to notify about.
88
+ return;
89
+ }
90
+
91
+ if (previousStackIndex !== currentStackIndex) {
92
+ onStackChange(currentStackIndex);
93
+ }
94
+ }, [onStackChange, previousStackIndex, currentStackIndex]);
95
+ return currentStackIndex;
96
+ }
@@ -0,0 +1,16 @@
1
+ import { useCallback, useRef } from 'react';
2
+ export default function useOnMotionFinish(_ref) {
3
+ var onOpenComplete = _ref.onOpenComplete,
4
+ onCloseComplete = _ref.onCloseComplete;
5
+ var motionRef = useRef(null);
6
+ var onMotionFinish = useCallback(function (state) {
7
+ if (state === 'entering' && onOpenComplete) {
8
+ onOpenComplete(motionRef.current, true);
9
+ }
10
+
11
+ if (state === 'exiting' && onCloseComplete) {
12
+ onCloseComplete(motionRef.current);
13
+ }
14
+ }, [onOpenComplete, onCloseComplete]);
15
+ return [motionRef, onMotionFinish];
16
+ }
@@ -0,0 +1,44 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { useCallback, useLayoutEffect, useState } from 'react';
3
+ import useWindowEvent from '@atlaskit/ds-lib/use-window-event';
4
+ /**
5
+ * Returns how far the body is scrolled from the top of the viewport.
6
+ *
7
+ * ____
8
+ * ||____|| <-- overflow
9
+ * | | <-- viewport
10
+ * |____|
11
+ *
12
+ * Scroll distance is the height of overflow outside the viewport.
13
+ */
14
+
15
+ function getScrollDistance() {
16
+ var _document$documentEle, _document$body;
17
+
18
+ return window.pageYOffset || ((_document$documentEle = document.documentElement) === null || _document$documentEle === void 0 ? void 0 : _document$documentEle.scrollTop) || ((_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.scrollTop) || 0;
19
+ }
20
+ /**
21
+ * Prevents programatic scrolling of the viewport with `scrollIntoView`.
22
+ * Should be used in conjunction with a scroll lock to prevent a user from scrolling.
23
+ *
24
+ * @returns scroll top offset of the viewport
25
+ */
26
+
27
+
28
+ export default function usePreventProgrammaticScroll() {
29
+ var _useState = useState(0),
30
+ _useState2 = _slicedToArray(_useState, 2),
31
+ scrollTopOffset = _useState2[0],
32
+ setScrollTopOffset = _useState2[1];
33
+
34
+ useLayoutEffect(function () {
35
+ setScrollTopOffset(getScrollDistance());
36
+ }, []);
37
+ var onWindowScroll = useCallback(function () {
38
+ if (getScrollDistance() !== scrollTopOffset) {
39
+ window.scrollTo(window.pageXOffset, scrollTopOffset);
40
+ }
41
+ }, [scrollTopOffset]);
42
+ useWindowEvent('scroll', onWindowScroll);
43
+ return scrollTopOffset;
44
+ }
@@ -0,0 +1,11 @@
1
+ import { useContext } from 'react';
2
+ import { ScrollContext } from '../context';
3
+ export default function useScroll() {
4
+ var shouldScrollInViewport = useContext(ScrollContext);
5
+
6
+ if (shouldScrollInViewport == null) {
7
+ throw Error('@atlaskit/modal-dialog: Scroll context unavailable – this component needs to be a child of ModalDialog.');
8
+ }
9
+
10
+ return shouldScrollInViewport;
11
+ }
@@ -0,0 +1,22 @@
1
+ import { width } from './constants';
2
+ export var dialogWidth = function dialogWidth(input) {
3
+ if (!input) {
4
+ return 'auto';
5
+ }
6
+
7
+ var isWidthName = width.values.indexOf(input.toString()) !== -1;
8
+ var widthName = isWidthName && input;
9
+
10
+ if (widthName) {
11
+ return "".concat(width.widths[widthName], "px");
12
+ }
13
+
14
+ return typeof input === 'number' ? "".concat(input, "px") : input;
15
+ };
16
+ export var dialogHeight = function dialogHeight(input) {
17
+ if (!input) {
18
+ return 'auto';
19
+ }
20
+
21
+ return typeof input === 'number' ? "".concat(input, "px") : input;
22
+ };
@@ -0,0 +1,49 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { css, jsx } from '@emotion/core';
4
+ import { TouchScrollable } from 'react-scrolllock';
5
+ import { useModal } from './hooks';
6
+ import ScrollContainer from './internal/components/scroll-container';
7
+ import { keylineHeight, padding } from './internal/constants';
8
+ import useScroll from './internal/hooks/use-scroll';
9
+ var bodyStyles = css({
10
+ /* This ensures the body fills the whole space between header and footer. */
11
+ flex: '1 1 auto'
12
+ });
13
+ /**
14
+ * Adding the padding here avoids cropping the keyline on its sides.
15
+ * The combined vertical spacing is maintained by subtracting the
16
+ * keyline height from header and footer. */
17
+
18
+ var bodyScrollStyles = css({
19
+ padding: "".concat(keylineHeight, "px ").concat(padding, "px")
20
+ });
21
+ /**
22
+ * Keylines will not be shown if scrolling in viewport so we do
23
+ * not account for them in this case. */
24
+
25
+ var viewportScrollStyles = css({
26
+ padding: "0px ".concat(padding, "px")
27
+ });
28
+
29
+ var ModalBody = function ModalBody(props) {
30
+ var children = props.children,
31
+ userDefinedTestId = props.testId;
32
+
33
+ var _useModal = useModal(),
34
+ modalTestId = _useModal.testId;
35
+
36
+ var shouldScrollInViewport = useScroll();
37
+ var testId = userDefinedTestId || modalTestId && "".concat(modalTestId, "--body");
38
+ return shouldScrollInViewport ? jsx("div", {
39
+ css: [bodyStyles, viewportScrollStyles],
40
+ "data-testid": testId
41
+ }, children) : jsx(TouchScrollable, null, jsx(ScrollContainer, {
42
+ testId: userDefinedTestId || modalTestId
43
+ }, jsx("div", {
44
+ css: [bodyStyles, bodyScrollStyles],
45
+ "data-testid": testId
46
+ }, children)));
47
+ };
48
+
49
+ export default ModalBody;