@atlaskit/page-layout 1.1.0 → 1.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 (107) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +3 -3
  3. package/__perf__/utils/perf-example.tsx +24 -17
  4. package/__perf__/utils/product-integration/NotificationsPopup.tsx +6 -5
  5. package/__perf__/utils/product-integration/SampleFooter.tsx +13 -13
  6. package/dist/cjs/common/hooks/index.js +23 -0
  7. package/dist/cjs/common/hooks/use-is-sidebar-collapsing.js +46 -0
  8. package/dist/cjs/common/hooks/use-is-sidebar-dragging.js +46 -0
  9. package/dist/cjs/components/resize-control/grab-area.js +42 -4
  10. package/dist/cjs/components/resize-control/index.js +22 -20
  11. package/dist/cjs/components/resize-control/resize-button.js +59 -4
  12. package/dist/cjs/components/resize-control/shadow.js +48 -0
  13. package/dist/cjs/components/skip-links/skip-link-components.js +49 -5
  14. package/dist/cjs/components/slots/banner.js +27 -11
  15. package/dist/cjs/components/slots/content.js +9 -2
  16. package/dist/cjs/components/slots/internal/left-sidebar-inner.js +65 -0
  17. package/dist/cjs/components/slots/internal/left-sidebar-outer.js +100 -0
  18. package/dist/cjs/components/slots/internal/resizable-children-wrapper.js +63 -0
  19. package/dist/cjs/components/slots/internal/slot-focus-ring.js +61 -0
  20. package/dist/cjs/components/slots/left-panel.js +26 -11
  21. package/dist/cjs/components/slots/left-sidebar-without-resize.js +10 -10
  22. package/dist/cjs/components/slots/left-sidebar.js +21 -16
  23. package/dist/cjs/components/slots/main.js +53 -6
  24. package/dist/cjs/components/slots/page-layout.js +10 -3
  25. package/dist/cjs/components/slots/right-panel.js +26 -11
  26. package/dist/cjs/components/slots/right-sidebar.js +57 -13
  27. package/dist/cjs/components/slots/top-navigation.js +27 -11
  28. package/dist/cjs/controllers/sidebar-resize-context.js +2 -1
  29. package/dist/cjs/controllers/sidebar-resize-controller.js +10 -5
  30. package/dist/cjs/version.json +1 -1
  31. package/dist/es2019/common/hooks/index.js +2 -0
  32. package/dist/es2019/common/hooks/use-is-sidebar-collapsing.js +29 -0
  33. package/dist/es2019/common/hooks/use-is-sidebar-dragging.js +29 -0
  34. package/dist/es2019/components/resize-control/grab-area.js +46 -4
  35. package/dist/es2019/components/resize-control/index.js +12 -9
  36. package/dist/es2019/components/resize-control/resize-button.js +61 -4
  37. package/dist/es2019/components/resize-control/shadow.js +43 -0
  38. package/dist/es2019/components/skip-links/skip-link-components.js +47 -5
  39. package/dist/es2019/components/slots/banner.js +21 -7
  40. package/dist/es2019/components/slots/content.js +8 -2
  41. package/dist/es2019/components/slots/internal/left-sidebar-inner.js +52 -0
  42. package/dist/es2019/components/slots/internal/left-sidebar-outer.js +79 -0
  43. package/dist/es2019/components/slots/internal/resizable-children-wrapper.js +49 -0
  44. package/dist/es2019/components/slots/internal/slot-focus-ring.js +50 -0
  45. package/dist/es2019/components/slots/left-panel.js +20 -7
  46. package/dist/es2019/components/slots/left-sidebar-without-resize.js +10 -11
  47. package/dist/es2019/components/slots/left-sidebar.js +20 -17
  48. package/dist/es2019/components/slots/main.js +46 -6
  49. package/dist/es2019/components/slots/page-layout.js +15 -3
  50. package/dist/es2019/components/slots/right-panel.js +20 -7
  51. package/dist/es2019/components/slots/right-sidebar.js +50 -8
  52. package/dist/es2019/components/slots/top-navigation.js +21 -7
  53. package/dist/es2019/controllers/sidebar-resize-context.js +2 -1
  54. package/dist/es2019/controllers/sidebar-resize-controller.js +10 -5
  55. package/dist/es2019/version.json +1 -1
  56. package/dist/esm/common/hooks/index.js +2 -0
  57. package/dist/esm/common/hooks/use-is-sidebar-collapsing.js +34 -0
  58. package/dist/esm/common/hooks/use-is-sidebar-dragging.js +34 -0
  59. package/dist/esm/components/resize-control/grab-area.js +42 -4
  60. package/dist/esm/components/resize-control/index.js +23 -20
  61. package/dist/esm/components/resize-control/resize-button.js +57 -4
  62. package/dist/esm/components/resize-control/shadow.js +37 -0
  63. package/dist/esm/components/skip-links/skip-link-components.js +47 -5
  64. package/dist/esm/components/slots/banner.js +27 -12
  65. package/dist/esm/components/slots/content.js +8 -2
  66. package/dist/esm/components/slots/internal/left-sidebar-inner.js +53 -0
  67. package/dist/esm/components/slots/internal/left-sidebar-outer.js +82 -0
  68. package/dist/esm/components/slots/internal/resizable-children-wrapper.js +51 -0
  69. package/dist/esm/components/slots/internal/slot-focus-ring.js +51 -0
  70. package/dist/esm/components/slots/left-panel.js +26 -12
  71. package/dist/esm/components/slots/left-sidebar-without-resize.js +10 -10
  72. package/dist/esm/components/slots/left-sidebar.js +20 -16
  73. package/dist/esm/components/slots/main.js +49 -8
  74. package/dist/esm/components/slots/page-layout.js +12 -3
  75. package/dist/esm/components/slots/right-panel.js +26 -12
  76. package/dist/esm/components/slots/right-sidebar.js +57 -14
  77. package/dist/esm/components/slots/top-navigation.js +27 -12
  78. package/dist/esm/controllers/sidebar-resize-context.js +2 -1
  79. package/dist/esm/controllers/sidebar-resize-controller.js +10 -5
  80. package/dist/esm/version.json +1 -1
  81. package/dist/types/common/hooks/index.d.ts +2 -0
  82. package/dist/types/common/hooks/use-is-sidebar-collapsing.d.ts +2 -0
  83. package/dist/types/common/hooks/use-is-sidebar-dragging.d.ts +2 -0
  84. package/dist/types/common/utils.d.ts +0 -1
  85. package/dist/types/components/resize-control/shadow.d.ts +6 -0
  86. package/dist/types/components/slots/internal/left-sidebar-inner.d.ts +9 -0
  87. package/dist/types/components/slots/internal/left-sidebar-outer.d.ts +13 -0
  88. package/dist/types/components/slots/internal/resizable-children-wrapper.d.ts +10 -0
  89. package/dist/types/components/slots/internal/slot-focus-ring.d.ts +19 -0
  90. package/dist/types/controllers/sidebar-resize-context.d.ts +1 -0
  91. package/package.json +10 -7
  92. package/dist/cjs/components/resize-control/styles.js +0 -158
  93. package/dist/cjs/components/skip-links/styles.js +0 -58
  94. package/dist/cjs/components/slots/left-sidebar-styles.js +0 -116
  95. package/dist/cjs/components/slots/styles.js +0 -154
  96. package/dist/es2019/components/resize-control/styles.js +0 -139
  97. package/dist/es2019/components/skip-links/styles.js +0 -41
  98. package/dist/es2019/components/slots/left-sidebar-styles.js +0 -96
  99. package/dist/es2019/components/slots/styles.js +0 -130
  100. package/dist/esm/components/resize-control/styles.js +0 -133
  101. package/dist/esm/components/skip-links/styles.js +0 -45
  102. package/dist/esm/components/slots/left-sidebar-styles.js +0 -94
  103. package/dist/esm/components/slots/styles.js +0 -117
  104. package/dist/types/components/resize-control/styles.d.ts +0 -41
  105. package/dist/types/components/skip-links/styles.d.ts +0 -2
  106. package/dist/types/components/slots/left-sidebar-styles.d.ts +0 -5
  107. package/dist/types/components/slots/styles.d.ts +0 -23
