@equinor/cpl-top-bar-react 0.3.3 → 0.5.0

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/dist/index.d.mts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React$1 from 'react';
3
+ import React__default from 'react';
2
4
  import * as styled_components_dist_types from 'styled-components/dist/types';
3
5
  import * as styled_components from 'styled-components';
4
- import * as react from 'react';
5
6
 
6
7
  interface FeedbackLinkProps {
7
8
  link: string;
@@ -15,6 +16,50 @@ interface FeedbackLinkProps {
15
16
  */
16
17
  declare function FeedbackLink({ link, subject, body }: FeedbackLinkProps): react_jsx_runtime.JSX.Element;
17
18
 
19
+ type MenuHeaderProps = {
20
+ appName: string;
21
+ icon: React.ReactNode;
22
+ };
23
+ declare function MenuHeader({ appName, icon }: MenuHeaderProps): react_jsx_runtime.JSX.Element;
24
+
25
+ type AppUrls = {
26
+ [appName: string]: {
27
+ dev: string;
28
+ test: string;
29
+ prod: string;
30
+ };
31
+ };
32
+
33
+ type MenuItems = MenuItem | MenuItemGroup;
34
+ type MenuItem = {
35
+ name: string;
36
+ url?: string;
37
+ external?: boolean;
38
+ appName?: string;
39
+ };
40
+ type MenuItemGroup = {
41
+ title: string;
42
+ items: MenuItem[];
43
+ isExpanded?: boolean;
44
+ };
45
+
46
+ type SideMenuProps = {
47
+ isOpen: boolean;
48
+ onToggle: React__default.Dispatch<React__default.SetStateAction<boolean>>;
49
+ mainMenuItems: MenuItems[];
50
+ currentEnvironment: string;
51
+ appUrls: AppUrls;
52
+ titleOtherMenuItems?: string;
53
+ otherMenuItems?: MenuItems[];
54
+ logoElement?: JSX.Element;
55
+ versionInfo?: React__default.ReactNode;
56
+ /**
57
+ * supports next/link and react-router-dom, will default to using a regular anchor-element if not provided
58
+ */
59
+ linkComponent?: React__default.ElementType;
60
+ };
61
+ declare function SideMenu({ isOpen, onToggle, mainMenuItems, logoElement, versionInfo, currentEnvironment, titleOtherMenuItems, otherMenuItems, appUrls, linkComponent, }: SideMenuProps): react_jsx_runtime.JSX.Element;
62
+
18
63
  interface TopBarProps {
19
64
  appName: string;
20
65
  logoLink: string;
@@ -34,7 +79,7 @@ interface TopBarProps {
34
79
  * and set the theme to 'dark'.
35
80
  */
36
81
  declare function TopBar({ appName, logoLink, sideMenuOpen, setSideMenuOpen, feedbackLink, documentationLink, documentationName, userMenu, logoPath, logoAlt, }: TopBarProps): react_jsx_runtime.JSX.Element;
37
- declare const StyledLink: styled_components_dist_types.IStyledComponentBase<"web", styled_components.FastOmit<react.DetailedHTMLProps<react.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
82
+ declare const StyledLink: styled_components_dist_types.IStyledComponentBase<"web", styled_components.FastOmit<React$1.DetailedHTMLProps<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
38
83
 
39
84
  interface UserMenuProps {
40
85
  logout: string | (() => void);
@@ -47,4 +92,4 @@ interface UserMenuProps {
47
92
  }
48
93
  declare function UserMenu({ user, logout, settingsLink, children }: UserMenuProps): react_jsx_runtime.JSX.Element;
49
94
 
50
- export { FeedbackLink, StyledLink, TopBar, UserMenu };
95
+ export { type AppUrls, FeedbackLink, MenuHeader, SideMenu, StyledLink, TopBar, UserMenu };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React$1 from 'react';
3
+ import React__default from 'react';
2
4
  import * as styled_components_dist_types from 'styled-components/dist/types';
3
5
  import * as styled_components from 'styled-components';
4
- import * as react from 'react';
5
6
 
6
7
  interface FeedbackLinkProps {
7
8
  link: string;
@@ -15,6 +16,50 @@ interface FeedbackLinkProps {
15
16
  */
16
17
  declare function FeedbackLink({ link, subject, body }: FeedbackLinkProps): react_jsx_runtime.JSX.Element;
17
18
 
19
+ type MenuHeaderProps = {
20
+ appName: string;
21
+ icon: React.ReactNode;
22
+ };
23
+ declare function MenuHeader({ appName, icon }: MenuHeaderProps): react_jsx_runtime.JSX.Element;
24
+
25
+ type AppUrls = {
26
+ [appName: string]: {
27
+ dev: string;
28
+ test: string;
29
+ prod: string;
30
+ };
31
+ };
32
+
33
+ type MenuItems = MenuItem | MenuItemGroup;
34
+ type MenuItem = {
35
+ name: string;
36
+ url?: string;
37
+ external?: boolean;
38
+ appName?: string;
39
+ };
40
+ type MenuItemGroup = {
41
+ title: string;
42
+ items: MenuItem[];
43
+ isExpanded?: boolean;
44
+ };
45
+
46
+ type SideMenuProps = {
47
+ isOpen: boolean;
48
+ onToggle: React__default.Dispatch<React__default.SetStateAction<boolean>>;
49
+ mainMenuItems: MenuItems[];
50
+ currentEnvironment: string;
51
+ appUrls: AppUrls;
52
+ titleOtherMenuItems?: string;
53
+ otherMenuItems?: MenuItems[];
54
+ logoElement?: JSX.Element;
55
+ versionInfo?: React__default.ReactNode;
56
+ /**
57
+ * supports next/link and react-router-dom, will default to using a regular anchor-element if not provided
58
+ */
59
+ linkComponent?: React__default.ElementType;
60
+ };
61
+ declare function SideMenu({ isOpen, onToggle, mainMenuItems, logoElement, versionInfo, currentEnvironment, titleOtherMenuItems, otherMenuItems, appUrls, linkComponent, }: SideMenuProps): react_jsx_runtime.JSX.Element;
62
+
18
63
  interface TopBarProps {
19
64
  appName: string;
20
65
  logoLink: string;
@@ -34,7 +79,7 @@ interface TopBarProps {
34
79
  * and set the theme to 'dark'.
35
80
  */
36
81
  declare function TopBar({ appName, logoLink, sideMenuOpen, setSideMenuOpen, feedbackLink, documentationLink, documentationName, userMenu, logoPath, logoAlt, }: TopBarProps): react_jsx_runtime.JSX.Element;
37
- declare const StyledLink: styled_components_dist_types.IStyledComponentBase<"web", styled_components.FastOmit<react.DetailedHTMLProps<react.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
82
+ declare const StyledLink: styled_components_dist_types.IStyledComponentBase<"web", styled_components.FastOmit<React$1.DetailedHTMLProps<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
38
83
 
39
84
  interface UserMenuProps {
40
85
  logout: string | (() => void);
@@ -47,4 +92,4 @@ interface UserMenuProps {
47
92
  }
48
93
  declare function UserMenu({ user, logout, settingsLink, children }: UserMenuProps): react_jsx_runtime.JSX.Element;
49
94
 
50
- export { FeedbackLink, StyledLink, TopBar, UserMenu };
95
+ export { type AppUrls, FeedbackLink, MenuHeader, SideMenu, StyledLink, TopBar, UserMenu };
package/dist/index.js CHANGED
@@ -31,6 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  FeedbackLink: () => FeedbackLink,
34
+ MenuHeader: () => MenuHeader,
35
+ SideMenu: () => SideMenu,
34
36
  StyledLink: () => StyledLink,
35
37
  TopBar: () => TopBar,
36
38
  UserMenu: () => UserMenu
@@ -96,6 +98,10 @@ var AppNameContainer = import_styled_components.default.div`
96
98
  display: flex;
97
99
  gap: 1rem;
98
100
  align-items: center;
101
+
102
+ a {
103
+ text-decoration: none;
104
+ }
99
105
  `;
100
106
  var StyledTypography = (0, import_styled_components.default)(import_eds_core_react.Typography)`
101
107
  color: ${import_eds_tokens.tokens.colors.text.static_icons__default.rgba};
@@ -110,7 +116,6 @@ var StyledLink = import_styled_components.default.a`
110
116
  display: flex;
111
117
  align-items: center;
112
118
  gap: 0.3rem;
113
- text-decoration: none;
114
119
  color: ${import_eds_tokens.tokens.colors.text.static_icons__default.rgba};
115
120
  `;
116
121
 
@@ -131,17 +136,379 @@ function FeedbackLink({ link, subject, body }) {
131
136
  );
132
137
  }
133
138
 
134
- // src/UserMenu/UserMenu.tsx
135
- var import_eds_core_react3 = require("@equinor/eds-core-react");
136
- var import_eds_icons3 = require("@equinor/eds-icons");
139
+ // src/SideMenu/components/MenuHeader.tsx
137
140
  var import_eds_tokens2 = require("@equinor/eds-tokens");
138
- var import_react = require("react");
139
- var import_styled_components2 = __toESM(require("styled-components"));
141
+ var import_styled_components2 = require("styled-components");
140
142
  var import_jsx_runtime3 = require("react/jsx-runtime");
143
+ function MenuHeader({ appName, icon }) {
144
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LogoWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(LogoStyle, { children: [
145
+ icon,
146
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: appName })
147
+ ] }) });
148
+ }
149
+ var LogoWrapper = import_styled_components2.styled.div`
150
+ padding: 0 ${import_eds_tokens2.tokens.spacings.comfortable.medium} ${import_eds_tokens2.tokens.spacings.comfortable.small}
151
+ ${import_eds_tokens2.tokens.spacings.comfortable.medium};
152
+ text-align: center;
153
+ font-weight: 500;
154
+ `;
155
+ var LogoStyle = import_styled_components2.styled.div`
156
+ align-items: center;
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: ${import_eds_tokens2.tokens.spacings.comfortable.small};
160
+ justify-content: center;
161
+ text-align: center;
162
+ `;
163
+
164
+ // src/SideMenu/SideMenu.tsx
165
+ var import_eds_core_react5 = require("@equinor/eds-core-react");
166
+ var import_eds_icons4 = require("@equinor/eds-icons");
167
+ var import_eds_tokens5 = require("@equinor/eds-tokens");
168
+ var import_react = require("react");
169
+ var import_styled_components5 = __toESM(require("styled-components"));
170
+
171
+ // src/SideMenu/components/MenuList.tsx
172
+ var import_eds_core_react4 = require("@equinor/eds-core-react");
173
+ var import_eds_tokens4 = require("@equinor/eds-tokens");
174
+ var import_styled_components4 = require("styled-components");
175
+
176
+ // src/SideMenu/components/MenuLink.tsx
177
+ var import_eds_core_react3 = require("@equinor/eds-core-react");
178
+ var import_eds_icons3 = require("@equinor/eds-icons");
179
+ var import_eds_tokens3 = require("@equinor/eds-tokens");
180
+ var import_navigation = require("next/navigation");
181
+ var import_styled_components3 = require("styled-components");
182
+
183
+ // src/SideMenu/useAppUrlByNameAndEnvironment.ts
184
+ function useAppUrlByNameAndEnvironment(appName, currentEnvironment, appUrls) {
185
+ if (!currentEnvironment || !appName) return "";
186
+ if (currentEnvironment === "local") {
187
+ currentEnvironment = "dev";
188
+ }
189
+ const configByEnvironment = appUrls[appName];
190
+ const appUrlInCurrentEnvironment = configByEnvironment[currentEnvironment];
191
+ return appUrlInCurrentEnvironment || "";
192
+ }
193
+
194
+ // src/SideMenu/components/MenuLink.tsx
195
+ var import_jsx_runtime4 = require("react/jsx-runtime");
196
+ function MenuLink({
197
+ item,
198
+ environment,
199
+ appUrls,
200
+ linkComponent: LinkComponent
201
+ }) {
202
+ var _a, _b;
203
+ const urlByNameAndEnvironment = (_a = useAppUrlByNameAndEnvironment(item.appName, environment, appUrls)) != null ? _a : "";
204
+ const url = (_b = item == null ? void 0 : item.url) != null ? _b : urlByNameAndEnvironment;
205
+ const pathName = (0, import_navigation.usePathname)();
206
+ let isActive = !item.external && pathName == item.url;
207
+ const linkContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
208
+ item.name,
209
+ item.external && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_eds_core_react3.Icon, { data: import_eds_icons3.external_link, size: 16 })
210
+ ] });
211
+ if (item.external) {
212
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StyledLink2, { href: url, target: "_blank", rel: "noopener noreferrer", children: linkContent });
213
+ }
214
+ if (LinkComponent) {
215
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
216
+ StyledLink2,
217
+ {
218
+ as: LinkComponent,
219
+ to: url,
220
+ href: url,
221
+ $active: isActive,
222
+ children: linkContent
223
+ }
224
+ );
225
+ }
226
+ isActive = typeof window !== "undefined" ? window.location.pathname === item.url : false;
227
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StyledLink2, { href: url, $active: isActive, children: linkContent });
228
+ }
229
+ var StyledLink2 = import_styled_components3.styled.a`
230
+ text-decoration: none;
231
+ padding: 12px 16px 12px 19px;
232
+ display: inline-block;
233
+ width: 100%;
234
+ color: ${import_eds_tokens3.tokens.colors.interactive.secondary__resting.rgba};
235
+ background-color: ${({ $active }) => $active ? import_eds_tokens3.tokens.colors.interactive.primary__selected_highlight.rgba : "transparent"};
236
+ font-weight: ${({ $active }) => $active ? 700 : 400};
237
+ font-size: 0.875rem;
238
+
239
+ &:hover {
240
+ //TODO: check hover color for dark theme with designer when back
241
+ background: var(--cpl-sidebar-hover-color);
242
+ }
243
+
244
+ &:focus-visible {
245
+ outline-offset: -2px;
246
+ }
247
+
248
+ span {
249
+ align-items: center;
250
+ display: flex;
251
+ gap: 1rem;
252
+ justify-content: space-between;
253
+ font-size: 0.875rem;
254
+ }
255
+
256
+ span svg {
257
+ opacity: 60%;
258
+ }
259
+ `;
260
+
261
+ // src/SideMenu/components/MenuList.tsx
262
+ var import_jsx_runtime5 = require("react/jsx-runtime");
263
+ function MenuList({
264
+ items,
265
+ currentEnvironment,
266
+ appUrls,
267
+ onToggleMenuGroup,
268
+ linkComponent
269
+ }) {
270
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { children: items.map((menuItem) => {
271
+ if (isMenuItemGroup(menuItem)) {
272
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_eds_core_react4.Accordion, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(AccordionItem, { isExpanded: menuItem.isExpanded, children: [
273
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_eds_core_react4.Accordion.Header, { onToggle: onToggleMenuGroup, children: menuItem.title }),
274
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_eds_core_react4.Accordion.Panel, { "aria-label": `Links for ${menuItem.title}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { children: menuItem.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
275
+ MenuLink,
276
+ {
277
+ item,
278
+ environment: currentEnvironment,
279
+ appUrls,
280
+ linkComponent
281
+ }
282
+ ) }, menuItem.title + "-" + item.name)) }) })
283
+ ] }, menuItem.title) }, menuItem.title) }, menuItem.title);
284
+ } else {
285
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
286
+ MenuLink,
287
+ {
288
+ item: menuItem,
289
+ environment: currentEnvironment,
290
+ appUrls,
291
+ linkComponent
292
+ }
293
+ ) }, menuItem.name);
294
+ }
295
+ }) });
296
+ }
297
+ function isMenuItemGroup(item) {
298
+ return typeof item === "object" && "title" in item && "items" in item;
299
+ }
300
+ var AccordionItem = (0, import_styled_components4.styled)(import_eds_core_react4.Accordion.Item)`
301
+ a {
302
+ display: block;
303
+ padding: 12px ${import_eds_tokens4.tokens.spacings.comfortable.medium} 12px ${import_eds_tokens4.tokens.spacings.comfortable.x_large};
304
+ }
305
+
306
+ h2 {
307
+ background: transparent;
308
+ border: 0;
309
+ color: ${import_eds_tokens4.tokens.colors.interactive.secondary__resting.rgba};
310
+ }
311
+
312
+ h2 + div {
313
+ background: transparent;
314
+ border: 0;
315
+ padding: 0;
316
+ min-height: 3.5rem;
317
+ }
318
+
319
+ h2 button svg {
320
+ width: 14px;
321
+ height: 14px;
322
+ margin-right: ${import_eds_tokens4.tokens.spacings.comfortable.x_small};
323
+ transform: rotate(-90deg);
324
+ fill: ${import_eds_tokens4.tokens.colors.interactive.secondary__resting.rgba};
325
+ }
326
+
327
+ h2 button span {
328
+ color: ${import_eds_tokens4.tokens.colors.interactive.secondary__resting.rgba};
329
+ font-weight: 700;
330
+ font-size: 0.875rem;
331
+ }
332
+
333
+ h2 button[aria-expanded='true'] svg {
334
+ transform: rotate(180deg);
335
+ }
336
+
337
+ h2 button:hover,
338
+ li a:hover {
339
+ background-color: var(--cpl-sidebar-hover-color);
340
+ }
341
+
342
+ h2 button:focus-visible {
343
+ outline-offset: -2px;
344
+ }
345
+ `;
346
+
347
+ // src/SideMenu/SideMenu.tsx
348
+ var import_jsx_runtime6 = require("react/jsx-runtime");
349
+ function SideMenu({
350
+ isOpen,
351
+ onToggle,
352
+ mainMenuItems,
353
+ logoElement,
354
+ versionInfo,
355
+ currentEnvironment,
356
+ titleOtherMenuItems,
357
+ otherMenuItems,
358
+ appUrls,
359
+ linkComponent
360
+ }) {
361
+ var _a;
362
+ const width = "268px";
363
+ const [hasOverflow, setHasOverflow] = (0, import_react.useState)(false);
364
+ const [scrolledDown, setScrolledDown] = (0, import_react.useState)(false);
365
+ const containerRef = (0, import_react.useRef)(null);
366
+ const checkOverflow = (0, import_react.useCallback)(() => {
367
+ requestAnimationFrame(() => {
368
+ const element = containerRef.current;
369
+ if (element) {
370
+ setHasOverflow(element.scrollHeight > element.clientHeight);
371
+ }
372
+ });
373
+ }, []);
374
+ const handleScroll = (0, import_react.useCallback)(() => {
375
+ const element = containerRef.current;
376
+ if (element) {
377
+ setScrolledDown(element.scrollTop > 0);
378
+ }
379
+ }, []);
380
+ (0, import_react.useEffect)(() => {
381
+ checkOverflow();
382
+ window.addEventListener("resize", checkOverflow);
383
+ return () => window.removeEventListener("resize", checkOverflow);
384
+ }, [checkOverflow]);
385
+ (0, import_react.useEffect)(() => {
386
+ const element = containerRef.current;
387
+ if (element) {
388
+ element.addEventListener("scroll", handleScroll);
389
+ handleScroll();
390
+ return () => element.removeEventListener("scroll", handleScroll);
391
+ }
392
+ }, [handleScroll]);
393
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Sidebar, { $isOpen: isOpen, $width: isOpen ? width : "", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(InnerWrapper, { ref: containerRef, $width: width, children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
395
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StickyCloseButton, { $showBorder: hasOverflow && scrolledDown, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
396
+ import_eds_core_react5.Button,
397
+ {
398
+ variant: "ghost_icon",
399
+ color: "secondary",
400
+ "aria-label": "Toggle side menu",
401
+ onClick: () => onToggle(!isOpen),
402
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_eds_core_react5.Icon, { data: import_eds_icons4.collapse, size: 24 })
403
+ }
404
+ ) }),
405
+ logoElement,
406
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("nav", { children: [
407
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
408
+ MenuList,
409
+ {
410
+ items: mainMenuItems,
411
+ currentEnvironment,
412
+ appUrls,
413
+ onToggleMenuGroup: checkOverflow,
414
+ linkComponent
415
+ }
416
+ ),
417
+ otherMenuItems && otherMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
418
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StyledDivider, {}),
419
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
420
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
421
+ import_eds_core_react5.Typography,
422
+ {
423
+ variant: "label",
424
+ group: "navigation",
425
+ as: "h2",
426
+ style: {
427
+ color: import_eds_tokens5.tokens.colors.interactive.secondary__resting.rgba,
428
+ padding: "12px 19px 4px 19px"
429
+ },
430
+ children: (_a = titleOtherMenuItems == null ? void 0 : titleOtherMenuItems.toUpperCase()) != null ? _a : "OTHER SOLUTIONS"
431
+ }
432
+ ),
433
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
434
+ MenuList,
435
+ {
436
+ items: otherMenuItems,
437
+ currentEnvironment,
438
+ appUrls,
439
+ onToggleMenuGroup: checkOverflow
440
+ }
441
+ )
442
+ ] })
443
+ ] })
444
+ ] }),
445
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StyledDivider, {})
446
+ ] }),
447
+ versionInfo
448
+ ] }) });
449
+ }
450
+ var StyledDivider = (0, import_styled_components5.default)(import_eds_core_react5.Divider)`
451
+ background-color: var(--cpl-divider-color);
452
+ margin: 8px 0;
453
+ `;
454
+ var Sidebar = import_styled_components5.default.div`
455
+ width: ${(props) => props.$isOpen ? props.$width : "0px"};
456
+ opacity: ${(props) => props.$isOpen ? 1 : 0};
457
+ transition:
458
+ width 0.5s,
459
+ opacity 0.5s;
460
+ height: 100%;
461
+ overflow: hidden;
462
+ position: relative;
463
+ z-index: 0;
464
+
465
+ ul {
466
+ list-style-type: none;
467
+ margin: 0;
468
+ padding: 0;
469
+ }
470
+
471
+ *,
472
+ *::before,
473
+ *::after {
474
+ box-sizing: border-box;
475
+ }
476
+ `;
477
+ var InnerWrapper = import_styled_components5.default.div`
478
+ overflow: auto;
479
+ background: var(--cpl-ui-background-temporary-nav);
480
+ padding: 0;
481
+ height: 100%;
482
+ width: ${(props) => props.$width};
483
+ position: fixed;
484
+ display: flex;
485
+ flex-direction: column;
486
+ justify-content: space-between;
487
+ border-right: 1px solid var(--cpl-sidebar-border-color);
488
+ border-bottom: 1px solid var(--cpl-sidebar-border-color);
489
+ `;
490
+ var StickyCloseButton = import_styled_components5.default.div`
491
+ z-index: 10;
492
+ position: sticky;
493
+ top: 0;
494
+ display: flex;
495
+ justify-content: flex-end;
496
+ padding: ${import_eds_tokens5.tokens.spacings.comfortable.xx_small};
497
+ background-color: var(--cpl-ui-background-temporary-nav);
498
+ border-bottom: ${({ $showBorder }) => $showBorder ? "1px solid var(--cpl-divider-color)" : "0"};
499
+ `;
500
+
501
+ // src/UserMenu/UserMenu.tsx
502
+ var import_eds_core_react6 = require("@equinor/eds-core-react");
503
+ var import_eds_icons5 = require("@equinor/eds-icons");
504
+ var import_eds_tokens6 = require("@equinor/eds-tokens");
505
+ var import_react2 = require("react");
506
+ var import_styled_components6 = __toESM(require("styled-components"));
507
+ var import_jsx_runtime7 = require("react/jsx-runtime");
141
508
  function UserMenu({ user, logout, settingsLink, children }) {
142
509
  var _a, _b, _c, _d, _e;
143
- const [isOpen, setIsOpen] = (0, import_react.useState)(false);
144
- const [anchorEl, setAnchorEl] = (0, import_react.useState)(null);
510
+ const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
511
+ const [anchorEl, setAnchorEl] = (0, import_react2.useState)(null);
145
512
  const openMenu = () => {
146
513
  setIsOpen(true);
147
514
  };
@@ -150,20 +517,20 @@ function UserMenu({ user, logout, settingsLink, children }) {
150
517
  };
151
518
  const LogOutMenuItem = () => {
152
519
  if (typeof logout === "string") {
153
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_eds_core_react3.Menu.Item, { as: "a", href: logout, className: "menu-item", id: "logout-button", children: [
154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_eds_core_react3.Icon, { data: import_eds_icons3.log_out }),
155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Log out" })
520
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_eds_core_react6.Menu.Item, { as: "a", href: logout, className: "menu-item", id: "logout-button", children: [
521
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_eds_core_react6.Icon, { data: import_eds_icons5.log_out }),
522
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Log out" })
156
523
  ] });
157
524
  } else {
158
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_eds_core_react3.Menu.Item, { as: "button", onClick: logout, className: "menu-item", id: "logout-button", children: [
159
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_eds_core_react3.Icon, { data: import_eds_icons3.log_out }),
160
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Log out" })
525
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_eds_core_react6.Menu.Item, { as: "button", onClick: logout, className: "menu-item", id: "logout-button", children: [
526
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_eds_core_react6.Icon, { data: import_eds_icons5.log_out }),
527
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Log out" })
161
528
  ] });
162
529
  }
