@atlaskit/side-navigation 1.1.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.
- package/CHANGELOG.md +517 -0
- package/LICENSE +13 -0
- package/README.md +16 -0
- package/build/tsconfig.json +17 -0
- package/codemods/0.8.0-change-css-fn-prop.ts +184 -0
- package/codemods/__tests__/0.8.0-change-css-fn-prop.ts +360 -0
- package/codemods/helpers/generic.ts +674 -0
- package/dist/cjs/common/constants.js +10 -0
- package/dist/cjs/common/styles.js +104 -0
- package/dist/cjs/components/Footer/index.js +67 -0
- package/dist/cjs/components/Header/index.js +73 -0
- package/dist/cjs/components/Item/button-item.js +47 -0
- package/dist/cjs/components/Item/custom-item.js +52 -0
- package/dist/cjs/components/Item/go-back-item.js +65 -0
- package/dist/cjs/components/Item/index.js +47 -0
- package/dist/cjs/components/Item/link-item.js +47 -0
- package/dist/cjs/components/Item/skeleton-item.js +43 -0
- package/dist/cjs/components/LoadingItems/index.js +51 -0
- package/dist/cjs/components/NavigationContent/index.js +52 -0
- package/dist/cjs/components/NavigationContent/styles.js +152 -0
- package/dist/cjs/components/NavigationFooter/index.js +27 -0
- package/dist/cjs/components/NavigationHeader/index.js +27 -0
- package/dist/cjs/components/NestableNavigationContent/context.js +51 -0
- package/dist/cjs/components/NestableNavigationContent/index.js +182 -0
- package/dist/cjs/components/NestableNavigationContent/nesting-motion.js +40 -0
- package/dist/cjs/components/NestingItem/hack-for-ert.js +8 -0
- package/dist/cjs/components/NestingItem/index.js +173 -0
- package/dist/cjs/components/NestingItem/styles.js +47 -0
- package/dist/cjs/components/Section/heading-item.js +35 -0
- package/dist/cjs/components/Section/index.js +31 -0
- package/dist/cjs/components/Section/section.js +45 -0
- package/dist/cjs/components/Section/skeleton-heading-item.js +39 -0
- package/dist/cjs/components/SideNavigation/index.js +41 -0
- package/dist/cjs/components/index.js +131 -0
- package/dist/cjs/index.js +131 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/common/constants.js +2 -0
- package/dist/es2019/common/styles.js +78 -0
- package/dist/es2019/components/Footer/index.js +52 -0
- package/dist/es2019/components/Header/index.js +46 -0
- package/dist/es2019/components/Item/button-item.js +25 -0
- package/dist/es2019/components/Item/custom-item.js +31 -0
- package/dist/es2019/components/Item/go-back-item.js +34 -0
- package/dist/es2019/components/Item/index.js +5 -0
- package/dist/es2019/components/Item/link-item.js +25 -0
- package/dist/es2019/components/Item/skeleton-item.js +28 -0
- package/dist/es2019/components/LoadingItems/index.js +38 -0
- package/dist/es2019/components/NavigationContent/index.js +38 -0
- package/dist/es2019/components/NavigationContent/styles.js +120 -0
- package/dist/es2019/components/NavigationFooter/index.js +18 -0
- package/dist/es2019/components/NavigationHeader/index.js +20 -0
- package/dist/es2019/components/NestableNavigationContent/context.js +41 -0
- package/dist/es2019/components/NestableNavigationContent/index.js +148 -0
- package/dist/es2019/components/NestableNavigationContent/nesting-motion.js +21 -0
- package/dist/es2019/components/NestingItem/hack-for-ert.js +1 -0
- package/dist/es2019/components/NestingItem/index.js +128 -0
- package/dist/es2019/components/NestingItem/styles.js +39 -0
- package/dist/es2019/components/Section/heading-item.js +22 -0
- package/dist/es2019/components/Section/index.js +3 -0
- package/dist/es2019/components/Section/section.js +25 -0
- package/dist/es2019/components/Section/skeleton-heading-item.js +24 -0
- package/dist/es2019/components/SideNavigation/index.js +30 -0
- package/dist/es2019/components/index.js +11 -0
- package/dist/es2019/index.js +3 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/common/constants.js +2 -0
- package/dist/esm/common/styles.js +82 -0
- package/dist/esm/components/Footer/index.js +51 -0
- package/dist/esm/components/Header/index.js +50 -0
- package/dist/esm/components/Item/button-item.js +25 -0
- package/dist/esm/components/Item/custom-item.js +31 -0
- package/dist/esm/components/Item/go-back-item.js +41 -0
- package/dist/esm/components/Item/index.js +5 -0
- package/dist/esm/components/Item/link-item.js +25 -0
- package/dist/esm/components/Item/skeleton-item.js +29 -0
- package/dist/esm/components/LoadingItems/index.js +39 -0
- package/dist/esm/components/NavigationContent/index.js +37 -0
- package/dist/esm/components/NavigationContent/styles.js +130 -0
- package/dist/esm/components/NavigationFooter/index.js +17 -0
- package/dist/esm/components/NavigationHeader/index.js +18 -0
- package/dist/esm/components/NestableNavigationContent/context.js +36 -0
- package/dist/esm/components/NestableNavigationContent/index.js +163 -0
- package/dist/esm/components/NestableNavigationContent/nesting-motion.js +28 -0
- package/dist/esm/components/NestingItem/hack-for-ert.js +1 -0
- package/dist/esm/components/NestingItem/index.js +144 -0
- package/dist/esm/components/NestingItem/styles.js +34 -0
- package/dist/esm/components/Section/heading-item.js +21 -0
- package/dist/esm/components/Section/index.js +3 -0
- package/dist/esm/components/Section/section.js +24 -0
- package/dist/esm/components/Section/skeleton-heading-item.js +25 -0
- package/dist/esm/components/SideNavigation/index.js +28 -0
- package/dist/esm/components/index.js +11 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/common/constants.d.ts +2 -0
- package/dist/types/common/styles.d.ts +10 -0
- package/dist/types/components/Footer/index.d.ts +4 -0
- package/dist/types/components/Header/index.d.ts +43 -0
- package/dist/types/components/Item/button-item.d.ts +5 -0
- package/dist/types/components/Item/custom-item.d.ts +13 -0
- package/dist/types/components/Item/go-back-item.d.ts +5 -0
- package/dist/types/components/Item/index.d.ts +10 -0
- package/dist/types/components/Item/link-item.d.ts +5 -0
- package/dist/types/components/Item/skeleton-item.d.ts +4 -0
- package/dist/types/components/LoadingItems/index.d.ts +30 -0
- package/dist/types/components/NavigationContent/index.d.ts +17 -0
- package/dist/types/components/NavigationContent/styles.d.ts +91 -0
- package/dist/types/components/NavigationFooter/index.d.ts +7 -0
- package/dist/types/components/NavigationHeader/index.d.ts +5 -0
- package/dist/types/components/NestableNavigationContent/context.d.ts +20 -0
- package/dist/types/components/NestableNavigationContent/index.d.ts +58 -0
- package/dist/types/components/NestableNavigationContent/nesting-motion.d.ts +18 -0
- package/dist/types/components/NestingItem/hack-for-ert.d.ts +2 -0
- package/dist/types/components/NestingItem/index.d.ts +91 -0
- package/dist/types/components/NestingItem/styles.d.ts +28 -0
- package/dist/types/components/Section/heading-item.d.ts +4 -0
- package/dist/types/components/Section/index.d.ts +6 -0
- package/dist/types/components/Section/section.d.ts +25 -0
- package/dist/types/components/Section/skeleton-heading-item.d.ts +4 -0
- package/dist/types/components/SideNavigation/index.d.ts +23 -0
- package/dist/types/components/index.d.ts +22 -0
- package/dist/types/index.d.ts +4 -0
- package/docs/00-intro.tsx +70 -0
- package/docs/01-side-navigation.tsx +33 -0
- package/docs/02-navigation-header.tsx +39 -0
- package/docs/03-navigation-content.tsx +40 -0
- package/docs/04-nestable-navigation-content.tsx +95 -0
- package/docs/05-navigation-footer.tsx +38 -0
- package/docs/99-loading-states.tsx +95 -0
- package/docs/button-item.tsx +38 -0
- package/docs/custom-item.tsx +45 -0
- package/docs/go-back-item.tsx +31 -0
- package/docs/heading-item.tsx +30 -0
- package/docs/link-item.tsx +39 -0
- package/docs/nesting-item.tsx +52 -0
- package/docs/section.tsx +40 -0
- package/docs/skeleton-heading-item.tsx +30 -0
- package/docs/skeleton-item.tsx +30 -0
- package/package.json +71 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
|
|
3
|
+
/** @jsx jsx */
|
|
4
|
+
import { jsx } from '@emotion/core';
|
|
5
|
+
import { ExitingPersistence, FadeIn, mediumDurationMs } from '@atlaskit/motion';
|
|
6
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
7
|
+
|
|
8
|
+
var LoadingItems = function LoadingItems(_ref) {
|
|
9
|
+
var children = _ref.children,
|
|
10
|
+
isLoading = _ref.isLoading,
|
|
11
|
+
fallback = _ref.fallback,
|
|
12
|
+
testId = _ref.testId;
|
|
13
|
+
|
|
14
|
+
var _useShouldNestedEleme = useShouldNestedElementRender(),
|
|
15
|
+
shouldRender = _useShouldNestedEleme.shouldRender;
|
|
16
|
+
|
|
17
|
+
if (!shouldRender) {
|
|
18
|
+
return children;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return jsx(ExitingPersistence, null, jsx(FadeIn, {
|
|
22
|
+
key: "loading-section-".concat(isLoading),
|
|
23
|
+
duration: mediumDurationMs
|
|
24
|
+
}, function (motion, state) {
|
|
25
|
+
return jsx("span", _extends({}, motion, {
|
|
26
|
+
"data-testid": testId && "".concat(testId, "--").concat(state),
|
|
27
|
+
css: {
|
|
28
|
+
// Used to have the exiting section appear above the entering one.
|
|
29
|
+
position: state === 'entering' ? undefined : 'absolute',
|
|
30
|
+
zIndex: state === 'entering' ? 2 : 1,
|
|
31
|
+
top: 0,
|
|
32
|
+
left: 0,
|
|
33
|
+
right: 0
|
|
34
|
+
}
|
|
35
|
+
}), isLoading ? fallback : children);
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default LoadingItems;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { jsx } from '@emotion/core';
|
|
4
|
+
import useScrollbarWidth from '@atlaskit/ds-lib/use-scrollbar-width';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
import { containerCSS, innerContainerCSS, outerContainerCSS } from './styles';
|
|
7
|
+
var NavigationContent = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
8
|
+
var showTopScrollIndicator = props.showTopScrollIndicator,
|
|
9
|
+
children = props.children;
|
|
10
|
+
|
|
11
|
+
var _useShouldNestedEleme = useShouldNestedElementRender(),
|
|
12
|
+
shouldRender = _useShouldNestedEleme.shouldRender;
|
|
13
|
+
|
|
14
|
+
var scrollbar = useScrollbarWidth();
|
|
15
|
+
|
|
16
|
+
if (!shouldRender) {
|
|
17
|
+
return children;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return jsx("div", {
|
|
21
|
+
ref: ref,
|
|
22
|
+
css: outerContainerCSS({
|
|
23
|
+
showTopScrollIndicator: showTopScrollIndicator,
|
|
24
|
+
scrollbarWidth: scrollbar.width
|
|
25
|
+
})
|
|
26
|
+
}, jsx("div", {
|
|
27
|
+
ref: scrollbar.ref,
|
|
28
|
+
css: innerContainerCSS({
|
|
29
|
+
showTopScrollIndicator: showTopScrollIndicator
|
|
30
|
+
})
|
|
31
|
+
}, jsx("div", {
|
|
32
|
+
css: containerCSS({
|
|
33
|
+
showTopScrollIndicator: showTopScrollIndicator
|
|
34
|
+
})
|
|
35
|
+
}, children)));
|
|
36
|
+
});
|
|
37
|
+
export default NavigationContent;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
|
|
3
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
4
|
+
|
|
5
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
6
|
+
|
|
7
|
+
import { N10, N30 } from '@atlaskit/theme/colors';
|
|
8
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
9
|
+
import { headingSizes } from '@atlaskit/theme/typography';
|
|
10
|
+
import { token } from '@atlaskit/tokens';
|
|
11
|
+
import { VAR_SCROLL_INDICATOR_COLOR, VAR_SEPARATOR_COLOR } from '../../common/constants';
|
|
12
|
+
var scrollIndicatorMaskZIndex = 2;
|
|
13
|
+
var scrollIndicatorZIndex = 1;
|
|
14
|
+
var scrollIndicatorHeight = 2;
|
|
15
|
+
var scrollIndicatorBorderRadius = 1;
|
|
16
|
+
var containerPadding = gridSize();
|
|
17
|
+
var itemHeadingTopMargin = containerPadding * 2.5;
|
|
18
|
+
var itemHeadingBottomMargin = containerPadding * 0.75; // Skeleton content is slightly shorter than the real content.
|
|
19
|
+
// Because of that we slightly increase the top margin to offset this so the
|
|
20
|
+
// containing size both real and skeleton always equal approx 30px.
|
|
21
|
+
|
|
22
|
+
var itemHeadingContentHeight = headingSizes.h100.lineHeight;
|
|
23
|
+
var skeletonHeadingHeight = containerPadding;
|
|
24
|
+
var skeletonHeadingMarginOffset = 3;
|
|
25
|
+
var skeletonHeadingTopMargin = itemHeadingTopMargin + (itemHeadingContentHeight - skeletonHeadingHeight) - skeletonHeadingMarginOffset; // We want to move the entire body up by 3px without affecting the height of the skeleton container.
|
|
26
|
+
|
|
27
|
+
var skeletonHeadingBottomMargin = itemHeadingBottomMargin + skeletonHeadingMarginOffset;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* This outer container css contains the "real" scroll indicators which are
|
|
31
|
+
* always rendered to the screen.
|
|
32
|
+
* They are "conditionally" shown from the users perspective using the inner container CSS
|
|
33
|
+
* which has other pseudo elements which "mask" the "real" scroll indicators.
|
|
34
|
+
*/
|
|
35
|
+
export var outerContainerCSS = function outerContainerCSS(opts) {
|
|
36
|
+
return {
|
|
37
|
+
// Flex is needed to ensure the overflow indicators are positioned correctly.
|
|
38
|
+
display: 'flex',
|
|
39
|
+
height: '100%',
|
|
40
|
+
overflow: 'hidden',
|
|
41
|
+
position: 'relative',
|
|
42
|
+
'&::before': {
|
|
43
|
+
content: "''",
|
|
44
|
+
display: 'block',
|
|
45
|
+
left: containerPadding,
|
|
46
|
+
right: containerPadding + opts.scrollbarWidth,
|
|
47
|
+
height: scrollIndicatorHeight,
|
|
48
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
49
|
+
backgroundColor: "var(".concat(VAR_SEPARATOR_COLOR, ", ").concat(token('color.border.neutral', N30), ")"),
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
zIndex: scrollIndicatorZIndex
|
|
52
|
+
},
|
|
53
|
+
'&::after': {
|
|
54
|
+
content: "''",
|
|
55
|
+
position: 'absolute',
|
|
56
|
+
display: 'block',
|
|
57
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
58
|
+
flexShrink: 0,
|
|
59
|
+
height: scrollIndicatorHeight,
|
|
60
|
+
left: containerPadding,
|
|
61
|
+
right: containerPadding + opts.scrollbarWidth,
|
|
62
|
+
bottom: 0,
|
|
63
|
+
zIndex: scrollIndicatorZIndex,
|
|
64
|
+
backgroundColor: "var(".concat(VAR_SEPARATOR_COLOR, ", ").concat(token('color.border.neutral', N30), ")")
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* This inner container css contains the "mask" logic for the scroll indicators.
|
|
70
|
+
* Essentially they cover (mask) the "real" scroll indicators when the user is scrolled
|
|
71
|
+
* to the top or bottom of the container.
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
export var innerContainerCSS = function innerContainerCSS(opts) {
|
|
75
|
+
return _objectSpread(_objectSpread({
|
|
76
|
+
display: 'flex',
|
|
77
|
+
overflow: 'auto',
|
|
78
|
+
width: '100%',
|
|
79
|
+
position: 'relative',
|
|
80
|
+
boxSizing: 'border-box',
|
|
81
|
+
flexDirection: 'column'
|
|
82
|
+
}, !opts.showTopScrollIndicator && {
|
|
83
|
+
'&::before': {
|
|
84
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
85
|
+
content: "''",
|
|
86
|
+
left: 0,
|
|
87
|
+
right: 0,
|
|
88
|
+
height: scrollIndicatorHeight,
|
|
89
|
+
backgroundColor: "var(".concat(VAR_SCROLL_INDICATOR_COLOR, ", ").concat(token('color.background.default', N10), ")"),
|
|
90
|
+
position: 'absolute',
|
|
91
|
+
display: 'block',
|
|
92
|
+
zIndex: scrollIndicatorMaskZIndex
|
|
93
|
+
}
|
|
94
|
+
}), {}, {
|
|
95
|
+
// This after pseudo element abuses being a flex child and pushes itself down to the
|
|
96
|
+
// very bottom of the container - doing so ends up "masking" the actual scroll indicator.
|
|
97
|
+
'&::after': {
|
|
98
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
99
|
+
content: "''",
|
|
100
|
+
display: 'block',
|
|
101
|
+
flexShrink: 0,
|
|
102
|
+
height: scrollIndicatorHeight,
|
|
103
|
+
// This is used to "push" the element to the bottom of the flex container.
|
|
104
|
+
marginTop: 'auto',
|
|
105
|
+
position: 'relative',
|
|
106
|
+
zIndex: scrollIndicatorMaskZIndex,
|
|
107
|
+
backgroundColor: "var(".concat(VAR_SCROLL_INDICATOR_COLOR, ", ").concat(token('color.background.default', N10), ")")
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
export var containerCSS = function containerCSS(opts) {
|
|
112
|
+
return {
|
|
113
|
+
// When the scroll indicator is always shown we need to add some padding
|
|
114
|
+
// so the spacing between matches what it would be if the indicator was a "block" element.
|
|
115
|
+
// We use margin here so any child absolutely positioned elements are positioned correctly.
|
|
116
|
+
marginTop: opts.showTopScrollIndicator ? scrollIndicatorHeight : 0,
|
|
117
|
+
marginLeft: containerPadding,
|
|
118
|
+
marginRight: containerPadding,
|
|
119
|
+
// Enables child absolutely positioned elements to be positioned relative to this element.
|
|
120
|
+
position: 'relative',
|
|
121
|
+
'& [data-ds--menu--heading-item]': {
|
|
122
|
+
marginTop: itemHeadingTopMargin,
|
|
123
|
+
marginBottom: itemHeadingBottomMargin
|
|
124
|
+
},
|
|
125
|
+
'& [data-ds--menu--skeleton-heading-item]': {
|
|
126
|
+
marginTop: skeletonHeadingTopMargin,
|
|
127
|
+
marginBottom: skeletonHeadingBottomMargin
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
4
|
+
var footerCSS = {
|
|
5
|
+
position: 'relative',
|
|
6
|
+
padding: gridSize(),
|
|
7
|
+
paddingBottom: gridSize() * 1.75
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
var NavigationFooter = function NavigationFooter(_ref) {
|
|
11
|
+
var children = _ref.children;
|
|
12
|
+
return jsx("div", {
|
|
13
|
+
css: footerCSS
|
|
14
|
+
}, children);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default NavigationFooter;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
4
|
+
|
|
5
|
+
var NavigationHeader = function NavigationHeader(props) {
|
|
6
|
+
var children = props.children;
|
|
7
|
+
return jsx("div", {
|
|
8
|
+
"data-navheader": true,
|
|
9
|
+
css: {
|
|
10
|
+
paddingTop: gridSize() * 3,
|
|
11
|
+
paddingBottom: gridSize(),
|
|
12
|
+
paddingLeft: gridSize(),
|
|
13
|
+
paddingRight: gridSize()
|
|
14
|
+
}
|
|
15
|
+
}, children);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default NavigationHeader;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export var NestedContext = /*#__PURE__*/createContext(undefined);
|
|
3
|
+
export var useNestedContext = function useNestedContext() {
|
|
4
|
+
var context = useContext(NestedContext);
|
|
5
|
+
|
|
6
|
+
if (!context) {
|
|
7
|
+
var error = '';
|
|
8
|
+
|
|
9
|
+
if (process.env.NODE_ENV === 'development') {
|
|
10
|
+
error = "\nTo use a <NestingItem /> it needs to be a descendant of <NestableNavigationContent>.\nYou probably need to replace your <NavigationContent> with <NestableNavigationContent>.\n\nimport { NestableNavigationContent } from '@atlaskit/side-navigation';\n ";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
throw new Error(error);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return context;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Used by children of the NestableNavigationContent component to see if they should render or not.
|
|
20
|
+
* If `shouldRender` returns `true` - return your nodes.
|
|
21
|
+
* If it returns `false` - either return `null` or `children` if you have children.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export var useShouldNestedElementRender = function useShouldNestedElementRender() {
|
|
25
|
+
var context = useContext(NestedContext);
|
|
26
|
+
|
|
27
|
+
if (!context) {
|
|
28
|
+
return {
|
|
29
|
+
shouldRender: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
shouldRender: context.currentStackId === context.parentId
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
|
|
4
|
+
/** @jsx jsx */
|
|
5
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { jsx } from '@emotion/core';
|
|
7
|
+
import { ExitingPersistence } from '@atlaskit/motion';
|
|
8
|
+
import { GoBackItem as GoBackButton } from '../Item';
|
|
9
|
+
import { default as NestingItem } from '../NestingItem';
|
|
10
|
+
import { NestedContext } from './context';
|
|
11
|
+
import { NestingMotion } from './nesting-motion'; // Named so ERT doesn't pick up the override name as a type.
|
|
12
|
+
|
|
13
|
+
export var ROOT_ID = 'ATLASKIT_NESTED_ROOT';
|
|
14
|
+
|
|
15
|
+
var NestableNavigationContent = function NestableNavigationContent(props) {
|
|
16
|
+
var containerRef = useRef(null);
|
|
17
|
+
var children = props.children,
|
|
18
|
+
testId = props.testId,
|
|
19
|
+
overrides = props.overrides,
|
|
20
|
+
initialStack = props.initialStack,
|
|
21
|
+
onChange = props.onChange,
|
|
22
|
+
stack = props.stack;
|
|
23
|
+
|
|
24
|
+
var _useState = useState(stack || initialStack || []),
|
|
25
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
26
|
+
committedStack = _useState2[0],
|
|
27
|
+
setCommittedStack = _useState2[1];
|
|
28
|
+
|
|
29
|
+
var controlledStack = stack || undefined;
|
|
30
|
+
var currentStackId = committedStack[committedStack.length - 1] || ROOT_ID;
|
|
31
|
+
|
|
32
|
+
var _useState3 = useState('nesting'),
|
|
33
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
34
|
+
transition = _useState4[0],
|
|
35
|
+
setTransition = _useState4[1];
|
|
36
|
+
|
|
37
|
+
var backTestId = testId && "".concat(testId, "--go-back-item");
|
|
38
|
+
var renderGoBackItem = overrides && overrides.GoBackItem && overrides.GoBackItem.render ? overrides.GoBackItem.render : function (props) {
|
|
39
|
+
return jsx(GoBackButton, props, "Go back");
|
|
40
|
+
};
|
|
41
|
+
var onNestHandler = useCallback(function (layerId) {
|
|
42
|
+
onChange && onChange(committedStack.concat(layerId));
|
|
43
|
+
|
|
44
|
+
if (controlledStack) {
|
|
45
|
+
// We are in controlled mode - ignore the steps.
|
|
46
|
+
return;
|
|
47
|
+
} // We need to split the state update into to parts.
|
|
48
|
+
// First: Updating the direction of the motions.
|
|
49
|
+
// Second: Actually updating the stack (which will cause elements to enter & leave).
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
setTransition('nesting');
|
|
53
|
+
requestAnimationFrame(function () {
|
|
54
|
+
setCommittedStack(function (prev) {
|
|
55
|
+
var newStack = prev.concat(layerId);
|
|
56
|
+
return newStack;
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}, [controlledStack, onChange, committedStack]);
|
|
60
|
+
var onUnNestHandler = useCallback(function () {
|
|
61
|
+
onChange && onChange(committedStack.slice(0, committedStack.length - 1));
|
|
62
|
+
|
|
63
|
+
if (controlledStack) {
|
|
64
|
+
// We are in controlled mode - ignore the steps.
|
|
65
|
+
return;
|
|
66
|
+
} // We need to split the state update into to parts.
|
|
67
|
+
// First: Updating the direction of the motions.
|
|
68
|
+
// Second: Actually updating the stack (which will cause elements to enter & leave).
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
setTransition('unnesting');
|
|
72
|
+
requestAnimationFrame(function () {
|
|
73
|
+
setCommittedStack(function (prev) {
|
|
74
|
+
var newStack = prev.slice(0, prev.length - 1);
|
|
75
|
+
return newStack;
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}, [controlledStack, onChange, committedStack]);
|
|
79
|
+
useEffect(function () {
|
|
80
|
+
if (!controlledStack) {
|
|
81
|
+
// We aren't in controlled mode - bail out.
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (JSON.stringify(committedStack) === JSON.stringify(controlledStack)) {
|
|
86
|
+
// stacks are equal - do nothing!
|
|
87
|
+
return;
|
|
88
|
+
} // Controlled prop updated, let's figure out if we're nesting or unnesting.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if (controlledStack.length < committedStack.length) {
|
|
92
|
+
// We are unnesting (removing from the stack)
|
|
93
|
+
setTransition('unnesting');
|
|
94
|
+
} else {
|
|
95
|
+
// We are nesting (adding to the stack)
|
|
96
|
+
setTransition('nesting');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
requestAnimationFrame(function () {
|
|
100
|
+
setCommittedStack(controlledStack);
|
|
101
|
+
});
|
|
102
|
+
}, [committedStack, controlledStack]);
|
|
103
|
+
var backButton = renderGoBackItem({
|
|
104
|
+
onClick: onUnNestHandler,
|
|
105
|
+
testId: backTestId
|
|
106
|
+
});
|
|
107
|
+
var context = useMemo(function () {
|
|
108
|
+
return {
|
|
109
|
+
currentStackId: currentStackId,
|
|
110
|
+
backButton: backButton,
|
|
111
|
+
stack: committedStack,
|
|
112
|
+
onNest: onNestHandler,
|
|
113
|
+
onUnNest: onUnNestHandler,
|
|
114
|
+
parentId: ROOT_ID
|
|
115
|
+
};
|
|
116
|
+
}, [onNestHandler, onUnNestHandler, backButton, committedStack, currentStackId]);
|
|
117
|
+
|
|
118
|
+
var manageFocus = function manageFocus(event) {
|
|
119
|
+
var triggeredByKeyboard = event.nativeEvent.detail === 0;
|
|
120
|
+
|
|
121
|
+
if (triggeredByKeyboard) {
|
|
122
|
+
containerRef.current && containerRef.current.focus();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return jsx("div", {
|
|
127
|
+
"data-testid": testId,
|
|
128
|
+
css: {
|
|
129
|
+
position: 'relative',
|
|
130
|
+
height: '100%',
|
|
131
|
+
outline: 'none'
|
|
132
|
+
},
|
|
133
|
+
ref: containerRef,
|
|
134
|
+
tabIndex: -1,
|
|
135
|
+
onClick: manageFocus
|
|
136
|
+
}, jsx(ExitingPersistence, null, jsx(NestingMotion // Key is needed to have a unique react instance per stack name.
|
|
137
|
+
// This enables us to easily animate it in & out with exiting persistence.
|
|
138
|
+
, {
|
|
139
|
+
key: currentStackId,
|
|
140
|
+
enterFrom: transition === 'nesting' ? 'right' : 'left',
|
|
141
|
+
exitTo: transition === 'nesting' ? 'left' : 'right',
|
|
142
|
+
testId: testId && "".concat(testId, "-anim")
|
|
143
|
+
}, function (motion) {
|
|
144
|
+
return jsx("div", _extends({
|
|
145
|
+
css: {
|
|
146
|
+
position: 'absolute',
|
|
147
|
+
width: '100%',
|
|
148
|
+
height: '100%',
|
|
149
|
+
display: 'flex',
|
|
150
|
+
flexDirection: 'column'
|
|
151
|
+
}
|
|
152
|
+
}, motion), jsx(NestedContext.Provider, {
|
|
153
|
+
// This provider is inside the NestingMotion to ensure it keeps a stale
|
|
154
|
+
// reference to the previous value.
|
|
155
|
+
value: context
|
|
156
|
+
}, jsx(NestingItem, {
|
|
157
|
+
title: "",
|
|
158
|
+
id: ROOT_ID
|
|
159
|
+
}, children)));
|
|
160
|
+
})));
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export default NestableNavigationContent;
|