@atlaskit/navigation-system 1.2.0 → 2.1.0
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.
- package/CHANGELOG.md +50 -0
- package/dist/cjs/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +2 -3
- package/dist/cjs/ui/page-layout/aside.js +8 -1
- package/dist/cjs/ui/page-layout/panel-splitter/context.js +11 -2
- package/dist/cjs/ui/page-layout/panel-splitter/get-width.js +5 -0
- package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +8 -1
- package/dist/cjs/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +47 -0
- package/dist/cjs/ui/page-layout/panel.js +9 -1
- package/dist/cjs/ui/page-layout/side-nav/side-nav.js +9 -1
- package/dist/cjs/ui/page-layout/use-safe-default-width.js +32 -0
- package/dist/es2019/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +2 -3
- package/dist/es2019/ui/page-layout/aside.js +8 -1
- package/dist/es2019/ui/page-layout/panel-splitter/context.js +10 -1
- package/dist/es2019/ui/page-layout/panel-splitter/get-width.js +5 -0
- package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +9 -2
- package/dist/es2019/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +38 -0
- package/dist/es2019/ui/page-layout/panel.js +9 -1
- package/dist/es2019/ui/page-layout/side-nav/side-nav.js +9 -1
- package/dist/es2019/ui/page-layout/use-safe-default-width.js +28 -0
- package/dist/esm/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +2 -3
- package/dist/esm/ui/page-layout/aside.js +8 -1
- package/dist/esm/ui/page-layout/panel-splitter/context.js +10 -1
- package/dist/esm/ui/page-layout/panel-splitter/get-width.js +5 -0
- package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +9 -2
- package/dist/esm/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +38 -0
- package/dist/esm/ui/page-layout/panel.js +9 -1
- package/dist/esm/ui/page-layout/side-nav/side-nav.js +9 -1
- package/dist/esm/ui/page-layout/use-safe-default-width.js +27 -0
- package/dist/types/ui/page-layout/aside.d.ts +2 -2
- package/dist/types/ui/page-layout/panel-splitter/context.d.ts +8 -0
- package/dist/types/ui/page-layout/panel-splitter/panel-splitter.d.ts +1 -1
- package/dist/types/ui/page-layout/panel-splitter/side-nav-panel-splitter.d.ts +20 -0
- package/dist/types/ui/page-layout/panel.d.ts +2 -2
- package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +2 -1
- package/dist/types/ui/page-layout/use-safe-default-width.d.ts +21 -0
- package/dist/types-ts4.5/ui/page-layout/aside.d.ts +2 -2
- package/dist/types-ts4.5/ui/page-layout/panel-splitter/context.d.ts +8 -0
- package/dist/types-ts4.5/ui/page-layout/panel-splitter/panel-splitter.d.ts +1 -1
- package/dist/types-ts4.5/ui/page-layout/panel-splitter/side-nav-panel-splitter.d.ts +20 -0
- package/dist/types-ts4.5/ui/page-layout/panel.d.ts +2 -2
- package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +2 -1
- package/dist/types-ts4.5/ui/page-layout/use-safe-default-width.d.ts +21 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @atlassian/navigation-system
|
|
2
2
|
|
|
3
|
+
## 2.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`8f30ac4ceb737`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8f30ac4ceb737) -
|
|
8
|
+
Adds extra guards for resizable slots to avoid invalid widths being set. This change is behind the
|
|
9
|
+
`platform_dst_nav4_panel_splitter_guards` feature gate.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 2.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- [`ca468a8bbccd9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ca468a8bbccd9) -
|
|
20
|
+
The elemBefore chevron icon button in the link (selectable) variants of
|
|
21
|
+
`ExpandableMenuItemTrigger` is now labelled by the menu item (specifically, its anchor element)
|
|
22
|
+
through the aria-labelledby attribute. This is to provide context on what will be expanded or
|
|
23
|
+
collapsed to screen readers. Assistive technology users will still have the `aria-expanded`
|
|
24
|
+
attribute to determine the expanded state.
|
|
25
|
+
|
|
26
|
+
This change was previously behind a feature flag, which has now been removed.
|
|
27
|
+
|
|
28
|
+
**More details:**
|
|
29
|
+
|
|
30
|
+
Previously, the chevron icon button would be labelled by the hardcoded strings "Expand" or
|
|
31
|
+
"Collapse" - which is not helpful for screen readers.
|
|
32
|
+
|
|
33
|
+
Now, the chevron icon button is labelled by the menu item trigger content (children).
|
|
34
|
+
|
|
35
|
+
For example, for the below expandable menu item trigger:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<ExpandableMenuItemTrigger href="#">Recent</ExpandableMenuItemTrigger>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Previously, the chevron icon button would be a `button` element with the name "Expand" or
|
|
42
|
+
"Collapse", based on the expanded state.
|
|
43
|
+
|
|
44
|
+
Now, the chevron icon button will be a `button` element with the name "Recent".
|
|
45
|
+
|
|
46
|
+
You will likely need to update your tests to account for this change, by using a different
|
|
47
|
+
selector.
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- Updated dependencies
|
|
52
|
+
|
|
3
53
|
## 1.2.0
|
|
4
54
|
|
|
5
55
|
### Minor Changes
|
|
@@ -14,7 +14,6 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
14
14
|
var _new = require("@atlaskit/button/new");
|
|
15
15
|
var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/core/chevron-down"));
|
|
16
16
|
var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/core/chevron-right"));
|
|
17
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
18
17
|
var _menuItem = require("../menu-item");
|
|
19
18
|
var _useScrollMenuItemIntoView = require("../use-scroll-menu-item-into-view");
|
|
20
19
|
var _expandableMenuItemContext = require("./expandable-menu-item-context");
|
|
@@ -108,11 +107,11 @@ var ExpandableMenuItemTrigger = exports.ExpandableMenuItemTrigger = /*#__PURE__*
|
|
|
108
107
|
// `aria-expanded` attribute to indicate the expanded state of the menu item.
|
|
109
108
|
// We are not using the `aria-label` attribute here as it is not supported by the `IconButton` component.
|
|
110
109
|
,
|
|
111
|
-
"aria-labelledby":
|
|
110
|
+
"aria-labelledby": id
|
|
112
111
|
// IconButton requires a label prop, however it will not be used by screen readers as we are setting
|
|
113
112
|
// `aria-labelledby`, which will be used instead.
|
|
114
113
|
,
|
|
115
|
-
label:
|
|
114
|
+
label: "",
|
|
116
115
|
appearance: "subtle",
|
|
117
116
|
spacing: "compact",
|
|
118
117
|
onClick: handleIconClick,
|
|
@@ -22,6 +22,7 @@ var _hoistUtils = require("./hoist-utils");
|
|
|
22
22
|
var _idUtils = require("./id-utils");
|
|
23
23
|
var _provider = require("./panel-splitter/provider");
|
|
24
24
|
var _useResizingWidthCssVarOnRootElement = require("./use-resizing-width-css-var-on-root-element");
|
|
25
|
+
var _useSafeDefaultWidth = require("./use-safe-default-width");
|
|
25
26
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
26
27
|
var panelSplitterResizingVar = '--n_asdRsz';
|
|
27
28
|
/**
|
|
@@ -54,6 +55,7 @@ var styles = {
|
|
|
54
55
|
root: "_nd5lns35 _vchhusvi _kqswh2mm _glte1kzp _ndwch9n0",
|
|
55
56
|
inner: "_1reo1wug _18m91wug _152timx3 _4t3i1osq _165teqxy _13wn1if8"
|
|
56
57
|
};
|
|
58
|
+
var fallbackDefaultWidth = 330;
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
61
|
* The Aside is rendered to the right (inline end) of the Main area.
|
|
@@ -64,7 +66,7 @@ function Aside(_ref) {
|
|
|
64
66
|
var children = _ref.children,
|
|
65
67
|
xcss = _ref.xcss,
|
|
66
68
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
67
|
-
|
|
69
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
68
70
|
_ref$label = _ref.label,
|
|
69
71
|
label = _ref$label === void 0 ? 'Aside' : _ref$label,
|
|
70
72
|
_ref$skipLinkLabel = _ref.skipLinkLabel,
|
|
@@ -75,6 +77,11 @@ function Aside(_ref) {
|
|
|
75
77
|
var id = (0, _idUtils.useLayoutId)({
|
|
76
78
|
providedId: providedId
|
|
77
79
|
});
|
|
80
|
+
var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({
|
|
81
|
+
defaultWidthProp: defaultWidthProp,
|
|
82
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
83
|
+
slotName: 'Aside'
|
|
84
|
+
});
|
|
78
85
|
|
|
79
86
|
/**
|
|
80
87
|
* Don't show the skip link if the slot has 0 width.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.PanelSplitterContext = void 0;
|
|
6
|
+
exports.PanelSplitterContext = exports.OnDoubleClickContext = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
// Disabling the rule to allow for `Type` suffix, to differentiate from the Context object.
|
|
9
9
|
// eslint-disable-next-line @repo/internal/react/consistent-types-definitions
|
|
@@ -11,4 +11,13 @@ var _react = require("react");
|
|
|
11
11
|
/**
|
|
12
12
|
* Context for the panel splitter. Only internally exported.
|
|
13
13
|
*/
|
|
14
|
-
var PanelSplitterContext = exports.PanelSplitterContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
14
|
+
var PanelSplitterContext = exports.PanelSplitterContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Context for the panel splitter's double click handler. Only internally exported.
|
|
18
|
+
*
|
|
19
|
+
* NOTE: This context is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
20
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
21
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context should be removed.
|
|
22
|
+
*/
|
|
23
|
+
var OnDoubleClickContext = exports.OnDoubleClickContext = /*#__PURE__*/(0, _react.createContext)(undefined);
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getWidthFromDragLocation = exports.getPixelWidth = void 0;
|
|
7
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
7
8
|
var getWidthFromDragLocation = exports.getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
|
|
8
9
|
var initialWidth = _ref.initialWidth,
|
|
9
10
|
location = _ref.location,
|
|
@@ -25,6 +26,10 @@ var getWidthFromDragLocation = exports.getWidthFromDragLocation = function getWi
|
|
|
25
26
|
* Returns the computed width of an element in pixels.
|
|
26
27
|
*/
|
|
27
28
|
var getPixelWidth = exports.getPixelWidth = function getPixelWidth(element) {
|
|
29
|
+
if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_panel_splitter_guards')) {
|
|
30
|
+
// Always returns an integer. Returns 0 if element is hidden / removed.
|
|
31
|
+
return element.offsetWidth;
|
|
32
|
+
}
|
|
28
33
|
var _window$getComputedSt = window.getComputedStyle(element),
|
|
29
34
|
width = _window$getComputedSt.width;
|
|
30
35
|
return parseInt(width);
|
|
@@ -92,6 +92,13 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
92
92
|
rangeInputBounds = _useState4[0],
|
|
93
93
|
setRangeInputBounds = _useState4[1];
|
|
94
94
|
var openLayerObserver = (0, _openLayerObserver.useOpenLayerObserver)();
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* This is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
98
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
99
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
|
|
100
|
+
*/
|
|
101
|
+
var onDoubleClick = (0, _react.useContext)(_context.OnDoubleClickContext);
|
|
95
102
|
(0, _react.useEffect)(function () {
|
|
96
103
|
var splitter = splitterRef.current;
|
|
97
104
|
(0, _tinyInvariant.default)(splitter, 'Splitter ref must be set');
|
|
@@ -164,7 +171,6 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
164
171
|
var source = _ref5.source;
|
|
165
172
|
(0, _tinyInvariant.default)(isPanelSplitterDragData(source.data));
|
|
166
173
|
_preventUnhandled.preventUnhandled.stop();
|
|
167
|
-
(0, _tinyInvariant.default)(isPanelSplitterDragData(source.data));
|
|
168
174
|
var finalWidth = (0, _getWidth.getPixelWidth)(panel);
|
|
169
175
|
onCompleteResize(finalWidth);
|
|
170
176
|
onResizeEnd === null || onResizeEnd === void 0 || onResizeEnd({
|
|
@@ -276,6 +282,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
276
282
|
}, /*#__PURE__*/React.createElement("div", {
|
|
277
283
|
ref: splitterRef,
|
|
278
284
|
"data-testid": testId,
|
|
285
|
+
onDoubleClick: onDoubleClick,
|
|
279
286
|
className: (0, _runtime.ax)([grabAreaStyles.root])
|
|
280
287
|
}, /*#__PURE__*/React.createElement(_visuallyHidden.default, null, /*#__PURE__*/React.createElement("input", {
|
|
281
288
|
type: "range",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.SideNavPanelSplitter = void 0;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _tinyInvariant = _interopRequireDefault(require("tiny-invariant"));
|
|
11
|
+
var _constants = require("../constants");
|
|
12
|
+
var _useToggleSideNav = require("../side-nav/use-toggle-side-nav");
|
|
13
|
+
var _context = require("./context");
|
|
14
|
+
var _panelSplitter = require("./panel-splitter");
|
|
15
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
16
|
+
/**
|
|
17
|
+
* _SideNavPanelSplitter_
|
|
18
|
+
*
|
|
19
|
+
* A component that allows the user to resize or collapse the side nav.
|
|
20
|
+
* It must be used within the `SideNav` layout area.
|
|
21
|
+
*
|
|
22
|
+
* Example usage:
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <SideNav>
|
|
25
|
+
* <SideNavPanelSplitter label="Resize or collapse Side Nav" />
|
|
26
|
+
* </SideNav>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
var SideNavPanelSplitter = exports.SideNavPanelSplitter = function SideNavPanelSplitter(_ref) {
|
|
30
|
+
var label = _ref.label,
|
|
31
|
+
onResizeStart = _ref.onResizeStart,
|
|
32
|
+
onResizeEnd = _ref.onResizeEnd,
|
|
33
|
+
testId = _ref.testId,
|
|
34
|
+
_ref$shouldCollapseOn = _ref.shouldCollapseOnDoubleClick,
|
|
35
|
+
shouldCollapseOnDoubleClick = _ref$shouldCollapseOn === void 0 ? true : _ref$shouldCollapseOn;
|
|
36
|
+
var context = (0, _react.useContext)(_context.PanelSplitterContext);
|
|
37
|
+
(0, _tinyInvariant.default)((context === null || context === void 0 ? void 0 : context.panelId) === _constants.sideNavPanelSplitterId, 'SideNavPanelSplitter must be rendered as a child of <SideNav />.');
|
|
38
|
+
var toggleSideNav = (0, _useToggleSideNav.useToggleSideNav)();
|
|
39
|
+
return /*#__PURE__*/_react.default.createElement(_context.OnDoubleClickContext.Provider, {
|
|
40
|
+
value: shouldCollapseOnDoubleClick ? toggleSideNav : undefined
|
|
41
|
+
}, /*#__PURE__*/_react.default.createElement(_panelSplitter.PanelSplitter, {
|
|
42
|
+
label: label,
|
|
43
|
+
onResizeStart: onResizeStart,
|
|
44
|
+
onResizeEnd: onResizeEnd,
|
|
45
|
+
testId: testId
|
|
46
|
+
}));
|
|
47
|
+
};
|
|
@@ -23,6 +23,7 @@ var _idUtils = require("./id-utils");
|
|
|
23
23
|
var _provider = require("./panel-splitter/provider");
|
|
24
24
|
var _elementContext = require("./side-nav/element-context");
|
|
25
25
|
var _useResizingWidthCssVarOnRootElement = require("./use-resizing-width-css-var-on-root-element");
|
|
26
|
+
var _useSafeDefaultWidth = require("./use-safe-default-width");
|
|
26
27
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
27
28
|
var panelSplitterResizingVar = '--n_pnlRsz';
|
|
28
29
|
|
|
@@ -41,6 +42,7 @@ var styles = {
|
|
|
41
42
|
oldMobileWidth: "_1bsb1adv",
|
|
42
43
|
newMobileWidth: "_1bsb1dxx"
|
|
43
44
|
};
|
|
45
|
+
var fallbackDefaultWidth = 365;
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
48
|
* The Panel layout area is rendered to the right (inline end) of the Main area, or the Aside area if it is present.
|
|
@@ -52,7 +54,7 @@ var styles = {
|
|
|
52
54
|
function Panel(_ref) {
|
|
53
55
|
var children = _ref.children,
|
|
54
56
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
55
|
-
|
|
57
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
56
58
|
_ref$label = _ref.label,
|
|
57
59
|
label = _ref$label === void 0 ? 'Panel' : _ref$label,
|
|
58
60
|
_ref$skipLinkLabel = _ref.skipLinkLabel,
|
|
@@ -66,6 +68,12 @@ function Panel(_ref) {
|
|
|
66
68
|
var id = (0, _idUtils.useLayoutId)({
|
|
67
69
|
providedId: providedId
|
|
68
70
|
});
|
|
71
|
+
var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({
|
|
72
|
+
defaultWidthProp: defaultWidthProp,
|
|
73
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
74
|
+
slotName: 'Panel'
|
|
75
|
+
});
|
|
76
|
+
|
|
69
77
|
/**
|
|
70
78
|
* Don't show the skip link if the slot has 0 width.
|
|
71
79
|
*
|
|
@@ -29,6 +29,7 @@ var _hoistUtils = require("../hoist-utils");
|
|
|
29
29
|
var _idUtils = require("../id-utils");
|
|
30
30
|
var _provider = require("../panel-splitter/provider");
|
|
31
31
|
var _useResizingWidthCssVarOnRootElement = require("../use-resizing-width-css-var-on-root-element");
|
|
32
|
+
var _useSafeDefaultWidth = require("../use-safe-default-width");
|
|
32
33
|
var _elementContext = require("./element-context");
|
|
33
34
|
var _flyoutCloseDelayMs = require("./flyout-close-delay-ms");
|
|
34
35
|
var _toggleButtonContext = require("./toggle-button-context");
|
|
@@ -59,6 +60,8 @@ var styles = {
|
|
|
59
60
|
hiddenMobileOnly: "_1e0cglyw _dm2518uv",
|
|
60
61
|
hiddenDesktopOnly: "_dm25glyw"
|
|
61
62
|
};
|
|
63
|
+
var fallbackDefaultWidth = 320;
|
|
64
|
+
|
|
62
65
|
/**
|
|
63
66
|
* We need an additional component layer so we can wrap the side nav in a `OpenLayerObserver` and have access to the
|
|
64
67
|
* context value.
|
|
@@ -67,7 +70,7 @@ function SideNavInternal(_ref) {
|
|
|
67
70
|
var children = _ref.children,
|
|
68
71
|
defaultCollapsed = _ref.defaultCollapsed,
|
|
69
72
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
70
|
-
|
|
73
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
71
74
|
testId = _ref.testId,
|
|
72
75
|
_ref$label = _ref.label,
|
|
73
76
|
label = _ref$label === void 0 ? 'Sidebar' : _ref$label,
|
|
@@ -113,6 +116,11 @@ function SideNavInternal(_ref) {
|
|
|
113
116
|
var _useState = (0, _react.useState)(defaultCollapsed),
|
|
114
117
|
_useState2 = (0, _slicedToArray2.default)(_useState, 1),
|
|
115
118
|
initialDefaultCollapsed = _useState2[0];
|
|
119
|
+
var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({
|
|
120
|
+
defaultWidthProp: defaultWidthProp,
|
|
121
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
122
|
+
slotName: 'SideNav'
|
|
123
|
+
});
|
|
116
124
|
var _useState3 = (0, _react.useState)(defaultWidth),
|
|
117
125
|
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
118
126
|
width = _useState4[0],
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useSafeDefaultWidth = useSafeDefaultWidth;
|
|
7
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
8
|
+
/**
|
|
9
|
+
* When `platform_dst_nav4_panel_splitter_guards` is disabled,
|
|
10
|
+
* `useSafeDefaultWidth` returns the provided `defaultWidthProp`.
|
|
11
|
+
*
|
|
12
|
+
* When `platform_dst_nav4_panel_splitter_guards` is enabled,
|
|
13
|
+
* `useSafeDefaultWidth` returns the `fallbackWidth` if the provided `defaultWidthProp` is not an integer value.
|
|
14
|
+
*/
|
|
15
|
+
function useSafeDefaultWidth(_ref) {
|
|
16
|
+
var defaultWidthProp = _ref.defaultWidthProp,
|
|
17
|
+
fallbackDefaultWidth = _ref.fallbackDefaultWidth,
|
|
18
|
+
slotName = _ref.slotName;
|
|
19
|
+
if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_panel_splitter_guards')) {
|
|
20
|
+
// If the provided `defaultWidth` is invalid then we use our fallback.
|
|
21
|
+
// We are using a runtime check because some invalid numbers like `NaN` are not caught by types,
|
|
22
|
+
// and we saw some issues in products where our experience broke due to this.
|
|
23
|
+
if (!Number.isInteger(defaultWidthProp)) {
|
|
24
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.error("The defaultWidth value must be an integer, but '".concat(defaultWidthProp, "' was provided to ").concat(slotName, ". Falling back to ").concat(fallbackDefaultWidth, "px instead."));
|
|
27
|
+
}
|
|
28
|
+
return fallbackDefaultWidth;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return defaultWidthProp;
|
|
32
|
+
}
|
|
@@ -6,7 +6,6 @@ import React, { forwardRef, useCallback, useId, useRef } from 'react';
|
|
|
6
6
|
import { IconButton } from '@atlaskit/button/new';
|
|
7
7
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
8
8
|
import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
|
|
9
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
9
|
import { MenuItemBase, nestedOpenPopupCSSSelector } from '../menu-item';
|
|
11
10
|
import { useScrollMenuItemIntoView } from '../use-scroll-menu-item-into-view';
|
|
12
11
|
import { useIsExpanded, useOnExpansionToggle, useSetIsExpanded } from './expandable-menu-item-context';
|
|
@@ -99,11 +98,11 @@ export const ExpandableMenuItemTrigger = /*#__PURE__*/forwardRef(({
|
|
|
99
98
|
// `aria-expanded` attribute to indicate the expanded state of the menu item.
|
|
100
99
|
// We are not using the `aria-label` attribute here as it is not supported by the `IconButton` component.
|
|
101
100
|
,
|
|
102
|
-
"aria-labelledby":
|
|
101
|
+
"aria-labelledby": id
|
|
103
102
|
// IconButton requires a label prop, however it will not be used by screen readers as we are setting
|
|
104
103
|
// `aria-labelledby`, which will be used instead.
|
|
105
104
|
,
|
|
106
|
-
label:
|
|
105
|
+
label: "",
|
|
107
106
|
appearance: "subtle",
|
|
108
107
|
spacing: "compact",
|
|
109
108
|
onClick: handleIconClick,
|
|
@@ -12,6 +12,7 @@ import { DangerouslyHoistCssVarToDocumentRoot } from './hoist-utils';
|
|
|
12
12
|
import { useLayoutId } from './id-utils';
|
|
13
13
|
import { PanelSplitterProvider } from './panel-splitter/provider';
|
|
14
14
|
import { useResizingWidthCssVarOnRootElement } from './use-resizing-width-css-var-on-root-element';
|
|
15
|
+
import { useSafeDefaultWidth } from './use-safe-default-width';
|
|
15
16
|
const panelSplitterResizingVar = '--n_asdRsz';
|
|
16
17
|
/**
|
|
17
18
|
* The bounds for Aside and Panel are purposely set to support the current usage in Jira.
|
|
@@ -43,6 +44,7 @@ const styles = {
|
|
|
43
44
|
root: "_nd5lns35 _vchhusvi _kqswh2mm _glte1kzp _ndwch9n0",
|
|
44
45
|
inner: "_1reo1wug _18m91wug _152timx3 _4t3i1osq _165teqxy _13wn1if8"
|
|
45
46
|
};
|
|
47
|
+
const fallbackDefaultWidth = 330;
|
|
46
48
|
|
|
47
49
|
/**
|
|
48
50
|
* The Aside is rendered to the right (inline end) of the Main area.
|
|
@@ -52,7 +54,7 @@ const styles = {
|
|
|
52
54
|
export function Aside({
|
|
53
55
|
children,
|
|
54
56
|
xcss,
|
|
55
|
-
defaultWidth =
|
|
57
|
+
defaultWidth: defaultWidthProp = fallbackDefaultWidth,
|
|
56
58
|
label = 'Aside',
|
|
57
59
|
skipLinkLabel = label,
|
|
58
60
|
testId,
|
|
@@ -62,6 +64,11 @@ export function Aside({
|
|
|
62
64
|
const id = useLayoutId({
|
|
63
65
|
providedId
|
|
64
66
|
});
|
|
67
|
+
const defaultWidth = useSafeDefaultWidth({
|
|
68
|
+
defaultWidthProp,
|
|
69
|
+
fallbackDefaultWidth,
|
|
70
|
+
slotName: 'Aside'
|
|
71
|
+
});
|
|
65
72
|
|
|
66
73
|
/**
|
|
67
74
|
* Don't show the skip link if the slot has 0 width.
|
|
@@ -6,4 +6,13 @@ import { createContext } from 'react';
|
|
|
6
6
|
/**
|
|
7
7
|
* Context for the panel splitter. Only internally exported.
|
|
8
8
|
*/
|
|
9
|
-
export const PanelSplitterContext = /*#__PURE__*/createContext(null);
|
|
9
|
+
export const PanelSplitterContext = /*#__PURE__*/createContext(null);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Context for the panel splitter's double click handler. Only internally exported.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: This context is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
15
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
16
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context should be removed.
|
|
17
|
+
*/
|
|
18
|
+
export const OnDoubleClickContext = /*#__PURE__*/createContext(undefined);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
1
2
|
export const getWidthFromDragLocation = ({
|
|
2
3
|
initialWidth,
|
|
3
4
|
location,
|
|
@@ -20,6 +21,10 @@ export const getWidthFromDragLocation = ({
|
|
|
20
21
|
* Returns the computed width of an element in pixels.
|
|
21
22
|
*/
|
|
22
23
|
export const getPixelWidth = element => {
|
|
24
|
+
if (fg('platform_dst_nav4_panel_splitter_guards')) {
|
|
25
|
+
// Always returns an integer. Returns 0 if element is hidden / removed.
|
|
26
|
+
return element.offsetWidth;
|
|
27
|
+
}
|
|
23
28
|
const {
|
|
24
29
|
width
|
|
25
30
|
} = window.getComputedStyle(element);
|
|
@@ -15,7 +15,7 @@ import { blockDraggingToIFrames } from '@atlaskit/pragmatic-drag-and-drop/elemen
|
|
|
15
15
|
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
|
|
16
16
|
import { preventUnhandled } from '@atlaskit/pragmatic-drag-and-drop/prevent-unhandled';
|
|
17
17
|
import VisuallyHidden from '@atlaskit/visually-hidden';
|
|
18
|
-
import { PanelSplitterContext } from './context';
|
|
18
|
+
import { OnDoubleClickContext, PanelSplitterContext } from './context';
|
|
19
19
|
import { convertResizeBoundToPixels } from './convert-resize-bound-to-pixels';
|
|
20
20
|
import { getPercentageWithinPixelBounds } from './get-percentage-within-pixel-bounds';
|
|
21
21
|
import { getPixelWidth, getWidthFromDragLocation } from './get-width';
|
|
@@ -77,6 +77,13 @@ const PortaledPanelSplitter = ({
|
|
|
77
77
|
max: 500
|
|
78
78
|
});
|
|
79
79
|
const openLayerObserver = useOpenLayerObserver();
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* This is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
83
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
84
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
|
|
85
|
+
*/
|
|
86
|
+
const onDoubleClick = useContext(OnDoubleClickContext);
|
|
80
87
|
useEffect(() => {
|
|
81
88
|
const splitter = splitterRef.current;
|
|
82
89
|
invariant(splitter, 'Splitter ref must be set');
|
|
@@ -154,7 +161,6 @@ const PortaledPanelSplitter = ({
|
|
|
154
161
|
}) {
|
|
155
162
|
invariant(isPanelSplitterDragData(source.data));
|
|
156
163
|
preventUnhandled.stop();
|
|
157
|
-
invariant(isPanelSplitterDragData(source.data));
|
|
158
164
|
const finalWidth = getPixelWidth(panel);
|
|
159
165
|
onCompleteResize(finalWidth);
|
|
160
166
|
onResizeEnd === null || onResizeEnd === void 0 ? void 0 : onResizeEnd({
|
|
@@ -254,6 +260,7 @@ const PortaledPanelSplitter = ({
|
|
|
254
260
|
}, /*#__PURE__*/React.createElement("div", {
|
|
255
261
|
ref: splitterRef,
|
|
256
262
|
"data-testid": testId,
|
|
263
|
+
onDoubleClick: onDoubleClick,
|
|
257
264
|
className: ax([grabAreaStyles.root])
|
|
258
265
|
}, /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement("input", {
|
|
259
266
|
type: "range",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { sideNavPanelSplitterId } from '../constants';
|
|
4
|
+
import { useToggleSideNav } from '../side-nav/use-toggle-side-nav';
|
|
5
|
+
import { OnDoubleClickContext, PanelSplitterContext } from './context';
|
|
6
|
+
import { PanelSplitter } from './panel-splitter';
|
|
7
|
+
/**
|
|
8
|
+
* _SideNavPanelSplitter_
|
|
9
|
+
*
|
|
10
|
+
* A component that allows the user to resize or collapse the side nav.
|
|
11
|
+
* It must be used within the `SideNav` layout area.
|
|
12
|
+
*
|
|
13
|
+
* Example usage:
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <SideNav>
|
|
16
|
+
* <SideNavPanelSplitter label="Resize or collapse Side Nav" />
|
|
17
|
+
* </SideNav>
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const SideNavPanelSplitter = ({
|
|
21
|
+
label,
|
|
22
|
+
onResizeStart,
|
|
23
|
+
onResizeEnd,
|
|
24
|
+
testId,
|
|
25
|
+
shouldCollapseOnDoubleClick = true
|
|
26
|
+
}) => {
|
|
27
|
+
const context = useContext(PanelSplitterContext);
|
|
28
|
+
invariant((context === null || context === void 0 ? void 0 : context.panelId) === sideNavPanelSplitterId, 'SideNavPanelSplitter must be rendered as a child of <SideNav />.');
|
|
29
|
+
const toggleSideNav = useToggleSideNav();
|
|
30
|
+
return /*#__PURE__*/React.createElement(OnDoubleClickContext.Provider, {
|
|
31
|
+
value: shouldCollapseOnDoubleClick ? toggleSideNav : undefined
|
|
32
|
+
}, /*#__PURE__*/React.createElement(PanelSplitter, {
|
|
33
|
+
label: label,
|
|
34
|
+
onResizeStart: onResizeStart,
|
|
35
|
+
onResizeEnd: onResizeEnd,
|
|
36
|
+
testId: testId
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
@@ -13,6 +13,7 @@ import { useLayoutId } from './id-utils';
|
|
|
13
13
|
import { PanelSplitterProvider } from './panel-splitter/provider';
|
|
14
14
|
import { useSideNavRef } from './side-nav/element-context';
|
|
15
15
|
import { useResizingWidthCssVarOnRootElement } from './use-resizing-width-css-var-on-root-element';
|
|
16
|
+
import { useSafeDefaultWidth } from './use-safe-default-width';
|
|
16
17
|
const panelSplitterResizingVar = '--n_pnlRsz';
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -30,6 +31,7 @@ const styles = {
|
|
|
30
31
|
oldMobileWidth: "_1bsb1adv",
|
|
31
32
|
newMobileWidth: "_1bsb1dxx"
|
|
32
33
|
};
|
|
34
|
+
const fallbackDefaultWidth = 365;
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* The Panel layout area is rendered to the right (inline end) of the Main area, or the Aside area if it is present.
|
|
@@ -40,7 +42,7 @@ const styles = {
|
|
|
40
42
|
*/
|
|
41
43
|
export function Panel({
|
|
42
44
|
children,
|
|
43
|
-
defaultWidth =
|
|
45
|
+
defaultWidth: defaultWidthProp = fallbackDefaultWidth,
|
|
44
46
|
label = 'Panel',
|
|
45
47
|
skipLinkLabel = label,
|
|
46
48
|
testId,
|
|
@@ -52,6 +54,12 @@ export function Panel({
|
|
|
52
54
|
const id = useLayoutId({
|
|
53
55
|
providedId
|
|
54
56
|
});
|
|
57
|
+
const defaultWidth = useSafeDefaultWidth({
|
|
58
|
+
defaultWidthProp,
|
|
59
|
+
fallbackDefaultWidth,
|
|
60
|
+
slotName: 'Panel'
|
|
61
|
+
});
|
|
62
|
+
|
|
55
63
|
/**
|
|
56
64
|
* Don't show the skip link if the slot has 0 width.
|
|
57
65
|
*
|
|
@@ -19,6 +19,7 @@ import { DangerouslyHoistCssVarToDocumentRoot } from '../hoist-utils';
|
|
|
19
19
|
import { useLayoutId } from '../id-utils';
|
|
20
20
|
import { PanelSplitterProvider } from '../panel-splitter/provider';
|
|
21
21
|
import { useResizingWidthCssVarOnRootElement } from '../use-resizing-width-css-var-on-root-element';
|
|
22
|
+
import { useSafeDefaultWidth } from '../use-safe-default-width';
|
|
22
23
|
import { useSideNavRef } from './element-context';
|
|
23
24
|
import { sideNavFlyoutCloseDelayMs } from './flyout-close-delay-ms';
|
|
24
25
|
import { SideNavToggleButtonElement } from './toggle-button-context';
|
|
@@ -48,6 +49,8 @@ const styles = {
|
|
|
48
49
|
hiddenMobileOnly: "_1e0cglyw _dm2518uv",
|
|
49
50
|
hiddenDesktopOnly: "_dm25glyw"
|
|
50
51
|
};
|
|
52
|
+
const fallbackDefaultWidth = 320;
|
|
53
|
+
|
|
51
54
|
/**
|
|
52
55
|
* We need an additional component layer so we can wrap the side nav in a `OpenLayerObserver` and have access to the
|
|
53
56
|
* context value.
|
|
@@ -55,7 +58,7 @@ const styles = {
|
|
|
55
58
|
function SideNavInternal({
|
|
56
59
|
children,
|
|
57
60
|
defaultCollapsed,
|
|
58
|
-
defaultWidth =
|
|
61
|
+
defaultWidth: defaultWidthProp = fallbackDefaultWidth,
|
|
59
62
|
testId,
|
|
60
63
|
label = 'Sidebar',
|
|
61
64
|
skipLinkLabel = label,
|
|
@@ -99,6 +102,11 @@ function SideNavInternal({
|
|
|
99
102
|
// This is so we can use it in an effect _that only runs once_, after the initial render on the client,
|
|
100
103
|
// to sync the side nav context (provided in `<Root>`) with the `defaultCollapsed` prop provided to `<SideNav>`.
|
|
101
104
|
const [initialDefaultCollapsed] = useState(defaultCollapsed);
|
|
105
|
+
const defaultWidth = useSafeDefaultWidth({
|
|
106
|
+
defaultWidthProp,
|
|
107
|
+
fallbackDefaultWidth,
|
|
108
|
+
slotName: 'SideNav'
|
|
109
|
+
});
|
|
102
110
|
const [width, setWidth] = useState(defaultWidth);
|
|
103
111
|
const clampedWidth = `clamp(${widthResizeBounds.min}, ${width}px, ${widthResizeBounds.max})`;
|
|
104
112
|
const dangerouslyHoistSlotSizes = useContext(DangerouslyHoistSlotSizes);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* When `platform_dst_nav4_panel_splitter_guards` is disabled,
|
|
5
|
+
* `useSafeDefaultWidth` returns the provided `defaultWidthProp`.
|
|
6
|
+
*
|
|
7
|
+
* When `platform_dst_nav4_panel_splitter_guards` is enabled,
|
|
8
|
+
* `useSafeDefaultWidth` returns the `fallbackWidth` if the provided `defaultWidthProp` is not an integer value.
|
|
9
|
+
*/
|
|
10
|
+
export function useSafeDefaultWidth({
|
|
11
|
+
defaultWidthProp,
|
|
12
|
+
fallbackDefaultWidth,
|
|
13
|
+
slotName
|
|
14
|
+
}) {
|
|
15
|
+
if (fg('platform_dst_nav4_panel_splitter_guards')) {
|
|
16
|
+
// If the provided `defaultWidth` is invalid then we use our fallback.
|
|
17
|
+
// We are using a runtime check because some invalid numbers like `NaN` are not caught by types,
|
|
18
|
+
// and we saw some issues in products where our experience broke due to this.
|
|
19
|
+
if (!Number.isInteger(defaultWidthProp)) {
|
|
20
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
21
|
+
// eslint-disable-next-line no-console
|
|
22
|
+
console.error(`The defaultWidth value must be an integer, but '${defaultWidthProp}' was provided to ${slotName}. Falling back to ${fallbackDefaultWidth}px instead.`);
|
|
23
|
+
}
|
|
24
|
+
return fallbackDefaultWidth;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return defaultWidthProp;
|
|
28
|
+
}
|
|
@@ -6,7 +6,6 @@ import React, { forwardRef, useCallback, useId, useRef } from 'react';
|
|
|
6
6
|
import { IconButton } from '@atlaskit/button/new';
|
|
7
7
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
8
8
|
import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
|
|
9
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
9
|
import { MenuItemBase, nestedOpenPopupCSSSelector } from '../menu-item';
|
|
11
10
|
import { useScrollMenuItemIntoView } from '../use-scroll-menu-item-into-view';
|
|
12
11
|
import { useIsExpanded, useOnExpansionToggle, useSetIsExpanded } from './expandable-menu-item-context';
|
|
@@ -99,11 +98,11 @@ export var ExpandableMenuItemTrigger = /*#__PURE__*/forwardRef(function (_ref2,
|
|
|
99
98
|
// `aria-expanded` attribute to indicate the expanded state of the menu item.
|
|
100
99
|
// We are not using the `aria-label` attribute here as it is not supported by the `IconButton` component.
|
|
101
100
|
,
|
|
102
|
-
"aria-labelledby":
|
|
101
|
+
"aria-labelledby": id
|
|
103
102
|
// IconButton requires a label prop, however it will not be used by screen readers as we are setting
|
|
104
103
|
// `aria-labelledby`, which will be used instead.
|
|
105
104
|
,
|
|
106
|
-
label:
|
|
105
|
+
label: "",
|
|
107
106
|
appearance: "subtle",
|
|
108
107
|
spacing: "compact",
|
|
109
108
|
onClick: handleIconClick,
|
|
@@ -14,6 +14,7 @@ import { DangerouslyHoistCssVarToDocumentRoot } from './hoist-utils';
|
|
|
14
14
|
import { useLayoutId } from './id-utils';
|
|
15
15
|
import { PanelSplitterProvider } from './panel-splitter/provider';
|
|
16
16
|
import { useResizingWidthCssVarOnRootElement } from './use-resizing-width-css-var-on-root-element';
|
|
17
|
+
import { useSafeDefaultWidth } from './use-safe-default-width';
|
|
17
18
|
var panelSplitterResizingVar = '--n_asdRsz';
|
|
18
19
|
/**
|
|
19
20
|
* The bounds for Aside and Panel are purposely set to support the current usage in Jira.
|
|
@@ -45,6 +46,7 @@ var styles = {
|
|
|
45
46
|
root: "_nd5lns35 _vchhusvi _kqswh2mm _glte1kzp _ndwch9n0",
|
|
46
47
|
inner: "_1reo1wug _18m91wug _152timx3 _4t3i1osq _165teqxy _13wn1if8"
|
|
47
48
|
};
|
|
49
|
+
var fallbackDefaultWidth = 330;
|
|
48
50
|
|
|
49
51
|
/**
|
|
50
52
|
* The Aside is rendered to the right (inline end) of the Main area.
|
|
@@ -55,7 +57,7 @@ export function Aside(_ref) {
|
|
|
55
57
|
var children = _ref.children,
|
|
56
58
|
xcss = _ref.xcss,
|
|
57
59
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
58
|
-
|
|
60
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
59
61
|
_ref$label = _ref.label,
|
|
60
62
|
label = _ref$label === void 0 ? 'Aside' : _ref$label,
|
|
61
63
|
_ref$skipLinkLabel = _ref.skipLinkLabel,
|
|
@@ -66,6 +68,11 @@ export function Aside(_ref) {
|
|
|
66
68
|
var id = useLayoutId({
|
|
67
69
|
providedId: providedId
|
|
68
70
|
});
|
|
71
|
+
var defaultWidth = useSafeDefaultWidth({
|
|
72
|
+
defaultWidthProp: defaultWidthProp,
|
|
73
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
74
|
+
slotName: 'Aside'
|
|
75
|
+
});
|
|
69
76
|
|
|
70
77
|
/**
|
|
71
78
|
* Don't show the skip link if the slot has 0 width.
|
|
@@ -6,4 +6,13 @@ import { createContext } from 'react';
|
|
|
6
6
|
/**
|
|
7
7
|
* Context for the panel splitter. Only internally exported.
|
|
8
8
|
*/
|
|
9
|
-
export var PanelSplitterContext = /*#__PURE__*/createContext(null);
|
|
9
|
+
export var PanelSplitterContext = /*#__PURE__*/createContext(null);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Context for the panel splitter's double click handler. Only internally exported.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: This context is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
15
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
16
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context should be removed.
|
|
17
|
+
*/
|
|
18
|
+
export var OnDoubleClickContext = /*#__PURE__*/createContext(undefined);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
1
2
|
export var getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
|
|
2
3
|
var initialWidth = _ref.initialWidth,
|
|
3
4
|
location = _ref.location,
|
|
@@ -19,6 +20,10 @@ export var getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
|
|
|
19
20
|
* Returns the computed width of an element in pixels.
|
|
20
21
|
*/
|
|
21
22
|
export var getPixelWidth = function getPixelWidth(element) {
|
|
23
|
+
if (fg('platform_dst_nav4_panel_splitter_guards')) {
|
|
24
|
+
// Always returns an integer. Returns 0 if element is hidden / removed.
|
|
25
|
+
return element.offsetWidth;
|
|
26
|
+
}
|
|
22
27
|
var _window$getComputedSt = window.getComputedStyle(element),
|
|
23
28
|
width = _window$getComputedSt.width;
|
|
24
29
|
return parseInt(width);
|
|
@@ -19,7 +19,7 @@ import { blockDraggingToIFrames } from '@atlaskit/pragmatic-drag-and-drop/elemen
|
|
|
19
19
|
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
|
|
20
20
|
import { preventUnhandled } from '@atlaskit/pragmatic-drag-and-drop/prevent-unhandled';
|
|
21
21
|
import VisuallyHidden from '@atlaskit/visually-hidden';
|
|
22
|
-
import { PanelSplitterContext } from './context';
|
|
22
|
+
import { OnDoubleClickContext, PanelSplitterContext } from './context';
|
|
23
23
|
import { convertResizeBoundToPixels } from './convert-resize-bound-to-pixels';
|
|
24
24
|
import { getPercentageWithinPixelBounds } from './get-percentage-within-pixel-bounds';
|
|
25
25
|
import { getPixelWidth, getWidthFromDragLocation } from './get-width';
|
|
@@ -82,6 +82,13 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
82
82
|
rangeInputBounds = _useState4[0],
|
|
83
83
|
setRangeInputBounds = _useState4[1];
|
|
84
84
|
var openLayerObserver = useOpenLayerObserver();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* This is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
88
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
89
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
|
|
90
|
+
*/
|
|
91
|
+
var onDoubleClick = useContext(OnDoubleClickContext);
|
|
85
92
|
useEffect(function () {
|
|
86
93
|
var splitter = splitterRef.current;
|
|
87
94
|
invariant(splitter, 'Splitter ref must be set');
|
|
@@ -154,7 +161,6 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
154
161
|
var source = _ref5.source;
|
|
155
162
|
invariant(isPanelSplitterDragData(source.data));
|
|
156
163
|
preventUnhandled.stop();
|
|
157
|
-
invariant(isPanelSplitterDragData(source.data));
|
|
158
164
|
var finalWidth = getPixelWidth(panel);
|
|
159
165
|
onCompleteResize(finalWidth);
|
|
160
166
|
onResizeEnd === null || onResizeEnd === void 0 || onResizeEnd({
|
|
@@ -266,6 +272,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref) {
|
|
|
266
272
|
}, /*#__PURE__*/React.createElement("div", {
|
|
267
273
|
ref: splitterRef,
|
|
268
274
|
"data-testid": testId,
|
|
275
|
+
onDoubleClick: onDoubleClick,
|
|
269
276
|
className: ax([grabAreaStyles.root])
|
|
270
277
|
}, /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement("input", {
|
|
271
278
|
type: "range",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { sideNavPanelSplitterId } from '../constants';
|
|
4
|
+
import { useToggleSideNav } from '../side-nav/use-toggle-side-nav';
|
|
5
|
+
import { OnDoubleClickContext, PanelSplitterContext } from './context';
|
|
6
|
+
import { PanelSplitter } from './panel-splitter';
|
|
7
|
+
/**
|
|
8
|
+
* _SideNavPanelSplitter_
|
|
9
|
+
*
|
|
10
|
+
* A component that allows the user to resize or collapse the side nav.
|
|
11
|
+
* It must be used within the `SideNav` layout area.
|
|
12
|
+
*
|
|
13
|
+
* Example usage:
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <SideNav>
|
|
16
|
+
* <SideNavPanelSplitter label="Resize or collapse Side Nav" />
|
|
17
|
+
* </SideNav>
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export var SideNavPanelSplitter = function SideNavPanelSplitter(_ref) {
|
|
21
|
+
var label = _ref.label,
|
|
22
|
+
onResizeStart = _ref.onResizeStart,
|
|
23
|
+
onResizeEnd = _ref.onResizeEnd,
|
|
24
|
+
testId = _ref.testId,
|
|
25
|
+
_ref$shouldCollapseOn = _ref.shouldCollapseOnDoubleClick,
|
|
26
|
+
shouldCollapseOnDoubleClick = _ref$shouldCollapseOn === void 0 ? true : _ref$shouldCollapseOn;
|
|
27
|
+
var context = useContext(PanelSplitterContext);
|
|
28
|
+
invariant((context === null || context === void 0 ? void 0 : context.panelId) === sideNavPanelSplitterId, 'SideNavPanelSplitter must be rendered as a child of <SideNav />.');
|
|
29
|
+
var toggleSideNav = useToggleSideNav();
|
|
30
|
+
return /*#__PURE__*/React.createElement(OnDoubleClickContext.Provider, {
|
|
31
|
+
value: shouldCollapseOnDoubleClick ? toggleSideNav : undefined
|
|
32
|
+
}, /*#__PURE__*/React.createElement(PanelSplitter, {
|
|
33
|
+
label: label,
|
|
34
|
+
onResizeStart: onResizeStart,
|
|
35
|
+
onResizeEnd: onResizeEnd,
|
|
36
|
+
testId: testId
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
@@ -15,6 +15,7 @@ import { useLayoutId } from './id-utils';
|
|
|
15
15
|
import { PanelSplitterProvider } from './panel-splitter/provider';
|
|
16
16
|
import { useSideNavRef } from './side-nav/element-context';
|
|
17
17
|
import { useResizingWidthCssVarOnRootElement } from './use-resizing-width-css-var-on-root-element';
|
|
18
|
+
import { useSafeDefaultWidth } from './use-safe-default-width';
|
|
18
19
|
var panelSplitterResizingVar = '--n_pnlRsz';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -32,6 +33,7 @@ var styles = {
|
|
|
32
33
|
oldMobileWidth: "_1bsb1adv",
|
|
33
34
|
newMobileWidth: "_1bsb1dxx"
|
|
34
35
|
};
|
|
36
|
+
var fallbackDefaultWidth = 365;
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
39
|
* The Panel layout area is rendered to the right (inline end) of the Main area, or the Aside area if it is present.
|
|
@@ -43,7 +45,7 @@ var styles = {
|
|
|
43
45
|
export function Panel(_ref) {
|
|
44
46
|
var children = _ref.children,
|
|
45
47
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
46
|
-
|
|
48
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
47
49
|
_ref$label = _ref.label,
|
|
48
50
|
label = _ref$label === void 0 ? 'Panel' : _ref$label,
|
|
49
51
|
_ref$skipLinkLabel = _ref.skipLinkLabel,
|
|
@@ -57,6 +59,12 @@ export function Panel(_ref) {
|
|
|
57
59
|
var id = useLayoutId({
|
|
58
60
|
providedId: providedId
|
|
59
61
|
});
|
|
62
|
+
var defaultWidth = useSafeDefaultWidth({
|
|
63
|
+
defaultWidthProp: defaultWidthProp,
|
|
64
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
65
|
+
slotName: 'Panel'
|
|
66
|
+
});
|
|
67
|
+
|
|
60
68
|
/**
|
|
61
69
|
* Don't show the skip link if the slot has 0 width.
|
|
62
70
|
*
|
|
@@ -21,6 +21,7 @@ import { DangerouslyHoistCssVarToDocumentRoot } from '../hoist-utils';
|
|
|
21
21
|
import { useLayoutId } from '../id-utils';
|
|
22
22
|
import { PanelSplitterProvider } from '../panel-splitter/provider';
|
|
23
23
|
import { useResizingWidthCssVarOnRootElement } from '../use-resizing-width-css-var-on-root-element';
|
|
24
|
+
import { useSafeDefaultWidth } from '../use-safe-default-width';
|
|
24
25
|
import { useSideNavRef } from './element-context';
|
|
25
26
|
import { sideNavFlyoutCloseDelayMs } from './flyout-close-delay-ms';
|
|
26
27
|
import { SideNavToggleButtonElement } from './toggle-button-context';
|
|
@@ -50,6 +51,8 @@ var styles = {
|
|
|
50
51
|
hiddenMobileOnly: "_1e0cglyw _dm2518uv",
|
|
51
52
|
hiddenDesktopOnly: "_dm25glyw"
|
|
52
53
|
};
|
|
54
|
+
var fallbackDefaultWidth = 320;
|
|
55
|
+
|
|
53
56
|
/**
|
|
54
57
|
* We need an additional component layer so we can wrap the side nav in a `OpenLayerObserver` and have access to the
|
|
55
58
|
* context value.
|
|
@@ -58,7 +61,7 @@ function SideNavInternal(_ref) {
|
|
|
58
61
|
var children = _ref.children,
|
|
59
62
|
defaultCollapsed = _ref.defaultCollapsed,
|
|
60
63
|
_ref$defaultWidth = _ref.defaultWidth,
|
|
61
|
-
|
|
64
|
+
defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
|
|
62
65
|
testId = _ref.testId,
|
|
63
66
|
_ref$label = _ref.label,
|
|
64
67
|
label = _ref$label === void 0 ? 'Sidebar' : _ref$label,
|
|
@@ -104,6 +107,11 @@ function SideNavInternal(_ref) {
|
|
|
104
107
|
var _useState = useState(defaultCollapsed),
|
|
105
108
|
_useState2 = _slicedToArray(_useState, 1),
|
|
106
109
|
initialDefaultCollapsed = _useState2[0];
|
|
110
|
+
var defaultWidth = useSafeDefaultWidth({
|
|
111
|
+
defaultWidthProp: defaultWidthProp,
|
|
112
|
+
fallbackDefaultWidth: fallbackDefaultWidth,
|
|
113
|
+
slotName: 'SideNav'
|
|
114
|
+
});
|
|
107
115
|
var _useState3 = useState(defaultWidth),
|
|
108
116
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
109
117
|
width = _useState4[0],
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* When `platform_dst_nav4_panel_splitter_guards` is disabled,
|
|
5
|
+
* `useSafeDefaultWidth` returns the provided `defaultWidthProp`.
|
|
6
|
+
*
|
|
7
|
+
* When `platform_dst_nav4_panel_splitter_guards` is enabled,
|
|
8
|
+
* `useSafeDefaultWidth` returns the `fallbackWidth` if the provided `defaultWidthProp` is not an integer value.
|
|
9
|
+
*/
|
|
10
|
+
export function useSafeDefaultWidth(_ref) {
|
|
11
|
+
var defaultWidthProp = _ref.defaultWidthProp,
|
|
12
|
+
fallbackDefaultWidth = _ref.fallbackDefaultWidth,
|
|
13
|
+
slotName = _ref.slotName;
|
|
14
|
+
if (fg('platform_dst_nav4_panel_splitter_guards')) {
|
|
15
|
+
// If the provided `defaultWidth` is invalid then we use our fallback.
|
|
16
|
+
// We are using a runtime check because some invalid numbers like `NaN` are not caught by types,
|
|
17
|
+
// and we saw some issues in products where our experience broke due to this.
|
|
18
|
+
if (!Number.isInteger(defaultWidthProp)) {
|
|
19
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.error("The defaultWidth value must be an integer, but '".concat(defaultWidthProp, "' was provided to ").concat(slotName, ". Falling back to ").concat(fallbackDefaultWidth, "px instead."));
|
|
22
|
+
}
|
|
23
|
+
return fallbackDefaultWidth;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return defaultWidthProp;
|
|
27
|
+
}
|
|
@@ -5,7 +5,7 @@ import type { CommonSlotProps } from './types';
|
|
|
5
5
|
*
|
|
6
6
|
* You can optionally render a `PanelSplitter` as a child to make the aside area resizable.
|
|
7
7
|
*/
|
|
8
|
-
export declare function Aside({ children, xcss, defaultWidth, label, skipLinkLabel, testId, id: providedId, }: CommonSlotProps & {
|
|
8
|
+
export declare function Aside({ children, xcss, defaultWidth: defaultWidthProp, label, skipLinkLabel, testId, id: providedId, }: CommonSlotProps & {
|
|
9
9
|
/**
|
|
10
10
|
* The content of the layout area.
|
|
11
11
|
*/
|
|
@@ -21,7 +21,7 @@ export declare function Aside({ children, xcss, defaultWidth, label, skipLinkLab
|
|
|
21
21
|
/**
|
|
22
22
|
* The default width of the layout area.
|
|
23
23
|
*
|
|
24
|
-
* It should be between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
24
|
+
* It should be an integer between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
25
25
|
*/
|
|
26
26
|
defaultWidth?: number;
|
|
27
27
|
}): JSX.Element;
|
|
@@ -52,3 +52,11 @@ export type PanelSplitterContextType = {
|
|
|
52
52
|
* Context for the panel splitter. Only internally exported.
|
|
53
53
|
*/
|
|
54
54
|
export declare const PanelSplitterContext: import("react").Context<PanelSplitterContextType | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Context for the panel splitter's double click handler. Only internally exported.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: This context is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
59
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
60
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context should be removed.
|
|
61
|
+
*/
|
|
62
|
+
export declare const OnDoubleClickContext: import("react").Context<(() => void) | undefined>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type ReactNode } from 'react';
|
|
6
6
|
import type { ResizeBounds, ResizeEndCallback, ResizeStartCallback } from './types';
|
|
7
|
-
type PanelSplitterProps = {
|
|
7
|
+
export type PanelSplitterProps = {
|
|
8
8
|
/**
|
|
9
9
|
* The accessible label for the panel splitter. It is visually hidden, but is required for accessibility.
|
|
10
10
|
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelSplitterProps } from './panel-splitter';
|
|
3
|
+
type SideNavPanelSplitterProps = Omit<PanelSplitterProps, 'onDoubleClick'> & {
|
|
4
|
+
shouldCollapseOnDoubleClick?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* _SideNavPanelSplitter_
|
|
8
|
+
*
|
|
9
|
+
* A component that allows the user to resize or collapse the side nav.
|
|
10
|
+
* It must be used within the `SideNav` layout area.
|
|
11
|
+
*
|
|
12
|
+
* Example usage:
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <SideNav>
|
|
15
|
+
* <SideNavPanelSplitter label="Resize or collapse Side Nav" />
|
|
16
|
+
* </SideNav>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const SideNavPanelSplitter: ({ label, onResizeStart, onResizeEnd, testId, shouldCollapseOnDoubleClick, }: SideNavPanelSplitterProps) => ReactNode;
|
|
20
|
+
export {};
|
|
@@ -7,7 +7,7 @@ import type { CommonSlotProps } from './types';
|
|
|
7
7
|
*
|
|
8
8
|
* You can optionally render a `PanelSplitter` as a child to make the panel area resizable.
|
|
9
9
|
*/
|
|
10
|
-
export declare function Panel({ children, defaultWidth, label, skipLinkLabel, testId, id: providedId, xcss, hasBorder, }: CommonSlotProps & {
|
|
10
|
+
export declare function Panel({ children, defaultWidth: defaultWidthProp, label, skipLinkLabel, testId, id: providedId, xcss, hasBorder, }: CommonSlotProps & {
|
|
11
11
|
/**
|
|
12
12
|
* The content of the layout area.
|
|
13
13
|
*/
|
|
@@ -19,7 +19,7 @@ export declare function Panel({ children, defaultWidth, label, skipLinkLabel, te
|
|
|
19
19
|
/**
|
|
20
20
|
* The default width of the layout area.
|
|
21
21
|
*
|
|
22
|
-
* It should be between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
22
|
+
* It should be an integer between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
23
23
|
*
|
|
24
24
|
* This value is also used as the minimum resizing width, except when the `defaultWidth` is greater then `400px`,
|
|
25
25
|
* in which case `400px` will be used as the minimum resizing width instead.
|
|
@@ -26,7 +26,8 @@ type SideNavProps = CommonSlotProps & {
|
|
|
26
26
|
defaultCollapsed?: boolean;
|
|
27
27
|
/**
|
|
28
28
|
* The default width of the side nav layout area.
|
|
29
|
-
*
|
|
29
|
+
*
|
|
30
|
+
* It should be an integer between the resize bounds - the minimum is 240px and the maximum is 50% of the viewport width.
|
|
30
31
|
*
|
|
31
32
|
* It is only used when the side nav is first mounted, but you should continuously update your
|
|
32
33
|
* persisted state using the `onResizeEnd` callback of `PanelSplitter`, to ensure it is up to date
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When `platform_dst_nav4_panel_splitter_guards` is disabled,
|
|
3
|
+
* `useSafeDefaultWidth` returns the provided `defaultWidthProp`.
|
|
4
|
+
*
|
|
5
|
+
* When `platform_dst_nav4_panel_splitter_guards` is enabled,
|
|
6
|
+
* `useSafeDefaultWidth` returns the `fallbackWidth` if the provided `defaultWidthProp` is not an integer value.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useSafeDefaultWidth({ defaultWidthProp, fallbackDefaultWidth, slotName, }: {
|
|
9
|
+
/**
|
|
10
|
+
* The `defaultWidth` passed in by the app.
|
|
11
|
+
*/
|
|
12
|
+
defaultWidthProp: number;
|
|
13
|
+
/**
|
|
14
|
+
* The fallback value for `defaultWidth` if `defaultWidthProp` is invalid.
|
|
15
|
+
*/
|
|
16
|
+
fallbackDefaultWidth: number;
|
|
17
|
+
/**
|
|
18
|
+
* The name of the slot, used for the dev-time console error.
|
|
19
|
+
*/
|
|
20
|
+
slotName: string;
|
|
21
|
+
}): number;
|
|
@@ -5,7 +5,7 @@ import type { CommonSlotProps } from './types';
|
|
|
5
5
|
*
|
|
6
6
|
* You can optionally render a `PanelSplitter` as a child to make the aside area resizable.
|
|
7
7
|
*/
|
|
8
|
-
export declare function Aside({ children, xcss, defaultWidth, label, skipLinkLabel, testId, id: providedId, }: CommonSlotProps & {
|
|
8
|
+
export declare function Aside({ children, xcss, defaultWidth: defaultWidthProp, label, skipLinkLabel, testId, id: providedId, }: CommonSlotProps & {
|
|
9
9
|
/**
|
|
10
10
|
* The content of the layout area.
|
|
11
11
|
*/
|
|
@@ -21,7 +21,7 @@ export declare function Aside({ children, xcss, defaultWidth, label, skipLinkLab
|
|
|
21
21
|
/**
|
|
22
22
|
* The default width of the layout area.
|
|
23
23
|
*
|
|
24
|
-
* It should be between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
24
|
+
* It should be an integer between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
25
25
|
*/
|
|
26
26
|
defaultWidth?: number;
|
|
27
27
|
}): JSX.Element;
|
|
@@ -52,3 +52,11 @@ export type PanelSplitterContextType = {
|
|
|
52
52
|
* Context for the panel splitter. Only internally exported.
|
|
53
53
|
*/
|
|
54
54
|
export declare const PanelSplitterContext: import("react").Context<PanelSplitterContextType | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Context for the panel splitter's double click handler. Only internally exported.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: This context is a temporary workaround to enable the `SideNavPanelSplitter` component
|
|
59
|
+
* to collapse the side nav on double click, without exposing the `onDoubleClick` prop on `PanelSplitter`.
|
|
60
|
+
* Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context should be removed.
|
|
61
|
+
*/
|
|
62
|
+
export declare const OnDoubleClickContext: import("react").Context<(() => void) | undefined>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type ReactNode } from 'react';
|
|
6
6
|
import type { ResizeBounds, ResizeEndCallback, ResizeStartCallback } from './types';
|
|
7
|
-
type PanelSplitterProps = {
|
|
7
|
+
export type PanelSplitterProps = {
|
|
8
8
|
/**
|
|
9
9
|
* The accessible label for the panel splitter. It is visually hidden, but is required for accessibility.
|
|
10
10
|
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelSplitterProps } from './panel-splitter';
|
|
3
|
+
type SideNavPanelSplitterProps = Omit<PanelSplitterProps, 'onDoubleClick'> & {
|
|
4
|
+
shouldCollapseOnDoubleClick?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* _SideNavPanelSplitter_
|
|
8
|
+
*
|
|
9
|
+
* A component that allows the user to resize or collapse the side nav.
|
|
10
|
+
* It must be used within the `SideNav` layout area.
|
|
11
|
+
*
|
|
12
|
+
* Example usage:
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <SideNav>
|
|
15
|
+
* <SideNavPanelSplitter label="Resize or collapse Side Nav" />
|
|
16
|
+
* </SideNav>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const SideNavPanelSplitter: ({ label, onResizeStart, onResizeEnd, testId, shouldCollapseOnDoubleClick, }: SideNavPanelSplitterProps) => ReactNode;
|
|
20
|
+
export {};
|
|
@@ -7,7 +7,7 @@ import type { CommonSlotProps } from './types';
|
|
|
7
7
|
*
|
|
8
8
|
* You can optionally render a `PanelSplitter` as a child to make the panel area resizable.
|
|
9
9
|
*/
|
|
10
|
-
export declare function Panel({ children, defaultWidth, label, skipLinkLabel, testId, id: providedId, xcss, hasBorder, }: CommonSlotProps & {
|
|
10
|
+
export declare function Panel({ children, defaultWidth: defaultWidthProp, label, skipLinkLabel, testId, id: providedId, xcss, hasBorder, }: CommonSlotProps & {
|
|
11
11
|
/**
|
|
12
12
|
* The content of the layout area.
|
|
13
13
|
*/
|
|
@@ -19,7 +19,7 @@ export declare function Panel({ children, defaultWidth, label, skipLinkLabel, te
|
|
|
19
19
|
/**
|
|
20
20
|
* The default width of the layout area.
|
|
21
21
|
*
|
|
22
|
-
* It should be between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
22
|
+
* It should be an integer between the resize bounds - the minimum is 120px and the maximum is 50% of the viewport width.
|
|
23
23
|
*
|
|
24
24
|
* This value is also used as the minimum resizing width, except when the `defaultWidth` is greater then `400px`,
|
|
25
25
|
* in which case `400px` will be used as the minimum resizing width instead.
|
|
@@ -26,7 +26,8 @@ type SideNavProps = CommonSlotProps & {
|
|
|
26
26
|
defaultCollapsed?: boolean;
|
|
27
27
|
/**
|
|
28
28
|
* The default width of the side nav layout area.
|
|
29
|
-
*
|
|
29
|
+
*
|
|
30
|
+
* It should be an integer between the resize bounds - the minimum is 240px and the maximum is 50% of the viewport width.
|
|
30
31
|
*
|
|
31
32
|
* It is only used when the side nav is first mounted, but you should continuously update your
|
|
32
33
|
* persisted state using the `onResizeEnd` callback of `PanelSplitter`, to ensure it is up to date
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When `platform_dst_nav4_panel_splitter_guards` is disabled,
|
|
3
|
+
* `useSafeDefaultWidth` returns the provided `defaultWidthProp`.
|
|
4
|
+
*
|
|
5
|
+
* When `platform_dst_nav4_panel_splitter_guards` is enabled,
|
|
6
|
+
* `useSafeDefaultWidth` returns the `fallbackWidth` if the provided `defaultWidthProp` is not an integer value.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useSafeDefaultWidth({ defaultWidthProp, fallbackDefaultWidth, slotName, }: {
|
|
9
|
+
/**
|
|
10
|
+
* The `defaultWidth` passed in by the app.
|
|
11
|
+
*/
|
|
12
|
+
defaultWidthProp: number;
|
|
13
|
+
/**
|
|
14
|
+
* The fallback value for `defaultWidth` if `defaultWidthProp` is invalid.
|
|
15
|
+
*/
|
|
16
|
+
fallbackDefaultWidth: number;
|
|
17
|
+
/**
|
|
18
|
+
* The name of the slot, used for the dev-time console error.
|
|
19
|
+
*/
|
|
20
|
+
slotName: string;
|
|
21
|
+
}): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/navigation-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "The latest navigation system for Atlassian apps.",
|
|
5
5
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
|
|
6
6
|
"author": "Atlassian Pty Ltd",
|
|
@@ -120,8 +120,8 @@
|
|
|
120
120
|
"@atlaskit/pragmatic-drag-and-drop": "^1.7.0",
|
|
121
121
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
|
|
122
122
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
|
|
123
|
-
"@atlaskit/primitives": "^14.
|
|
124
|
-
"@atlaskit/tokens": "^6.
|
|
123
|
+
"@atlaskit/primitives": "^14.12.0",
|
|
124
|
+
"@atlaskit/tokens": "^6.1.0",
|
|
125
125
|
"@atlaskit/tooltip": "^20.4.0",
|
|
126
126
|
"@atlaskit/visually-hidden": "^3.0.0",
|
|
127
127
|
"@babel/runtime": "^7.0.0",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"@atlaskit/banner": "^14.0.0",
|
|
143
143
|
"@atlaskit/breadcrumbs": "^15.3.0",
|
|
144
144
|
"@atlaskit/dropdown-menu": "^16.3.0",
|
|
145
|
-
"@atlaskit/form": "^12.
|
|
145
|
+
"@atlaskit/form": "^12.4.0",
|
|
146
146
|
"@atlaskit/heading": "^5.2.0",
|
|
147
147
|
"@atlaskit/link": "^3.2.0",
|
|
148
148
|
"@atlaskit/lozenge": "^13.0.0",
|
|
@@ -214,9 +214,6 @@
|
|
|
214
214
|
"platform_dst_nav4_flyout_use_capture_outside": {
|
|
215
215
|
"type": "boolean"
|
|
216
216
|
},
|
|
217
|
-
"platform_dst_expandable_menu_item_elembefore_label": {
|
|
218
|
-
"type": "boolean"
|
|
219
|
-
},
|
|
220
217
|
"platform_dst_nav4_skip_links_hydration_fix": {
|
|
221
218
|
"type": "boolean"
|
|
222
219
|
},
|
|
@@ -225,6 +222,9 @@
|
|
|
225
222
|
},
|
|
226
223
|
"platform_dst_nav4_flyoutmenuitem_render_to_parent": {
|
|
227
224
|
"type": "boolean"
|
|
225
|
+
},
|
|
226
|
+
"platform_dst_nav4_panel_splitter_guards": {
|
|
227
|
+
"type": "boolean"
|
|
228
228
|
}
|
|
229
229
|
},
|
|
230
230
|
"homepage": "https://atlassian.design/components/navigation-system"
|