163
530
  };
164
531
  const firstLetter = (_c = (_b = (_a = user == null ? void 0 : user.email) == null ? void 0 : _a[0]) == null ? void 0 : _b.toUpperCase()) != null ? _c : "-";
165
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
166
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
532
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
533
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
167
534
  StyledUserButton,
168
535
  {
169
536
  id: "user-button",
@@ -176,7 +543,7 @@ function UserMenu({ user, logout, settingsLink, children }) {
176
543
  children: firstLetter
177
544
  }
178
545
  ),
179
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
546
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
180
547
  MenuWrapper,
181
548
  {
182
549
  id: "user-menu",
@@ -186,16 +553,16 @@ function UserMenu({ user, logout, settingsLink, children }) {
186
553
  anchorEl,
187
554
  style: { padding: 0, paddingBottom: 2 },
188
555
  children: [
189
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(IconAndTextWrapper, { children: [
190
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LetterCircle, { children: firstLetter }),
191
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
192
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontWeight: "bold", lineHeight: 0.9, marginBottom: 2 }, children: (_d = user == null ? void 0 : user.name) != null ? _d : "-" }),
193
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: (_e = user == null ? void 0 : user.email) != null ? _e : "-" })
556
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(IconAndTextWrapper, { children: [
557
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LetterCircle, { children: firstLetter }),
558
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
559
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: "bold", lineHeight: 0.9, marginBottom: 2 }, children: (_d = user == null ? void 0 : user.name) != null ? _d : "-" }),
560
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: (_e = user == null ? void 0 : user.email) != null ? _e : "-" })
194
561
  ] })