@@ -21,11 +21,22 @@ var _utils = require("../../common/utils");
21
21
 
22
22
  var _controllers = require("../../controllers");
23
23
 
24
- var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
24
+ var _slotFocusRing = _interopRequireDefault(require("./internal/slot-focus-ring"));
25
25
 
26
- var _styles = require("./styles");
26
+ var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
27
27
 
28
28
  /** @jsx jsx */
29
+ var baseStyles = (0, _core.css)({
30
+ gridArea: _constants.RIGHT_PANEL
31
+ });
32
+ var fixedStyles = (0, _core.css)({
33
+ width: _constants.RIGHT_PANEL_WIDTH,
34
+ position: 'fixed',
35
+ top: 0,
36
+ right: 0,
37
+ bottom: 0
38
+ });
39
+
29
40
  var RightPanel = function RightPanel(props) {
30
41
  var children = props.children,
31
42
  isFixed = props.isFixed,
@@ -40,17 +51,21 @@ var RightPanel = function RightPanel(props) {
40
51
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_RIGHT_PANEL_WIDTH, rightPanelWidth));
41
52
  return function () {
42
53
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_RIGHT_PANEL_WIDTH, 0));
43
- }; // eslint-disable-next-line react-hooks/exhaustive-deps
54
+ };
44
55
  }, [rightPanelWidth]);
