orcs-design-system 3.2.39 → 3.2.41
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/es/components/ActionsMenu/index.js +14 -4
- package/es/components/SideNav/SideNav.stories.js +32 -21
- package/es/components/SideNav/index.js +1 -1
- package/es/components/StyledLink/StyledLink.stories.js +4 -3
- package/es/components/Tabs/Tabs.stories.js +67 -0
- package/es/components/Tabs/index.js +188 -178
- package/es/components.test.js +1 -2
- package/es/index.js +1 -1
- package/package.json +17 -9
- package/es/components/Tabs/Tab.stories.js +0 -91
- package/es/components/Tabs/TabsContainer.stories.js +0 -48
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useImperativeHandle, createContext, useContext, useMemo, useId, useLayoutEffect } from "react";
|
|
2
|
-
import styled, { keyframes, ThemeProvider } from "styled-components";
|
|
2
|
+
import styled, { css, keyframes, ThemeProvider } from "styled-components";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { space, layout } from "styled-system";
|
|
5
5
|
import { themeGet } from "@styled-system/theme-get";
|
|
@@ -88,6 +88,11 @@ export const ActionsMenuItem = styled(props => {
|
|
|
88
88
|
["data-action-menu-id"]: id
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
+
if (props.Component) return /*#__PURE__*/_jsx(props.Component, {
|
|
92
|
+
...newProps,
|
|
93
|
+
onClick: onClick,
|
|
94
|
+
disabled: disabled
|
|
95
|
+
});
|
|
91
96
|
return /*#__PURE__*/_jsx(Component, {
|
|
92
97
|
...newProps,
|
|
93
98
|
onClick: onClick,
|
|
@@ -98,8 +103,13 @@ export const ActionsMenuItem = styled(props => {
|
|
|
98
103
|
}).withConfig({
|
|
99
104
|
displayName: "ActionsMenu__ActionsMenuItem",
|
|
100
105
|
componentId: "sc-yvbni2-6"
|
|
101
|
-
})(["
|
|
102
|
-
|
|
106
|
+
})(["", ""], _ref => {
|
|
107
|
+
let {
|
|
108
|
+
Component
|
|
109
|
+
} = _ref;
|
|
110
|
+
return Component ? "" : css(["white-space:nowrap;display:block;width:100%;text-align:left;cursor:pointer;margin:0;padding:8px;appearance:none;background-color:", ";border:none;border-bottom:solid 1px ", ";border-radius:0;color:", ";font-size:", ";line-height:", ";font-family:", ";font-weight:", ";text-decoration:none;transition:", ";&:hover,&:focus{outline:0;background-color:", ";}&:first-child{border-radius:", " ", " 0 0;}&:last-child{border:0;border-radius:0 0 ", " ", ";}&:only-child{border-radius:", ";}"], props => props.selected ? themeGet("colors.successDark")(props) : "transparent", props => themeGet("colors.greyDarkest")(props), props => themeGet("colors.white")(props), props => themeGet("fontSizes.1")(props), props => themeGet("fontSizes.1")(props), props => themeGet("fonts.main")(props), props => themeGet("fontWeights.2")(props), props => themeGet("transition.transitionDefault")(props), props => themeGet("colors.primaryDark")(props), props => themeGet("radii.2")(props), props => themeGet("radii.2")(props), props => themeGet("radii.2")(props), props => themeGet("radii.2")(props), props => themeGet("radii.2")(props));
|
|
111
|
+
});
|
|
112
|
+
export const ActionsMenuBody = _ref2 => {
|
|
103
113
|
let {
|
|
104
114
|
theme,
|
|
105
115
|
onToggle,
|
|
@@ -115,7 +125,7 @@ export const ActionsMenuBody = _ref => {
|
|
|
115
125
|
closeOnClick = false,
|
|
116
126
|
"data-testid": dataTestId = "ActionsMenu",
|
|
117
127
|
...props
|
|
118
|
-
} =
|
|
128
|
+
} = _ref2;
|
|
119
129
|
const id = useId();
|
|
120
130
|
const actionMenu = useActionMenu({
|
|
121
131
|
placement: direction,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable react/prop-types */
|
|
2
2
|
import React from "react";
|
|
3
3
|
import SideNav from "./index";
|
|
4
|
-
import { BrowserRouter as Router, Route, Link,
|
|
4
|
+
import { BrowserRouter as Router, Route, Link, useLocation, matchPath, Switch, Redirect, useParams } from "react-router-dom";
|
|
5
5
|
import { H5, P } from "../Typography";
|
|
6
6
|
import Box from "../Box";
|
|
7
7
|
import { far } from "@fortawesome/free-regular-svg-icons";
|
|
@@ -59,46 +59,59 @@ const PageCard = _ref2 => {
|
|
|
59
59
|
});
|
|
60
60
|
};
|
|
61
61
|
const SideBarWithConfig = () => {
|
|
62
|
-
const
|
|
63
|
-
const isProfile = useMatch("/profile");
|
|
64
|
-
const isSearch = useMatch("/search");
|
|
62
|
+
const location = useLocation();
|
|
65
63
|
const items = [{
|
|
66
64
|
iconName: "building",
|
|
67
65
|
name: "Home",
|
|
68
66
|
component: makeLinkComponent("/"),
|
|
69
67
|
actionType: "link",
|
|
70
|
-
isActive:
|
|
68
|
+
isActive: matchPath(location.pathname, {
|
|
69
|
+
path: "/",
|
|
70
|
+
exact: true
|
|
71
|
+
})
|
|
71
72
|
}, {
|
|
72
73
|
iconName: "user",
|
|
73
74
|
name: "My profile",
|
|
74
75
|
component: makeLinkComponent("/profile"),
|
|
75
76
|
actionType: "link",
|
|
76
|
-
isActive:
|
|
77
|
+
isActive: matchPath(location.pathname, {
|
|
78
|
+
path: "/profile"
|
|
79
|
+
})
|
|
77
80
|
}, {
|
|
78
81
|
iconName: "id-card",
|
|
79
82
|
name: "Search Page",
|
|
80
83
|
component: makeLinkComponent("/search"),
|
|
81
84
|
actionType: "link",
|
|
82
|
-
isActive:
|
|
85
|
+
isActive: matchPath(location.pathname, {
|
|
86
|
+
path: "/search"
|
|
87
|
+
})
|
|
83
88
|
}, {
|
|
84
89
|
iconName: "snowflake",
|
|
85
90
|
name: "Filter",
|
|
86
|
-
hide: !
|
|
91
|
+
hide: !matchPath(location.pathname, {
|
|
92
|
+
path: "/search"
|
|
93
|
+
}),
|
|
87
94
|
// Specify hide if you want to hide this item
|
|
88
95
|
component: makePanelComponent("Filter"),
|
|
89
96
|
actionType: "component",
|
|
90
97
|
// Use 'component' for a component
|
|
91
|
-
pageSpecific:
|
|
98
|
+
pageSpecific: matchPath(location.pathname, {
|
|
99
|
+
path: "/search"
|
|
100
|
+
}),
|
|
92
101
|
isExpandedByDefault: true
|
|
93
102
|
}, {
|
|
94
103
|
iconName: "sun",
|
|
95
104
|
name: "People",
|
|
96
|
-
hide: !
|
|
105
|
+
hide: !matchPath(location.pathname, {
|
|
106
|
+
path: "/profile"
|
|
107
|
+
}),
|
|
97
108
|
// Specify hide if you want to hide this item
|
|
98
109
|
component: makePanelComponent("People"),
|
|
99
110
|
actionType: "component",
|
|
100
111
|
// Use 'component' for a component
|
|
101
|
-
pageSpecific:
|
|
112
|
+
pageSpecific: matchPath(location.pathname, {
|
|
113
|
+
path: "/profile"
|
|
114
|
+
}),
|
|
102
115
|
isExpandedByDefault: true
|
|
103
116
|
}, {
|
|
104
117
|
iconName: "bell",
|
|
@@ -159,32 +172,30 @@ const SideBarWithConfig = () => {
|
|
|
159
172
|
children: [/*#__PURE__*/_jsx(SideNav, {
|
|
160
173
|
items: items,
|
|
161
174
|
sideNavHeight: "500px"
|
|
162
|
-
}), /*#__PURE__*/_jsxs(
|
|
175
|
+
}), /*#__PURE__*/_jsxs(Switch, {
|
|
163
176
|
children: [/*#__PURE__*/_jsx(Route, {
|
|
177
|
+
exact: true,
|
|
164
178
|
path: "/",
|
|
165
|
-
|
|
179
|
+
children: /*#__PURE__*/_jsx(PageCard, {
|
|
166
180
|
children: /*#__PURE__*/_jsx("div", {
|
|
167
181
|
children: "Home"
|
|
168
182
|
})
|
|
169
183
|
})
|
|
170
184
|
}), /*#__PURE__*/_jsx(Route, {
|
|
171
185
|
path: "/profile",
|
|
172
|
-
|
|
186
|
+
children: /*#__PURE__*/_jsx(PageCard, {
|
|
173
187
|
children: /*#__PURE__*/_jsx("div", {
|
|
174
188
|
children: "Profile route"
|
|
175
189
|
})
|
|
176
190
|
})
|
|
177
191
|
}), /*#__PURE__*/_jsx(Route, {
|
|
178
192
|
path: "/teams/:teamId",
|
|
179
|
-
|
|
193
|
+
children: /*#__PURE__*/_jsx(PageCard, {
|
|
180
194
|
children: /*#__PURE__*/_jsx(Teams, {})
|
|
181
195
|
})
|
|
182
|
-
}), /*#__PURE__*/_jsx(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
to: "/",
|
|
186
|
-
replace: true
|
|
187
|
-
})
|
|
196
|
+
}), /*#__PURE__*/_jsx(Redirect, {
|
|
197
|
+
from: "/iframe.html",
|
|
198
|
+
to: "/"
|
|
188
199
|
})]
|
|
189
200
|
})]
|
|
190
201
|
});
|
|
@@ -91,7 +91,7 @@ const SideNavExpanded = styled("div").withConfig({
|
|
|
91
91
|
maxWidth: props.large ? "calc(" + themeGet("appScale.sidebarMaxWidthLarge")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")" : "calc(" + themeGet("appScale.sidebarMaxWidth")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")",
|
|
92
92
|
height: "inherit",
|
|
93
93
|
overflowY: "auto",
|
|
94
|
-
padding: "
|
|
94
|
+
padding: "16px",
|
|
95
95
|
borderLeft: `solid 1px ${themeGet("colors.greyLighter")(props)}`,
|
|
96
96
|
"&:focus": {
|
|
97
97
|
outline: "0"
|
|
@@ -3,7 +3,7 @@ import StyledLink from ".";
|
|
|
3
3
|
import Box from "../Box";
|
|
4
4
|
import Flex from "../Flex";
|
|
5
5
|
import Spacer from "../Spacer";
|
|
6
|
-
import { BrowserRouter, Route,
|
|
6
|
+
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
|
7
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
8
|
export default {
|
|
9
9
|
title: "Components/StyledLink",
|
|
@@ -72,10 +72,11 @@ export const reactLink = () => /*#__PURE__*/_jsxs(BrowserRouter, {
|
|
|
72
72
|
children: [routes.map(route => /*#__PURE__*/_jsx(StyledLink, {
|
|
73
73
|
to: route.path,
|
|
74
74
|
children: route.label
|
|
75
|
-
}, route.path)), /*#__PURE__*/_jsx(
|
|
75
|
+
}, route.path)), /*#__PURE__*/_jsx(Switch, {
|
|
76
76
|
children: routes.map(route => /*#__PURE__*/_jsx(Route, {
|
|
77
77
|
path: route.path,
|
|
78
|
-
|
|
78
|
+
exact: route.exact,
|
|
79
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
79
80
|
style: {
|
|
80
81
|
padding: "100px"
|
|
81
82
|
},
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Tabs from ".";
|
|
3
|
+
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
|
4
|
+
import Box from "../Box";
|
|
5
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
+
export default {
|
|
7
|
+
title: "Components/Tabs",
|
|
8
|
+
decorators: [storyFn => /*#__PURE__*/_jsx(Box, {
|
|
9
|
+
bg: "greyLightest",
|
|
10
|
+
p: "xl",
|
|
11
|
+
pb: "300px",
|
|
12
|
+
children: storyFn()
|
|
13
|
+
})],
|
|
14
|
+
component: Tabs
|
|
15
|
+
};
|
|
16
|
+
const tabsList = [{
|
|
17
|
+
label: "Details",
|
|
18
|
+
path: "/details"
|
|
19
|
+
}, {
|
|
20
|
+
label: "Strategy",
|
|
21
|
+
path: "/strategy"
|
|
22
|
+
}, {
|
|
23
|
+
label: "Associations",
|
|
24
|
+
path: "/associations"
|
|
25
|
+
}, {
|
|
26
|
+
label: "Visualisation",
|
|
27
|
+
path: "/visualisation"
|
|
28
|
+
}, {
|
|
29
|
+
label: "Principles",
|
|
30
|
+
path: "/principles"
|
|
31
|
+
}, {
|
|
32
|
+
label: "Planner",
|
|
33
|
+
path: "/planner"
|
|
34
|
+
}, {
|
|
35
|
+
label: "Forecast",
|
|
36
|
+
path: "/forecast"
|
|
37
|
+
}, {
|
|
38
|
+
label: "Team Builder",
|
|
39
|
+
path: "/teambuilder"
|
|
40
|
+
}, {
|
|
41
|
+
label: "History",
|
|
42
|
+
path: "/history",
|
|
43
|
+
isVisible: false
|
|
44
|
+
}];
|
|
45
|
+
export const defaultTabs = () => /*#__PURE__*/_jsxs(BrowserRouter, {
|
|
46
|
+
children: [/*#__PURE__*/_jsx(Tabs, {
|
|
47
|
+
tabsList: tabsList
|
|
48
|
+
}), /*#__PURE__*/_jsx(Switch, {
|
|
49
|
+
children: tabsList.map(tab => /*#__PURE__*/_jsx(Route, {
|
|
50
|
+
path: tab.path,
|
|
51
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
52
|
+
bg: "white",
|
|
53
|
+
borderRadius: 2,
|
|
54
|
+
boxBorder: "default",
|
|
55
|
+
p: "l",
|
|
56
|
+
mt: "l",
|
|
57
|
+
children: ["ROUTE RENDERED: ", tab.label]
|
|
58
|
+
})
|
|
59
|
+
}, tab.path))
|
|
60
|
+
})]
|
|
61
|
+
});
|
|
62
|
+
defaultTabs.storyName = "Default";
|
|
63
|
+
defaultTabs.__docgenInfo = {
|
|
64
|
+
"description": "",
|
|
65
|
+
"methods": [],
|
|
66
|
+
"displayName": "defaultTabs"
|
|
67
|
+
};
|
|
@@ -1,196 +1,206 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import React, { useState, useRef, useEffect, useCallback } from "react";
|
|
2
|
+
import styled, { css } from "styled-components";
|
|
3
|
+
import { NavLink, useLocation } from "react-router-dom";
|
|
4
|
+
import { isEqual } from "lodash";
|
|
5
|
+
import ActionsMenu, { ActionsMenuItem } from "../ActionsMenu";
|
|
6
|
+
import Icon from "../Icon";
|
|
7
|
+
import FlexItem from "../Flex";
|
|
4
8
|
import { themeGet } from "@styled-system/theme-get";
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
displayName: "Tabs__TabsContainerItem",
|
|
9
|
+
import PropTypes from "prop-types";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
const TabsContainer = styled.div.withConfig({
|
|
12
|
+
displayName: "Tabs__TabsContainer",
|
|
10
13
|
componentId: "sc-15tpvnt-0"
|
|
11
|
-
})(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
alignItems: "center",
|
|
15
|
-
flexWrap: "wrap",
|
|
16
|
-
bg: "transparent"
|
|
17
|
-
}), space);
|
|
18
|
-
export const TabItem = styled("div").withConfig({
|
|
19
|
-
displayName: "Tabs__TabItem",
|
|
14
|
+
})(["position:relative;"]);
|
|
15
|
+
const TabWrapper = styled.div.withConfig({
|
|
16
|
+
displayName: "Tabs__TabWrapper",
|
|
20
17
|
componentId: "sc-15tpvnt-1"
|
|
21
|
-
})(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
color: themeGet("colors.greyDarker")(props),
|
|
32
|
-
display: "flex",
|
|
33
|
-
alignItems: "center",
|
|
34
|
-
position: "relative",
|
|
35
|
-
whiteSpace: "nowrap",
|
|
36
|
-
textDecoration: "none",
|
|
37
|
-
textAlign: "center",
|
|
38
|
-
textTransform: "uppercase",
|
|
39
|
-
cursor: "pointer",
|
|
40
|
-
"&:hover": {
|
|
41
|
-
bg: themeGet("colors.greyLight")(props),
|
|
42
|
-
color: themeGet("colors.greyDarker")(props),
|
|
43
|
-
outline: "0"
|
|
44
|
-
},
|
|
45
|
-
"&:focus": {
|
|
46
|
-
color: themeGet("colors.greyDarker")(props),
|
|
47
|
-
outline: "0",
|
|
48
|
-
boxShadow: themeGet("shadows.thinOutline")(props) + " " + themeGet("colors.grey")(props)
|
|
49
|
-
},
|
|
50
|
-
button: {
|
|
51
|
-
marginLeft: 2
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
"&.active": {
|
|
55
|
-
a: {
|
|
56
|
-
color: themeGet("colors.primary")(props),
|
|
57
|
-
bg: themeGet("colors.white")(props),
|
|
58
|
-
"&:hover": {
|
|
59
|
-
cursor: "default"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"&.notification": {
|
|
64
|
-
a: {
|
|
65
|
-
"&::after": {
|
|
66
|
-
position: "absolute",
|
|
67
|
-
top: "calc(8px * -1)",
|
|
68
|
-
right: "calc(4px * -2)",
|
|
69
|
-
display: "flex",
|
|
70
|
-
alignItems: "center",
|
|
71
|
-
justifyContent: "center",
|
|
72
|
-
width: "20px",
|
|
73
|
-
height: "20px",
|
|
74
|
-
borderRadius: "50%",
|
|
75
|
-
fontSize: themeGet("fontSizes.0")(props),
|
|
76
|
-
fontWeight: themeGet("fontWeights.2")(props),
|
|
77
|
-
content: `"${props.notification}"`,
|
|
78
|
-
bg: themeGet("colors.danger")(props),
|
|
79
|
-
color: themeGet("colors.white")(props),
|
|
80
|
-
zIndex: 4
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}), space, color);
|
|
85
|
-
export const Tab = _ref => {
|
|
18
|
+
})(["position:relative;"]);
|
|
19
|
+
const VisibleTabs = styled.div.withConfig({
|
|
20
|
+
displayName: "Tabs__VisibleTabs",
|
|
21
|
+
componentId: "sc-15tpvnt-2"
|
|
22
|
+
})(["flex-shrink:1;display:flex;align-items:center;overflow:hidden;"]);
|
|
23
|
+
const activeTabStyle = css(["background-color:", ";color:", ";cursor:default;&:hover{background-color:", ";color:", ";}&:focus{color:", ";}"], themeGet("colors.white"), themeGet("colors.primary"), themeGet("colors.white"), themeGet("colors.primary"), themeGet("colors.primary"));
|
|
24
|
+
const Tab = styled(NavLink).withConfig({
|
|
25
|
+
displayName: "Tabs__Tab",
|
|
26
|
+
componentId: "sc-15tpvnt-3"
|
|
27
|
+
})(["width:", ";display:block;border-radius:", ";transition:background 200ms ease-in-out,color 200ms ease-in-out;padding:", " ", ";font-size:", ";font-weight:", ";position:relative;white-space:nowrap;text-decoration:none;text-align:center;text-transform:uppercase;background-color:", ";color:", ";cursor:pointer;", " &:hover{outline:0;background-color:", ";color:", ";}&:focus{outline:0;color:", ";box-shadow:inset ", " ", ";}&.active{", "}"], _ref => {
|
|
86
28
|
let {
|
|
87
|
-
|
|
88
|
-
children,
|
|
89
|
-
active,
|
|
90
|
-
notification,
|
|
91
|
-
...props
|
|
29
|
+
fullWidth
|
|
92
30
|
} = _ref;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
notification: notification,
|
|
96
|
-
role: "presentation",
|
|
97
|
-
className: `${active ? "active" : ""} ${notification ? "notification notification-" + notification : ""}`,
|
|
98
|
-
...props,
|
|
99
|
-
children: React.Children.map(children, child => /*#__PURE__*/React.cloneElement(child, {
|
|
100
|
-
role: "tab",
|
|
101
|
-
"aria-selected": `${active}`
|
|
102
|
-
}))
|
|
103
|
-
});
|
|
104
|
-
return theme ? /*#__PURE__*/_jsx(ThemeProvider, {
|
|
105
|
-
theme: theme,
|
|
106
|
-
children: component
|
|
107
|
-
}) : component;
|
|
108
|
-
};
|
|
109
|
-
Tab.propTypes = {
|
|
110
|
-
/** Specifies whether the tab is the active tab */
|
|
111
|
-
active: PropTypes.bool,
|
|
112
|
-
/** Specifies any notifications attached to the Tab */
|
|
113
|
-
notification: PropTypes.string,
|
|
114
|
-
/** Specifies the colour theme */
|
|
115
|
-
theme: PropTypes.object,
|
|
116
|
-
/** The content of the Tab is passed as a child. */
|
|
117
|
-
children: PropTypes.node
|
|
118
|
-
};
|
|
119
|
-
export const TabsContainer = _ref2 => {
|
|
31
|
+
return fullWidth ? "100%" : "fit-content";
|
|
32
|
+
}, themeGet("radii.2"), themeGet("space.3"), themeGet("space.4"), themeGet("fontSizes.1"), themeGet("fontWeights.2"), themeGet("colors.greyLighter"), themeGet("colors.greyDarker"), _ref2 => {
|
|
120
33
|
let {
|
|
121
|
-
|
|
122
|
-
children,
|
|
123
|
-
...props
|
|
34
|
+
tabInShowMore
|
|
124
35
|
} = _ref2;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
36
|
+
return tabInShowMore ? css(["position:absolute;visibility:hidden;"]) : "";
|
|
37
|
+
}, themeGet("colors.greyLight"), themeGet("colors.greyDarker"), themeGet("colors.greyDarker"), themeGet("shadows.thinOutline"), themeGet("colors.grey"), activeTabStyle);
|
|
38
|
+
const ShowMoreButton = styled.button.withConfig({
|
|
39
|
+
displayName: "Tabs__ShowMoreButton",
|
|
40
|
+
componentId: "sc-15tpvnt-4"
|
|
41
|
+
})(["appearance:none;border:none;font-family:", ";font-size:", ";font-weight:", ";border-radius:", ";background-color:", ";transition:", ";padding:", " ", ";color:", ";display:", ";align-items:center;&:hover{background-color:", ";color:", ";outline:0;}&:focus{color:", ";outline:0;box-shadow:inset ", " ", ";}&.hasActive{", "}"], themeGet("fonts.main"), themeGet("fontSizes.1"), themeGet("fontWeights.2"), themeGet("radii.2"), themeGet("colors.greyLighter"), themeGet("transition.transitionDefault"), themeGet("space.3"), themeGet("space.4"), themeGet("colors.greyDarker"), _ref3 => {
|
|
42
|
+
let {
|
|
43
|
+
showMoreVisible
|
|
44
|
+
} = _ref3;
|
|
45
|
+
return showMoreVisible ? "flex" : "none";
|
|
46
|
+
}, themeGet("colors.greyLight"), themeGet("colors.greyDarker"), themeGet("colors.greyDarker"), themeGet("shadows.thinOutline"), themeGet("colors.grey"), activeTabStyle);
|
|
47
|
+
const ShowMoreTabs = styled.div.withConfig({
|
|
48
|
+
displayName: "Tabs__ShowMoreTabs",
|
|
49
|
+
componentId: "sc-15tpvnt-5"
|
|
50
|
+
})(["border-radius:", ";background-color:", ";min-width:84px;display:flex;flex-direction:column;align-items:center;gap:6px;padding:6px;box-shadow:inset ", " ", ",", ";"], themeGet("radii.2"), themeGet("colors.white"), themeGet("shadows.thinOutline"), themeGet("colors.greyLighter"), themeGet("shadows.boxDefault"));
|
|
51
|
+
const tabsGap = 6;
|
|
52
|
+
const Tabs = _ref4 => {
|
|
53
|
+
let {
|
|
54
|
+
tabsList
|
|
55
|
+
} = _ref4;
|
|
56
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
57
|
+
const containerRef = useRef(null);
|
|
58
|
+
const showMoreButtonRef = useRef();
|
|
59
|
+
const containerVisibleWidth = useRef(0);
|
|
60
|
+
const [showMoreTabs, setShowMoreTabs] = useState([]);
|
|
61
|
+
const calculateVisibility = useCallback(actionElements => {
|
|
62
|
+
const showMoreButtonWidth = showMoreButtonRef?.current?.offsetWidth ?? 0;
|
|
63
|
+
// as we loop through the tabs, we need to calculate the width of the visible tabs.
|
|
64
|
+
let calculatedWidth = showMoreTabs.length ? showMoreButtonWidth : 0;
|
|
65
|
+
|
|
66
|
+
// variable for the list of hidden tabs which will be put to react state
|
|
67
|
+
const newShowMoreTabs = [];
|
|
68
|
+
[...actionElements].filter(el => el.tagName === "A") // this ensures that the ShowMore button is not included in this logic
|
|
69
|
+
.forEach((actionEl, i) => {
|
|
70
|
+
// visibleElementsWidth will be increased by
|
|
71
|
+
// the corresponding width of the element + gapWidth
|
|
72
|
+
calculatedWidth += actionEl.offsetWidth + tabsGap;
|
|
73
|
+
|
|
74
|
+
// compare computed widths and push into newShowMoreTabs if current tab width is bigger than container width
|
|
75
|
+
if (calculatedWidth >= containerVisibleWidth.current) {
|
|
76
|
+
newShowMoreTabs.push(i);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
if (!isEqual(showMoreTabs, newShowMoreTabs)) {
|
|
80
|
+
// update React state with the list of hidden tabs
|
|
81
|
+
setShowMoreTabs(newShowMoreTabs);
|
|
82
|
+
}
|
|
83
|
+
}, [showMoreTabs]);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const actionElements = containerRef.current?.children || [];
|
|
86
|
+
const resizeObserver = new ResizeObserver(entries => {
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (entry.contentBoxSize) {
|
|
89
|
+
const contentBoxSize = entry.contentBoxSize[0];
|
|
90
|
+
|
|
91
|
+
// Math.ceil is necessary to round up and return
|
|
92
|
+
// the smallest integer for the size of observed element
|
|
93
|
+
containerVisibleWidth.current = Math.ceil(contentBoxSize.inlineSize);
|
|
94
|
+
|
|
95
|
+
// invoke the functions which calculates tabs visibility
|
|
96
|
+
// and sets data to the list of hidden tabs
|
|
97
|
+
calculateVisibility(actionElements);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// This is to help in cases where useEffect callback is triggered before React repaint.
|
|
103
|
+
if (!isMounted) {
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
setIsMounted(true);
|
|
106
|
+
calculateVisibility(actionElements);
|
|
107
|
+
}, 500);
|
|
108
|
+
} else {
|
|
109
|
+
// adding ResizeObserver to the observed container
|
|
110
|
+
resizeObserver.observe(containerRef.current);
|
|
111
|
+
}
|
|
112
|
+
}, [calculateVisibility, isMounted]);
|
|
113
|
+
const visibleTabsList = tabsList.filter(tab => tab.isVisible ?? true);
|
|
114
|
+
const showMoreTabsList = visibleTabsList.filter((_tab, i) => showMoreTabs.includes(i));
|
|
115
|
+
const location = useLocation();
|
|
116
|
+
const showMoreItemActive = showMoreTabsList.find(action => location.pathname.endsWith(action.path));
|
|
117
|
+
return /*#__PURE__*/_jsx(TabsContainer, {
|
|
118
|
+
children: /*#__PURE__*/_jsx(TabWrapper, {
|
|
119
|
+
children: /*#__PURE__*/_jsxs(VisibleTabs, {
|
|
120
|
+
style: {
|
|
121
|
+
gap: tabsGap
|
|
122
|
+
},
|
|
123
|
+
ref: containerRef,
|
|
124
|
+
children: [visibleTabsList.map((tab, i) => /*#__PURE__*/_jsx(Tab, {
|
|
125
|
+
className: tab.className,
|
|
126
|
+
id: tab.id,
|
|
127
|
+
"data-testid": tab["data-testid"],
|
|
128
|
+
tabInShowMore: showMoreTabs.includes(i),
|
|
129
|
+
to: tab.path,
|
|
130
|
+
children: tab.label
|
|
131
|
+
}, tab.path)), /*#__PURE__*/_jsx(ActionsMenu, {
|
|
132
|
+
direction: "bottom-end",
|
|
133
|
+
customTriggerComponent: /*#__PURE__*/_jsxs(ShowMoreButton, {
|
|
134
|
+
ref: showMoreButtonRef,
|
|
135
|
+
showMoreVisible: showMoreTabsList.length,
|
|
136
|
+
className: showMoreItemActive && "hasActive",
|
|
137
|
+
children: [/*#__PURE__*/_jsx(FlexItem, {
|
|
138
|
+
flex: "0 0 auto",
|
|
139
|
+
children: "More"
|
|
140
|
+
}), /*#__PURE__*/_jsx(FlexItem, {
|
|
141
|
+
flex: "0 0 auto",
|
|
142
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
143
|
+
icon: ["fas", "chevron-down"],
|
|
144
|
+
title: "Down",
|
|
145
|
+
ml: "s",
|
|
146
|
+
size: "sm"
|
|
147
|
+
})
|
|
148
|
+
})]
|
|
149
|
+
}),
|
|
150
|
+
closeOnClick: true,
|
|
151
|
+
children: /*#__PURE__*/_jsx(ShowMoreTabs, {
|
|
152
|
+
children: showMoreTabsList.map(tab => /*#__PURE__*/_jsx(ActionsMenuItem, {
|
|
153
|
+
className: tab.className,
|
|
154
|
+
id: tab.id,
|
|
155
|
+
"data-testid": tab["data-testid"],
|
|
156
|
+
Component: Tab,
|
|
157
|
+
fullWidth: true,
|
|
158
|
+
to: tab.path,
|
|
159
|
+
children: tab.label
|
|
160
|
+
}, tab.path))
|
|
161
|
+
})
|
|
162
|
+
})]
|
|
163
|
+
})
|
|
164
|
+
})
|
|
129
165
|
});
|
|
130
|
-
return theme ? /*#__PURE__*/_jsx(ThemeProvider, {
|
|
131
|
-
theme: theme,
|
|
132
|
-
children: component
|
|
133
|
-
}) : component;
|
|
134
166
|
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
167
|
+
Tabs.propTypes = {
|
|
168
|
+
/** isVisible defaults to true if not passed */
|
|
169
|
+
tabsList: PropTypes.arrayOf(PropTypes.shape({
|
|
170
|
+
label: PropTypes.string.isRequired,
|
|
171
|
+
path: PropTypes.string.isRequired,
|
|
172
|
+
isVisible: PropTypes.bool
|
|
173
|
+
})).isRequired
|
|
140
174
|
};
|
|
141
|
-
|
|
175
|
+
Tabs.__docgenInfo = {
|
|
142
176
|
"description": "",
|
|
143
177
|
"methods": [],
|
|
144
|
-
"displayName": "
|
|
178
|
+
"displayName": "Tabs",
|
|
145
179
|
"props": {
|
|
146
|
-
"
|
|
147
|
-
"description": "
|
|
148
|
-
"type": {
|
|
149
|
-
"name": "bool"
|
|
150
|
-
},
|
|
151
|
-
"required": false
|
|
152
|
-
},
|
|
153
|
-
"notification": {
|
|
154
|
-
"description": "Specifies any notifications attached to the Tab",
|
|
155
|
-
"type": {
|
|
156
|
-
"name": "string"
|
|
157
|
-
},
|
|
158
|
-
"required": false
|
|
159
|
-
},
|
|
160
|
-
"theme": {
|
|
161
|
-
"description": "Specifies the colour theme",
|
|
162
|
-
"type": {
|
|
163
|
-
"name": "object"
|
|
164
|
-
},
|
|
165
|
-
"required": false
|
|
166
|
-
},
|
|
167
|
-
"children": {
|
|
168
|
-
"description": "The content of the Tab is passed as a child.",
|
|
180
|
+
"tabsList": {
|
|
181
|
+
"description": "isVisible defaults to true if not passed",
|
|
169
182
|
"type": {
|
|
170
|
-
"name": "
|
|
183
|
+
"name": "arrayOf",
|
|
184
|
+
"value": {
|
|
185
|
+
"name": "shape",
|
|
186
|
+
"value": {
|
|
187
|
+
"label": {
|
|
188
|
+
"name": "string",
|
|
189
|
+
"required": true
|
|
190
|
+
},
|
|
191
|
+
"path": {
|
|
192
|
+
"name": "string",
|
|
193
|
+
"required": true
|
|
194
|
+
},
|
|
195
|
+
"isVisible": {
|
|
196
|
+
"name": "bool",
|
|
197
|
+
"required": false
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
171
201
|
},
|
|
172
|
-
"required":
|
|
202
|
+
"required": true
|
|
173
203
|
}
|
|
174
204
|
}
|
|
175
205
|
};
|
|
176
|
-
|
|
177
|
-
"description": "",
|
|
178
|
-
"methods": [],
|
|
179
|
-
"displayName": "TabsContainer",
|
|
180
|
-
"props": {
|
|
181
|
-
"children": {
|
|
182
|
-
"description": "The contents of the TabsContainer are passed as a child.",
|
|
183
|
-
"type": {
|
|
184
|
-
"name": "node"
|
|
185
|
-
},
|
|
186
|
-
"required": false
|
|
187
|
-
},
|
|
188
|
-
"theme": {
|
|
189
|
-
"description": "Specifies the colour theme of the container",
|
|
190
|
-
"type": {
|
|
191
|
-
"name": "object"
|
|
192
|
-
},
|
|
193
|
-
"required": false
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
};
|
|
206
|
+
export default Tabs;
|
package/es/components.test.js
CHANGED
package/es/index.js
CHANGED
|
@@ -37,7 +37,7 @@ export { default as Spacer } from "./components/Spacer";
|
|
|
37
37
|
export { default as StatusDot } from "./components/StatusDot";
|
|
38
38
|
export { default as StyledLink, styleLink } from "./components/StyledLink";
|
|
39
39
|
export { default as Table } from "./components/Table";
|
|
40
|
-
export {
|
|
40
|
+
export { default as Tabs } from "./components/Tabs";
|
|
41
41
|
export { default as Tag } from "./components/Tag";
|
|
42
42
|
export { default as TextInput } from "./components/TextInput";
|
|
43
43
|
export { default as TextArea } from "./components/TextArea";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orcs-design-system",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.41",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": "20.12.2"
|
|
6
6
|
},
|
|
@@ -47,16 +47,15 @@
|
|
|
47
47
|
"@emotion/react": "^11.11.4",
|
|
48
48
|
"@emotion/styled": "^11.11.5",
|
|
49
49
|
"@floating-ui/react": "^0.26.19",
|
|
50
|
-
"@mui/icons-material": "^
|
|
51
|
-
"@mui/material": "^
|
|
52
|
-
"@mui/
|
|
53
|
-
"@mui/x-date-pickers": "^7.16.0",
|
|
50
|
+
"@mui/icons-material": "^5.16.7",
|
|
51
|
+
"@mui/material": "^5.16.7",
|
|
52
|
+
"@mui/x-date-pickers": "^7.14.0",
|
|
54
53
|
"@styled-system/css": "^5.1.5",
|
|
55
54
|
"@styled-system/prop-types": "^5.1.5",
|
|
56
55
|
"@styled-system/should-forward-prop": "^5.1.5",
|
|
57
56
|
"@styled-system/theme-get": "^5.1.2",
|
|
58
57
|
"focus-trap-react": "^10.2.3",
|
|
59
|
-
"material-react-table": "^2.13.
|
|
58
|
+
"material-react-table": "^2.13.2",
|
|
60
59
|
"polished": "^3.7.1",
|
|
61
60
|
"prop-types": "^15.6.2",
|
|
62
61
|
"react-app-polyfill": "^2.0.0",
|
|
@@ -66,7 +65,7 @@
|
|
|
66
65
|
"react-intersection-observer": "^9.4.3",
|
|
67
66
|
"react-moment-proptypes": "^1.8.1",
|
|
68
67
|
"react-number-format": "^5.3.0",
|
|
69
|
-
"react-router-dom": "^
|
|
68
|
+
"react-router-dom": "^5.3.4",
|
|
70
69
|
"react-select": "^5.7.4",
|
|
71
70
|
"styled-system": "^5.1.5"
|
|
72
71
|
},
|
|
@@ -97,7 +96,7 @@
|
|
|
97
96
|
"@storybook/core-events": "^8.1.7",
|
|
98
97
|
"@storybook/manager-api": "^8.1.7",
|
|
99
98
|
"@storybook/mdx1-csf": "^1.0.0",
|
|
100
|
-
"@storybook/preset-create-react-app": "^8.
|
|
99
|
+
"@storybook/preset-create-react-app": "^8.3.3",
|
|
101
100
|
"@storybook/react": "^8.1.7",
|
|
102
101
|
"@storybook/react-webpack5": "^8.2.9",
|
|
103
102
|
"@storybook/storybook-deployer": "2.8.16",
|
|
@@ -161,7 +160,16 @@
|
|
|
161
160
|
"path-to-regexp": "0.1.10"
|
|
162
161
|
},
|
|
163
162
|
"send": "0.19.0",
|
|
164
|
-
"redux": "4.2.1"
|
|
163
|
+
"redux": "4.2.1",
|
|
164
|
+
"workbox-build": {
|
|
165
|
+
"rollup": ">=3.29.5"
|
|
166
|
+
},
|
|
167
|
+
"@rollup/plugin-babel": {
|
|
168
|
+
"rollup": ">=3.29.5"
|
|
169
|
+
},
|
|
170
|
+
"@rollup/plugin-replace": {
|
|
171
|
+
"rollup": ">=3.29.5"
|
|
172
|
+
}
|
|
165
173
|
},
|
|
166
174
|
"browserslist": [
|
|
167
175
|
">0.2%",
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import Box from "../Box";
|
|
3
|
-
import { TabsContainer, Tab } from ".";
|
|
4
|
-
import Popover from "../Popover";
|
|
5
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
-
export default {
|
|
7
|
-
title: "Components/Tabs/Tab",
|
|
8
|
-
decorators: [storyFn => /*#__PURE__*/_jsx(Box, {
|
|
9
|
-
bg: "greyLightest",
|
|
10
|
-
p: "xl",
|
|
11
|
-
children: storyFn()
|
|
12
|
-
})],
|
|
13
|
-
component: Tab
|
|
14
|
-
};
|
|
15
|
-
export const activeTab = () => /*#__PURE__*/_jsxs(TabsContainer, {
|
|
16
|
-
children: [/*#__PURE__*/_jsx(Tab, {
|
|
17
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
18
|
-
href: "#",
|
|
19
|
-
children: "Details"
|
|
20
|
-
})
|
|
21
|
-
}), /*#__PURE__*/_jsx(Tab, {
|
|
22
|
-
active: true,
|
|
23
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
24
|
-
href: "#",
|
|
25
|
-
children: "Planning"
|
|
26
|
-
})
|
|
27
|
-
})]
|
|
28
|
-
});
|
|
29
|
-
activeTab.story = {
|
|
30
|
-
name: "Active Tab"
|
|
31
|
-
};
|
|
32
|
-
export const withNotificationsTab = () => /*#__PURE__*/_jsxs(TabsContainer, {
|
|
33
|
-
children: [/*#__PURE__*/_jsx(Tab, {
|
|
34
|
-
notification: "1",
|
|
35
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
36
|
-
href: "#",
|
|
37
|
-
children: "Details"
|
|
38
|
-
})
|
|
39
|
-
}), /*#__PURE__*/_jsx(Tab, {
|
|
40
|
-
notification: "7",
|
|
41
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
42
|
-
href: "#",
|
|
43
|
-
children: "Planning"
|
|
44
|
-
})
|
|
45
|
-
})]
|
|
46
|
-
});
|
|
47
|
-
activeTab.story = {
|
|
48
|
-
name: "With Notifications Tab"
|
|
49
|
-
};
|
|
50
|
-
export const withPopoverTab = () => /*#__PURE__*/_jsxs(TabsContainer, {
|
|
51
|
-
children: [/*#__PURE__*/_jsx(Popover, {
|
|
52
|
-
direction: "right",
|
|
53
|
-
text: "Example with tooltip explaining tab",
|
|
54
|
-
width: "218px",
|
|
55
|
-
children: /*#__PURE__*/_jsx(Tab, {
|
|
56
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
57
|
-
href: "#",
|
|
58
|
-
children: "Details"
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
}), /*#__PURE__*/_jsx(Popover, {
|
|
62
|
-
direction: "top",
|
|
63
|
-
text: "Example with tooltip explaining tab",
|
|
64
|
-
width: "218px",
|
|
65
|
-
children: /*#__PURE__*/_jsx(Tab, {
|
|
66
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
67
|
-
href: "#",
|
|
68
|
-
tabIndex: "-1",
|
|
69
|
-
children: "Additional information"
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
})]
|
|
73
|
-
});
|
|
74
|
-
withPopoverTab.story = {
|
|
75
|
-
name: "With Popover Tab"
|
|
76
|
-
};
|
|
77
|
-
activeTab.__docgenInfo = {
|
|
78
|
-
"description": "",
|
|
79
|
-
"methods": [],
|
|
80
|
-
"displayName": "activeTab"
|
|
81
|
-
};
|
|
82
|
-
withNotificationsTab.__docgenInfo = {
|
|
83
|
-
"description": "",
|
|
84
|
-
"methods": [],
|
|
85
|
-
"displayName": "withNotificationsTab"
|
|
86
|
-
};
|
|
87
|
-
withPopoverTab.__docgenInfo = {
|
|
88
|
-
"description": "",
|
|
89
|
-
"methods": [],
|
|
90
|
-
"displayName": "withPopoverTab"
|
|
91
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import Box from "../Box";
|
|
3
|
-
import Popover from "../Popover";
|
|
4
|
-
import { TabsContainer, Tab } from ".";
|
|
5
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
-
export default {
|
|
7
|
-
title: "Components/Tabs",
|
|
8
|
-
decorators: [storyFn => /*#__PURE__*/_jsx(Box, {
|
|
9
|
-
bg: "greyLightest",
|
|
10
|
-
p: "xl",
|
|
11
|
-
children: storyFn()
|
|
12
|
-
})],
|
|
13
|
-
component: TabsContainer
|
|
14
|
-
};
|
|
15
|
-
export const defaultTabs = () => /*#__PURE__*/_jsxs(TabsContainer, {
|
|
16
|
-
children: [/*#__PURE__*/_jsx(Tab, {
|
|
17
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
18
|
-
href: "#",
|
|
19
|
-
children: "Details"
|
|
20
|
-
})
|
|
21
|
-
}), /*#__PURE__*/_jsx(Popover, {
|
|
22
|
-
direction: "top",
|
|
23
|
-
text: "Example with tooltip explaining tab",
|
|
24
|
-
width: "218px",
|
|
25
|
-
children: /*#__PURE__*/_jsx(Tab, {
|
|
26
|
-
active: true,
|
|
27
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
28
|
-
href: "#",
|
|
29
|
-
tabIndex: "-1",
|
|
30
|
-
children: "Additional information"
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
}), /*#__PURE__*/_jsx(Tab, {
|
|
34
|
-
notification: "97",
|
|
35
|
-
children: /*#__PURE__*/_jsx("a", {
|
|
36
|
-
href: "#",
|
|
37
|
-
children: "Planning"
|
|
38
|
-
})
|
|
39
|
-
})]
|
|
40
|
-
});
|
|
41
|
-
defaultTabs.story = {
|
|
42
|
-
name: "Default Tabs"
|
|
43
|
-
};
|
|
44
|
-
defaultTabs.__docgenInfo = {
|
|
45
|
-
"description": "",
|
|
46
|
-
"methods": [],
|
|
47
|
-
"displayName": "defaultTabs"
|
|
48
|
-
};
|