195
562
  ] }),
196
- settingsLink && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_eds_core_react3.Menu.Item, { as: "a", href: settingsLink, className: "menu-item", children: [
197
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_eds_core_react3.Icon, { data: import_eds_icons3.settings }),
198
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Settings" })
563
+ settingsLink && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_eds_core_react6.Menu.Item, { as: "a", href: settingsLink, className: "menu-item", children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_eds_core_react6.Icon, { data: import_eds_icons5.settings }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Settings" })
199
566
  ] }),
200
567
  LogOutMenuItem(),
201
568
  children
@@ -204,25 +571,25 @@ function UserMenu({ user, logout, settingsLink, children }) {
204
571
  )
205
572
  ] });
206
573
  }
207
- var MenuWrapper = (0, import_styled_components2.default)(import_eds_core_react3.Menu)`
208
- border-radius: ${import_eds_tokens2.tokens.shape.corners.borderRadius};
209
- margin-top: ${import_eds_tokens2.tokens.spacings.comfortable.small};
210
- margin-bottom: -${import_eds_tokens2.tokens.spacings.comfortable.small};
211
- padding-bottom: ${import_eds_tokens2.tokens.spacings.comfortable.small};
574
+ var MenuWrapper = (0, import_styled_components6.default)(import_eds_core_react6.Menu)`
575
+ border-radius: ${import_eds_tokens6.tokens.shape.corners.borderRadius};
576
+ margin-top: ${import_eds_tokens6.tokens.spacings.comfortable.small};
577
+ margin-bottom: -${import_eds_tokens6.tokens.spacings.comfortable.small};
578
+ padding-bottom: ${import_eds_tokens6.tokens.spacings.comfortable.small};
212
579
  padding-left: 0;
