@camunda/camunda-composite-components 0.0.38-rc1 → 0.0.38-rc2
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/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-info-sidebar.js +2 -5
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.js +14 -3
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.d.ts +4 -1
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-notification-sidebar.js +22 -21
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-org-sidebar.js +6 -7
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.d.ts +27 -0
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.js +27 -0
- package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-user-sidebar.js +5 -6
- package/lib/esm/components/c3-navigation/c3-navigation.d.ts +1 -1
- package/lib/esm/components/c3-navigation/c3-navigation.js +68 -55
- package/lib/esm/components/c3-navigation/c3-navigation.types.d.ts +0 -3
- package/lib/esm/components/c3-navigation/helpers.js +15 -13
- package/lib/esm/components/c3-navigation/story-templates.d.ts +9 -0
- package/lib/esm/components/c3-navigation/story-templates.js +31 -0
- package/package.json +1 -1
- package/lib/esm/components/c3-navigation/c3-info-button.d.ts +0 -4
- package/lib/esm/components/c3-navigation/c3-info-button.js +0 -5
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { SwitcherDivider } from "./components";
|
|
3
3
|
import { Help } from "@carbon/react/icons";
|
|
4
4
|
import C3NavigationSideBar from "./c3-navigation-sidebar";
|
|
5
5
|
const C3InfoSidebar = ({ sideBar, }) => {
|
|
6
|
-
const { version,
|
|
7
|
-
const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
|
|
6
|
+
const { version, ...sideBarProps } = sideBar;
|
|
8
7
|
return (React.createElement(C3NavigationSideBar, { sideBar: {
|
|
9
8
|
...sideBarProps,
|
|
10
9
|
ariaLabel: sideBarProps.ariaLabel || "Info Sidebar",
|
|
11
|
-
isOpen: isSidebarOpen,
|
|
12
|
-
setIsOpen: setIsSidebarOpen,
|
|
13
10
|
}, icon: React.createElement(Help, { size: 20 }), bottomChildren: version !== undefined && (React.createElement(React.Fragment, null,
|
|
14
11
|
React.createElement(SwitcherDivider, null),
|
|
15
12
|
React.createElement("span", { className: "cds--switcher__item", style: {
|
|
@@ -3,6 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { useOnClickOutside } from "../helpers";
|
|
4
4
|
import C3NavigationSidebarElement from "./c3-navigation-sidebar-element";
|
|
5
5
|
import styled from "styled-components";
|
|
6
|
+
import { useSidebarState } from "./c3-sidebar-state-provider";
|
|
6
7
|
const HeaderPanel = styled(CarbonHeaderPanel) `
|
|
7
8
|
visibility: ${({ expanded }) => (expanded ? "visible" : "hidden")};
|
|
8
9
|
display: grid;
|
|
@@ -13,11 +14,21 @@ const HeaderPanel = styled(CarbonHeaderPanel) `
|
|
|
13
14
|
`;
|
|
14
15
|
const C3NavigationSideBar = (props) => {
|
|
15
16
|
const { icon, sideBar, children, bottomChildren } = props;
|
|
16
|
-
const {
|
|
17
|
+
const { callbacks } = sideBar;
|
|
18
|
+
const { isOpen, setIsOpen: setOpenState } = useSidebarState()[sideBar.type];
|
|
19
|
+
const setIsOpen = (open) => {
|
|
20
|
+
if (open)
|
|
21
|
+
callbacks?.beforeOpening?.();
|
|
22
|
+
setOpenState(open);
|
|
23
|
+
if (!open)
|
|
24
|
+
callbacks?.afterClosing?.();
|
|
25
|
+
};
|
|
17
26
|
const itemTabIndex = isOpen ? undefined : -1;
|
|
18
|
-
const [panelRef, iconRef] = useOnClickOutside(() =>
|
|
27
|
+
const [panelRef, iconRef] = useOnClickOutside(() => setIsOpen(false));
|
|
19
28
|
return (React.createElement(React.Fragment, null,
|
|
20
|
-
React.createElement(HeaderGlobalAction, { ref: iconRef, "aria-label": `Open ${sideBar.ariaLabel}`, onClick: () =>
|
|
29
|
+
React.createElement(HeaderGlobalAction, { ref: iconRef, "aria-label": `Open ${sideBar.ariaLabel}`, onClick: () => {
|
|
30
|
+
setIsOpen(!isOpen);
|
|
31
|
+
}, isActive: isOpen, tooltipAlignment: sideBar.type === "user" ? "end" : "center" }, icon),
|
|
21
32
|
React.createElement(HeaderPanel, { ref: panelRef, "aria-label": sideBar.ariaLabel, expanded: isOpen },
|
|
22
33
|
React.createElement(Stack, null,
|
|
23
34
|
children,
|
package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.d.ts
CHANGED
|
@@ -56,5 +56,8 @@ export declare type C3NavigationAppBarProps = C3NavigationSideBarBaseProps & {
|
|
|
56
56
|
type: "app";
|
|
57
57
|
};
|
|
58
58
|
export declare type C3NavigationSideBarProps = {
|
|
59
|
-
|
|
59
|
+
callbacks?: {
|
|
60
|
+
beforeOpening?: () => void;
|
|
61
|
+
afterClosing?: () => void;
|
|
62
|
+
};
|
|
60
63
|
} & (C3NavigationOrgSideBarProps | C3NavigationInfoSideBarProps | C3NavigationUserSideBarProps | C3NavigationNotificationsSideBarProps | C3NavigationAppBarProps);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Button } from "@carbon/react";
|
|
2
2
|
import { Notification as NotificationIcon } from "@carbon/react/icons";
|
|
3
|
-
import React, { useContext, useEffect, useState } from "react";
|
|
3
|
+
import React, { useContext, useEffect, useRef, useState } from "react";
|
|
4
4
|
import styled from "styled-components";
|
|
5
5
|
import { C3BellIcon, C3NotificationsUnreadIcon } from "../../../icons/c3-icons";
|
|
6
6
|
import C3NotificationContainer, { NotificationDescription, NotificationTitle, } from "../c3-notification-provider/c3-notification-container";
|
|
7
7
|
import { C3NotificationContext } from "../c3-notification-provider/c3-notification-provider";
|
|
8
8
|
import C3NavigationSideBar from "./c3-navigation-sidebar";
|
|
9
|
+
import { useNotificationSidebarState } from "./c3-sidebar-state-provider";
|
|
9
10
|
const PanelHeader = styled.div `
|
|
10
11
|
background: var(--cds-layer-01);
|
|
11
12
|
box-shadow: inset 0px -1px 0px var(--cds-border-subtle-01);
|
|
@@ -41,33 +42,34 @@ const EmptyStateDescription = styled(NotificationDescription) `
|
|
|
41
42
|
margin-top: 8px;
|
|
42
43
|
`;
|
|
43
44
|
export const C3NotificationSidebar = ({ sideBar }) => {
|
|
44
|
-
const {
|
|
45
|
-
const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
|
|
45
|
+
const { onLinkClick } = sideBar;
|
|
46
46
|
const { notifications, markAsRead, dismiss, markAllAsRead, dismissAll, analytics, enabled, } = useContext(C3NotificationContext);
|
|
47
47
|
const [unreadNotifications, setUnreadNotifications] = useState([]);
|
|
48
48
|
const hasUnreadNotifications = notifications.some(({ state }) => state === "new");
|
|
49
|
+
const { isOpen } = useNotificationSidebarState();
|
|
50
|
+
const notificationsRef = useRef();
|
|
51
|
+
notificationsRef.current = notifications;
|
|
49
52
|
const markAllAsReadSidebar = () => {
|
|
50
|
-
const newNotifications =
|
|
51
|
-
|
|
53
|
+
const newNotifications = notificationsRef.current?.filter((notification) => notification.state === "new");
|
|
54
|
+
if (newNotifications)
|
|
55
|
+
markAllAsRead(newNotifications);
|
|
52
56
|
};
|
|
53
57
|
const dismissAllSidebar = () => dismissAll(notifications);
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
setUnreadNotifications(
|
|
58
|
+
const beforeOpening = () => {
|
|
59
|
+
// remember new notifications, so the dots can be displayed
|
|
60
|
+
if (notificationsRef.current)
|
|
61
|
+
setUnreadNotifications(notificationsRef.current
|
|
58
62
|
.filter(({ state }) => state === "new")
|
|
59
63
|
.map(({ uuid }) => uuid));
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
setIsSidebarOpen(open);
|
|
66
|
-
if (!open) {
|
|
67
|
-
markAllAsReadSidebar();
|
|
68
|
-
setUnreadNotifications([]);
|
|
64
|
+
markAllAsReadSidebar();
|
|
65
|
+
if (enabled && analytics) {
|
|
66
|
+
analytics("notification-panel-opened");
|
|
69
67
|
}
|
|
70
68
|
};
|
|
69
|
+
const afterClosing = () => {
|
|
70
|
+
markAllAsReadSidebar();
|
|
71
|
+
setUnreadNotifications([]);
|
|
72
|
+
};
|
|
71
73
|
const sortNotificationsDescending = (a, b) => {
|
|
72
74
|
if (new Date(a.timestamp) > new Date(b.timestamp))
|
|
73
75
|
return -1;
|
|
@@ -76,15 +78,14 @@ export const C3NotificationSidebar = ({ sideBar }) => {
|
|
|
76
78
|
useEffect(() => {
|
|
77
79
|
// mark notifications as read on unmount
|
|
78
80
|
return () => {
|
|
79
|
-
if (
|
|
81
|
+
if (isOpen)
|
|
80
82
|
markAllAsReadSidebar();
|
|
81
83
|
};
|
|
82
84
|
}, []);
|
|
83
85
|
return (React.createElement(C3NavigationSideBar, { sideBar: {
|
|
84
86
|
...sideBar,
|
|
85
87
|
ariaLabel: sideBar.ariaLabel || "Notification Sidebar",
|
|
86
|
-
|
|
87
|
-
setIsOpen,
|
|
88
|
+
callbacks: { beforeOpening, afterClosing },
|
|
88
89
|
}, icon: hasUnreadNotifications ? (React.createElement(C3NotificationsUnreadIcon, { size: 20 })) : (React.createElement(NotificationIcon, { size: 20, label: "Notifications" })) },
|
|
89
90
|
React.createElement(PanelHeader, null,
|
|
90
91
|
React.createElement(PanelTitle, null, "Notifications"),
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { Button, FormLabel } from "@carbon/react";
|
|
3
3
|
import { Enterprise } from "@carbon/react/icons";
|
|
4
4
|
import C3NavigationSideBar from "./c3-navigation-sidebar";
|
|
5
5
|
import { SwitcherDivider } from "./components";
|
|
6
|
+
import { useOrgSidebarState } from "./c3-sidebar-state-provider";
|
|
6
7
|
const C3OrgSidebar = ({ sideBar }) => {
|
|
7
|
-
const { customElements,
|
|
8
|
+
const { customElements, ...sideBarProps } = sideBar;
|
|
8
9
|
const activeOrganization = customElements?.activeOrganization;
|
|
9
|
-
const
|
|
10
|
-
const itemTabIndex =
|
|
10
|
+
const { isOpen, setIsOpen } = useOrgSidebarState();
|
|
11
|
+
const itemTabIndex = isOpen ? undefined : -1;
|
|
11
12
|
return (React.createElement(C3NavigationSideBar, { sideBar: {
|
|
12
13
|
...sideBarProps,
|
|
13
14
|
ariaLabel: sideBarProps.ariaLabel || "Organization Sidebars",
|
|
14
|
-
isOpen: isSidebarOpen,
|
|
15
|
-
setIsOpen: setIsSidebarOpen,
|
|
16
15
|
}, icon: React.createElement(Enterprise, { size: 20 }) }, activeOrganization && (React.createElement(React.Fragment, null,
|
|
17
16
|
React.createElement("div", { style: {
|
|
18
17
|
padding: "1rem",
|
|
@@ -39,7 +38,7 @@ const C3OrgSidebar = ({ sideBar }) => {
|
|
|
39
38
|
React.createElement(Button, { size: "md", kind: "ghost", key: "org-management", onClick: () => {
|
|
40
39
|
activeOrganization.action.onClick();
|
|
41
40
|
if (sideBar.closeOnClick !== false) {
|
|
42
|
-
|
|
41
|
+
setIsOpen(false);
|
|
43
42
|
}
|
|
44
43
|
}, tabIndex: itemTabIndex }, activeOrganization.action.label)),
|
|
45
44
|
sideBar.elements && sideBar.elements.length > 0 && (React.createElement(React.Fragment, null,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { FC } from "react";
|
|
2
|
+
declare type DefaultValues = {
|
|
3
|
+
isNotificationSidebarOpen?: boolean;
|
|
4
|
+
isOrgSidebarOpen?: boolean;
|
|
5
|
+
isInfoSidebarOpen?: boolean;
|
|
6
|
+
isUserSidebarOpen?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare type SideBarState = {
|
|
9
|
+
isOpen: boolean;
|
|
10
|
+
setIsOpen: (isOpen: boolean) => void;
|
|
11
|
+
};
|
|
12
|
+
declare type C3SidebarsState = {
|
|
13
|
+
notifications: SideBarState;
|
|
14
|
+
org: SideBarState;
|
|
15
|
+
info: SideBarState;
|
|
16
|
+
user: SideBarState;
|
|
17
|
+
};
|
|
18
|
+
export declare const C3SidebarStateContext: React.Context<C3SidebarsState | null>;
|
|
19
|
+
export declare const C3SidebarStateProvider: FC<DefaultValues & {
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const useSidebarState: () => C3SidebarsState;
|
|
23
|
+
export declare const useNotificationSidebarState: () => SideBarState;
|
|
24
|
+
export declare const useOrgSidebarState: () => SideBarState;
|
|
25
|
+
export declare const useInfoSidebarState: () => SideBarState;
|
|
26
|
+
export declare const useUserSidebarState: () => SideBarState;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { useContext, useState } from "react";
|
|
2
|
+
export const C3SidebarStateContext = React.createContext(null);
|
|
3
|
+
export const C3SidebarStateProvider = ({ children, ...value }) => {
|
|
4
|
+
const [isNotificationSidebarOpen, setIsNotificationSidebarOpen] = useState(value.isNotificationSidebarOpen || false);
|
|
5
|
+
const [isOrgSidebarOpen, setIsOrgSidebarOpen] = useState(value.isOrgSidebarOpen || false);
|
|
6
|
+
const [isInfoSidebarOpen, setIsInfoSidebarOpen] = useState(value.isInfoSidebarOpen || false);
|
|
7
|
+
const [isUserSidebarOpen, setIsUserSidebarOpen] = useState(value.isUserSidebarOpen || false);
|
|
8
|
+
return (React.createElement(C3SidebarStateContext.Provider, { value: {
|
|
9
|
+
notifications: {
|
|
10
|
+
isOpen: isNotificationSidebarOpen,
|
|
11
|
+
setIsOpen: setIsNotificationSidebarOpen,
|
|
12
|
+
},
|
|
13
|
+
org: { isOpen: isOrgSidebarOpen, setIsOpen: setIsOrgSidebarOpen },
|
|
14
|
+
info: { isOpen: isInfoSidebarOpen, setIsOpen: setIsInfoSidebarOpen },
|
|
15
|
+
user: { isOpen: isUserSidebarOpen, setIsOpen: setIsUserSidebarOpen },
|
|
16
|
+
} }, children));
|
|
17
|
+
};
|
|
18
|
+
export const useSidebarState = () => {
|
|
19
|
+
const value = useContext(C3SidebarStateContext);
|
|
20
|
+
if (!value)
|
|
21
|
+
throw new Error("No C3SidebarStateContextProvider found.");
|
|
22
|
+
return value;
|
|
23
|
+
};
|
|
24
|
+
export const useNotificationSidebarState = () => useSidebarState().notifications;
|
|
25
|
+
export const useOrgSidebarState = () => useSidebarState().org;
|
|
26
|
+
export const useInfoSidebarState = () => useSidebarState().info;
|
|
27
|
+
export const useUserSidebarState = () => useSidebarState().user;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import C3NavigationSideBar from "./c3-navigation-sidebar";
|
|
3
3
|
import { FormLabel, RadioButton, RadioButtonGroup, Stack, SwitcherDivider, Toggle, } from "@carbon/react";
|
|
4
4
|
import { UserAvatar } from "@carbon/react/icons";
|
|
5
|
+
import { useUserSidebarState } from "./c3-sidebar-state-provider";
|
|
5
6
|
const C3UserSidebar = ({ sideBar }) => {
|
|
6
|
-
const { customElements,
|
|
7
|
+
const { customElements, ...sideBarProps } = sideBar;
|
|
7
8
|
const profile = customElements?.profile;
|
|
8
9
|
const themeSelector = customElements?.themeSelector;
|
|
9
10
|
const stageToggle = customElements?.stageToggle;
|
|
10
11
|
const customSection = customElements?.customSection;
|
|
11
|
-
const
|
|
12
|
-
const itemTabIndex =
|
|
12
|
+
const { isOpen } = useUserSidebarState();
|
|
13
|
+
const itemTabIndex = isOpen ? undefined : -1;
|
|
13
14
|
return (React.createElement(C3NavigationSideBar, { sideBar: {
|
|
14
15
|
...sideBarProps,
|
|
15
16
|
ariaLabel: sideBarProps.ariaLabel || "User Sidebar",
|
|
16
|
-
isOpen: isSidebarOpen,
|
|
17
|
-
setIsOpen: setIsSidebarOpen,
|
|
18
17
|
}, icon: React.createElement(UserAvatar, { size: 20 }), bottomChildren: customSection },
|
|
19
18
|
profile && (React.createElement("div", { style: {
|
|
20
19
|
padding: "1rem",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { C3NavigationProps } from "./c3-navigation.types";
|
|
3
|
-
export declare const C3Navigation: ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar,
|
|
3
|
+
export declare const C3Navigation: ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar, userSideBar, notificationSideBar, }: C3NavigationProps) => JSX.Element;
|
|
@@ -8,7 +8,7 @@ import { useMediaQuery } from "./helpers";
|
|
|
8
8
|
import { C3NavigationAppBar } from "./c3-navigation-appbar";
|
|
9
9
|
import styled from "styled-components";
|
|
10
10
|
import { CamundaLogo } from "../../icons/c3-icons";
|
|
11
|
-
import {
|
|
11
|
+
import { C3SidebarStateProvider } from "./c3-navigation-sidebar/c3-sidebar-state-provider";
|
|
12
12
|
/**
|
|
13
13
|
* UI SHELL
|
|
14
14
|
* Docs: https://react.carbondesignsystem.com/?path=/story/components-ui-shell--fixed-side-nav
|
|
@@ -28,62 +28,75 @@ const StyledToggletipContent = styled(ToggletipContent) `
|
|
|
28
28
|
color: var(--cds-link-hover-text-color);
|
|
29
29
|
}
|
|
30
30
|
`;
|
|
31
|
-
export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar,
|
|
31
|
+
export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar, userSideBar, notificationSideBar, }) => {
|
|
32
32
|
const isLargeScreen = useMediaQuery(`(min-width: ${BREAKPOINT_LG_WIDTH}`);
|
|
33
33
|
const appBarElementsLength = appBar.elements?.length ?? 0;
|
|
34
34
|
const displayAppBar = appBarElementsLength > 0 || (!isLargeScreen && navbar.elements.length > 0);
|
|
35
|
-
return (React.createElement(
|
|
36
|
-
|
|
37
|
-
React.createElement(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
React.createElement(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
React.createElement("
|
|
44
|
-
|
|
45
|
-
React.createElement(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
navbar.tags
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
35
|
+
return (React.createElement(C3SidebarStateProvider, { isNotificationSidebarOpen: notificationSideBar?.isOpen, isOrgSidebarOpen: orgSideBar?.isOpen, isInfoSidebarOpen: infoSideBar?.isOpen, isUserSidebarOpen: userSideBar?.isOpen },
|
|
36
|
+
React.createElement(HeaderContainer, { render: () => {
|
|
37
|
+
return (React.createElement(Header, { "aria-label": app.ariaLabel },
|
|
38
|
+
React.createElement(SkipToContent, null),
|
|
39
|
+
displayAppBar && (React.createElement(C3NavigationAppBar, { app: app, appBar: appBar, forwardRef: forwardRef, navbar: navbar })),
|
|
40
|
+
React.createElement(HeaderName, { element: forwardRef, prefix: "", ...app.routeProps },
|
|
41
|
+
React.createElement(CamundaLogo, { "aria-label": "Camunda" }),
|
|
42
|
+
React.createElement("span", null, app.name)),
|
|
43
|
+
React.createElement(HeaderNavigation, { "aria-label": app.ariaLabel }, navbar.elements.map((element) => (React.createElement(HeaderMenuItem, { key: element.key, element: element.routeProps && forwardRef, isCurrentPage: element.isCurrentPage, ...element.routeProps },
|
|
44
|
+
React.createElement("span", null, element.label))))),
|
|
45
|
+
React.createElement(HeaderGlobalBar, null,
|
|
46
|
+
React.createElement("div", { style: {
|
|
47
|
+
display: "grid",
|
|
48
|
+
gridAutoFlow: "column",
|
|
49
|
+
gap: ".5rem",
|
|
50
|
+
paddingRight: ".5rem",
|
|
51
|
+
} },
|
|
52
|
+
navbar.tags &&
|
|
53
|
+
navbar.tags.length > 0 &&
|
|
54
|
+
navbar.tags.map((tag) => {
|
|
55
|
+
if (tag?.tooltip !== undefined) {
|
|
56
|
+
const { content, buttonLabel } = tag.tooltip;
|
|
57
|
+
return (React.createElement("div", { key: tag.key, style: {
|
|
58
|
+
height: "1.5rem",
|
|
59
|
+
marginTop: "0.50rem",
|
|
60
|
+
} },
|
|
61
|
+
React.createElement(Toggletip, null,
|
|
62
|
+
React.createElement(ToggletipButton, { label: buttonLabel },
|
|
63
|
+
React.createElement(Tag, { type: tag.color, style: {
|
|
64
|
+
padding: "0 1rem",
|
|
65
|
+
marginRight: 0,
|
|
66
|
+
marginLeft: 0,
|
|
67
|
+
cursor: "pointer",
|
|
68
|
+
} }, tag.label)),
|
|
69
|
+
React.createElement(StyledToggletipContent, null, content))));
|
|
70
|
+
}
|
|
71
|
+
return (React.createElement(Tag, { key: tag.key, style: {
|
|
57
72
|
height: "1.5rem",
|
|
58
|
-
marginTop: "0.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
userSideBar && (React.createElement(C3UserSidebar, { sideBar: { ...userSideBar, type: "user" } })))));
|
|
88
|
-
} }));
|
|
73
|
+
marginTop: "0.75rem",
|
|
74
|
+
padding: "0 1rem",
|
|
75
|
+
}, type: tag.color }, tag.label));
|
|
76
|
+
}),
|
|
77
|
+
navbar.orgName && (React.createElement("div", { className: "bodyText", style: {
|
|
78
|
+
fontSize: "14px",
|
|
79
|
+
lineHeight: "3rem",
|
|
80
|
+
textOverflow: "ellipsis",
|
|
81
|
+
whiteSpace: "nowrap",
|
|
82
|
+
overflow: "hidden",
|
|
83
|
+
maxWidth: "150px",
|
|
84
|
+
} }, navbar.orgName))),
|
|
85
|
+
notificationSideBar && (React.createElement(C3NotificationSidebar, { sideBar: {
|
|
86
|
+
...notificationSideBar,
|
|
87
|
+
type: "notifications",
|
|
88
|
+
} })),
|
|
89
|
+
orgSideBar && (React.createElement(C3OrgSidebar, { sideBar: {
|
|
90
|
+
...orgSideBar,
|
|
91
|
+
type: "org",
|
|
92
|
+
} })),
|
|
93
|
+
infoSideBar && (React.createElement(C3InfoSidebar, { sideBar: {
|
|
94
|
+
...infoSideBar,
|
|
95
|
+
type: "info",
|
|
96
|
+
} })),
|
|
97
|
+
userSideBar && (React.createElement(C3UserSidebar, { sideBar: {
|
|
98
|
+
...userSideBar,
|
|
99
|
+
type: "user",
|
|
100
|
+
} })))));
|
|
101
|
+
} })));
|
|
89
102
|
};
|
|
@@ -53,9 +53,6 @@ export interface C3NavigationProps {
|
|
|
53
53
|
appBar: WithoutType<C3NavigationAppBarProps>;
|
|
54
54
|
orgSideBar?: WithoutType<C3NavigationOrgSideBarProps>;
|
|
55
55
|
infoSideBar?: WithoutType<C3NavigationInfoSideBarProps>;
|
|
56
|
-
infoButton?: {
|
|
57
|
-
onClick: () => void;
|
|
58
|
-
};
|
|
59
56
|
userSideBar?: WithoutType<C3NavigationUserSideBarProps>;
|
|
60
57
|
notificationSideBar?: WithoutType<C3NavigationNotificationsSideBarProps>;
|
|
61
58
|
navbar: C3NavigationNavBarProps;
|
|
@@ -2,36 +2,38 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
2
2
|
export function useOnClickOutside(handler) {
|
|
3
3
|
const panelRef = useRef(null);
|
|
4
4
|
const iconRef = useRef(null);
|
|
5
|
+
const listener = (event) => {
|
|
6
|
+
if (!panelRef.current ||
|
|
7
|
+
!iconRef.current ||
|
|
8
|
+
(event.target instanceof Node &&
|
|
9
|
+
(panelRef.current.contains(event.target) ||
|
|
10
|
+
iconRef.current.contains(event.target)))) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
handler(event);
|
|
14
|
+
};
|
|
5
15
|
const setListener = () => {
|
|
6
|
-
const listener = (event) => {
|
|
7
|
-
if (!panelRef.current ||
|
|
8
|
-
!iconRef.current ||
|
|
9
|
-
(event.target instanceof Node &&
|
|
10
|
-
(panelRef.current.contains(event.target) ||
|
|
11
|
-
iconRef.current.contains(event.target)))) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
handler(event);
|
|
15
|
-
};
|
|
16
16
|
document.addEventListener("mousedown", listener);
|
|
17
17
|
document.addEventListener("touchstart", listener);
|
|
18
|
+
};
|
|
19
|
+
useEffect(() => {
|
|
18
20
|
return () => {
|
|
19
21
|
document.removeEventListener("mousedown", listener);
|
|
20
22
|
document.removeEventListener("touchstart", listener);
|
|
21
23
|
};
|
|
22
|
-
};
|
|
24
|
+
}, []);
|
|
23
25
|
const setPanelRef = useCallback((node) => {
|
|
24
26
|
if (node && node instanceof HTMLElement) {
|
|
25
27
|
panelRef.current = node;
|
|
26
28
|
setListener();
|
|
27
29
|
}
|
|
28
|
-
}, [
|
|
30
|
+
}, []);
|
|
29
31
|
const setIconRef = useCallback((node) => {
|
|
30
32
|
if (node && node instanceof HTMLElement) {
|
|
31
33
|
iconRef.current = node;
|
|
32
34
|
setListener();
|
|
33
35
|
}
|
|
34
|
-
}, [
|
|
36
|
+
}, []);
|
|
35
37
|
return [setPanelRef, setIconRef];
|
|
36
38
|
}
|
|
37
39
|
export function executeMediaQuery(mediaQuery) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { C3Navigation } from "./c3-navigation";
|
|
3
|
+
import { ComponentStory } from "@storybook/react";
|
|
4
|
+
export declare const DefaultTemplate: ComponentStory<typeof C3Navigation>;
|
|
5
|
+
export declare const SuperUserToggle: FC<{
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
onChange?: (newValue: boolean) => void;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const NavbarWithCustomSection: FC;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { C3Navigation } from "./c3-navigation";
|
|
3
|
+
import { createAppBarProps, createAppProps, createNavBarBarProps, createUserSideBarProps, } from "./story-helpers";
|
|
4
|
+
import { SwitcherDivider, Toggle } from "@carbon/react";
|
|
5
|
+
export const DefaultTemplate = (args) => (React.createElement(C3Navigation, { ...args }));
|
|
6
|
+
export const SuperUserToggle = ({ isActive, onChange }) => {
|
|
7
|
+
return (React.createElement(React.Fragment, null,
|
|
8
|
+
React.createElement(SwitcherDivider, null),
|
|
9
|
+
React.createElement("div", { style: { padding: ".5rem 1rem" } },
|
|
10
|
+
React.createElement(Toggle, { size: "sm", id: "toggle-super-admin-mode", defaultToggled: isActive, onToggle: (superAdminModeActive) => onChange?.(superAdminModeActive), labelText: "Enter super-admin mode" }))));
|
|
11
|
+
};
|
|
12
|
+
export const NavbarWithCustomSection = () => {
|
|
13
|
+
const [isSuperAdminModeActive, setIsSuperAdminModeActive] = useState(true);
|
|
14
|
+
return (React.createElement(C3Navigation, { app: createAppProps(), appBar: createAppBarProps(), navbar: {
|
|
15
|
+
...createNavBarBarProps(),
|
|
16
|
+
tags: isSuperAdminModeActive
|
|
17
|
+
? [
|
|
18
|
+
{
|
|
19
|
+
key: "superUserMode",
|
|
20
|
+
label: "Super-user mode",
|
|
21
|
+
color: "high-contrast",
|
|
22
|
+
},
|
|
23
|
+
]
|
|
24
|
+
: undefined,
|
|
25
|
+
}, userSideBar: {
|
|
26
|
+
...createUserSideBarProps({ isOpen: false }),
|
|
27
|
+
customElements: {
|
|
28
|
+
customSection: (React.createElement(SuperUserToggle, { isActive: isSuperAdminModeActive, onChange: setIsSuperAdminModeActive })),
|
|
29
|
+
},
|
|
30
|
+
} }));
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { HeaderGlobalAction } from "@carbon/react";
|
|
3
|
-
import { Help } from "@carbon/react/icons";
|
|
4
|
-
export const InfoButton = ({ onClick }) => (React.createElement(HeaderGlobalAction, { "aria-label": "Open Help Center", tooltipAlignment: "center", onClick: onClick },
|
|
5
|
-
React.createElement(Help, { size: 20 })));
|