@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,78 @@
|
|
|
1
|
+
import { B400, B50, N10, N30, N500 } from '@atlaskit/theme/colors';
|
|
2
|
+
import { borderRadius as borderRadiusFn, gridSize as gridSizeFn } from '@atlaskit/theme/constants';
|
|
3
|
+
import { token } from '@atlaskit/tokens';
|
|
4
|
+
const gridSize = gridSizeFn();
|
|
5
|
+
const borderRadius = borderRadiusFn();
|
|
6
|
+
const itemIconSize = gridSize * 3;
|
|
7
|
+
const leftIconRightSpacing = gridSize * 2;
|
|
8
|
+
export const ITEM_SIDE_PADDING = gridSize * 1.25;
|
|
9
|
+
/**
|
|
10
|
+
* Allows chaining of style functions on top of base style functions
|
|
11
|
+
* @param baseStyle the base custom cssFn
|
|
12
|
+
* @param newStyle a new cssFn to be applied after the base style
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export const overrideStyleFunction = (baseStyle, newStyle = () => ({})) => {
|
|
16
|
+
return state => {
|
|
17
|
+
return [baseStyle(state), newStyle(state)];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const defaultStyles = {
|
|
21
|
+
'&:hover': {
|
|
22
|
+
color: token('color.text.mediumEmphasis', N500),
|
|
23
|
+
backgroundColor: token('color.background.transparentNeutral.hover', N30)
|
|
24
|
+
},
|
|
25
|
+
'&:active': {
|
|
26
|
+
color: token('color.text.mediumEmphasis', B400),
|
|
27
|
+
backgroundColor: token('color.background.transparentNeutral.pressed', B50)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const selectedStyles = {
|
|
31
|
+
backgroundColor: token('color.background.selected.resting', N30),
|
|
32
|
+
color: token('color.text.selected', B400),
|
|
33
|
+
':visited': {
|
|
34
|
+
color: token('color.text.selected', B400)
|
|
35
|
+
},
|
|
36
|
+
'&:hover': {
|
|
37
|
+
backgroundColor: token('color.background.selected.hover', N30),
|
|
38
|
+
color: token('color.text.selected', N500)
|
|
39
|
+
},
|
|
40
|
+
'&:active': {
|
|
41
|
+
backgroundColor: token('color.background.selected.pressed', B50),
|
|
42
|
+
color: token('color.text.selected', B400)
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export const baseSideNavItemStyle = ({
|
|
46
|
+
isSelected,
|
|
47
|
+
isDisabled
|
|
48
|
+
}) => {
|
|
49
|
+
return {
|
|
50
|
+
// This padding is set to ensure that the center of the left icon
|
|
51
|
+
// is approximately center aligned with the horizontal app switcher.
|
|
52
|
+
padding: `${gridSize}px ${ITEM_SIDE_PADDING}px`,
|
|
53
|
+
borderRadius,
|
|
54
|
+
// -- TODO: DELETE THESE COLOR OVERRIDES WHEN CLEANING UP FALLBACK THEMING --
|
|
55
|
+
// Menu and side navigation are now color aligned so they do not need this!
|
|
56
|
+
// See: https://product-fabric.atlassian.net/browse/DSP-1684
|
|
57
|
+
backgroundColor: token('color.background.default', N10),
|
|
58
|
+
...(!isDisabled && !isSelected && defaultStyles),
|
|
59
|
+
...(!isDisabled && isSelected && selectedStyles),
|
|
60
|
+
// -- END TODO --------------------------------------------------------------
|
|
61
|
+
['& [data-item-elem-before]']: {
|
|
62
|
+
// TODO: Can this be moved into menu?
|
|
63
|
+
// center align icons with app-switcher regardless of size
|
|
64
|
+
display: 'flex',
|
|
65
|
+
height: itemIconSize,
|
|
66
|
+
width: itemIconSize,
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
justifyContent: 'center',
|
|
69
|
+
marginRight: leftIconRightSpacing
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
export const sectionHeaderStyle = () => {
|
|
74
|
+
return {
|
|
75
|
+
paddingLeft: `${ITEM_SIDE_PADDING}px`,
|
|
76
|
+
paddingRight: `${ITEM_SIDE_PADDING}px`
|
|
77
|
+
};
|
|
78
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { N500 } from '@atlaskit/theme/colors';
|
|
4
|
+
import { token } from '@atlaskit/tokens';
|
|
5
|
+
import { overrideStyleFunction } from '../../common/styles';
|
|
6
|
+
import { CustomItem } from '../Item';
|
|
7
|
+
|
|
8
|
+
const Container = props => {
|
|
9
|
+
return /*#__PURE__*/React.createElement("div", props);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const Footer = props => {
|
|
13
|
+
const cssFn = overrideStyleFunction(() => ({
|
|
14
|
+
userSelect: 'auto',
|
|
15
|
+
div: {
|
|
16
|
+
display: 'block',
|
|
17
|
+
textAlign: 'center',
|
|
18
|
+
minHeight: '24px',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
width: '100%'
|
|
21
|
+
},
|
|
22
|
+
['[data-item-elem-before]']: {
|
|
23
|
+
marginRight: 0,
|
|
24
|
+
marginBottom: '8px',
|
|
25
|
+
display: 'inline-block'
|
|
26
|
+
},
|
|
27
|
+
['[data-item-title]']: {
|
|
28
|
+
textAlign: 'center',
|
|
29
|
+
fontSize: 12
|
|
30
|
+
},
|
|
31
|
+
['[data-item-description]']: {
|
|
32
|
+
textAlign: 'center',
|
|
33
|
+
display: 'inline-block',
|
|
34
|
+
margin: '6px'
|
|
35
|
+
},
|
|
36
|
+
// Will look interactive if the `component` is anything other than a div.
|
|
37
|
+
'div&:hover': {
|
|
38
|
+
backgroundColor: 'transparent',
|
|
39
|
+
cursor: 'default'
|
|
40
|
+
},
|
|
41
|
+
'div&:active': {
|
|
42
|
+
backgroundColor: 'transparent',
|
|
43
|
+
color: token('color.text.mediumEmphasis', N500)
|
|
44
|
+
}
|
|
45
|
+
}), props.cssFn);
|
|
46
|
+
return /*#__PURE__*/React.createElement(CustomItem, _extends({}, props, {
|
|
47
|
+
component: props.component || Container,
|
|
48
|
+
cssFn: cssFn
|
|
49
|
+
}));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default Footer;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import { N500 } from '@atlaskit/theme/colors';
|
|
4
|
+
import { headingSizes } from '@atlaskit/theme/typography';
|
|
5
|
+
import { token } from '@atlaskit/tokens';
|
|
6
|
+
import { overrideStyleFunction } from '../../common/styles';
|
|
7
|
+
import { CustomItem } from '../Item';
|
|
8
|
+
|
|
9
|
+
const Container = props => {
|
|
10
|
+
return /*#__PURE__*/React.createElement("div", props);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Header = /*#__PURE__*/forwardRef((props, ref) => {
|
|
14
|
+
const cssFn = overrideStyleFunction(() => ({
|
|
15
|
+
userSelect: 'auto',
|
|
16
|
+
['[data-item-title]']: {
|
|
17
|
+
fontSize: headingSizes.h400.size,
|
|
18
|
+
letterSpacing: '-0.003em',
|
|
19
|
+
fontWeight: 600,
|
|
20
|
+
color: token('color.text.highEmphasis', N500)
|
|
21
|
+
},
|
|
22
|
+
// Will look interactive if the `component` is anything other than a div.
|
|
23
|
+
'div&:hover': {
|
|
24
|
+
backgroundColor: 'transparent',
|
|
25
|
+
cursor: 'default'
|
|
26
|
+
},
|
|
27
|
+
'div&:active': {
|
|
28
|
+
backgroundColor: 'transparent',
|
|
29
|
+
color: token('color.text.highEmphasis', N500)
|
|
30
|
+
}
|
|
31
|
+
}), props.cssFn);
|
|
32
|
+
return /*#__PURE__*/React.createElement(CustomItem, _extends({}, props, {
|
|
33
|
+
ref: ref,
|
|
34
|
+
component: props.component || Container,
|
|
35
|
+
cssFn: cssFn,
|
|
36
|
+
overrides: {
|
|
37
|
+
Title: {
|
|
38
|
+
render: (_, {
|
|
39
|
+
children,
|
|
40
|
+
...props
|
|
41
|
+
}) => /*#__PURE__*/React.createElement("h2", props, children)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
export default Header;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import { ButtonItem as Button } from '@atlaskit/menu';
|
|
4
|
+
import { baseSideNavItemStyle, overrideStyleFunction } from '../../common/styles';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
const ButtonItem = /*#__PURE__*/forwardRef( // Type needed on props to extract types with extract react types.
|
|
7
|
+
({
|
|
8
|
+
cssFn,
|
|
9
|
+
...rest
|
|
10
|
+
}, ref) => {
|
|
11
|
+
const {
|
|
12
|
+
shouldRender
|
|
13
|
+
} = useShouldNestedElementRender();
|
|
14
|
+
|
|
15
|
+
if (!shouldRender) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const cssOverride = overrideStyleFunction(baseSideNavItemStyle, cssFn);
|
|
20
|
+
return /*#__PURE__*/React.createElement(Button, _extends({
|
|
21
|
+
ref: ref,
|
|
22
|
+
cssFn: cssOverride
|
|
23
|
+
}, rest));
|
|
24
|
+
});
|
|
25
|
+
export default ButtonItem;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import { CustomItem as Custom } from '@atlaskit/menu';
|
|
4
|
+
import { baseSideNavItemStyle, overrideStyleFunction } from '../../common/styles';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Used to support any custom items needed by products alongside the Header and Footer patterns.
|
|
9
|
+
* Specific implementation of headers and footers are provided in the examples folder.
|
|
10
|
+
*/
|
|
11
|
+
const CustomItem = /*#__PURE__*/forwardRef( // Type needed on props to extract types with extract react types.
|
|
12
|
+
({
|
|
13
|
+
cssFn,
|
|
14
|
+
...rest
|
|
15
|
+
}, ref) => {
|
|
16
|
+
const {
|
|
17
|
+
shouldRender
|
|
18
|
+
} = useShouldNestedElementRender();
|
|
19
|
+
|
|
20
|
+
if (!shouldRender) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const cssOverride = overrideStyleFunction(baseSideNavItemStyle, cssFn);
|
|
25
|
+
return /*#__PURE__*/React.createElement(Custom, _extends({
|
|
26
|
+
ref: ref,
|
|
27
|
+
cssFn: cssOverride
|
|
28
|
+
}, rest));
|
|
29
|
+
} // Dirty hack to get generics working with forward ref [2/2]
|
|
30
|
+
);
|
|
31
|
+
export default CustomItem;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { forwardRef, useCallback, useState } from 'react';
|
|
3
|
+
import LeftArrow from '@atlaskit/icon/glyph/arrow-left-circle';
|
|
4
|
+
import { N10 } from '@atlaskit/theme/colors';
|
|
5
|
+
import { token } from '@atlaskit/tokens';
|
|
6
|
+
import ButtonItem from './button-item';
|
|
7
|
+
const GoBackItem = /*#__PURE__*/forwardRef(({
|
|
8
|
+
cssFn,
|
|
9
|
+
iconBefore = /*#__PURE__*/React.createElement(LeftArrow, {
|
|
10
|
+
secondaryColor: token('color.background.default', N10),
|
|
11
|
+
label: ""
|
|
12
|
+
}),
|
|
13
|
+
onClick,
|
|
14
|
+
isSelected,
|
|
15
|
+
...rest
|
|
16
|
+
}, ref) => {
|
|
17
|
+
const [isInteracted, setIsInteracted] = useState(false);
|
|
18
|
+
const onClickHandler = useCallback(e => {
|
|
19
|
+
if (isInteracted) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setIsInteracted(true);
|
|
24
|
+
onClick && onClick(e);
|
|
25
|
+
}, [onClick, isInteracted]);
|
|
26
|
+
return /*#__PURE__*/React.createElement(ButtonItem, _extends({
|
|
27
|
+
isSelected: isSelected || isInteracted,
|
|
28
|
+
cssFn: cssFn,
|
|
29
|
+
iconBefore: iconBefore,
|
|
30
|
+
onClick: onClickHandler,
|
|
31
|
+
ref: ref
|
|
32
|
+
}, rest));
|
|
33
|
+
});
|
|
34
|
+
export default GoBackItem;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as ButtonItem } from './button-item';
|
|
2
|
+
export { default as CustomItem } from './custom-item';
|
|
3
|
+
export { default as GoBackItem } from './go-back-item';
|
|
4
|
+
export { default as LinkItem } from './link-item';
|
|
5
|
+
export { default as SkeletonItem } from './skeleton-item';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import { LinkItem as Link } from '@atlaskit/menu';
|
|
4
|
+
import { baseSideNavItemStyle, overrideStyleFunction } from '../../common/styles';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
const LinkItem = /*#__PURE__*/forwardRef( // Type needed on props to extract types with extract react types.
|
|
7
|
+
({
|
|
8
|
+
cssFn,
|
|
9
|
+
...rest
|
|
10
|
+
}, ref) => {
|
|
11
|
+
const {
|
|
12
|
+
shouldRender
|
|
13
|
+
} = useShouldNestedElementRender();
|
|
14
|
+
|
|
15
|
+
if (!shouldRender) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const cssOverride = overrideStyleFunction(baseSideNavItemStyle, cssFn);
|
|
20
|
+
return /*#__PURE__*/React.createElement(Link, _extends({
|
|
21
|
+
ref: ref,
|
|
22
|
+
cssFn: cssOverride
|
|
23
|
+
}, rest));
|
|
24
|
+
});
|
|
25
|
+
export default LinkItem;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { SkeletonItem as SkelItem } from '@atlaskit/menu';
|
|
4
|
+
import { ITEM_SIDE_PADDING } from '../../common/styles';
|
|
5
|
+
import { useShouldNestedElementRender } from '../NestableNavigationContent/context';
|
|
6
|
+
|
|
7
|
+
const SkeletonItem = props => {
|
|
8
|
+
const {
|
|
9
|
+
shouldRender
|
|
10
|
+
} = useShouldNestedElementRender();
|
|
11
|
+
|
|
12
|
+
if (!shouldRender) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return /*#__PURE__*/React.createElement(SkelItem, _extends({
|
|
17
|
+
cssFn: () => ({
|
|
18
|
+
paddingLeft: ITEM_SIDE_PADDING,
|
|
19
|
+
paddingRight: ITEM_SIDE_PADDING,
|
|
20
|
+
'&&::before': {
|
|
21
|
+
// This doubles up & to get a higher specificity as well as to not overwite the base styles.
|
|
22
|
+
marginRight: 18
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
}, props));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default SkeletonItem;
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
const LoadingItems = ({
|
|
9
|
+
children,
|
|
10
|
+
isLoading,
|
|
11
|
+
fallback,
|
|
12
|
+
testId
|
|
13
|
+
}) => {
|
|
14
|
+
const {
|
|
15
|
+
shouldRender
|
|
16
|
+
} = useShouldNestedElementRender();
|
|
17
|
+
|
|
18
|
+
if (!shouldRender) {
|
|
19
|
+
return children;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return jsx(ExitingPersistence, null, jsx(FadeIn, {
|
|
23
|
+
key: `loading-section-${isLoading}`,
|
|
24
|
+
duration: mediumDurationMs
|
|
25
|
+
}, (motion, state) => jsx("span", _extends({}, motion, {
|
|
26
|
+
"data-testid": testId && `${testId}--${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
|
+
export default LoadingItems;
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
const NavigationContent = /*#__PURE__*/forwardRef((props, ref) => {
|
|
8
|
+
const {
|
|
9
|
+
showTopScrollIndicator,
|
|
10
|
+
children
|
|
11
|
+
} = props;
|
|
12
|
+
const {
|
|
13
|
+
shouldRender
|
|
14
|
+
} = useShouldNestedElementRender();
|
|
15
|
+
const scrollbar = useScrollbarWidth();
|
|
16
|
+
|
|
17
|
+
if (!shouldRender) {
|
|
18
|
+
return children;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return jsx("div", {
|
|
22
|
+
ref: ref,
|
|
23
|
+
css: outerContainerCSS({
|
|
24
|
+
showTopScrollIndicator,
|
|
25
|
+
scrollbarWidth: scrollbar.width
|
|
26
|
+
})
|
|
27
|
+
}, jsx("div", {
|
|
28
|
+
ref: scrollbar.ref,
|
|
29
|
+
css: innerContainerCSS({
|
|
30
|
+
showTopScrollIndicator
|
|
31
|
+
})
|
|
32
|
+
}, jsx("div", {
|
|
33
|
+
css: containerCSS({
|
|
34
|
+
showTopScrollIndicator
|
|
35
|
+
})
|
|
36
|
+
}, children)));
|
|
37
|
+
});
|
|
38
|
+
export default NavigationContent;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { N10, N30 } from '@atlaskit/theme/colors';
|
|
2
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
3
|
+
import { headingSizes } from '@atlaskit/theme/typography';
|
|
4
|
+
import { token } from '@atlaskit/tokens';
|
|
5
|
+
import { VAR_SCROLL_INDICATOR_COLOR, VAR_SEPARATOR_COLOR } from '../../common/constants';
|
|
6
|
+
const scrollIndicatorMaskZIndex = 2;
|
|
7
|
+
const scrollIndicatorZIndex = 1;
|
|
8
|
+
const scrollIndicatorHeight = 2;
|
|
9
|
+
const scrollIndicatorBorderRadius = 1;
|
|
10
|
+
const containerPadding = gridSize();
|
|
11
|
+
const itemHeadingTopMargin = containerPadding * 2.5;
|
|
12
|
+
const itemHeadingBottomMargin = containerPadding * 0.75; // Skeleton content is slightly shorter than the real content.
|
|
13
|
+
// Because of that we slightly increase the top margin to offset this so the
|
|
14
|
+
// containing size both real and skeleton always equal approx 30px.
|
|
15
|
+
|
|
16
|
+
const itemHeadingContentHeight = headingSizes.h100.lineHeight;
|
|
17
|
+
const skeletonHeadingHeight = containerPadding;
|
|
18
|
+
const skeletonHeadingMarginOffset = 3;
|
|
19
|
+
const skeletonHeadingTopMargin = itemHeadingTopMargin + (itemHeadingContentHeight - skeletonHeadingHeight) - skeletonHeadingMarginOffset; // We want to move the entire body up by 3px without affecting the height of the skeleton container.
|
|
20
|
+
|
|
21
|
+
const skeletonHeadingBottomMargin = itemHeadingBottomMargin + skeletonHeadingMarginOffset;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This outer container css contains the "real" scroll indicators which are
|
|
25
|
+
* always rendered to the screen.
|
|
26
|
+
* They are "conditionally" shown from the users perspective using the inner container CSS
|
|
27
|
+
* which has other pseudo elements which "mask" the "real" scroll indicators.
|
|
28
|
+
*/
|
|
29
|
+
export const outerContainerCSS = opts => ({
|
|
30
|
+
// Flex is needed to ensure the overflow indicators are positioned correctly.
|
|
31
|
+
display: 'flex',
|
|
32
|
+
height: '100%',
|
|
33
|
+
overflow: 'hidden',
|
|
34
|
+
position: 'relative',
|
|
35
|
+
'&::before': {
|
|
36
|
+
content: "''",
|
|
37
|
+
display: 'block',
|
|
38
|
+
left: containerPadding,
|
|
39
|
+
right: containerPadding + opts.scrollbarWidth,
|
|
40
|
+
height: scrollIndicatorHeight,
|
|
41
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
42
|
+
backgroundColor: `var(${VAR_SEPARATOR_COLOR}, ${token('color.border.neutral', N30)})`,
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
zIndex: scrollIndicatorZIndex
|
|
45
|
+
},
|
|
46
|
+
'&::after': {
|
|
47
|
+
content: "''",
|
|
48
|
+
position: 'absolute',
|
|
49
|
+
display: 'block',
|
|
50
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
51
|
+
flexShrink: 0,
|
|
52
|
+
height: scrollIndicatorHeight,
|
|
53
|
+
left: containerPadding,
|
|
54
|
+
right: containerPadding + opts.scrollbarWidth,
|
|
55
|
+
bottom: 0,
|
|
56
|
+
zIndex: scrollIndicatorZIndex,
|
|
57
|
+
backgroundColor: `var(${VAR_SEPARATOR_COLOR}, ${token('color.border.neutral', N30)})`
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* This inner container css contains the "mask" logic for the scroll indicators.
|
|
62
|
+
* Essentially they cover (mask) the "real" scroll indicators when the user is scrolled
|
|
63
|
+
* to the top or bottom of the container.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
export const innerContainerCSS = opts => ({
|
|
67
|
+
display: 'flex',
|
|
68
|
+
overflow: 'auto',
|
|
69
|
+
width: '100%',
|
|
70
|
+
position: 'relative',
|
|
71
|
+
boxSizing: 'border-box',
|
|
72
|
+
flexDirection: 'column',
|
|
73
|
+
// This before pseudo element is works by being positioned at the top of this scrolling
|
|
74
|
+
// container - so when you scroll down it stops "masking" the actual scroll indicator.
|
|
75
|
+
...(!opts.showTopScrollIndicator && {
|
|
76
|
+
'&::before': {
|
|
77
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
78
|
+
content: "''",
|
|
79
|
+
left: 0,
|
|
80
|
+
right: 0,
|
|
81
|
+
height: scrollIndicatorHeight,
|
|
82
|
+
backgroundColor: `var(${VAR_SCROLL_INDICATOR_COLOR}, ${token('color.background.default', N10)})`,
|
|
83
|
+
position: 'absolute',
|
|
84
|
+
display: 'block',
|
|
85
|
+
zIndex: scrollIndicatorMaskZIndex
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
88
|
+
// This after pseudo element abuses being a flex child and pushes itself down to the
|
|
89
|
+
// very bottom of the container - doing so ends up "masking" the actual scroll indicator.
|
|
90
|
+
'&::after': {
|
|
91
|
+
borderRadius: scrollIndicatorBorderRadius,
|
|
92
|
+
content: "''",
|
|
93
|
+
display: 'block',
|
|
94
|
+
flexShrink: 0,
|
|
95
|
+
height: scrollIndicatorHeight,
|
|
96
|
+
// This is used to "push" the element to the bottom of the flex container.
|
|
97
|
+
marginTop: 'auto',
|
|
98
|
+
position: 'relative',
|
|
99
|
+
zIndex: scrollIndicatorMaskZIndex,
|
|
100
|
+
backgroundColor: `var(${VAR_SCROLL_INDICATOR_COLOR}, ${token('color.background.default', N10)})`
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
export const containerCSS = opts => ({
|
|
104
|
+
// When the scroll indicator is always shown we need to add some padding
|
|
105
|
+
// so the spacing between matches what it would be if the indicator was a "block" element.
|
|
106
|
+
// We use margin here so any child absolutely positioned elements are positioned correctly.
|
|
107
|
+
marginTop: opts.showTopScrollIndicator ? scrollIndicatorHeight : 0,
|
|
108
|
+
marginLeft: containerPadding,
|
|
109
|
+
marginRight: containerPadding,
|
|
110
|
+
// Enables child absolutely positioned elements to be positioned relative to this element.
|
|
111
|
+
position: 'relative',
|
|
112
|
+
'& [data-ds--menu--heading-item]': {
|
|
113
|
+
marginTop: itemHeadingTopMargin,
|
|
114
|
+
marginBottom: itemHeadingBottomMargin
|
|
115
|
+
},
|
|
116
|
+
'& [data-ds--menu--skeleton-heading-item]': {
|
|
117
|
+
marginTop: skeletonHeadingTopMargin,
|
|
118
|
+
marginBottom: skeletonHeadingBottomMargin
|
|
119
|
+
}
|
|
120
|
+
});
|