213
580
  padding-right: 0;
214
- padding-top: ${import_eds_tokens2.tokens.spacings.comfortable.small};
581
+ padding-top: ${import_eds_tokens6.tokens.spacings.comfortable.small};
215
582
  width: 315px;
216
583
 
217
- background: var(--ui-background-temporary-nav, #fff);
218
- color: ${import_eds_tokens2.tokens.colors.text.static_icons__default.rgba};
584
+ background: var(--cpl-ui-background-temporary-nav, #fff);
585
+ color: ${import_eds_tokens6.tokens.colors.text.static_icons__default.rgba};
219
586
 
220
587
  .menu-item {
221
588
  align-items: center;
222
589
  display: flex;
223
- gap: ${import_eds_tokens2.tokens.spacings.comfortable.medium};
590
+ gap: ${import_eds_tokens6.tokens.spacings.comfortable.medium};
224
591
  opacity: 0.85;
225
- padding: ${import_eds_tokens2.tokens.spacings.comfortable.small} ${import_eds_tokens2.tokens.spacings.comfortable.large};
592
+ padding: ${import_eds_tokens6.tokens.spacings.comfortable.small} ${import_eds_tokens6.tokens.spacings.comfortable.large};
226
593
 
227
594
  svg {
228
595
  opacity: 0.7;
@@ -230,14 +597,14 @@ var MenuWrapper = (0, import_styled_components2.default)(import_eds_core_react3.
230
597
  &:hover {
231
598
  opacity: 1;
232
599
  background-color: transparent;
233
-
600
+
234
601
  svg {
235
602
  opacity: 1;
236
603
  }
237
604
  }
238
605
  }
239
606
  `;
240
- var LetterCircle = import_styled_components2.default.span`
607
+ var LetterCircle = import_styled_components6.default.span`
241
608
  align-items: center;
242
609
  border-radius: 1000px;
243
610
  display: flex;
@@ -246,16 +613,16 @@ var LetterCircle = import_styled_components2.default.span`
246
613
  height: 32px;
247
614
  justify-content: center;
248
615
  width: 32px;
249
- background-color: ${import_eds_tokens2.tokens.colors.interactive.primary__resting.rgba};
250
- color: ${import_eds_tokens2.tokens.colors.text.static_icons__primary_white.rgba};
616
+ background-color: ${import_eds_tokens6.tokens.colors.interactive.primary__resting.rgba};
617
+ color: ${import_eds_tokens6.tokens.colors.text.static_icons__primary_white.rgba};
251
618
  `;
252
- var StyledUserButton = (0, import_styled_components2.default)(import_eds_core_react3.Button)`
619
+ var StyledUserButton = (0, import_styled_components6.default)(import_eds_core_react6.Button)`
253
620
  margin-left: 12px;
254
621
  font-weight: bold;
255
622
  width: 32px;
256
623
  height: 32px;
257
624
  `;
258
- var IconAndTextWrapper = (0, import_styled_components2.default)(import_eds_core_react3.Menu.Item)`
625
+ var IconAndTextWrapper = (0, import_styled_components6.default)(import_eds_core_react6.Menu.Item)`
259
626
  display: flex;
260
627
  gap: 12px;
261
628
  padding: 12px 20px;
@@ -271,6 +638,8 @@ var IconAndTextWrapper = (0, import_styled_components2.default)(import_eds_core_
271
638
  // Annotate the CommonJS export names for ESM import in node:
272
639
  0 && (module.exports = {
273
640
  FeedbackLink,
641
+ MenuHeader,
642
+ SideMenu,
274
643
  StyledLink,
275
644
  TopBar,
276
645
  UserMenu
package/dist/index.mjs CHANGED
@@ -57,6 +57,10 @@ var AppNameContainer = styled.div`
57
57
  display: flex;
58
58
  gap: 1rem;
59
59
  align-items: center;
60
+
61
+ a {
62
+ text-decoration: none;
63
+ }
60
64
  `;
61
65
  var StyledTypography = styled(Typography)`
62
66
  color: ${tokens.colors.text.static_icons__default.rgba};
@@ -71,7 +75,6 @@ var StyledLink = styled.a`
71
75
  display: flex;
72
76
  align-items: center;
73
77
  gap: 0.3rem;
74
- text-decoration: none;
75
78
  color: ${tokens.colors.text.static_icons__default.rgba};
76
79
  `;
77
80
 
@@ -92,17 +95,379 @@ function FeedbackLink({ link, subject, body }) {
92
95
  );
93
96
  }
94
97
 
98
+ // src/SideMenu/components/MenuHeader.tsx
99
+ import { tokens as tokens2 } from "@equinor/eds-tokens";
100
+ import { styled as styled2 } from "styled-components";
101
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
102
+ function MenuHeader({ appName, icon }) {
103
+ return /* @__PURE__ */ jsx3(LogoWrapper, { children: /* @__PURE__ */ jsxs3(LogoStyle, { children: [
104
+ icon,
105
+ /* @__PURE__ */ jsx3("span", { children: appName })
106
+ ] }) });
107
+ }
108
+ var LogoWrapper = styled2.div`
109
+ padding: 0 ${tokens2.spacings.comfortable.medium} ${tokens2.spacings.comfortable.small}
110
+ ${tokens2.spacings.comfortable.medium};
111
+ text-align: center;
112
+ font-weight: 500;
113
+ `;
114
+ var LogoStyle = styled2.div`
115
+ align-items: center;
116
+ display: flex;
117
+ flex-direction: column;
118
+ gap: ${tokens2.spacings.comfortable.small};
119
+ justify-content: center;
120
+ text-align: center;
121
+ `;
122
+
123
+ // src/SideMenu/SideMenu.tsx
124
+ import { Button as Button2, Divider, Icon as Icon4, Typography as Typography2 } from "@equinor/eds-core-react";
125
+ import { collapse } from "@equinor/eds-icons";
126
+ import { tokens as tokens5 } from "@equinor/eds-tokens";
127
+ import { useCallback, useEffect, useRef, useState } from "react";
128
+ import styled5 from "styled-components";
129
+
130
+ // src/SideMenu/components/MenuList.tsx
131
+ import { Accordion } from "@equinor/eds-core-react";
132
+ import { tokens as tokens4 } from "@equinor/eds-tokens";
133
+ import { styled as styled4 } from "styled-components";
134
+
135
+ // src/SideMenu/components/MenuLink.tsx
136
+ import { Icon as Icon3 } from "@equinor/eds-core-react";
137
+ import { external_link as external_link2 } from "@equinor/eds-icons";
138
+ import { tokens as tokens3 } from "@equinor/eds-tokens";
139
+ import { usePathname } from "next/navigation";
140
+ import { styled as styled3 } from "styled-components";
141
+
142
+ // src/SideMenu/useAppUrlByNameAndEnvironment.ts
143
+ function useAppUrlByNameAndEnvironment(appName, currentEnvironment, appUrls) {
144
+ if (!currentEnvironment || !appName) return "";
145
+ if (currentEnvironment === "local") {
146
+ currentEnvironment = "dev";
147
+ }
148
+ const configByEnvironment = appUrls[appName];
149
+ const appUrlInCurrentEnvironment = configByEnvironment[currentEnvironment];
150
+ return appUrlInCurrentEnvironment || "";
151
+ }
152
+
153
+ // src/SideMenu/components/MenuLink.tsx
154
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
155
+ function MenuLink({
156
+ item,
157
+ environment,
158
+ appUrls,
159
+ linkComponent: LinkComponent
160
+ }) {
161
+ var _a, _b;
162
+ const urlByNameAndEnvironment = (_a = useAppUrlByNameAndEnvironment(item.appName, environment, appUrls)) != null ? _a : "";
163
+ const url = (_b = item == null ? void 0 : item.url) != null ? _b : urlByNameAndEnvironment;
164
+ const pathName = usePathname();
165
+ let isActive = !item.external && pathName == item.url;
166
+ const linkContent = /* @__PURE__ */ jsxs4("span", { children: [
167
+ item.name,
168
+ item.external && /* @__PURE__ */ jsx4(Icon3, { data: external_link2, size: 16 })
169
+ ] });
170
+ if (item.external) {
171
+ return /* @__PURE__ */ jsx4(StyledLink2, { href: url, target: "_blank", rel: "noopener noreferrer", children: linkContent });
172
+ }
173
+ if (LinkComponent) {
174
+ return /* @__PURE__ */ jsx4(
175
+ StyledLink2,
176
+ {
177
+ as: LinkComponent,
178
+ to: url,
179
+ href: url,
180
+ $active: isActive,
181
+ children: linkContent
182
+ }
183
+ );
184
+ }
185
+ isActive = typeof window !== "undefined" ? window.location.pathname === item.url : false;
186
+ return /* @__PURE__ */ jsx4(StyledLink2, { href: url, $active: isActive, children: linkContent });
187
+ }
188
+ var StyledLink2 = styled3.a`
189
+ text-decoration: none;
190
+ padding: 12px 16px 12px 19px;
191
+ display: inline-block;
192
+ width: 100%;
193
+ color: ${tokens3.colors.interactive.secondary__resting.rgba};
194
+ background-color: ${({ $active }) => $active ? tokens3.colors.interactive.primary__selected_highlight.rgba : "transparent"};
195
+ font-weight: ${({ $active }) => $active ? 700 : 400};
196
+ font-size: 0.875rem;
197
+
198
+ &:hover {
199
+ //TODO: check hover color for dark theme with designer when back
200
+ background: var(--cpl-sidebar-hover-color);
201
+ }
202
+
203
+ &:focus-visible {
204
+ outline-offset: -2px;
205
+ }
206
+
207
+ span {
208
+ align-items: center;
209
+ display: flex;
210
+ gap: 1rem;
211
+ justify-content: space-between;
212
+ font-size: 0.875rem;
213
+ }
214
+
215
+ span svg {
216
+ opacity: 60%;
217
+ }
218
+ `;
219
+
220
+ // src/SideMenu/components/MenuList.tsx
221
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
222
+ function MenuList({
223
+ items,
224
+ currentEnvironment,
225
+ appUrls,
226
+ onToggleMenuGroup,
227
+ linkComponent
228
+ }) {
229
+ return /* @__PURE__ */ jsx5("ul", { children: items.map((menuItem) => {
230
+ if (isMenuItemGroup(menuItem)) {
231
+ return /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(Accordion, { children: /* @__PURE__ */ jsxs5(AccordionItem, { isExpanded: menuItem.isExpanded, children: [
232
+ /* @__PURE__ */ jsx5(Accordion.Header, { onToggle: onToggleMenuGroup, children: menuItem.title }),
233
+ /* @__PURE__ */ jsx5(Accordion.Panel, { "aria-label": `Links for ${menuItem.title}`, children: /* @__PURE__ */ jsx5("ul", { children: menuItem.items.map((item) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
234
+ MenuLink,
235
+ {
236
+ item,
237
+ environment: currentEnvironment,
238
+ appUrls,
239
+ linkComponent
240
+ }
241
+ ) }, menuItem.title + "-" + item.name)) }) })
242
+ ] }, menuItem.title) }, menuItem.title) }, menuItem.title);
243
+ } else {
244
+ return /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
245
+ MenuLink,
246
+ {
247
+ item: menuItem,
248
+ environment: currentEnvironment,
249
+ appUrls,
250
+ linkComponent
251
+ }
252
+ ) }, menuItem.name);
253
+ }
254
+ }) });
255
+ }
256
+ function isMenuItemGroup(item) {
257
+ return typeof item === "object" && "title" in item && "items" in item;
258
+ }
259
+ var AccordionItem = styled4(Accordion.Item)`
260
+ a {
261
+ display: block;
262
+ padding: 12px ${tokens4.spacings.comfortable.medium} 12px ${tokens4.spacings.comfortable.x_large};
263
+ }
264
+
265
+ h2 {
266
+ background: transparent;
267
+ border: 0;
268
+ color: ${tokens4.colors.interactive.secondary__resting.rgba};
269
+ }
270
+
271
+ h2 + div {
272
+ background: transparent;
273
+ border: 0;
274
+ padding: 0;
275
+ min-height: 3.5rem;
276
+ }
277
+
278
+ h2 button svg {
279
+ width: 14px;
280
+ height: 14px;
281
+ margin-right: ${tokens4.spacings.comfortable.x_small};
282
+ transform: rotate(-90deg);
283
+ fill: ${tokens4.colors.interactive.secondary__resting.rgba};
284
+ }
285
+
286
+ h2 button span {
287
+ color: ${tokens4.colors.interactive.secondary__resting.rgba};
288
+ font-weight: 700;
289
+ font-size: 0.875rem;
290
+ }
291
+
292
+ h2 button[aria-expanded='true'] svg {
293
+ transform: rotate(180deg);
294
+ }
295
+
296
+ h2 button:hover,
297
+ li a:hover {
298
+ background-color: var(--cpl-sidebar-hover-color);
299
+ }
300
+
301
+ h2 button:focus-visible {
302
+ outline-offset: -2px;
303
+ }
304
+ `;
305
+
306
+ // src/SideMenu/SideMenu.tsx
307
+ import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
308
+ function SideMenu({
309
+ isOpen,
310
+ onToggle,
311
+ mainMenuItems,
312
+ logoElement,
313
+ versionInfo,
314
+ currentEnvironment,
315
+ titleOtherMenuItems,
316
+ otherMenuItems,
317
+ appUrls,
318
+ linkComponent
319
+ }) {
320
+ var _a;
321
+ const width = "268px";
322
+ const [hasOverflow, setHasOverflow] = useState(false);
323
+ const [scrolledDown, setScrolledDown] = useState(false);
324
+ const containerRef = useRef(null);
325
+ const checkOverflow = useCallback(() => {
326
+ requestAnimationFrame(() => {
327
+ const element = containerRef.current;
328
+ if (element) {
329
+ setHasOverflow(element.scrollHeight > element.clientHeight);
330
+ }
331
+ });
332
+ }, []);
333
+ const handleScroll = useCallback(() => {
334
+ const element = containerRef.current;
335
+ if (element) {
336
+ setScrolledDown(element.scrollTop > 0);
337
+ }
338
+ }, []);
339
+ useEffect(() => {
340
+ checkOverflow();
341
+ window.addEventListener("resize", checkOverflow);
342
+ return () => window.removeEventListener("resize", checkOverflow);
343
+ }, [checkOverflow]);
344
+ useEffect(() => {
345
+ const element = containerRef.current;
346
+ if (element) {
347
+ element.addEventListener("scroll", handleScroll);
348
+ handleScroll();
349
+ return () => element.removeEventListener("scroll", handleScroll);
350
+ }
351
+ }, [handleScroll]);
352
+ return /* @__PURE__ */ jsx6(Sidebar, { $isOpen: isOpen, $width: isOpen ? width : "", children: /* @__PURE__ */ jsxs6(InnerWrapper, { ref: containerRef, $width: width, children: [
353
+ /* @__PURE__ */ jsxs6("div", { children: [
354
+ /* @__PURE__ */ jsx6(StickyCloseButton, { $showBorder: hasOverflow && scrolledDown, children: /* @__PURE__ */ jsx6(
355
+ Button2,
356
+ {
357
+ variant: "ghost_icon",
358
+ color: "secondary",
359
+ "aria-label": "Toggle side menu",
360
+ onClick: () => onToggle(!isOpen),
361
+ children: /* @__PURE__ */ jsx6(Icon4, { data: collapse, size: 24 })
362
+ }
363
+ ) }),
364
+ logoElement,
365
+ /* @__PURE__ */ jsxs6("nav", { children: [
366
+ /* @__PURE__ */ jsx6(
367
+ MenuList,
368
+ {
369
+ items: mainMenuItems,
370
+ currentEnvironment,
371
+ appUrls,
372
+ onToggleMenuGroup: checkOverflow,
373
+ linkComponent
374
+ }
375
+ ),
376
+ otherMenuItems && otherMenuItems.length > 0 && /* @__PURE__ */ jsxs6(Fragment, { children: [
377
+ /* @__PURE__ */ jsx6(StyledDivider, {}),
378
+ /* @__PURE__ */ jsxs6("div", { children: [
379
+ /* @__PURE__ */ jsx6(
380
+ Typography2,
381
+ {
382
+ variant: "label",
383
+ group: "navigation",
384
+ as: "h2",
385
+ style: {
386
+ color: tokens5.colors.interactive.secondary__resting.rgba,
387
+ padding: "12px 19px 4px 19px"
388
+ },
389
+ children: (_a = titleOtherMenuItems == null ? void 0 : titleOtherMenuItems.toUpperCase()) != null ? _a : "OTHER SOLUTIONS"
390
+ }
391
+ ),
392
+ /* @__PURE__ */ jsx6(
393
+ MenuList,
394
+ {
395
+ items: otherMenuItems,
396
+ currentEnvironment,
397
+ appUrls,
398
+ onToggleMenuGroup: checkOverflow
399
+ }
400
+ )
401
+ ] })
402
+ ] })
403
+ ] }),
404
+ /* @__PURE__ */ jsx6(StyledDivider, {})
405
+ ] }),
406
+ versionInfo
407
+ ] }) });
408
+ }
409
+ var StyledDivider = styled5(Divider)`
410
+ background-color: var(--cpl-divider-color);
411
+ margin: 8px 0;
412
+ `;
413
+ var Sidebar = styled5.div`
414
+ width: ${(props) => props.$isOpen ? props.$width : "0px"};
415
+ opacity: ${(props) => props.$isOpen ? 1 : 0};
416
+ transition:
417
+ width 0.5s,
418
+ opacity 0.5s;
419
+ height: 100%;
420
+ overflow: hidden;
421
+ position: relative;
422
+ z-index: 0;
423
+
424
+ ul {
425
+ list-style-type: none;
426
+ margin: 0;
427
+ padding: 0;
428
+ }
429
+
430
+ *,
431
+ *::before,
432
+ *::after {
433
+ box-sizing: border-box;
434
+ }
435
+ `;
436
+ var InnerWrapper = styled5.div`
437
+ overflow: auto;
438
+ background: var(--cpl-ui-background-temporary-nav);
439
+ padding: 0;
440
+ height: 100%;
441
+ width: ${(props) => props.$width};
442
+ position: fixed;
443
+ display: flex;
444
+ flex-direction: column;
445
+ justify-content: space-between;
446
+ border-right: 1px solid var(--cpl-sidebar-border-color);
447
+ border-bottom: 1px solid var(--cpl-sidebar-border-color);
448
+ `;
449
+ var StickyCloseButton = styled5.div`
450
+ z-index: 10;
451
+ position: sticky;
452
+ top: 0;
453
+ display: flex;
454
+ justify-content: flex-end;
455
+ padding: ${tokens5.spacings.comfortable.xx_small};
456
+ background-color: var(--cpl-ui-background-temporary-nav);
457
+ border-bottom: ${({ $showBorder }) => $showBorder ? "1px solid var(--cpl-divider-color)" : "0"};
458
+ `;
459
+
95
460
  // src/UserMenu/UserMenu.tsx
96
- import { Button as Button2, Icon as Icon3, Menu } from "@equinor/eds-core-react";
461
+ import { Button as Button3, Icon as Icon5, Menu } from "@equinor/eds-core-react";
97
462
  import { log_out, settings } from "@equinor/eds-icons";
98
- import { tokens as tokens2 } from "@equinor/eds-tokens";
99
- import { useState } from "react";
100
- import styled2 from "styled-components";
101
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
463
+ import { tokens as tokens6 } from "@equinor/eds-tokens";
464
+ import { useState as useState2 } from "react";
465
+ import styled6 from "styled-components";
466
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
102
467
  function UserMenu({ user, logout, settingsLink, children }) {
103
468
  var _a, _b, _c, _d, _e;
104
- const [isOpen, setIsOpen] = useState(false);
105
- const [anchorEl, setAnchorEl] = useState(null);
469
+ const [isOpen, setIsOpen] = useState2(false);
470
+ const [anchorEl, setAnchorEl] = useState2(null);
106
471
  const openMenu = () => {
107
472
  setIsOpen(true);
108
473
  };
@@ -111,20 +476,20 @@ function UserMenu({ user, logout, settingsLink, children }) {
111
476
  };
112
477
  const LogOutMenuItem = () => {
113
478
  if (typeof logout === "string") {
114
- return /* @__PURE__ */ jsxs3(Menu.Item, { as: "a", href: logout, className: "menu-item", id: "logout-button", children: [
115
- /* @__PURE__ */ jsx3(Icon3, { data: log_out }),
116
- /* @__PURE__ */ jsx3("span", { children: "Log out" })
479
+ return /* @__PURE__ */ jsxs7(Menu.Item, { as: "a", href: logout, className: "menu-item", id: "logout-button", children: [
480
+ /* @__PURE__ */ jsx7(Icon5, { data: log_out }),
481
+ /* @__PURE__ */ jsx7("span", { children: "Log out" })
117
482
  ] });
118
483
  } else {
119
- return /* @__PURE__ */ jsxs3(Menu.Item, { as: "button", onClick: logout, className: "menu-item", id: "logout-button", children: [
120
- /* @__PURE__ */ jsx3(Icon3, { data: log_out }),
121
- /* @__PURE__ */ jsx3("span", { children: "Log out" })
484
+ return /* @__PURE__ */ jsxs7(Menu.Item, { as: "button", onClick: logout, className: "menu-item", id: "logout-button", children: [
485
+ /* @__PURE__ */ jsx7(Icon5, { data: log_out }),
486
+ /* @__PURE__ */ jsx7("span", { children: "Log out" })
122
487
  ] });
123
488
  }
124
489
  };
125
490
  const firstLetter = (_c = (_b = (_a = user == null ? void 0 : user.email) == null ? void 0 : _a[0]) == null ? void 0 : _b.toUpperCase()) != null ? _c : "-";
126
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
127
- /* @__PURE__ */ jsx3(
491
+ return /* @__PURE__ */ jsxs7(Fragment2, { children: [
492
+ /* @__PURE__ */ jsx7(
128
493
  StyledUserButton,
129
494
  {
130
495
  id: "user-button",
@@ -137,7 +502,7 @@ function UserMenu({ user, logout, settingsLink, children }) {
137
502
  children: firstLetter
138
503
  }
139
504
  ),
140
- /* @__PURE__ */ jsxs3(
505
+ /* @__PURE__ */ jsxs7(
141
506
  MenuWrapper,
142
507
  {
143
508
  id: "user-menu",
@@ -147,16 +512,16 @@ function UserMenu({ user, logout, settingsLink, children }) {
147
512
  anchorEl,
148
513
  style: { padding: 0, paddingBottom: 2 },
149
514
  children: [
150
- /* @__PURE__ */ jsxs3(IconAndTextWrapper, { children: [
151
- /* @__PURE__ */ jsx3(LetterCircle, { children: firstLetter }),
152
- isOpen && /* @__PURE__ */ jsxs3("div", { children: [
153
- /* @__PURE__ */ jsx3("div", { style: { fontWeight: "bold", lineHeight: 0.9, marginBottom: 2 }, children: (_d = user == null ? void 0 : user.name) != null ? _d : "-" }),
154
- /* @__PURE__ */ jsx3("div", { children: (_e = user == null ? void 0 : user.email) != null ? _e : "-" })
515
+ /* @__PURE__ */ jsxs7(IconAndTextWrapper, { children: [
516
+ /* @__PURE__ */ jsx7(LetterCircle, { children: firstLetter }),
517
+ isOpen && /* @__PURE__ */ jsxs7("div", { children: [
518
+ /* @__PURE__ */ jsx7("div", { style: { fontWeight: "bold", lineHeight: 0.9, marginBottom: 2 }, children: (_d = user == null ? void 0 : user.name) != null ? _d : "-" }),
519
+ /* @__PURE__ */ jsx7("div", { children: (_e = user == null ? void 0 : user.email) != null ? _e : "-" })
155
520
  ] })
156
521
  ] }),
157
- settingsLink && /* @__PURE__ */ jsxs3(Menu.Item, { as: "a", href: settingsLink, className: "menu-item", children: [
158
- /* @__PURE__ */ jsx3(Icon3, { data: settings }),
159
- /* @__PURE__ */ jsx3("span", { children: "Settings" })
522
+ settingsLink && /* @__PURE__ */ jsxs7(Menu.Item, { as: "a", href: settingsLink, className: "menu-item", children: [
523
+ /* @__PURE__ */ jsx7(Icon5, { data: settings }),
524
+ /* @__PURE__ */ jsx7("span", { children: "Settings" })
160
525
  ] }),
161
526
  LogOutMenuItem(),
162
527
  children
@@ -165,25 +530,25 @@ function UserMenu({ user, logout, settingsLink, children }) {
165
530
  )
166
531
  ] });
167
532
  }
168
- var MenuWrapper = styled2(Menu)`
169
- border-radius: ${tokens2.shape.corners.borderRadius};
170
- margin-top: ${tokens2.spacings.comfortable.small};
171
- margin-bottom: -${tokens2.spacings.comfortable.small};
172
- padding-bottom: ${tokens2.spacings.comfortable.small};
533
+ var MenuWrapper = styled6(Menu)`
534
+ border-radius: ${tokens6.shape.corners.borderRadius};
535
+ margin-top: ${tokens6.spacings.comfortable.small};
536
+ margin-bottom: -${tokens6.spacings.comfortable.small};
537
+ padding-bottom: ${tokens6.spacings.comfortable.small};
173
538
  padding-left: 0;
174
539
  padding-right: 0;
175
- padding-top: ${tokens2.spacings.comfortable.small};
540
+ padding-top: ${tokens6.spacings.comfortable.small};
176
541
  width: 315px;
177
542
 
178
- background: var(--ui-background-temporary-nav, #fff);
179
- color: ${tokens2.colors.text.static_icons__default.rgba};
543
+ background: var(--cpl-ui-background-temporary-nav, #fff);
544
+ color: ${tokens6.colors.text.static_icons__default.rgba};
180
545
 
181
546
  .menu-item {
182
547
  align-items: center;
183
548
  display: flex;
184
- gap: ${tokens2.spacings.comfortable.medium};
549
+ gap: ${tokens6.spacings.comfortable.medium};
185
550
  opacity: 0.85;
186
- padding: ${tokens2.spacings.comfortable.small} ${tokens2.spacings.comfortable.large};
551
+ padding: ${tokens6.spacings.comfortable.small} ${tokens6.spacings.comfortable.large};
187
552
 
188
553
  svg {
189
554
  opacity: 0.7;
@@ -191,14 +556,14 @@ var MenuWrapper = styled2(Menu)`
191
556
  &:hover {
192
557
  opacity: 1;
193
558
  background-color: transparent;
194
-
559
+
195
560
  svg {
196
561
  opacity: 1;
197
562
  }
198
563
  }
199
564
  }
200
565
  `;
201
- var LetterCircle = styled2.span`
566
+ var LetterCircle = styled6.span`
202
567
  align-items: center;
203
568
  border-radius: 1000px;
204
569
  display: flex;
@@ -207,16 +572,16 @@ var LetterCircle = styled2.span`
207
572
  height: 32px;
208
573
  justify-content: center;
209
574
  width: 32px;
210
- background-color: ${tokens2.colors.interactive.primary__resting.rgba};
211
- color: ${tokens2.colors.text.static_icons__primary_white.rgba};
575
+ background-color: ${tokens6.colors.interactive.primary__resting.rgba};
576
+ color: ${tokens6.colors.text.static_icons__primary_white.rgba};
212
577
  `;
213
- var StyledUserButton = styled2(Button2)`
578
+ var StyledUserButton = styled6(Button3)`
214
579
  margin-left: 12px;
215
580
  font-weight: bold;
216
581
  width: 32px;
217
582
  height: 32px;
218
583
  `;
219
- var IconAndTextWrapper = styled2(Menu.Item)`
584
+ var IconAndTextWrapper = styled6(Menu.Item)`
220
585
  display: flex;
221
586
  gap: 12px;
222
587
  padding: 12px 20px;
@@ -231,6 +596,8 @@ var IconAndTextWrapper = styled2(Menu.Item)`
231
596
  `;
232
597
  export {
233
598
  FeedbackLink,
599
+ MenuHeader,
600
+ SideMenu,
234
601
  StyledLink,
235
602
  TopBar,
236
603
  UserMenu
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/cpl-top-bar-react",
3
- "version": "0.3.3",
3
+ "version": "0.5.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -10,7 +10,8 @@
10
10
  ],
11
11
  "dependencies": {
12
12
  "@equinor/eds-icons": "^0.21.0",
13
- "@equinor/eds-tokens": "^0.9.2"
13
+ "@equinor/eds-tokens": "^0.9.2",
14
+ "@equinor/cpl-env-meta-bar-react": "0.1.1"
14
15
  },
15
16
  "devDependencies": {
16
17
  "@equinor/eds-core-react": "^0.42.5",
@@ -30,7 +31,8 @@
30
31
  "@equinor/eds-core-react": ">=0.42.1",
31
32
  "react": ">=18.2.0",
32
33
  "react-dom": ">=18.2.0",
33
- "styled-components": ">=5.3.11"
34
+ "styled-components": ">=5.3.11",
35
+ "next": ">15.0.0"
34
36
  },
35
37
  "publishConfig": {
36
38
  "access": "public"