45
56
  (0, _controllers.useSkipLink)(id, skipLinkTitle);
46
- return (0, _core.jsx)("div", (0, _extends2.default)({
47
- css: (0, _styles.rightPanelStyles)(isFixed),
48
- "data-testid": testId,
49
- id: id
50
- }, (0, _utils.getPageLayoutSlotSelector)('right-panel')), (0, _core.jsx)(_slotDimensions.default, {
51
- variableName: _constants.VAR_RIGHT_PANEL_WIDTH,
52
- value: rightPanelWidth
53
- }), children);
57
+ return (0, _core.jsx)(_slotFocusRing.default, null, function (_ref) {
58
+ var className = _ref.className;
59
+ return (0, _core.jsx)("div", (0, _extends2.default)({
60
+ css: [baseStyles, isFixed && fixedStyles],
61
+ className: className,
62
+ "data-testid": testId,
63
+ id: id
64
+ }, (0, _utils.getPageLayoutSlotSelector)('right-panel')), (0, _core.jsx)(_slotDimensions.default, {
65
+ variableName: _constants.VAR_RIGHT_PANEL_WIDTH,
66
+ value: rightPanelWidth
67
+ }), children);
68
+ });
54
69
  };
55
70
 
56
71
  var _default = RightPanel;
@@ -21,11 +21,49 @@ var _utils = require("../../common/utils");
21
21
 
22
22
  var _controllers = require("../../controllers");
23
23
 
24
- var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
24
+ var _slotFocusRing = _interopRequireDefault(require("./internal/slot-focus-ring"));
25
25
 
26
- var _styles = require("./styles");
26
+ var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
27
27
 
28
28
  /** @jsx jsx */
29
+
30
+ /**
31
+ * This inner wrapper is required to allow the sidebar to be `position: fixed`.
32
+ *
33
+ * If we were to apply `position: fixed` to the outer wrapper, it will be popped
34
+ * out of its flex container and Main would stretch to occupy all the space.
35
+ */
36
+ var fixedInnerStyles = (0, _core.css)({
37
+ /**
38
+ * This width on the inner wrapper is required when it is using fixed
39
+ * positioning. Otherwise its width is slightly off.
40
+ */
41
+ width: _constants.RIGHT_SIDEBAR_WIDTH,
42
+ position: 'fixed',
43
+ top: "calc(".concat(_constants.BANNER_HEIGHT, " + ").concat(_constants.TOP_NAVIGATION_HEIGHT, ")"),
44
+ right: "calc(".concat(_constants.RIGHT_PANEL_WIDTH, ")"),
45
+ bottom: 0
46
+ });
47
+ var staticInnerStyles = (0, _core.css)({
48
+ height: '100%'
49
+ });
50
+ var outerStyles = (0, _core.css)({
51
+ width: _constants.RIGHT_SIDEBAR_WIDTH
52
+ });
53
+ /**
54
+ * In fixed mode this element's child is taken out of the document flow.
55
+ * It doesn't take up the width as expected,
56
+ * so the pseudo element forces it to take up the necessary width.
57
+ */
58
+
59
+ var fixedOuterStyles = (0, _core.css)({
60
+ '&::after': {
61
+ display: 'inline-block',
62
+ width: _constants.RIGHT_SIDEBAR_WIDTH,
63
+ content: "''"
64
+ }
65
+ });
66
+
29
67
  var RightSidebar = function RightSidebar(props) {
30
68
  var children = props.children,
31
69
  _props$width = props.width,
@@ -40,19 +78,25 @@ var RightSidebar = function RightSidebar(props) {
40
78
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_RIGHT_SIDEBAR_WIDTH, rightSidebarWidth));
41
79
  return function () {
42
80
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_RIGHT_SIDEBAR_WIDTH, 0));
43
- }; // eslint-disable-next-line react-hooks/exhaustive-deps
81
+ };
44
82
  }, [rightSidebarWidth, id]);
45
83
  (0, _controllers.useSkipLink)(id, skipLinkTitle);
