orcs-design-system 3.3.0 → 3.3.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.
@@ -9,7 +9,7 @@ export const Bar = styled("header").attrs(props => ({
9
9
  displayName: "Headerstyles__Bar",
10
10
  componentId: "sc-xs8ba0-0"
11
11
  })(props => ({
12
- height: themeGet("appScale.navBarSize")(props)
12
+ height: themeGet("appScale.newNavBarSize")(props)
13
13
  }), css({
14
14
  width: "100%",
15
15
  zIndex: 12,
@@ -56,7 +56,7 @@ export const SearchContainer = styled("div").withConfig({
56
56
  displayName: "Headerstyles__SearchContainer",
57
57
  componentId: "sc-xs8ba0-2"
58
58
  })(props => css({
59
- maxWidth: "600px",
59
+ maxWidth: "550px",
60
60
  flex: "1 1 auto",
61
61
  borderRadius: themeGet("radii.2")(props),
62
62
  boxShadow: themeGet("shadows.boxDefault")(props)
@@ -87,8 +87,8 @@ const SideNavExpanded = styled("div").withConfig({
87
87
  })(props => css({
88
88
  position: "relative",
89
89
  display: props.active ? "block" : "none",
90
- minWidth: props.large ? "calc(" + themeGet("appScale.sidebarMaxWidthLarge")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")" : "calc(" + themeGet("appScale.sidebarMaxWidth")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")",
91
- maxWidth: props.large ? "calc(" + themeGet("appScale.sidebarMaxWidthLarge")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")" : "calc(" + themeGet("appScale.sidebarMaxWidth")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")",
90
+ minWidth: props.large ? "calc(" + themeGet("appScale.sidebarMaxWidthLarge")(props) + " - " + themeGet("appScale.newNavBarSize")(props) + ")" : "calc(" + themeGet("appScale.sidebarMaxWidth")(props) + " - " + themeGet("appScale.newNavBarSize")(props) + ")",
91
+ maxWidth: props.large ? "calc(" + themeGet("appScale.sidebarMaxWidthLarge")(props) + " - " + themeGet("appScale.newNavBarSize")(props) + ")" : "calc(" + themeGet("appScale.sidebarMaxWidth")(props) + " - " + themeGet("appScale.newNavBarSize")(props) + ")",
92
92
  height: "inherit",
93
93
  overflowY: "auto",
94
94
  padding: "16px",
@@ -102,7 +102,7 @@ const SideNavExpanded = styled("div").withConfig({
102
102
  maxWidth: "initial",
103
103
  borderLeft: "none",
104
104
  borderBottom: `solid 1px ${themeGet("colors.greyLighter")(props)}`,
105
- height: "calc(" + themeGet("appScale.sidebarMobileHeight")(props) + " - " + themeGet("appScale.navBarSize")(props) + ")"
105
+ height: "calc(" + themeGet("appScale.sidebarMobileHeight")(props) + " - " + themeGet("appScale.newNavBarSize")(props) + ")"
106
106
  }
107
107
  }));
108
108
  const SideNav = _ref => {
@@ -0,0 +1,64 @@
1
+ import React from "react";
2
+ import TabsAlt 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/TabsAlt",
8
+ decorators: [storyFn => /*#__PURE__*/_jsx(Box, {
9
+ boxBorder: "default",
10
+ shadow: "default",
11
+ pb: "200px",
12
+ children: storyFn()
13
+ })],
14
+ component: TabsAlt
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(TabsAlt, {
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
+ p: "l",
53
+ mt: "l",
54
+ children: ["ROUTE RENDERED: ", tab.label]
55
+ })
56
+ }, tab.path))
57
+ })]
58
+ });
59
+ defaultTabs.storyName = "Default";
60
+ defaultTabs.__docgenInfo = {
61
+ "description": "",
62
+ "methods": [],
63
+ "displayName": "defaultTabs"
64
+ };
@@ -0,0 +1,211 @@
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";
8
+ import { themeGet } from "@styled-system/theme-get";
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: "TabsAlt__TabsContainer",
13
+ componentId: "sc-hkpvfu-0"
14
+ })(["position:relative;width:100%;&:after{content:\"\";position:absolute;bottom:0;width:100%;height:37px;background-color:", ";border-bottom:2px solid ", ";z-index:0;}"], themeGet("colors.white"), themeGet("colors.greyLighter"));
15
+ const TabWrapper = styled.div.withConfig({
16
+ displayName: "TabsAlt__TabWrapper",
17
+ componentId: "sc-hkpvfu-1"
18
+ })(["position:relative;width:100%;z-index:1;"]);
19
+ const VisibleTabs = styled.div.withConfig({
20
+ displayName: "TabsAlt__VisibleTabs",
21
+ componentId: "sc-hkpvfu-2"
22
+ })(["flex-shrink:1;display:flex;align-items:center;justify-content:flex-start;overflow:hidden;"]);
23
+ const activeTabStyle = css(["background-color:", ";color:", ";border-bottom:2px solid ", ";cursor:default;&:hover,&:focus{background-color:", ";color:", ";box-shadow:none;}"], themeGet("colors.white"), themeGet("colors.primary"), themeGet("colors.primary"), themeGet("colors.white"), themeGet("colors.primary"));
24
+ const Tab = styled(NavLink).withConfig({
25
+ displayName: "TabsAlt__Tab",
26
+ componentId: "sc-hkpvfu-3"
27
+ })(["width:", ";display:block;transition:background 200ms ease-in-out,color 200ms ease-in-out;border-bottom:2px solid ", ";padding:", " ", ";font-size:", ";font-weight:", ";position:relative;white-space:nowrap;text-decoration:none;text-align:center;background-color:", ";color:", ";cursor:pointer;", " &:hover{background-color:", ";color:", ";box-shadow:inset 0 2px 5px 0 ", ";}&:focus{outline:0;box-shadow:inset 0 2px 5px 0 ", ";}&.active{", "}"], _ref => {
28
+ let {
29
+ fullWidth
30
+ } = _ref;
31
+ return fullWidth ? "100%" : "fit-content";
32
+ }, themeGet("colors.greyLighter"), themeGet("space.3"), themeGet("space.4"), themeGet("fontSizes.1"), themeGet("fontWeights.2"), themeGet("colors.white"), themeGet("colors.greyDark"), _ref2 => {
33
+ let {
34
+ tabInShowMore
35
+ } = _ref2;
36
+ return tabInShowMore ? css(["position:absolute;visibility:hidden;"]) : "";
37
+ }, themeGet("colors.white"), themeGet("colors.primary"), themeGet("colors.primaryLightest"), themeGet("colors.primaryLightest"), activeTabStyle);
38
+ const ShowMoreButton = styled.button.withConfig({
39
+ displayName: "TabsAlt__ShowMoreButton",
40
+ componentId: "sc-hkpvfu-4"
41
+ })(["appearance:none;border:none;font-family:", ";font-size:", ";font-weight:", ";background-color:", ";border-bottom:2px solid ", ";transition:", ";padding:", " ", ";color:", ";display:", ";align-items:center;cursor:pointer;&:hover{background-color:", ";color:", ";box-shadow:inset 0 2px 5px 0 ", ";}&:focus{outline:0;box-shadow:inset 0 2px 5px 0 ", ";}&.hasActive{", "}"], themeGet("fonts.main"), themeGet("fontSizes.1"), themeGet("fontWeights.2"), themeGet("colors.white"), themeGet("colors.greyLighter"), themeGet("transition.transitionDefault"), themeGet("space.3"), themeGet("space.4"), themeGet("colors.greyDark"), _ref3 => {
42
+ let {
43
+ showMoreVisible
44
+ } = _ref3;
45
+ return showMoreVisible ? "flex" : "none";
46
+ }, themeGet("colors.white"), themeGet("colors.primary"), themeGet("colors.primaryLightest"), themeGet("colors.primaryLightest"), activeTabStyle);
47
+ const ShowMoreTabs = styled.div.withConfig({
48
+ displayName: "TabsAlt__ShowMoreTabs",
49
+ componentId: "sc-hkpvfu-5"
50
+ })(["border-radius:", ";background-color:", ";width:fit-content;overflow:hidden;display:flex;gap:1px;flex-direction:column;justify-content:flex-start;box-shadow:", ";& [class^=\"TabsAlt__Tab\"]{border:0;padding:", ";text-align:left;}"], themeGet("radii.2"), themeGet("colors.greyLighter"), themeGet("shadows.boxDefault"), themeGet("space.3"));
51
+ const tabsGap = 0;
52
+ const TabsAlt = _ref4 => {
53
+ let {
54
+ tabsList
55
+ } = _ref4;
56
+ const [isMounted, setIsMounted] = useState(false);
57
+ const containerRef = useRef(null);
58
+ const containerVisibleWidth = useRef(0);
59
+ const [showMoreTabs, setShowMoreTabs] = useState([]);
60
+ const calculateVisibility = useCallback(actionElements => {
61
+ const showMoreButton = document.getElementById("show-more-button");
62
+ const showMoreButtonWidth = showMoreButton?.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
+ role: "tablist",
125
+ children: [visibleTabsList.map((tab, i) => /*#__PURE__*/_jsx(Tab, {
126
+ className: tab.className,
127
+ id: tab.id,
128
+ "data-testid": tab["data-testid"],
129
+ tabInShowMore: showMoreTabs.includes(i),
130
+ to: tab.path,
131
+ role: "tab",
132
+ children: tab.label
133
+ }, tab.path)), /*#__PURE__*/_jsx(ActionsMenu, {
134
+ direction: "bottom-end",
135
+ role: "presentation",
136
+ renderTrigger: props => /*#__PURE__*/_jsxs(ShowMoreButton, {
137
+ ...props,
138
+ showMoreVisible: showMoreTabsList.length,
139
+ id: "show-more-button",
140
+ className: showMoreItemActive && "hasActive",
141
+ role: "tab",
142
+ children: [/*#__PURE__*/_jsx(FlexItem, {
143
+ flex: "0 0 auto",
144
+ children: "More"
145
+ }), /*#__PURE__*/_jsx(FlexItem, {
146
+ flex: "0 0 auto",
147
+ children: /*#__PURE__*/_jsx(Icon, {
148
+ icon: ["fas", "chevron-down"],
149
+ title: "Down",
150
+ ml: "xs",
151
+ size: "sm"
152
+ })
153
+ })]
154
+ }),
155
+ closeOnClick: true,
156
+ children: /*#__PURE__*/_jsx(ShowMoreTabs, {
157
+ children: showMoreTabsList.map(tab => /*#__PURE__*/_jsx(ActionsMenuItem, {
158
+ className: tab.className,
159
+ id: tab.id,
160
+ "data-testid": tab["data-testid"],
161
+ Component: Tab,
162
+ fullWidth: true,
163
+ to: tab.path,
164
+ children: tab.label
165
+ }, tab.path))
166
+ })
167
+ })]
168
+ })
169
+ })
170
+ });
171
+ };
172
+ TabsAlt.propTypes = {
173
+ /** isVisible defaults to true if not passed */
174
+ tabsList: PropTypes.arrayOf(PropTypes.shape({
175
+ label: PropTypes.string.isRequired,
176
+ path: PropTypes.string.isRequired,
177
+ isVisible: PropTypes.bool
178
+ })).isRequired
179
+ };
180
+ TabsAlt.__docgenInfo = {
181
+ "description": "",
182
+ "methods": [],
183
+ "displayName": "TabsAlt",
184
+ "props": {
185
+ "tabsList": {
186
+ "description": "isVisible defaults to true if not passed",
187
+ "type": {
188
+ "name": "arrayOf",
189
+ "value": {
190
+ "name": "shape",
191
+ "value": {
192
+ "label": {
193
+ "name": "string",
194
+ "required": true
195
+ },
196
+ "path": {
197
+ "name": "string",
198
+ "required": true
199
+ },
200
+ "isVisible": {
201
+ "name": "bool",
202
+ "required": false
203
+ }
204
+ }
205
+ }
206
+ },
207
+ "required": true
208
+ }
209
+ }
210
+ };
211
+ export default TabsAlt;
@@ -59,6 +59,7 @@ test("all components exported", () => {
59
59
  "SystemThemeProvider",
60
60
  "Table",
61
61
  "Tabs",
62
+ "TabsAlt",
62
63
  "Tag",
63
64
  "Text",
64
65
  "TextArea",
package/es/index.js CHANGED
@@ -40,6 +40,7 @@ export { default as StatusDot } from "./components/StatusDot";
40
40
  export { default as StyledLink, styleLink } from "./components/StyledLink";
41
41
  export { default as Table } from "./components/Table";
42
42
  export { default as Tabs } from "./components/Tabs";
43
+ export { default as TabsAlt } from "./components/TabsAlt";
43
44
  export { default as Tag } from "./components/Tag";
44
45
  export { default as TextInput } from "./components/TextInput";
45
46
  export { default as TextArea } from "./components/TextArea";
@@ -6,7 +6,7 @@ export const fonts = {
6
6
  };
7
7
  export const font = fonts.main;
8
8
  export const fontFamilies = fonts;
9
- export const fontSizes = ["1.1rem", "1.2rem", "1.4rem", "1.6rem", "1.8rem", "2.2rem", "2.6rem", "3.0rem", "3.4rem", "4.4rem", "6rem"];
9
+ export const fontSizes = ["1.1rem", "1.2rem", "1.3rem", "1.6rem", "1.8rem", "2.2rem", "2.6rem", "3.0rem", "3.4rem", "4.4rem", "6rem"];
10
10
  export const fontWeights = [300, 400, 600];
11
11
  export const lineHeights = [1, 1.5, 2];
12
12
 
@@ -214,7 +214,8 @@ export const mediaQueries = {
214
214
  // APP-SPECIFIC DIMENSIONS
215
215
 
216
216
  export const appScale = {
217
- navBarSize: "70px",
217
+ navBarSize: "50px",
218
+ newNavBarSize: "70px",
218
219
  sideNavSize: "42px",
219
220
  sidebarMaxWidth: "360px",
220
221
  sidebarMaxWidthLarge: "450px",
package/es/systemtheme.js CHANGED
@@ -6,7 +6,7 @@ export const fonts = {
6
6
  };
7
7
  export const font = fonts.main;
8
8
  export const fontFamilies = fonts;
9
- export const fontSizes = ["1.2rem", "1.4rem", "1.6rem", "1.8rem", "2.0rem", "2.4rem", "2.8rem", "3.2rem", "3.6rem", "4.8rem", "6.4rem"];
9
+ export const fontSizes = ["1.2rem", "1.4rem", "1.5rem", "1.8rem", "2.0rem", "2.4rem", "2.8rem", "3.2rem", "3.6rem", "4.8rem", "6.4rem"];
10
10
  export const fontWeights = [300, 400, 600];
11
11
  export const lineHeights = [1, 1.5, 2];
12
12
 
@@ -213,7 +213,8 @@ export const mediaQueries = {
213
213
  // APP-SPECIFIC DIMENSIONS
214
214
 
215
215
  export const appScale = {
216
- navBarSize: "70px",
216
+ navBarSize: "54px",
217
+ newNavBarSize: "70px",
217
218
  sideNavSize: "50px",
218
219
  sidebarMaxWidth: "360px",
219
220
  sidebarMaxWidthLarge: "550px",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orcs-design-system",
3
- "version": "3.3.0",
3
+ "version": "3.3.2",
4
4
  "engines": {
5
5
  "node": "20.12.2"
6
6
  },