akeneo-design-system 0.1.227 → 0.1.228
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/Avatar/Avatar.d.ts +1 -8
- package/lib/components/Avatar/Avatar.js +1 -1
- package/lib/components/Avatar/Avatar.js.map +1 -1
- package/lib/components/Avatar/Avatars.d.ts +2 -1
- package/lib/components/Avatar/Avatars.js +19 -3
- package/lib/components/Avatar/Avatars.js.map +1 -1
- package/lib/components/Avatar/types.d.ts +11 -0
- package/lib/components/Avatar/types.js +3 -0
- package/lib/components/Avatar/types.js.map +1 -0
- package/lib/components/Dropdown/Dropdown.d.ts +1 -0
- package/lib/components/Dropdown/Surtitle/Surtitle.d.ts +1 -0
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.d.ts +2 -0
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.js +28 -40
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.js.map +1 -1
- package/package.json +1 -1
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-content-with-collapse-component-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-content-without-padding-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-scrollable-content-correctly-1-snap.png +0 -0
- package/src/components/Avatar/Avatar.stories.mdx +1 -1
- package/src/components/Avatar/Avatar.tsx +2 -32
- package/src/components/Avatar/Avatars.tsx +27 -5
- package/src/components/Avatar/Avatars.unit.tsx +22 -2
- package/src/components/Avatar/types.ts +34 -0
- package/src/components/Dropdown/Surtitle/Surtitle.tsx +1 -1
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.stories.mdx +97 -25
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.tsx +58 -66
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.unit.tsx +3 -3
@@ -1,12 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import {
|
3
|
-
declare type AvatarProps = Override<React.HTMLAttributes<HTMLSpanElement>, {
|
4
|
-
username: string;
|
5
|
-
firstName: string;
|
6
|
-
lastName: string;
|
7
|
-
avatarUrl?: string;
|
8
|
-
size?: 'default' | 'big';
|
9
|
-
}>;
|
2
|
+
import { AvatarProps } from './types';
|
10
3
|
declare const Avatar: ({ username, firstName, lastName, avatarUrl, size, ...rest }: AvatarProps) => React.JSX.Element;
|
11
4
|
export { Avatar };
|
12
5
|
export type { AvatarProps };
|
@@ -62,7 +62,7 @@ var Avatar = function (_a) {
|
|
62
62
|
var username = _a.username, firstName = _a.firstName, lastName = _a.lastName, avatarUrl = _a.avatarUrl, _b = _a.size, size = _b === void 0 ? 'default' : _b, rest = __rest(_a, ["username", "firstName", "lastName", "avatarUrl", "size"]);
|
63
63
|
var theme = (0, hooks_1.useTheme)();
|
64
64
|
var fallback = (firstName.trim().charAt(0) + lastName.trim().charAt(0) || username.substring(0, 2)).toLocaleUpperCase();
|
65
|
-
var title = (firstName + " " + lastName).trim() || username;
|
65
|
+
var title = ((firstName || '') + " " + (lastName || '')).trim() || username;
|
66
66
|
var backgroundColor = (0, react_1.useMemo)(function () {
|
67
67
|
var colorId = username.split('').reduce(function (s, l) { return s + l.charCodeAt(0); }, 0);
|
68
68
|
var colors = [
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../src/components/Avatar/Avatar.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAqC;AACrC,qEAA8C;AAC9C,qCAAqC;
|
1
|
+
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../src/components/Avatar/Avatar.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAqC;AACrC,qEAA8C;AAC9C,qCAAqC;AACrC,qCAAwD;AAGxD,IAAM,eAAe,GAAG,2BAAM,CAAC,IAAI,2RAAiC,MAChE,EAeK,uCAEE,EAAiB,gKAMhB,EAAgD,KAC3D,KAxBG,UAAC,EAAM;QAAL,IAAI,UAAA;IACN,OAAA,IAAI,KAAK,SAAS;QAChB,CAAC,KAAC,uBAAG,2NAAA,uJAMF,KACH,CAAC,KAAC,uBAAG,+NAAA,2JAMF,IAAA;AAdL,CAcK,EAEE,IAAA,gBAAQ,EAAC,OAAO,CAAC,EAMhB,UAAC,EAAS;QAAR,OAAO,aAAA;IAAM,OAAA,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAAjC,CAAiC,CAC3D,CAAC;AAEF,IAAM,MAAM,GAAG,UAAC,EAAkF;IAAjF,IAAA,QAAQ,cAAA,EAAE,SAAS,eAAA,EAAE,QAAQ,cAAA,EAAE,SAAS,eAAA,EAAE,YAAgB,EAAhB,IAAI,mBAAG,SAAS,KAAA,EAAK,IAAI,cAApE,0DAAqE,CAAD;IAClF,IAAM,KAAK,GAAG,IAAA,gBAAQ,GAAE,CAAC;IAEzB,IAAM,QAAQ,GAAG,CACf,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CACnF,CAAC,iBAAiB,EAAE,CAAC;IACtB,IAAM,KAAK,GAAG,CAAA,CAAG,SAAS,IAAI,EAAE,WAAI,QAAQ,IAAI,EAAE,CAAE,CAAA,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC;IAExE,IAAM,eAAe,GAAG,IAAA,eAAO,EAAC;QAC9B,IAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAS,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAnB,CAAmB,EAAE,CAAC,CAAC,CAAC;QACpF,IAAM,MAAM,GAAG;YACb,KAAK,CAAC,gBAAgB,CAAC,QAAQ;YAC/B,KAAK,CAAC,gBAAgB,CAAC,WAAW;YAClC,KAAK,CAAC,gBAAgB,CAAC,cAAc;YACrC,KAAK,CAAC,gBAAgB,CAAC,aAAa;YACpC,KAAK,CAAC,gBAAgB,CAAC,OAAO;YAC9B,KAAK,CAAC,gBAAgB,CAAC,WAAW;YAClC,KAAK,CAAC,gBAAgB,CAAC,UAAU;YACjC,KAAK,CAAC,gBAAgB,CAAC,MAAM;YAC7B,KAAK,CAAC,gBAAgB,CAAC,WAAW;YAClC,KAAK,CAAC,gBAAgB,CAAC,SAAS;YAChC,KAAK,CAAC,gBAAgB,CAAC,SAAS;YAChC,KAAK,CAAC,gBAAgB,CAAC,YAAY;SACpC,CAAC;QAEF,OAAO,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtB,IAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,EAAC,eAAe,EAAE,SAAO,SAAS,MAAG,EAAC,CAAC,CAAC,CAAC,EAAC,eAAe,iBAAA,EAAC,CAAC;IAErF,OAAO,CACL,8BAAC,eAAe,aAAC,IAAI,EAAE,IAAI,IAAM,IAAI,IAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAC9D,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CACV,CACnB,CAAC;AACJ,CAAC,CAAC;AAEM,wBAAM"}
|
@@ -2,7 +2,8 @@ import React from 'react';
|
|
2
2
|
import { Override } from '../../shared';
|
3
3
|
declare type AvatarsProps = Override<React.HTMLAttributes<HTMLDivElement>, {
|
4
4
|
max: number;
|
5
|
+
maxTitle?: number;
|
5
6
|
}>;
|
6
|
-
declare const Avatars:
|
7
|
+
declare const Avatars: React.FC<AvatarsProps>;
|
7
8
|
export { Avatars };
|
8
9
|
export type { AvatarsProps };
|
@@ -53,14 +53,30 @@ var react_1 = __importStar(require("react"));
|
|
53
53
|
var styled_components_1 = __importDefault(require("styled-components"));
|
54
54
|
var theme_1 = require("../../theme");
|
55
55
|
var AvatarListContainer = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: flex;\n flex-direction: row-reverse;\n justify-content: flex-end;\n & > * {\n margin-right: -4px;\n position: relative;\n }\n"], ["\n display: flex;\n flex-direction: row-reverse;\n justify-content: flex-end;\n & > * {\n margin-right: -4px;\n position: relative;\n }\n"])));
|
56
|
-
var RemainingAvatar = styled_components_1.default.span(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 32px;\n width: 32px;\n
|
56
|
+
var RemainingAvatar = styled_components_1.default.span(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 32px;\n width: 32px;\n border: 1px solid ", ";\n line-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n border-radius: 32px;\n background-color: ", ";\n"], ["\n height: 32px;\n width: 32px;\n border: 1px solid ", ";\n line-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n border-radius: 32px;\n background-color: ", ";\n"])), (0, theme_1.getColor)('grey', 10), (0, theme_1.getColor)('white'));
|
57
57
|
var Avatars = function (_a) {
|
58
|
-
var max = _a.max, children = _a.children, rest = __rest(_a, ["max", "children"]);
|
58
|
+
var max = _a.max, _b = _a.maxTitle, maxTitle = _b === void 0 ? 10 : _b, children = _a.children, rest = __rest(_a, ["max", "maxTitle", "children"]);
|
59
59
|
var childrenArray = react_1.Children.toArray(children);
|
60
60
|
var displayedChildren = childrenArray.slice(0, max);
|
61
|
+
var remainingChildren = childrenArray.slice(max, childrenArray.length + 1);
|
61
62
|
var remainingChildrenCount = childrenArray.length - max;
|
62
63
|
var reverseChildren = displayedChildren.reverse();
|
63
|
-
|
64
|
+
var remainingUsersTitle = (0, react_1.useMemo)(function () {
|
65
|
+
var remainingNames = remainingChildren
|
66
|
+
.map(function (child) {
|
67
|
+
if (!react_1.default.isValidElement(child))
|
68
|
+
return;
|
69
|
+
var _a = child.props, firstName = _a.firstName, lastName = _a.lastName, username = _a.username;
|
70
|
+
return ((firstName || '') + " " + (lastName || '')).trim() || username;
|
71
|
+
})
|
72
|
+
.slice(0, maxTitle)
|
73
|
+
.join('\n');
|
74
|
+
if (remainingChildren.length > maxTitle) {
|
75
|
+
return remainingNames.concat('\n', '...');
|
76
|
+
}
|
77
|
+
return remainingNames;
|
78
|
+
}, [maxTitle, remainingChildren]);
|
79
|
+
return (react_1.default.createElement(AvatarListContainer, __assign({ title: rest.title || remainingUsersTitle }, rest),
|
64
80
|
remainingChildrenCount > 0 && react_1.default.createElement(RemainingAvatar, null,
|
65
81
|
"+",
|
66
82
|
remainingChildrenCount),
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Avatars.js","sourceRoot":"","sources":["../../../src/components/Avatar/Avatars.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
1
|
+
{"version":3,"file":"Avatars.js","sourceRoot":"","sources":["../../../src/components/Avatar/Avatars.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA+C;AAC/C,wEAAuC;AAEvC,qCAAwD;AAGxD,IAAM,mBAAmB,GAAG,2BAAM,CAAC,GAAG,yNAAkC,sJAQvE,IAAA,CAAC;AAEF,IAAM,eAAe,GAAG,2BAAM,CAAC,IAAI,sSAAA,yDAGb,EAAoB,iKAOpB,EAAiB,KACtC,KARqB,IAAA,gBAAQ,EAAC,MAAM,EAAE,EAAE,CAAC,EAOpB,IAAA,gBAAQ,EAAC,OAAO,CAAC,CACtC,CAAC;AAUF,IAAM,OAAO,GAA2B,UAAC,EAAuC;IAAtC,IAAA,GAAG,SAAA,EAAE,gBAAa,EAAb,QAAQ,mBAAG,EAAE,KAAA,EAAE,QAAQ,cAAA,EAAK,IAAI,cAAtC,+BAAuC,CAAD;IAC7E,IAAM,aAAa,GAAG,gBAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAM,iBAAiB,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,IAAM,iBAAiB,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAM,sBAAsB,GAAG,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC;IAC1D,IAAM,eAAe,GAAG,iBAAiB,CAAC,OAAO,EAAE,CAAC;IAEpD,IAAM,mBAAmB,GAAG,IAAA,eAAO,EAAC;QAClC,IAAM,cAAc,GAAG,iBAAiB;aACrC,GAAG,CAAC,UAAA,KAAK;YACR,IAAI,CAAC,eAAK,CAAC,cAAc,CAAc,KAAK,CAAC;gBAAE,OAAO;YAChD,IAAA,KAAkC,KAAK,CAAC,KAAK,EAA5C,SAAS,eAAA,EAAE,QAAQ,cAAA,EAAE,QAAQ,cAAe,CAAC;YAEpD,OAAO,CAAA,CAAG,SAAS,IAAI,EAAE,WAAI,QAAQ,IAAI,EAAE,CAAE,CAAA,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC;QACnE,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;aAClB,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,IAAI,iBAAiB,CAAC,MAAM,GAAG,QAAQ,EAAE;YACvC,OAAO,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SAC3C;QAED,OAAO,cAAc,CAAC;IACxB,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAElC,OAAO,CACL,8BAAC,mBAAmB,aAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,mBAAmB,IAAM,IAAI;QACpE,sBAAsB,GAAG,CAAC,IAAI,8BAAC,eAAe;;YAAG,sBAAsB,CAAmB;QAC1F,eAAe,CACI,CACvB,CAAC;AACJ,CAAC,CAAC;AAEM,0BAAO"}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { Override } from '../../shared';
|
2
|
+
import React from 'react';
|
3
|
+
export declare type User = {
|
4
|
+
username: string;
|
5
|
+
firstName: string;
|
6
|
+
lastName: string;
|
7
|
+
avatarUrl?: string;
|
8
|
+
};
|
9
|
+
export declare type AvatarProps = Override<React.HTMLAttributes<HTMLSpanElement>, User & {
|
10
|
+
size?: 'default' | 'big';
|
11
|
+
}>;
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/Avatar/types.ts"],"names":[],"mappings":""}
|
@@ -6,9 +6,11 @@ declare type SubNavigationPanelProps = {
|
|
6
6
|
close: () => void;
|
7
7
|
closeTitle?: string;
|
8
8
|
openTitle?: string;
|
9
|
+
noPadding?: boolean;
|
9
10
|
};
|
10
11
|
declare type SubNavigationPanelCompoundType = ForwardRefExoticComponent<PropsWithoutRef<SubNavigationPanelProps> & RefAttributes<HTMLDivElement>> & {
|
11
12
|
Collapsed?: any;
|
13
|
+
Section?: any;
|
12
14
|
};
|
13
15
|
declare const SubNavigationPanel: SubNavigationPanelCompoundType;
|
14
16
|
export { SubNavigationPanel };
|
@@ -49,62 +49,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
49
49
|
};
|
50
50
|
Object.defineProperty(exports, "__esModule", { value: true });
|
51
51
|
exports.SubNavigationPanel = void 0;
|
52
|
-
var react_1 =
|
53
|
-
var styled_components_1 =
|
52
|
+
var react_1 = __importStar(require("react"));
|
53
|
+
var styled_components_1 = __importDefault(require("styled-components"));
|
54
54
|
var icons_1 = require("../../../icons");
|
55
55
|
var theme_1 = require("../../../theme");
|
56
|
-
var
|
56
|
+
var Container = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n background-color: ", ";\n border-right: 1px solid ", ";\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n height: 100%;\n transition: width 0.3s linear;\n width: ", ";\n"], ["\n background-color: ", ";\n border-right: 1px solid ", ";\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n height: 100%;\n transition: width 0.3s linear;\n width: ", ";\n"])), (0, theme_1.getColor)('grey', 20), (0, theme_1.getColor)('grey', 80), function (_a) {
|
57
57
|
var isOpen = _a.isOpen;
|
58
|
-
return (isOpen ?
|
59
|
-
}, function (_a) {
|
60
|
-
var isOpen = _a.isOpen;
|
61
|
-
return !isOpen && (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: absolute;\n z-index: 0;\n "], ["\n position: absolute;\n z-index: 0;\n "])));
|
62
|
-
});
|
63
|
-
var Panel = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n height: calc(100% - 54px);\n width: 100%;\n position: absolute;\n overflow-y: ", ";\n overflow-x: hidden;\n"], ["\n display: flex;\n flex-direction: column;\n height: calc(100% - 54px);\n width: 100%;\n position: absolute;\n overflow-y: ", ";\n overflow-x: hidden;\n"])), function (_a) {
|
64
|
-
var isOpen = _a.isOpen;
|
65
|
-
return (isOpen ? 'auto' : 'hidden');
|
58
|
+
return (isOpen ? '280px' : '40px');
|
66
59
|
});
|
67
|
-
var
|
68
|
-
var isOpen = _a.isOpen;
|
69
|
-
return (isOpen ? '30px' : '10px 5px');
|
70
|
-
}, collapsableStyles);
|
71
|
-
var ToggleButton = styled_components_1.default.button(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n align-items: center;\n background: none;\n border: none;\n border-top: 1px solid ", ";\n cursor: pointer;\n height: 54px;\n margin: ", ";\n padding: ", ";\n transition: margin 0.3s ease-in-out, padding 0.3s ease-in-out;\n text-align: left;\n position: absolute;\n bottom: 0;\n width: ", ";\n\n svg {\n color: ", ";\n width: 15px;\n }\n"], ["\n align-items: center;\n background: none;\n border: none;\n border-top: 1px solid ", ";\n cursor: pointer;\n height: 54px;\n margin: ", ";\n padding: ", ";\n transition: margin 0.3s ease-in-out, padding 0.3s ease-in-out;\n text-align: left;\n position: absolute;\n bottom: 0;\n width: ", ";\n\n svg {\n color: ", ";\n width: 15px;\n }\n"])), (0, theme_1.getColor)('grey', 80), function (_a) {
|
60
|
+
var Content = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n overflow-x: hidden;\n overflow-y: auto;\n opacity: ", ";\n transition: ", ";\n padding: ", ";\n"], ["\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n overflow-x: hidden;\n overflow-y: auto;\n opacity: ", ";\n transition: ", ";\n padding: ", ";\n"])), function (_a) {
|
72
61
|
var isOpen = _a.isOpen;
|
73
|
-
return (isOpen ? '
|
62
|
+
return (isOpen ? '1' : '0');
|
74
63
|
}, function (_a) {
|
75
64
|
var isOpen = _a.isOpen;
|
76
|
-
return (isOpen ? '
|
65
|
+
return (isOpen ? 'opacity 300ms linear 300ms' : 'none');
|
77
66
|
}, function (_a) {
|
78
|
-
var
|
79
|
-
return (
|
80
|
-
}
|
81
|
-
var
|
82
|
-
|
83
|
-
return (isOpen ? '280px' : '40px');
|
84
|
-
}, (0, theme_1.getColor)('grey', 20), (0, theme_1.getColor)('grey', 80));
|
85
|
-
var Collapsed = styled_components_1.default.div(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n flex-grow: 1;\n padding: 10px 5px;\n ", "\n"], ["\n flex-grow: 1;\n padding: 10px 5px;\n ", "\n"])), collapsableStyles);
|
86
|
-
Collapsed.displayName = 'Collapsed';
|
87
|
-
Collapsed.defaultProps = {
|
88
|
-
isOpen: false,
|
89
|
-
};
|
67
|
+
var noPadding = _a.noPadding;
|
68
|
+
return (noPadding ? '0' : '30px');
|
69
|
+
});
|
70
|
+
var ToggleButton = styled_components_1.default.button(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n align-items: center;\n background: none;\n border: none;\n border-top: 1px solid ", ";\n box-sizing: border-box;\n cursor: pointer;\n display: flex;\n flex: 0 0 auto;\n height: 54px;\n padding: 0;\n padding-left: 12.5px;\n\n svg {\n color: ", ";\n width: 15px;\n }\n"], ["\n align-items: center;\n background: none;\n border: none;\n border-top: 1px solid ", ";\n box-sizing: border-box;\n cursor: pointer;\n display: flex;\n flex: 0 0 auto;\n height: 54px;\n padding: 0;\n padding-left: 12.5px;\n\n svg {\n color: ", ";\n width: 15px;\n }\n"])), (0, theme_1.getColor)('grey', 80), (0, theme_1.getColor)('grey', 100));
|
71
|
+
var Collapsed = styled_components_1.default.div(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n padding: 10px 5px;\n"], ["\n padding: 10px 5px;\n"])));
|
90
72
|
var SubNavigationPanel = react_1.default.forwardRef(function (_a, forwardedRef) {
|
91
|
-
var children = _a.children, _b = _a.isOpen, isOpen = _b === void 0 ? true : _b, open = _a.open, close = _a.close, _c = _a.closeTitle, closeTitle = _c === void 0 ? '' : _c, _d = _a.openTitle, openTitle = _d === void 0 ? '' : _d, rest = __rest(_a, ["children", "isOpen", "open", "close", "closeTitle", "openTitle"]);
|
92
|
-
var
|
93
|
-
var
|
73
|
+
var children = _a.children, _b = _a.isOpen, isOpen = _b === void 0 ? true : _b, open = _a.open, close = _a.close, _c = _a.closeTitle, closeTitle = _c === void 0 ? '' : _c, _d = _a.openTitle, openTitle = _d === void 0 ? '' : _d, _e = _a.noPadding, noPadding = _e === void 0 ? false : _e, rest = __rest(_a, ["children", "isOpen", "open", "close", "closeTitle", "openTitle", "noPadding"]);
|
74
|
+
var collapsedElements = [];
|
75
|
+
var contentElements = [];
|
94
76
|
react_1.default.Children.forEach(children, function (child) {
|
95
77
|
if (react_1.default.isValidElement(child) && child.type === Collapsed) {
|
96
|
-
|
97
|
-
|
78
|
+
collapsedElements.push(child);
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
contentElements.push(child);
|
98
82
|
}
|
99
|
-
contentChildren.push(child);
|
100
83
|
});
|
84
|
+
var _f = react_1.default.useState(isOpen), isOpenTransition = _f[0], setIsOpenTransition = _f[1];
|
85
|
+
(0, react_1.useLayoutEffect)(function () {
|
86
|
+
setIsOpenTransition(isOpen);
|
87
|
+
}, [isOpen]);
|
101
88
|
return (react_1.default.createElement(Container, __assign({ ref: forwardedRef, isOpen: isOpen }, rest),
|
102
|
-
|
103
|
-
|
104
|
-
react_1.default.createElement(PanelContent, { isOpen: isOpen }, isOpen && contentChildren)),
|
89
|
+
!isOpen && collapsedElements,
|
90
|
+
react_1.default.createElement(Content, { isOpen: isOpenTransition, noPadding: noPadding }, isOpen && contentElements),
|
105
91
|
react_1.default.createElement(ToggleButton, { isOpen: isOpen, onClick: function () { return (isOpen ? close() : open()); }, title: isOpen ? closeTitle : openTitle, "data-testid": "open-subnavigation-button" }, isOpen ? react_1.default.createElement(icons_1.PanelCloseIcon, null) : react_1.default.createElement(icons_1.PanelOpenIcon, null))));
|
106
92
|
});
|
107
93
|
exports.SubNavigationPanel = SubNavigationPanel;
|
94
|
+
SubNavigationPanel.displayName = 'SubNavigationPanel';
|
95
|
+
Collapsed.displayName = 'SubNavigationPanel.Collapsed';
|
108
96
|
SubNavigationPanel.Collapsed = Collapsed;
|
109
|
-
var templateObject_1, templateObject_2, templateObject_3, templateObject_4
|
97
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
|
110
98
|
//# sourceMappingURL=SubNavigationPanel.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SubNavigationPanel.js","sourceRoot":"","sources":["../../../../src/components/Navigation/SubNavigationPanel/SubNavigationPanel.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
1
|
+
{"version":3,"file":"SubNavigationPanel.js","sourceRoot":"","sources":["../../../../src/components/Navigation/SubNavigationPanel/SubNavigationPanel.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwG;AACxG,wEAAuC;AACvC,wCAA6D;AAC7D,wCAA2D;AAE3D,IAAM,SAAS,GAAG,2BAAM,CAAC,GAAG,8QAAuC,wBAC7C,EAAoB,+BACd,EAAoB,yIAMrC,EAAyC,KACnD,KARqB,IAAA,gBAAQ,EAAC,MAAM,EAAE,EAAE,CAAC,EACd,IAAA,gBAAQ,EAAC,MAAM,EAAE,EAAE,CAAC,EAMrC,UAAC,EAAQ;QAAP,MAAM,YAAA;IAAM,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAA3B,CAA2B,CACnD,CAAC;AAEF,IAAM,OAAO,GAAG,2BAAM,CAAC,GAAG,0OAAuC,yHAMpD,EAAkC,mBAC/B,EAA8D,gBACjE,EAA2C,KACvD,KAHY,UAAC,EAAQ;QAAP,MAAM,YAAA;IAAM,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAApB,CAAoB,EAC/B,UAAC,EAAQ;QAAP,MAAM,YAAA;IAAM,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,MAAM,CAAC;AAAhD,CAAgD,EACjE,UAAC,EAAW;QAAV,SAAS,eAAA;IAAM,OAAA,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;AAA1B,CAA0B,CACvD,CAAC;AAEF,IAAM,YAAY,GAAG,2BAAM,CAAC,MAAM,qWAAmB,0FAI3B,EAAoB,wKAUjC,EAAqB,4BAGjC,KAbyB,IAAA,gBAAQ,EAAC,MAAM,EAAE,EAAE,CAAC,EAUjC,IAAA,gBAAQ,EAAC,MAAM,EAAE,GAAG,CAAC,CAGjC,CAAC;AAEF,IAAM,SAAS,GAAG,2BAAM,CAAC,GAAG,6FAAA,0BAE3B,IAAA,CAAC;AAiDF,IAAM,kBAAkB,GAAmC,eAAK,CAAC,UAAU,CACzE,UACE,EAS0B,EAC1B,YAAuC;IATrC,IAAA,QAAQ,cAAA,EACR,cAAa,EAAb,MAAM,mBAAG,IAAI,KAAA,EACb,IAAI,UAAA,EACJ,KAAK,WAAA,EACL,kBAAe,EAAf,UAAU,mBAAG,EAAE,KAAA,EACf,iBAAc,EAAd,SAAS,mBAAG,EAAE,KAAA,EACd,iBAAiB,EAAjB,SAAS,mBAAG,KAAK,KAAA,EACd,IAAI,cART,+EASC,CADQ;IAIT,IAAM,iBAAiB,GAAsB,EAAE,CAAC;IAChD,IAAM,eAAe,GAAsB,EAAE,CAAC;IAE9C,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAA,KAAK;QACpC,IAAI,eAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;YAC3D,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC/B;aAAM;YACL,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC7B;IACH,CAAC,CAAC,CAAC;IAEG,IAAA,KAA0C,eAAK,CAAC,QAAQ,CAAU,MAAM,CAAC,EAAxE,gBAAgB,QAAA,EAAE,mBAAmB,QAAmC,CAAC;IAChF,IAAA,uBAAe,EAAC;QACd,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,CACL,8BAAC,SAAS,aAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IAAM,IAAI;QACnD,CAAC,MAAM,IAAI,iBAAiB;QAC7B,8BAAC,OAAO,IAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,IACpD,MAAM,IAAI,eAAe,CAClB;QACV,8BAAC,YAAY,IACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAM,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAA3B,CAA2B,EAC1C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,iBAC1B,2BAA2B,IAEtC,MAAM,CAAC,CAAC,CAAC,8BAAC,sBAAc,OAAG,CAAC,CAAC,CAAC,8BAAC,qBAAa,OAAG,CACnC,CACL,CACb,CAAC;AACJ,CAAC,CACF,CAAC;AAOM,gDAAkB;AAL1B,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;AACtD,SAAS,CAAC,WAAW,GAAG,8BAA8B,CAAC;AAEvD,kBAAkB,CAAC,SAAS,GAAG,SAAS,CAAC"}
|
package/package.json
CHANGED
Binary file
|
Binary file
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import React, {useMemo} from 'react';
|
2
2
|
import styled, {css} from 'styled-components';
|
3
3
|
import {useTheme} from '../../hooks';
|
4
|
-
import {Override} from '../../shared';
|
5
4
|
import {AkeneoThemedProps, getColor} from '../../theme';
|
5
|
+
import {AvatarProps} from './types';
|
6
6
|
|
7
7
|
const AvatarContainer = styled.span<AvatarProps & AkeneoThemedProps>`
|
8
8
|
${({size}) =>
|
@@ -31,43 +31,13 @@ const AvatarContainer = styled.span<AvatarProps & AkeneoThemedProps>`
|
|
31
31
|
cursor: ${({onClick}) => (onClick ? 'pointer' : 'default')};
|
32
32
|
`;
|
33
33
|
|
34
|
-
type AvatarProps = Override<
|
35
|
-
React.HTMLAttributes<HTMLSpanElement>,
|
36
|
-
{
|
37
|
-
/**
|
38
|
-
* Username to use as fallback if the avatar is not provided and the Firstname and Lastname are empty.
|
39
|
-
*/
|
40
|
-
username: string;
|
41
|
-
|
42
|
-
/**
|
43
|
-
* Firstname to use as fallback with the Lastname if the avatar is not provided.
|
44
|
-
*/
|
45
|
-
firstName: string;
|
46
|
-
|
47
|
-
/**
|
48
|
-
* Lastname to use as fallback with the Firstname if the avatar is not provided.
|
49
|
-
*/
|
50
|
-
lastName: string;
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Url of the avatar image.
|
54
|
-
*/
|
55
|
-
avatarUrl?: string;
|
56
|
-
|
57
|
-
/**
|
58
|
-
* Size of the avatar.
|
59
|
-
*/
|
60
|
-
size?: 'default' | 'big';
|
61
|
-
}
|
62
|
-
>;
|
63
|
-
|
64
34
|
const Avatar = ({username, firstName, lastName, avatarUrl, size = 'default', ...rest}: AvatarProps) => {
|
65
35
|
const theme = useTheme();
|
66
36
|
|
67
37
|
const fallback = (
|
68
38
|
firstName.trim().charAt(0) + lastName.trim().charAt(0) || username.substring(0, 2)
|
69
39
|
).toLocaleUpperCase();
|
70
|
-
const title = `${firstName} ${lastName}`.trim() || username;
|
40
|
+
const title = `${firstName || ''} ${lastName || ''}`.trim() || username;
|
71
41
|
|
72
42
|
const backgroundColor = useMemo(() => {
|
73
43
|
const colorId = username.split('').reduce<number>((s, l) => s + l.charCodeAt(0), 0);
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import React, {Children} from 'react';
|
1
|
+
import React, {Children, useMemo} from 'react';
|
2
2
|
import styled from 'styled-components';
|
3
3
|
import {Override} from '../../shared';
|
4
4
|
import {AkeneoThemedProps, getColor} from '../../theme';
|
5
|
+
import {AvatarProps} from './types';
|
5
6
|
|
6
7
|
const AvatarListContainer = styled.div<AvatarsProps & AkeneoThemedProps>`
|
7
8
|
display: flex;
|
@@ -16,10 +17,11 @@ const AvatarListContainer = styled.div<AvatarsProps & AkeneoThemedProps>`
|
|
16
17
|
const RemainingAvatar = styled.span`
|
17
18
|
height: 32px;
|
18
19
|
width: 32px;
|
19
|
-
display: inline-block;
|
20
20
|
border: 1px solid ${getColor('grey', 10)};
|
21
21
|
line-height: 32px;
|
22
|
-
|
22
|
+
display: flex;
|
23
|
+
align-items: center;
|
24
|
+
justify-content: center;
|
23
25
|
font-size: 15px;
|
24
26
|
border-radius: 32px;
|
25
27
|
background-color: ${getColor('white')};
|
@@ -29,17 +31,37 @@ type AvatarsProps = Override<
|
|
29
31
|
React.HTMLAttributes<HTMLDivElement>,
|
30
32
|
{
|
31
33
|
max: number;
|
34
|
+
maxTitle?: number;
|
32
35
|
}
|
33
36
|
>;
|
34
37
|
|
35
|
-
const Avatars = ({max, children, ...rest}
|
38
|
+
const Avatars: React.FC<AvatarsProps> = ({max, maxTitle = 10, children, ...rest}) => {
|
36
39
|
const childrenArray = Children.toArray(children);
|
37
40
|
const displayedChildren = childrenArray.slice(0, max);
|
41
|
+
const remainingChildren = childrenArray.slice(max, childrenArray.length + 1);
|
38
42
|
const remainingChildrenCount = childrenArray.length - max;
|
39
43
|
const reverseChildren = displayedChildren.reverse();
|
40
44
|
|
45
|
+
const remainingUsersTitle = useMemo(() => {
|
46
|
+
const remainingNames = remainingChildren
|
47
|
+
.map(child => {
|
48
|
+
if (!React.isValidElement<AvatarProps>(child)) return;
|
49
|
+
const {firstName, lastName, username} = child.props;
|
50
|
+
|
51
|
+
return `${firstName || ''} ${lastName || ''}`.trim() || username;
|
52
|
+
})
|
53
|
+
.slice(0, maxTitle)
|
54
|
+
.join('\n');
|
55
|
+
|
56
|
+
if (remainingChildren.length > maxTitle) {
|
57
|
+
return remainingNames.concat('\n', '...');
|
58
|
+
}
|
59
|
+
|
60
|
+
return remainingNames;
|
61
|
+
}, [maxTitle, remainingChildren]);
|
62
|
+
|
41
63
|
return (
|
42
|
-
<AvatarListContainer {...rest}>
|
64
|
+
<AvatarListContainer title={rest.title || remainingUsersTitle} {...rest}>
|
43
65
|
{remainingChildrenCount > 0 && <RemainingAvatar>+{remainingChildrenCount}</RemainingAvatar>}
|
44
66
|
{reverseChildren}
|
45
67
|
</AvatarListContainer>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import {render, screen} from '../../storybook/test-util';
|
2
|
+
import {fireEvent, render, screen} from '../../storybook/test-util';
|
3
3
|
import {Avatar} from './Avatar';
|
4
4
|
import {Avatars} from './Avatars';
|
5
5
|
|
@@ -24,7 +24,7 @@ test('renders a maximum number of avatars', () => {
|
|
24
24
|
);
|
25
25
|
|
26
26
|
expect(screen.getByTitle('John Doe')).toBeInTheDocument();
|
27
|
-
expect(screen.
|
27
|
+
expect(screen.queryByText('LD')).not.toBeInTheDocument();
|
28
28
|
expect(screen.getByText('+1')).toBeInTheDocument();
|
29
29
|
});
|
30
30
|
|
@@ -39,3 +39,23 @@ test('supports ...rest props', () => {
|
|
39
39
|
|
40
40
|
expect(screen.getByTestId('my_value')).toBeInTheDocument();
|
41
41
|
});
|
42
|
+
|
43
|
+
test('displays remaining users names on plus hover', () => {
|
44
|
+
const invalidChild = 'I should not be in the title';
|
45
|
+
render(
|
46
|
+
<Avatars max={1} maxTitle={1}>
|
47
|
+
<Avatar username="dSchrute" firstName="Dwight" lastName="Schrute" />
|
48
|
+
<Avatar username="mscott" firstName=" " lastName=" " />
|
49
|
+
<Avatar username="kMalone" firstName="Kevin" lastName="Malone" />
|
50
|
+
{invalidChild}
|
51
|
+
</Avatars>
|
52
|
+
);
|
53
|
+
|
54
|
+
expect(screen.getByText('DS')).toBeInTheDocument();
|
55
|
+
expect(screen.getByText('+3')).toBeInTheDocument();
|
56
|
+
// Kevin Malone should not be visible as it should be part of the +1
|
57
|
+
expect(screen.queryByText('mscott')).not.toBeInTheDocument();
|
58
|
+
|
59
|
+
fireEvent.mouseOver(screen.getByText('+3'));
|
60
|
+
expect(screen.getByTitle('mscott ...')).toBeInTheDocument();
|
61
|
+
});
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import {Override} from '../../shared';
|
2
|
+
import React from 'react';
|
3
|
+
|
4
|
+
export type User = {
|
5
|
+
/**
|
6
|
+
* Username to use as fallback if the avatar is not provided and the Firstname and Lastname are empty.
|
7
|
+
*/
|
8
|
+
username: string;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Firstname to use as fallback with the Lastname if the avatar is not provided.
|
12
|
+
*/
|
13
|
+
firstName: string;
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Lastname to use as fallback with the Firstname if the avatar is not provided.
|
17
|
+
*/
|
18
|
+
lastName: string;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Url of the avatar image.
|
22
|
+
*/
|
23
|
+
avatarUrl?: string;
|
24
|
+
};
|
25
|
+
|
26
|
+
export type AvatarProps = Override<
|
27
|
+
React.HTMLAttributes<HTMLSpanElement>,
|
28
|
+
User & {
|
29
|
+
/**
|
30
|
+
* Size of the avatar.
|
31
|
+
*/
|
32
|
+
size?: 'default' | 'big';
|
33
|
+
}
|
34
|
+
>;
|
@@ -19,7 +19,7 @@ const Title = styled.span`
|
|
19
19
|
text-overflow: ellipsis;
|
20
20
|
`;
|
21
21
|
|
22
|
-
type SurtitleProps = {label: string};
|
22
|
+
type SurtitleProps = {label: string; children?: React.ReactNode};
|
23
23
|
|
24
24
|
const Surtitle: React.FC<SurtitleProps> = ({label, children, ...rest}) => (
|
25
25
|
<SurtitleContainer {...rest}>
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
1
|
+
import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs';
|
2
|
+
import {SubNavigationPanel} from './SubNavigationPanel.tsx';
|
3
|
+
import {SpaceContainer} from '../../../storybook/PreviewGallery';
|
4
|
+
import {useBooleanState} from '../../../hooks';
|
5
|
+
import {MoreVerticalIcon} from '../../../icons';
|
6
|
+
import {Dropdown} from '../../Dropdown/Dropdown';
|
7
|
+
import {Link} from '../../Link/Link';
|
8
|
+
import {useState} from 'react';
|
9
|
+
import {Collapse} from '../../Collapse/Collapse';
|
8
10
|
|
9
11
|
<Meta
|
10
12
|
title="Components/Navigation/SubNavigationPanel"
|
@@ -12,7 +14,7 @@ import { Link } from "../../Link/Link";
|
|
12
14
|
SubNavigationPanel: SubNavigationPanel,
|
13
15
|
'SubNavigationPanel.Collapsed': SubNavigationPanel.Collapsed,
|
14
16
|
}}
|
15
|
-
args={{
|
17
|
+
args={{children: 'Some content', isOpen: true, closeTitle: 'Close', openTitle: 'Open'}}
|
16
18
|
/>
|
17
19
|
|
18
20
|
# SubNavigationPanel
|
@@ -33,9 +35,10 @@ When the panel is collapsed the content is hidden.
|
|
33
35
|
<Canvas>
|
34
36
|
<Story name="Standard">
|
35
37
|
{args => {
|
38
|
+
const [isOpen, open, close] = useBooleanState(true);
|
36
39
|
return (
|
37
40
|
<SpaceContainer height={200}>
|
38
|
-
<SubNavigationPanel {...args} />
|
41
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} />
|
39
42
|
</SpaceContainer>
|
40
43
|
);
|
41
44
|
}}
|
@@ -44,34 +47,44 @@ When the panel is collapsed the content is hidden.
|
|
44
47
|
|
45
48
|
<ArgsTable story="Standard" />
|
46
49
|
|
47
|
-
## Panel
|
50
|
+
## Panel with scrollable content
|
48
51
|
|
49
52
|
<Canvas>
|
50
|
-
<Story name="
|
53
|
+
<Story name="ScrollableContent">
|
51
54
|
{args => {
|
55
|
+
const [isOpen, open, close] = useBooleanState(true);
|
52
56
|
return (
|
53
57
|
<SpaceContainer height={200}>
|
54
|
-
<SubNavigationPanel {...args} isOpen={
|
58
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close}>
|
59
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
60
|
+
<br />
|
61
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
62
|
+
<br />
|
63
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
64
|
+
<br />
|
65
|
+
Aenean blandit metus a nibh blandit porta.
|
66
|
+
<br />
|
67
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
68
|
+
</SubNavigationPanel>
|
55
69
|
</SpaceContainer>
|
56
70
|
);
|
57
71
|
}}
|
58
72
|
</Story>
|
59
73
|
</Canvas>
|
60
74
|
|
61
|
-
|
62
|
-
## Panel with collapsed and expanded content
|
75
|
+
## Panel with collapsed content using Dropdown component
|
63
76
|
|
64
77
|
<Canvas>
|
65
78
|
<Story name="CollapsedExpandedContent">
|
66
79
|
{args => {
|
67
|
-
const [isOpen, open, close] = useBooleanState(
|
80
|
+
const [isOpen, open, close] = useBooleanState(false);
|
68
81
|
const [isDropdownOpen, openDropDown, closeDropDown] = useBooleanState(false);
|
69
82
|
return (
|
70
83
|
<SpaceContainer height={200}>
|
71
84
|
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close}>
|
72
85
|
<SubNavigationPanel.Collapsed>
|
73
86
|
<Dropdown>
|
74
|
-
<MoreVerticalIcon title="
|
87
|
+
<MoreVerticalIcon title="More" onClick={openDropDown} />
|
75
88
|
{isDropdownOpen && (
|
76
89
|
<Dropdown.Overlay onClose={closeDropDown}>
|
77
90
|
<Dropdown.ItemCollection>
|
@@ -81,15 +94,74 @@ When the panel is collapsed the content is hidden.
|
|
81
94
|
)}
|
82
95
|
</Dropdown>
|
83
96
|
</SubNavigationPanel.Collapsed>
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
Some content
|
98
|
+
</SubNavigationPanel>
|
99
|
+
</SpaceContainer>
|
100
|
+
);
|
101
|
+
}}
|
102
|
+
</Story>
|
103
|
+
</Canvas>
|
104
|
+
|
105
|
+
## Panel without padding
|
106
|
+
|
107
|
+
<Canvas>
|
108
|
+
<Story name="ContentWithoutPadding">
|
109
|
+
{args => {
|
110
|
+
const [isOpen, open, close] = useBooleanState(true);
|
111
|
+
const [collapse, setCollapse] = useState(1);
|
112
|
+
return (
|
113
|
+
<SpaceContainer height={200}>
|
114
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} noPadding>
|
115
|
+
Some content
|
116
|
+
</SubNavigationPanel>
|
117
|
+
</SpaceContainer>
|
118
|
+
);
|
119
|
+
}}
|
120
|
+
</Story>
|
121
|
+
</Canvas>
|
122
|
+
|
123
|
+
## Panel using Collapse components
|
124
|
+
|
125
|
+
<Canvas>
|
126
|
+
<Story name="ContentWithCollapseComponent">
|
127
|
+
{args => {
|
128
|
+
const [isOpen, open, close] = useBooleanState(true);
|
129
|
+
const [collapse, setCollapse] = useState(1);
|
130
|
+
return (
|
131
|
+
<SpaceContainer height={200}>
|
132
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} noPadding>
|
133
|
+
<Collapse
|
134
|
+
label="First Collapse"
|
135
|
+
collapseButtonLabel="Collapse"
|
136
|
+
isOpen={collapse === 1}
|
137
|
+
onCollapse={() => setCollapse(1)}
|
138
|
+
>
|
139
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
140
|
+
<br />
|
141
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
142
|
+
<br />
|
143
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
144
|
+
<br />
|
145
|
+
Aenean blandit metus a nibh blandit porta.
|
146
|
+
<br />
|
147
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
148
|
+
</Collapse>
|
149
|
+
<Collapse
|
150
|
+
label="Second Collapse"
|
151
|
+
collapseButtonLabel="Collapse"
|
152
|
+
isOpen={collapse === 2}
|
153
|
+
onCollapse={() => setCollapse(2)}
|
154
|
+
>
|
155
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
156
|
+
<br />
|
157
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
158
|
+
<br />
|
159
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
160
|
+
<br />
|
161
|
+
Aenean blandit metus a nibh blandit porta.
|
162
|
+
<br />
|
163
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
164
|
+
</Collapse>
|
93
165
|
</SubNavigationPanel>
|
94
166
|
</SpaceContainer>
|
95
167
|
);
|
@@ -1,54 +1,42 @@
|
|
1
|
-
import React, {ForwardRefExoticComponent, PropsWithoutRef,
|
2
|
-
import styled
|
1
|
+
import React, {ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, useLayoutEffect} from 'react';
|
2
|
+
import styled from 'styled-components';
|
3
3
|
import {PanelCloseIcon, PanelOpenIcon} from '../../../icons';
|
4
4
|
import {AkeneoThemedProps, getColor} from '../../../theme';
|
5
5
|
|
6
|
-
const
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
position: relative;
|
12
|
-
z-index: 1;
|
13
|
-
${({isOpen}) =>
|
14
|
-
!isOpen &&
|
15
|
-
css`
|
16
|
-
position: absolute;
|
17
|
-
z-index: 0;
|
18
|
-
`}
|
19
|
-
`;
|
20
|
-
const Panel = styled.div<{isOpen: boolean} & AkeneoThemedProps>`
|
6
|
+
const Container = styled.div<{isOpen: boolean} & AkeneoThemedProps>`
|
7
|
+
background-color: ${getColor('grey', 20)};
|
8
|
+
border-right: 1px solid ${getColor('grey', 80)};
|
9
|
+
box-sizing: border-box;
|
21
10
|
display: flex;
|
22
11
|
flex-direction: column;
|
23
|
-
height:
|
24
|
-
|
25
|
-
|
26
|
-
overflow-y: ${({isOpen}) => (isOpen ? 'auto' : 'hidden')};
|
27
|
-
overflow-x: hidden;
|
12
|
+
height: 100%;
|
13
|
+
transition: width 0.3s linear;
|
14
|
+
width: ${({isOpen}) => (isOpen ? '280px' : '40px')};
|
28
15
|
`;
|
29
16
|
|
30
|
-
const
|
31
|
-
|
17
|
+
const Content = styled.div<{isOpen: boolean; noPadding: boolean}>`
|
18
|
+
display: flex;
|
19
|
+
flex-direction: column;
|
32
20
|
flex-grow: 1;
|
33
|
-
|
34
|
-
|
35
|
-
${
|
21
|
+
overflow-x: hidden;
|
22
|
+
overflow-y: auto;
|
23
|
+
opacity: ${({isOpen}) => (isOpen ? '1' : '0')};
|
24
|
+
transition: ${({isOpen}) => (isOpen ? 'opacity 300ms linear 300ms' : 'none')};
|
25
|
+
padding: ${({noPadding}) => (noPadding ? '0' : '30px')};
|
36
26
|
`;
|
37
27
|
|
38
|
-
const ToggleButton = styled.button<
|
28
|
+
const ToggleButton = styled.button<AkeneoThemedProps>`
|
39
29
|
align-items: center;
|
40
30
|
background: none;
|
41
31
|
border: none;
|
42
32
|
border-top: 1px solid ${getColor('grey', 80)};
|
33
|
+
box-sizing: border-box;
|
43
34
|
cursor: pointer;
|
35
|
+
display: flex;
|
36
|
+
flex: 0 0 auto;
|
44
37
|
height: 54px;
|
45
|
-
|
46
|
-
padding:
|
47
|
-
transition: margin 0.3s ease-in-out, padding 0.3s ease-in-out;
|
48
|
-
text-align: left;
|
49
|
-
position: absolute;
|
50
|
-
bottom: 0;
|
51
|
-
width: ${({isOpen}) => (isOpen ? '240px' : '40px')};
|
38
|
+
padding: 0;
|
39
|
+
padding-left: 12.5px;
|
52
40
|
|
53
41
|
svg {
|
54
42
|
color: ${getColor('grey', 100)};
|
@@ -56,30 +44,10 @@ const ToggleButton = styled.button<{isOpen: boolean} & AkeneoThemedProps>`
|
|
56
44
|
}
|
57
45
|
`;
|
58
46
|
|
59
|
-
const
|
60
|
-
width: ${({isOpen}) => (isOpen ? '280px' : '40px')};
|
61
|
-
transition: width 0.3s linear;
|
62
|
-
position: relative;
|
63
|
-
order: -10;
|
64
|
-
background-color: ${getColor('grey', 20)};
|
65
|
-
border-right: 1px solid ${getColor('grey', 80)};
|
66
|
-
flex-shrink: 0;
|
67
|
-
height: 100%;
|
68
|
-
z-index: 802;
|
69
|
-
overflow: hidden;
|
70
|
-
`;
|
71
|
-
|
72
|
-
const Collapsed = styled.div<{isOpen: boolean} & AkeneoThemedProps>`
|
73
|
-
flex-grow: 1;
|
47
|
+
const Collapsed = styled.div`
|
74
48
|
padding: 10px 5px;
|
75
|
-
${collapsableStyles}
|
76
49
|
`;
|
77
50
|
|
78
|
-
Collapsed.displayName = 'Collapsed';
|
79
|
-
Collapsed.defaultProps = {
|
80
|
-
isOpen: false,
|
81
|
-
};
|
82
|
-
|
83
51
|
type SubNavigationPanelProps = {
|
84
52
|
/**
|
85
53
|
* The content of the panel.
|
@@ -110,12 +78,18 @@ type SubNavigationPanelProps = {
|
|
110
78
|
* Opening title to display for the ToggleButton
|
111
79
|
*/
|
112
80
|
openTitle?: string;
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Whether or not the panel should have padding.
|
84
|
+
*/
|
85
|
+
noPadding?: boolean;
|
113
86
|
};
|
114
87
|
|
115
88
|
type SubNavigationPanelCompoundType = ForwardRefExoticComponent<
|
116
89
|
PropsWithoutRef<SubNavigationPanelProps> & RefAttributes<HTMLDivElement>
|
117
90
|
> & {
|
118
91
|
Collapsed?: any;
|
92
|
+
Section?: any;
|
119
93
|
};
|
120
94
|
|
121
95
|
/**
|
@@ -123,25 +97,40 @@ type SubNavigationPanelCompoundType = ForwardRefExoticComponent<
|
|
123
97
|
*/
|
124
98
|
const SubNavigationPanel: SubNavigationPanelCompoundType = React.forwardRef<HTMLDivElement, SubNavigationPanelProps>(
|
125
99
|
(
|
126
|
-
{
|
100
|
+
{
|
101
|
+
children,
|
102
|
+
isOpen = true,
|
103
|
+
open,
|
104
|
+
close,
|
105
|
+
closeTitle = '',
|
106
|
+
openTitle = '',
|
107
|
+
noPadding = false,
|
108
|
+
...rest
|
109
|
+
}: SubNavigationPanelProps,
|
127
110
|
forwardedRef: React.Ref<HTMLDivElement>
|
128
111
|
) => {
|
129
|
-
const
|
130
|
-
|
112
|
+
const collapsedElements: React.ReactNode[] = [];
|
113
|
+
const contentElements: React.ReactNode[] = [];
|
114
|
+
|
131
115
|
React.Children.forEach(children, child => {
|
132
116
|
if (React.isValidElement(child) && child.type === Collapsed) {
|
133
|
-
|
134
|
-
|
117
|
+
collapsedElements.push(child);
|
118
|
+
} else {
|
119
|
+
contentElements.push(child);
|
135
120
|
}
|
136
|
-
contentChildren.push(child);
|
137
121
|
});
|
138
122
|
|
123
|
+
const [isOpenTransition, setIsOpenTransition] = React.useState<boolean>(isOpen);
|
124
|
+
useLayoutEffect(() => {
|
125
|
+
setIsOpenTransition(isOpen);
|
126
|
+
}, [isOpen]);
|
127
|
+
|
139
128
|
return (
|
140
129
|
<Container ref={forwardedRef} isOpen={isOpen} {...rest}>
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
</
|
130
|
+
{!isOpen && collapsedElements}
|
131
|
+
<Content isOpen={isOpenTransition} noPadding={noPadding}>
|
132
|
+
{isOpen && contentElements}
|
133
|
+
</Content>
|
145
134
|
<ToggleButton
|
146
135
|
isOpen={isOpen}
|
147
136
|
onClick={() => (isOpen ? close() : open())}
|
@@ -155,6 +144,9 @@ const SubNavigationPanel: SubNavigationPanelCompoundType = React.forwardRef<HTML
|
|
155
144
|
}
|
156
145
|
);
|
157
146
|
|
147
|
+
SubNavigationPanel.displayName = 'SubNavigationPanel';
|
148
|
+
Collapsed.displayName = 'SubNavigationPanel.Collapsed';
|
149
|
+
|
158
150
|
SubNavigationPanel.Collapsed = Collapsed;
|
159
151
|
|
160
152
|
export {SubNavigationPanel};
|
@@ -76,7 +76,7 @@ test('it shows collapsed content', () => {
|
|
76
76
|
);
|
77
77
|
|
78
78
|
expect(queryByText('SubNavigationPanel content')).not.toBeInTheDocument();
|
79
|
-
expect(getByText('Collapsed content')).
|
79
|
+
expect(getByText('Collapsed content')).toBeInTheDocument();
|
80
80
|
});
|
81
81
|
|
82
82
|
test('it hides collapsed content', () => {
|
@@ -89,6 +89,6 @@ test('it hides collapsed content', () => {
|
|
89
89
|
</SubNavigationPanel>
|
90
90
|
);
|
91
91
|
|
92
|
-
expect(
|
93
|
-
expect(
|
92
|
+
expect(getByText('SubNavigationPanel content')).toBeInTheDocument();
|
93
|
+
expect(queryByText('Collapsed content')).not.toBeInTheDocument();
|
94
94
|
});
|