46
- return (0, _core.jsx)("div", (0, _extends2.default)({
47
- "data-testid": testId,
48
- css: (0, _styles.rightSidebarStyles)(isFixed),
49
- id: id
50
- }, (0, _utils.getPageLayoutSlotSelector)('right-sidebar')), (0, _core.jsx)(_slotDimensions.default, {
51
- variableName: _constants.VAR_RIGHT_SIDEBAR_WIDTH,
52
- value: rightSidebarWidth
53
- }), (0, _core.jsx)("div", {
54
- css: (0, _styles.fixedRightSidebarInnerStyles)(isFixed)
55
- }, children));
84
+ return (0, _core.jsx)(_slotFocusRing.default, {
85
+ isSidebar: true
86
+ }, function (_ref) {
87
+ var className = _ref.className;
88
+ return (0, _core.jsx)("div", (0, _extends2.default)({
89
+ "data-testid": testId,
90
+ css: [outerStyles, isFixed && fixedOuterStyles],
91
+ className: className,
92
+ id: id
93
+ }, (0, _utils.getPageLayoutSlotSelector)('right-sidebar')), (0, _core.jsx)(_slotDimensions.default, {
94
+ variableName: _constants.VAR_RIGHT_SIDEBAR_WIDTH,
95
+ value: rightSidebarWidth
96
+ }), (0, _core.jsx)("div", {
97
+ css: [isFixed && fixedInnerStyles, !isFixed && staticInnerStyles]
98
+ }, children));
99
+ });
56
100
  };
57
101
 
58
102
  var _default = RightSidebar;
@@ -21,11 +21,23 @@ var _utils = require("../../common/utils");
21
21
 
22
22
  var _controllers = require("../../controllers");
23
23
 
24
- var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
24
+ var _slotFocusRing = _interopRequireDefault(require("./internal/slot-focus-ring"));
25
25
 
26
- var _styles = require("./styles");
26
+ var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
27
27
 
28
28
  /** @jsx jsx */
29
+ var topNavigationStyles = (0, _core.css)({
30
+ height: _constants.TOP_NAVIGATION_HEIGHT,
31
+ gridArea: _constants.TOP_NAVIGATION
32
+ });
33
+ var fixedStyles = (0, _core.css)({
34
+ position: 'fixed',
35
+ zIndex: 2,
36
+ top: _constants.BANNER_HEIGHT,
37
+ right: _constants.RIGHT_PANEL_WIDTH,
38
+ left: _constants.LEFT_PANEL_WIDTH
39
+ });
40
+
29
41
  var TopNavigation = function TopNavigation(props) {
30
42
  var children = props.children,
31
43
  _props$height = props.height,
@@ -41,17 +53,21 @@ var TopNavigation = function TopNavigation(props) {
41
53
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_TOP_NAVIGATION_HEIGHT, topNavigationHeight));
42
54
  return function () {
43
55
  (0, _controllers.publishGridState)((0, _defineProperty2.default)({}, _constants.VAR_TOP_NAVIGATION_HEIGHT, 0));
44
- }; // eslint-disable-next-line react-hooks/exhaustive-deps
56
+ };
45
57
  }, [topNavigationHeight]);
46
58
  (0, _controllers.useSkipLink)(id, skipLinkTitle);
47
- return (0, _core.jsx)("div", (0, _extends2.default)({
48
- css: (0, _styles.topNavigationStyles)(isFixed),
49
- "data-testid": testId,
50
- id: id
51
- }, (0, _utils.getPageLayoutSlotSelector)('top-navigation')), (0, _core.jsx)(_slotDimensions.default, {
52
- variableName: _constants.VAR_TOP_NAVIGATION_HEIGHT,
53
- value: topNavigationHeight
54
- }), children);
59
+ return (0, _core.jsx)(_slotFocusRing.default, null, function (_ref) {
60
+ var className = _ref.className;
61
+ return (0, _core.jsx)("div", (0, _extends2.default)({
62
+ css: [topNavigationStyles, isFixed && fixedStyles],
63
+ className: className,
64
+ "data-testid": testId,
65
+ id: id
66
+ }, (0, _utils.getPageLayoutSlotSelector)('top-navigation')), (0, _core.jsx)(_slotDimensions.default, {
67
+ variableName: _constants.VAR_TOP_NAVIGATION_HEIGHT,
68
+ value: topNavigationHeight
69
+ }), children);
70
+ });
55
71
  };
56
72
 
57
73
  var _default = TopNavigation;
@@ -27,7 +27,8 @@ var leftSidebarState = {
27
27
  isLeftSidebarCollapsed: false,
28
28
  leftSidebarWidth: 0,
29
29
  lastLeftSidebarWidth: 0,
30
- flyoutLockCount: 0
30
+ flyoutLockCount: 0,
31
+ isFixed: true
31
32
  };
32
33
  var SidebarResizeContext = /*#__PURE__*/(0, _react.createContext)({
33
34
  isLeftSidebarCollapsed: false,
@@ -46,7 +46,8 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
46
46
  isLeftSidebarCollapsed: false,
47
47
  leftSidebarWidth: 0,
48
48
  lastLeftSidebarWidth: 0,
49
- flyoutLockCount: 0
49
+ flyoutLockCount: 0,
50
+ isFixed: true
50
51
  }),
