@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,18 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
4
|
+
const footerCSS = {
|
|
5
|
+
position: 'relative',
|
|
6
|
+
padding: gridSize(),
|
|
7
|
+
paddingBottom: gridSize() * 1.75
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const NavigationFooter = ({
|
|
11
|
+
children
|
|
12
|
+
}) => {
|
|
13
|
+
return jsx("div", {
|
|
14
|
+
css: footerCSS
|
|
15
|
+
}, children);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default NavigationFooter;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
4
|
+
|
|
5
|
+
const NavigationHeader = props => {
|
|
6
|
+
const {
|
|
7
|
+
children
|
|
8
|
+
} = props;
|
|
9
|
+
return jsx("div", {
|
|
10
|
+
"data-navheader": true,
|
|
11
|
+
css: {
|
|
12
|
+
paddingTop: gridSize() * 3,
|
|
13
|
+
paddingBottom: gridSize(),
|
|
14
|
+
paddingLeft: gridSize(),
|
|
15
|
+
paddingRight: gridSize()
|
|
16
|
+
}
|
|
17
|
+
}, children);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default NavigationHeader;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const NestedContext = /*#__PURE__*/createContext(undefined);
|
|
3
|
+
export const useNestedContext = () => {
|
|
4
|
+
const context = useContext(NestedContext);
|
|
5
|
+
|
|
6
|
+
if (!context) {
|
|
7
|
+
let error = '';
|
|
8
|
+
|
|
9
|
+
if (process.env.NODE_ENV === 'development') {
|
|
10
|
+
error = `
|
|
11
|
+
To use a <NestingItem /> it needs to be a descendant of <NestableNavigationContent>.
|
|
12
|
+
You probably need to replace your <NavigationContent> with <NestableNavigationContent>.
|
|
13
|
+
|
|
14
|
+
import { NestableNavigationContent } from '@atlaskit/side-navigation';
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
throw new Error(error);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return context;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Used by children of the NestableNavigationContent component to see if they should render or not.
|
|
25
|
+
* If `shouldRender` returns `true` - return your nodes.
|
|
26
|
+
* If it returns `false` - either return `null` or `children` if you have children.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
export const useShouldNestedElementRender = () => {
|
|
30
|
+
const context = useContext(NestedContext);
|
|
31
|
+
|
|
32
|
+
if (!context) {
|
|
33
|
+
return {
|
|
34
|
+
shouldRender: true
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
shouldRender: context.currentStackId === context.parentId
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
|
|
3
|
+
/** @jsx jsx */
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { jsx } from '@emotion/core';
|
|
6
|
+
import { ExitingPersistence } from '@atlaskit/motion';
|
|
7
|
+
import { GoBackItem as GoBackButton } from '../Item';
|
|
8
|
+
import { default as NestingItem } from '../NestingItem';
|
|
9
|
+
import { NestedContext } from './context';
|
|
10
|
+
import { NestingMotion } from './nesting-motion'; // Named so ERT doesn't pick up the override name as a type.
|
|
11
|
+
|
|
12
|
+
export const ROOT_ID = 'ATLASKIT_NESTED_ROOT';
|
|
13
|
+
|
|
14
|
+
const NestableNavigationContent = props => {
|
|
15
|
+
const containerRef = useRef(null);
|
|
16
|
+
const {
|
|
17
|
+
children,
|
|
18
|
+
testId,
|
|
19
|
+
overrides,
|
|
20
|
+
initialStack,
|
|
21
|
+
onChange,
|
|
22
|
+
stack
|
|
23
|
+
} = props;
|
|
24
|
+
const [committedStack, setCommittedStack] = useState(stack || initialStack || []);
|
|
25
|
+
const controlledStack = stack || undefined;
|
|
26
|
+
const currentStackId = committedStack[committedStack.length - 1] || ROOT_ID;
|
|
27
|
+
const [transition, setTransition] = useState('nesting');
|
|
28
|
+
const backTestId = testId && `${testId}--go-back-item`;
|
|
29
|
+
const renderGoBackItem = overrides && overrides.GoBackItem && overrides.GoBackItem.render ? overrides.GoBackItem.render : props => jsx(GoBackButton, props, "Go back");
|
|
30
|
+
const onNestHandler = useCallback(layerId => {
|
|
31
|
+
onChange && onChange(committedStack.concat(layerId));
|
|
32
|
+
|
|
33
|
+
if (controlledStack) {
|
|
34
|
+
// We are in controlled mode - ignore the steps.
|
|
35
|
+
return;
|
|
36
|
+
} // We need to split the state update into to parts.
|
|
37
|
+
// First: Updating the direction of the motions.
|
|
38
|
+
// Second: Actually updating the stack (which will cause elements to enter & leave).
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
setTransition('nesting');
|
|
42
|
+
requestAnimationFrame(() => {
|
|
43
|
+
setCommittedStack(prev => {
|
|
44
|
+
const newStack = prev.concat(layerId);
|
|
45
|
+
return newStack;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}, [controlledStack, onChange, committedStack]);
|
|
49
|
+
const onUnNestHandler = useCallback(() => {
|
|
50
|
+
onChange && onChange(committedStack.slice(0, committedStack.length - 1));
|
|
51
|
+
|
|
52
|
+
if (controlledStack) {
|
|
53
|
+
// We are in controlled mode - ignore the steps.
|
|
54
|
+
return;
|
|
55
|
+
} // We need to split the state update into to parts.
|
|
56
|
+
// First: Updating the direction of the motions.
|
|
57
|
+
// Second: Actually updating the stack (which will cause elements to enter & leave).
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
setTransition('unnesting');
|
|
61
|
+
requestAnimationFrame(() => {
|
|
62
|
+
setCommittedStack(prev => {
|
|
63
|
+
const newStack = prev.slice(0, prev.length - 1);
|
|
64
|
+
return newStack;
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}, [controlledStack, onChange, committedStack]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!controlledStack) {
|
|
70
|
+
// We aren't in controlled mode - bail out.
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (JSON.stringify(committedStack) === JSON.stringify(controlledStack)) {
|
|
75
|
+
// stacks are equal - do nothing!
|
|
76
|
+
return;
|
|
77
|
+
} // Controlled prop updated, let's figure out if we're nesting or unnesting.
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if (controlledStack.length < committedStack.length) {
|
|
81
|
+
// We are unnesting (removing from the stack)
|
|
82
|
+
setTransition('unnesting');
|
|
83
|
+
} else {
|
|
84
|
+
// We are nesting (adding to the stack)
|
|
85
|
+
setTransition('nesting');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
requestAnimationFrame(() => {
|
|
89
|
+
setCommittedStack(controlledStack);
|
|
90
|
+
});
|
|
91
|
+
}, [committedStack, controlledStack]);
|
|
92
|
+
const backButton = renderGoBackItem({
|
|
93
|
+
onClick: onUnNestHandler,
|
|
94
|
+
testId: backTestId
|
|
95
|
+
});
|
|
96
|
+
const context = useMemo(() => ({
|
|
97
|
+
currentStackId,
|
|
98
|
+
backButton,
|
|
99
|
+
stack: committedStack,
|
|
100
|
+
onNest: onNestHandler,
|
|
101
|
+
onUnNest: onUnNestHandler,
|
|
102
|
+
parentId: ROOT_ID
|
|
103
|
+
}), [onNestHandler, onUnNestHandler, backButton, committedStack, currentStackId]);
|
|
104
|
+
|
|
105
|
+
const manageFocus = event => {
|
|
106
|
+
const triggeredByKeyboard = event.nativeEvent.detail === 0;
|
|
107
|
+
|
|
108
|
+
if (triggeredByKeyboard) {
|
|
109
|
+
containerRef.current && containerRef.current.focus();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return jsx("div", {
|
|
114
|
+
"data-testid": testId,
|
|
115
|
+
css: {
|
|
116
|
+
position: 'relative',
|
|
117
|
+
height: '100%',
|
|
118
|
+
outline: 'none'
|
|
119
|
+
},
|
|
120
|
+
ref: containerRef,
|
|
121
|
+
tabIndex: -1,
|
|
122
|
+
onClick: manageFocus
|
|
123
|
+
}, jsx(ExitingPersistence, null, jsx(NestingMotion // Key is needed to have a unique react instance per stack name.
|
|
124
|
+
// This enables us to easily animate it in & out with exiting persistence.
|
|
125
|
+
, {
|
|
126
|
+
key: currentStackId,
|
|
127
|
+
enterFrom: transition === 'nesting' ? 'right' : 'left',
|
|
128
|
+
exitTo: transition === 'nesting' ? 'left' : 'right',
|
|
129
|
+
testId: testId && `${testId}-anim`
|
|
130
|
+
}, motion => jsx("div", _extends({
|
|
131
|
+
css: {
|
|
132
|
+
position: 'absolute',
|
|
133
|
+
width: '100%',
|
|
134
|
+
height: '100%',
|
|
135
|
+
display: 'flex',
|
|
136
|
+
flexDirection: 'column'
|
|
137
|
+
}
|
|
138
|
+
}, motion), jsx(NestedContext.Provider, {
|
|
139
|
+
// This provider is inside the NestingMotion to ensure it keeps a stale
|
|
140
|
+
// reference to the previous value.
|
|
141
|
+
value: context
|
|
142
|
+
}, jsx(NestingItem, {
|
|
143
|
+
title: "",
|
|
144
|
+
id: ROOT_ID
|
|
145
|
+
}, children))))));
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default NestableNavigationContent;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import { easeOut, SlideIn } from '@atlaskit/motion';
|
|
4
|
+
export const NestingMotion = props => {
|
|
5
|
+
const {
|
|
6
|
+
children,
|
|
7
|
+
enterFrom,
|
|
8
|
+
exitTo,
|
|
9
|
+
testId
|
|
10
|
+
} = props;
|
|
11
|
+
return jsx(SlideIn, {
|
|
12
|
+
exitTo: exitTo,
|
|
13
|
+
enterFrom: enterFrom,
|
|
14
|
+
animationTimingFunction: _ => easeOut
|
|
15
|
+
}, (innerProps, direction) => children({
|
|
16
|
+
'data-enter-from': enterFrom,
|
|
17
|
+
'data-exit-to': exitTo,
|
|
18
|
+
'data-testid': testId && `${testId}-${direction}`,
|
|
19
|
+
...innerProps
|
|
20
|
+
}));
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function (_) {}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
|
|
3
|
+
/** @jsx jsx */
|
|
4
|
+
import React, { Fragment, useCallback, useMemo, useState } from 'react';
|
|
5
|
+
import { jsx } from '@emotion/core';
|
|
6
|
+
import RightArrow from '@atlaskit/icon/glyph/arrow-right-circle';
|
|
7
|
+
import { N10 } from '@atlaskit/theme/colors';
|
|
8
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
9
|
+
import { token } from '@atlaskit/tokens';
|
|
10
|
+
import { overrideStyleFunction } from '../../common/styles';
|
|
11
|
+
import { ButtonItem, CustomItem, NavigationContent } from '../index';
|
|
12
|
+
import { ROOT_ID } from '../NestableNavigationContent';
|
|
13
|
+
import { NestedContext, useNestedContext } from '../NestableNavigationContent/context';
|
|
14
|
+
import { nestingItemStyle } from './styles';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* NestingItem will render itself differently depending in what context it is rendered in.
|
|
18
|
+
* When not open - it will render itself as an item.
|
|
19
|
+
* When open - it will render its children.
|
|
20
|
+
*/
|
|
21
|
+
const NestingItem = props => {
|
|
22
|
+
const {
|
|
23
|
+
children,
|
|
24
|
+
iconAfter,
|
|
25
|
+
title,
|
|
26
|
+
onClick,
|
|
27
|
+
cssFn,
|
|
28
|
+
isSelected,
|
|
29
|
+
id,
|
|
30
|
+
component,
|
|
31
|
+
testId,
|
|
32
|
+
...rest
|
|
33
|
+
} = props;
|
|
34
|
+
const {
|
|
35
|
+
currentStackId,
|
|
36
|
+
onNest,
|
|
37
|
+
onUnNest,
|
|
38
|
+
backButton: contextualBackButton,
|
|
39
|
+
stack
|
|
40
|
+
} = useNestedContext();
|
|
41
|
+
const mergedStyles = overrideStyleFunction(nestingItemStyle, cssFn);
|
|
42
|
+
const [isInteracted, setIsInteracted] = useState(false);
|
|
43
|
+
const backButton = props.overrides && props.overrides.GoBackItem && props.overrides.GoBackItem.render && props.overrides.GoBackItem.render({
|
|
44
|
+
onClick: onUnNest,
|
|
45
|
+
testId: testId && `${testId}--go-back-item`
|
|
46
|
+
}) || contextualBackButton;
|
|
47
|
+
const context = useMemo(() => ({
|
|
48
|
+
stack,
|
|
49
|
+
currentStackId,
|
|
50
|
+
onNest,
|
|
51
|
+
onUnNest,
|
|
52
|
+
backButton,
|
|
53
|
+
parentId: id
|
|
54
|
+
}), [onNest, onUnNest, backButton, stack, id, currentStackId]);
|
|
55
|
+
|
|
56
|
+
const isNormalClick = e => !(e.button || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
57
|
+
/**
|
|
58
|
+
* We want both the on nest handler and the onclick handler to be called.
|
|
59
|
+
* We create a wrapper function to call both.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
const onClickHandler = useCallback(e => {
|
|
64
|
+
if (isInteracted) {
|
|
65
|
+
// We return early if this has been interacted with because its assumed
|
|
66
|
+
// this will be already exiting - so we don't want to double up the click.
|
|
67
|
+
return;
|
|
68
|
+
} // Avoid a nesting transition if a modifier key is detected during click.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if (isNormalClick(e)) {
|
|
72
|
+
setIsInteracted(true);
|
|
73
|
+
onNest(id);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
onClick && onClick(e);
|
|
77
|
+
}, [isInteracted, onClick, onNest, id]);
|
|
78
|
+
|
|
79
|
+
if (currentStackId === id) {
|
|
80
|
+
return jsx(NestedContext.Provider, {
|
|
81
|
+
value: context
|
|
82
|
+
}, stack.length >= 1 && jsx("div", {
|
|
83
|
+
css: {
|
|
84
|
+
marginLeft: gridSize(),
|
|
85
|
+
marginRight: gridSize(),
|
|
86
|
+
// This padding bottom needs to match the section margin inside @atlaskit/menu.
|
|
87
|
+
paddingTop: gridSize() * 0.75,
|
|
88
|
+
paddingBottom: gridSize() * 0.75
|
|
89
|
+
}
|
|
90
|
+
}, backButton), jsx(NavigationContent, {
|
|
91
|
+
testId: testId,
|
|
92
|
+
showTopScrollIndicator: stack.length >= 1
|
|
93
|
+
}, children));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if ([ROOT_ID, ...stack].includes(id)) {
|
|
97
|
+
return children;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const componentProps = {
|
|
101
|
+
iconAfter: jsx(Fragment, null, iconAfter ? jsx("span", {
|
|
102
|
+
"data-custom-icon": true
|
|
103
|
+
}, iconAfter) : null, jsx("span", {
|
|
104
|
+
"data-right-arrow": true
|
|
105
|
+
}, jsx(RightArrow, {
|
|
106
|
+
testId: testId && `${testId}--item--right-arrow`,
|
|
107
|
+
secondaryColor: token('color.background.default', N10),
|
|
108
|
+
label: ""
|
|
109
|
+
}))),
|
|
110
|
+
onClick: onClickHandler,
|
|
111
|
+
isSelected: isSelected || isInteracted,
|
|
112
|
+
testId: testId && `${testId}--item`,
|
|
113
|
+
...rest,
|
|
114
|
+
children: title,
|
|
115
|
+
cssFn: mergedStyles
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (component) {
|
|
119
|
+
return jsx(CustomItem, _extends({}, componentProps, {
|
|
120
|
+
//@ts-expect-error TODO Fix legit TypeScript 3.9.6 improved inference error
|
|
121
|
+
component: component
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return jsx(ButtonItem, componentProps);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export default NestingItem;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// exposed for testing purposes
|
|
2
|
+
export const enabledCSS = {
|
|
3
|
+
['&:hover [data-custom-icon]']: {
|
|
4
|
+
display: 'none'
|
|
5
|
+
},
|
|
6
|
+
['&:active [data-custom-icon]']: {
|
|
7
|
+
display: 'none'
|
|
8
|
+
},
|
|
9
|
+
['&:focus [data-custom-icon]']: {
|
|
10
|
+
display: 'none'
|
|
11
|
+
},
|
|
12
|
+
['& [data-custom-icon]']: {
|
|
13
|
+
display: 'inherit'
|
|
14
|
+
},
|
|
15
|
+
['&:hover [data-right-arrow]']: {
|
|
16
|
+
display: 'inherit'
|
|
17
|
+
},
|
|
18
|
+
['&:active [data-right-arrow]']: {
|
|
19
|
+
display: 'inherit'
|
|
20
|
+
},
|
|
21
|
+
['&:focus [data-right-arrow]']: {
|
|
22
|
+
display: 'inherit'
|
|
23
|
+
},
|
|
24
|
+
['& [data-right-arrow]']: {
|
|
25
|
+
display: 'none'
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const disabledCSS = {
|
|
29
|
+
['[data-item-elem-after]']: {
|
|
30
|
+
opacity: 0
|
|
31
|
+
},
|
|
32
|
+
['& [data-right-arrow]']: {
|
|
33
|
+
display: 'none'
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
export const nestingItemStyle = state => {
|
|
37
|
+
return { ...(state.isDisabled ? disabledCSS : enabledCSS)
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { HeadingItem as MenuHeadingItem } from '@atlaskit/menu';
|
|
4
|
+
import { overrideStyleFunction, sectionHeaderStyle } from '../../common/styles';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
|
|
7
|
+
const HeadingItem = props => {
|
|
8
|
+
const {
|
|
9
|
+
shouldRender
|
|
10
|
+
} = useShouldNestedElementRender();
|
|
11
|
+
|
|
12
|
+
if (!shouldRender) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const cssFn = overrideStyleFunction(sectionHeaderStyle, props.cssFn);
|
|
17
|
+
return /*#__PURE__*/React.createElement(MenuHeadingItem, _extends({}, props, {
|
|
18
|
+
cssFn: cssFn
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default HeadingItem;
|