51
52
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
52
53
  leftSidebarState = _useState2[0],
@@ -74,7 +75,8 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
74
75
  var expandLeftSidebar = (0, _react.useCallback)(function () {
75
76
  var lastLeftSidebarWidth = leftSidebarState.lastLeftSidebarWidth,
76
77
  isResizing = leftSidebarState.isResizing,
77
- flyoutLockCount = leftSidebarState.flyoutLockCount;
78
+ flyoutLockCount = leftSidebarState.flyoutLockCount,
79
+ isFixed = leftSidebarState.isFixed;
78
80
 
79
81
  if (isResizing) {
80
82
  return;
@@ -87,7 +89,8 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
87
89
  leftSidebarWidth: width,
88
90
  lastLeftSidebarWidth: lastLeftSidebarWidth,
89
91
  isResizing: isResizing,
90
- flyoutLockCount: flyoutLockCount
92
+ flyoutLockCount: flyoutLockCount,
93
+ isFixed: isFixed
91
94
  };
92
95
  setLeftSidebarState(updatedLeftSidebarState); // onTransitionEnd isn't triggered when a user prefers reduced motion
93
96
 
@@ -98,7 +101,8 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
98
101
  var collapseLeftSidebar = (0, _react.useCallback)(function (event, collapseWithoutTransition) {
99
102
  var leftSidebarWidth = leftSidebarState.leftSidebarWidth,
100
103
  isResizing = leftSidebarState.isResizing,
101
- flyoutLockCount = leftSidebarState.flyoutLockCount;
104
+ flyoutLockCount = leftSidebarState.flyoutLockCount,
105
+ isFixed = leftSidebarState.isFixed;
102
106
 
103
107
  if (isResizing) {
104
108
  return;
@@ -113,7 +117,8 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
113
117
  leftSidebarWidth: _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH,
114
118
  lastLeftSidebarWidth: leftSidebarWidth,
115
119
  isResizing: isResizing,
116
- flyoutLockCount: flyoutLockCount
120
+ flyoutLockCount: flyoutLockCount,
121
+ isFixed: isFixed
117
122
  };
118
123
  setLeftSidebarState(updatedLeftSidebarState); // onTransitionEnd isn't triggered when a user prefers reduced motion
119
124
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/page-layout",
3
- "version": "1.1.0",
3
+ "version": "1.2.2",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,2 @@
1
+ export { default as useIsSidebarCollapsing } from './use-is-sidebar-collapsing';
2
+ export { default as useIsSidebarDragging } from './use-is-sidebar-dragging';
@@ -0,0 +1,29 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { IS_SIDEBAR_COLLAPSING } from '../constants';
3
+
4
+ const getIsCollapsing = () => {
5
+ // SSR bail-out because document is undefined on the server
6
+ if (typeof document === 'undefined') {
7
+ return false;
8
+ }
9
+
10
+ return document.documentElement.getAttribute(IS_SIDEBAR_COLLAPSING) === 'true';
11
+ };
12
+
13
+ const useIsSidebarCollapsing = () => {
14
+ const [isCollapsing, setIsCollapsing] = useState(getIsCollapsing);
15
+ useEffect(() => {
16
+ const observer = new MutationObserver(() => {
17
+ setIsCollapsing(getIsCollapsing);
18
+ });
19
+ observer.observe(document.documentElement, {
20
+ attributeFilter: [IS_SIDEBAR_COLLAPSING]
21
+ });
22
+ return () => {
23
+ observer.disconnect();
24
+ };
25
+ }, []);
26
+ return isCollapsing;
27
+ };
28
+
29
+ export default useIsSidebarCollapsing;
@@ -0,0 +1,29 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { IS_SIDEBAR_DRAGGING } from '../constants';
3
+
4
+ const getIsDragging = () => {
5
+ // SSR bail-out because document is undefined on the server
6
+ if (typeof document === 'undefined') {
7
+ return false;
8
+ }
9
+
10
+ return document.documentElement.getAttribute(IS_SIDEBAR_DRAGGING) === 'true';
11
+ };
12
+
13
+ const useIsSidebarDragging = () => {
14
+ const [isDragging, setIsDragging] = useState(getIsDragging);
15
+ useEffect(() => {
16
+ const observer = new MutationObserver(() => {
17
+ setIsDragging(getIsDragging);
18
+ });
19
+ observer.observe(document.documentElement, {
20
+ attributeFilter: [IS_SIDEBAR_DRAGGING]
21
+ });
22
+ return () => {
23
+ observer.disconnect();
24
+ };
25
+ }, []);
26
+ return isDragging;
27
+ };
28
+
29
+ export default useIsSidebarDragging;
@@ -1,9 +1,51 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
 
3
3
  /** @jsx jsx */
4
- import { jsx } from '@emotion/core';
4
+ import { css, jsx } from '@emotion/core';
5
+ import { B100, B200 } from '@atlaskit/theme/colors';
5
6
  import { GRAB_AREA_LINE_SELECTOR, GRAB_AREA_SELECTOR } from '../../common/constants';
6
- import { grabAreaCSS, lineCSS } from './styles';
7
+
8
+ /**
9
+ * Determines the color of the grab line.
10
+ *
11
+ * Used on internal leaf node, so naming collisions won't matter.
12
+ */
13
+ const varLineColor = '--ds-line';
14
+ const grabAreaStyles = css({
15
+ width: 24,
16
+ height: '100%',
17
+ padding: 0,
18
+ backgroundColor: 'transparent',
19
+ border: 0,
20
+ cursor: 'ew-resize',
21
+ '&::-moz-focus-inner': {
22
+ border: 0
23
+ },
24
+ ':focus': {
25
+ outline: 0
26
+ },
27
+ ':enabled': {
28
+ ':hover': {
29
+ [varLineColor]: `var(--ds-border-selected, ${B100})`
30
+ },
31
+ ':active, :focus': {
32
+ [varLineColor]: `var(--ds-border-selected, ${B200})`
33
+ }
34
+ }
35
+ });
36
+ const grabAreaCollapsedStyles = css({
37
+ padding: 0,
38
+ backgroundColor: 'transparent',
39
+ border: 0,
40
+ cursor: 'default'
41
+ });
42
+ const lineStyles = css({
43
+ display: 'block',
44
+ width: 2,
45
+ height: '100%',
46
+ backgroundColor: `var(${varLineColor})`,
47
+ transition: 'background-color 200ms'
48
+ });
7
49
  const grabAreaLineSelector = {
8
50
  [GRAB_AREA_LINE_SELECTOR]: true
9
51
  };
@@ -18,9 +60,9 @@ const GrabArea = ({
18
60
  }) => jsx("button", _extends({}, grabAreaSelector, {
19
61
  "data-testid": testId,
20
62
  type: "button",
21
- css: grabAreaCSS(isLeftSidebarCollapsed)
63
+ css: [grabAreaStyles, isLeftSidebarCollapsed && grabAreaCollapsedStyles]
22
64
  }, rest), jsx("span", _extends({
23
- css: lineCSS(isLeftSidebarCollapsed)
65
+ css: lineStyles
24
66
  }, grabAreaLineSelector)));
25
67
 
26
68
  export default GrabArea;
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
 
3
3
  /** @jsx jsx */
4
4
  import { useCallback, useContext, useMemo, useRef, useState } from 'react';
5
- import { jsx } from '@emotion/core';
5
+ import { css, jsx } from '@emotion/core';
6
6
  import rafSchd from 'raf-schd';
7
7
  import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH, IS_SIDEBAR_DRAGGING, MIN_LEFT_SIDEBAR_DRAG_THRESHOLD, RESIZE_BUTTON_SELECTOR, RESIZE_CONTROL_SELECTOR, VAR_LEFT_SIDEBAR_WIDTH } from '../../common/constants';
8
8
  import { getLeftPanelWidth, getLeftSidebarPercentage } from '../../common/utils';
@@ -11,16 +11,19 @@ import { SidebarResizeContext } from '../../controllers/sidebar-resize-context';
11
11
 
12
12
  import GrabArea from './grab-area';
13
13
  import ResizeButton from './resize-button';
14
- import { resizeControlCSS, shadowCSS } from './styles';
14
+ import Shadow from './shadow';
15
15
  const cssSelector = {
16
16
  [RESIZE_CONTROL_SELECTOR]: true
17
17
  };
18
-
19
- const Shadow = ({
20
- testId
21
- }) => jsx("div", {
22
- "data-testid": testId,
23
- css: shadowCSS
18
+ const resizeControlStyles = css({
19
+ position: 'absolute',
20
+ top: 0,
21
+ bottom: 0,
22
+ left: '100%',
23
+ outline: 'none'
24
+ });
25
+ const showResizeButtonStyles = css({
26
+ '--ds--resize-button--opacity': 1
24
27
  });
25
28
 
26
29
  const ResizeControl = ({
@@ -236,7 +239,7 @@ const ResizeControl = ({
236
239
  /* eslint-disable jsx-a11y/role-supports-aria-props */
237
240
 
238
241
  return jsx("div", _extends({}, cssSelector, {
239
- css: resizeControlCSS(isGrabAreaFocused, isLeftSidebarCollapsed)
242
+ css: [resizeControlStyles, (isGrabAreaFocused || isLeftSidebarCollapsed) && showResizeButtonStyles]
240
243
  }), jsx(Shadow, {
241
244
  testId: testId && `${testId}-shadow`
242
245
  }), jsx(GrabArea, {
@@ -1,10 +1,67 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
 
3
3
  /** @jsx jsx */
4
- import { jsx } from '@emotion/core';
4
+ import { css, jsx } from '@emotion/core';
5
5
  import ChevronRight from '@atlaskit/icon/glyph/chevron-right';
6
+ import { easeOut } from '@atlaskit/motion/curves';
7
+ import { mediumDurationMs, smallDurationMs } from '@atlaskit/motion/durations';
8
+ import { B100, B200, N0, N200, N30A } from '@atlaskit/theme/colors';
6
9
  import { RESIZE_BUTTON_SELECTOR } from '../../common/constants';
7
- import { increaseHitArea, resizeIconButtonCSS } from './styles';
10
+ const increaseHitAreaStyles = css({
11
+ position: 'absolute',
12
+ top: -8,
13
+ right: -12,
14
+ bottom: -8,
15
+ left: -8
16
+ });
17
+ const resizeIconButtonStyles = css({
18
+ width: 24,
19
+ height: 24,
20
+ padding: 0,
21
+ position: 'absolute',
22
+ top: 32,
23
+ left: 0,
24
+ backgroundColor: `var(--ds-surface-overlay, ${N0})`,
25
+ border: 0,
26
+ borderRadius: '50%',
27
+
28
+ /**
29
+ * TODO: https://product-fabric.atlassian.net/browse/DSP-3392
30
+ * This shadow needs further investigation,
31
+ * along with the hover and active background colors.
32
+ */
33
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
34
+ boxShadow: `0 0 0 1px ${N30A}, 0 2px 4px 1px ${N30A}`,
35
+ color: `var(--ds-text-subtle, ${N200})`,
36
+ cursor: 'pointer',
37
+
38
+ /**
39
+ * The fallback value of 0 ensures that the button is hidden by default,
40
+ * unless some parent (or the button itself) overrides it.
41
+ */
42
+ opacity: `var(--ds--resize-button--opacity,0)`,
43
+ outline: 0,
44
+ transform: 'translateX(-50%)',
45
+ transition: `
46
+ background-color ${smallDurationMs}ms linear,
47
+ color ${smallDurationMs}ms linear,
48
+ opacity ${mediumDurationMs}ms ${easeOut}
49
+ `,
50
+ ':hover': {
51
+ backgroundColor: `var(--ds-background-selected-bold, ${B100})`,
52
+ color: `var(--ds-text-inverse, ${N0})`,
53
+ opacity: 1
54
+ },
55
+ ':active, :focus': {
56
+ backgroundColor: `var(--ds-background-selected-bold-hovered, ${B200})`,
57
+ color: `var(--ds-text-inverse, ${N0})`,
58
+ opacity: 1
59
+ }
60
+ });
61
+ const resizeIconButtonExpandedStyles = css({
62
+ transform: 'rotate(180deg)',
63
+ transformOrigin: 7
64
+ });
8
65
 
9
66
  const preventDefault = event => event.preventDefault();
10
67
 
@@ -22,7 +79,7 @@ const ResizeButton = ({
22
79
  "aria-expanded": !isLeftSidebarCollapsed,
23
80
  "aria-label": label,
24
81
  type: "button",
25
- css: resizeIconButtonCSS(isLeftSidebarCollapsed),
82
+ css: [resizeIconButtonStyles, !isLeftSidebarCollapsed && resizeIconButtonExpandedStyles],
26
83
  "data-testid": testId // Prevents focus staying attached to the button
27
84
  // when pressed
28
85
  ,
@@ -30,7 +87,7 @@ const ResizeButton = ({
30
87
  }, props), jsx(ChevronRight, {
31
88
  label: ""
32
89
  }), jsx("div", {
33
- css: increaseHitArea
90
+ css: increaseHitAreaStyles
34
91
  }));
35
92
 
36
93
  export default ResizeButton;
@@ -0,0 +1,43 @@
1
+ /** @jsx jsx */
2
+ import { css, jsx } from '@emotion/core';
3
+ import { easeOut } from '@atlaskit/motion';
4
+ import { useIsSidebarDragging } from '../../common/hooks';
5
+ const colorStops = `
6
+ rgba(0, 0, 0, 0.2) 0px,
7
+ rgba(0, 0, 0, 0.2) 1px,
8
+ rgba(0, 0, 0, 0.1) 1px,
9
+ rgba(0, 0, 0, 0) 100%
10
+ `;
11
+ const direction = 'to left';
12
+ const transitionDuration = '0.22s';
13
+ const shadowStyles = css({
14
+ width: 3,
15
+ position: 'absolute',
16
+ top: 0,
17
+ bottom: 0,
18
+ left: -1,
19
+ background: `var(--ds-border, ${`linear-gradient(${direction}, ${colorStops})`})`,
20
+ opacity: 0.5,
21
+ pointerEvents: 'none',
22
+ transitionDuration: transitionDuration,
23
+ transitionProperty: 'left, opacity, width',
24
+ transitionTimingFunction: easeOut
25
+ });
26
+ const draggingStyles = css({
27
+ width: 6,
28
+ left: -6,
29
+ background: `var(--ds-background-neutral-subtle, ${`linear-gradient(${direction}, ${colorStops})`})`,
30
+ opacity: 0.8
31
+ });
32
+
33
+ const Shadow = ({
34
+ testId
35
+ }) => {
36
+ const isDragging = useIsSidebarDragging();
37
+ return jsx("div", {
38
+ "data-testid": testId,
39
+ css: [shadowStyles, isDragging && draggingStyles]
40
+ });
41
+ };
42
+
43
+ export default Shadow;
@@ -1,8 +1,46 @@
1
1
  /** @jsx jsx */
2
- import { jsx } from '@emotion/core';
2
+ import { css, jsx } from '@emotion/core';
3
+ import { easeOut, prefersReducedMotion } from '@atlaskit/motion';
4
+ import { N30A, N60A } from '@atlaskit/theme/colors';
3
5
  import { PAGE_LAYOUT_CONTAINER_SELECTOR } from '../../common/constants';
4
6
  import { useSkipLinks } from '../../controllers';
5
- import { skipLinkStyles } from './styles';
7
+ // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
8
+ const prefersReducedMotionStyles = css(prefersReducedMotion());
9
+ const skipLinkStyles = css({
10
+ margin: 10,
11
+ padding: '0.8rem 1rem',
12
+ position: 'fixed',
13
+ zIndex: -1,
14
+ left: -999999,
15
+ background: "var(--ds-surface-overlay, white)",
16
+ border: 'none',
17
+ borderRadius: 3,
18
+ boxShadow: `var(--ds-shadow-overlay, ${`0 0 0 1px ${N30A}, 0 2px 10px ${N30A}, 0 0 20px -4px ${N60A}`})`,
19
+ opacity: 0,
20
+
21
+ /* Do the transform when focused */
22
+ transform: 'translateY(-50%)',
23
+ transition: `transform 0.3s ${easeOut}`,
24
+ ':focus-within': {
25
+ /**
26
+ * Max z-index is 2147483647. Skip links always be on top,
27
+ * but giving a few digits extra space just in case there's a future need.
28
+ */
29
+ zIndex: 2147483640,
30
+ left: 0,
31
+ opacity: 1,
32
+ transform: 'translateY(0%)'
33
+ }
34
+ });
35
+ const skipLinkListStyles = css({
36
+ marginTop: 4,
37
+ paddingLeft: 0,
38
+ listStylePosition: 'outside',
39
+ listStyleType: 'none'
40
+ });
41
+ const skipLinkListItemStyles = css({
42
+ marginTop: 0
43
+ });
6
44
 
7
45
  const assignIndex = (num, arr) => {
8
46
  if (!arr.includes(num)) {
@@ -58,9 +96,11 @@ export const SkipLinkWrapper = ({
58
96
  return jsx("div", {
59
97
  onFocus: attachEscHandler,
60
98
  onBlur: removeEscHandler,
61
- css: skipLinkStyles,
99
+ css: [skipLinkStyles, prefersReducedMotionStyles],
62
100
  "data-skip-link-wrapper": true
63
- }, jsx("h5", null, skipLinksLabel), jsx("ol", null, sortSkipLinks(skipLinksData).map(({
101
+ }, jsx("h5", null, skipLinksLabel), jsx("ol", {
102
+ css: skipLinkListStyles
103
+ }, sortSkipLinks(skipLinksData).map(({
64
104
  id,
65
105
  skipLinkTitle
66
106
  }) => jsx(SkipLink, {
@@ -110,7 +150,9 @@ export const SkipLink = ({
110
150
  isFocusable,
111
151
  title
112
152
  }) => {
113
- return jsx("li", null, jsx("a", {
153
+ return jsx("li", {
154
+ css: skipLinkListItemStyles
155
+ }, jsx("a", {
114
156
  tabIndex: isFocusable ? 0 : -1,
115
157
  href: href,
116
158
  onClick: focusTargetRef(href),