Skip to content

Commit 7bf90c9

Browse files
authored
Added Menu components to mds (#342)
1 parent bfa9cca commit 7bf90c9

23 files changed

+2006
-17
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ lint:
88

99
test:
1010
@(yarn install; yarn test;)
11+
12+
test-warnings:
13+
./check-warnings.sh

check-warnings.sh

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
yell() { echo "$0: $*" >&2; }
4+
5+
die() {
6+
yell "$*"
7+
cat yarn.log
8+
exit 111
9+
}
10+
11+
try() { "$@" &> yarn.log || die "cannot $*"; }
12+
13+
rm -f yarn.log
14+
try make build
15+
16+
if cat yarn.log | grep "Compiled with warnings"; then
17+
echo "There are warnings in the code"
18+
exit 1
19+
fi
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// This file is part of MinIO Design System
2+
// Copyright (c) 2023 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import * as React from "react";
18+
import { SVGProps } from "react";
19+
20+
const CollapseMenuIcon = (props: SVGProps<SVGSVGElement>) => (
21+
<svg
22+
xmlns="http://www.w3.org/2000/svg"
23+
className={`min-icon`}
24+
fill={"currentcolor"}
25+
viewBox="0 0 256 256"
26+
{...props}
27+
>
28+
<g transform="translate(0 0.004)">
29+
<path
30+
d="M79.8,115.3h158c2.7-0.4,5.5,0.4,7.6,2.3c2.2,1.9,3.1,5,2.3,7.8c-0.7,3-3.1,5.3-6.1,5.9
31+
c-1.4,0.2-2.7,0.2-4.1,0.2H79.2c1,1,1.6,1.8,2.3,2.5l56.7,56.7c2.4,2,3.4,5.2,2.5,8.2c-0.7,3-3.1,5.3-6.1,5.9
32+
c-2.8,0.5-5.7-0.5-7.6-2.7L114,189.2c-19.4-19.4-39.1-38.9-58.3-58.5c-1.7-1.8-3-4-3.7-6.3c-0.4-3,0.7-5.9,3.1-7.8
33+
C75.5,96.1,96,75.8,116.3,55.4c3.7-3.7,7.4-7.6,11.3-11.1c2.7-2.5,6.7-3,9.8-1c3.1,1.5,4.6,5.1,3.5,8.4c-0.6,1.9-1.8,3.6-3.3,4.9
34+
c-18.6,18.8-37.5,37.5-56.3,56.3l-2.3,2.3L79.8,115.3z"
35+
/>
36+
<path
37+
d="M25.6,128.2V16.9c0.1-1.4-0.1-2.9-0.4-4.3C24.5,9.5,22.1,7,19,6.2c-2.9-0.8-6,0.2-8,2.5
38+
c-2,2.2-2.9,5.1-2.5,8v111.6l0,0v111.4c-0.1,1.4,0.1,2.9,0.4,4.3c0.6,3.1,3,5.6,6.1,6.3c2.9,0.9,6.1-0.1,8-2.5
39+
c1.9-2.2,2.8-5.1,2.5-8L25.6,128.2C25.6,128.2,25.6,128.2,25.6,128.2z"
40+
/>
41+
</g>
42+
</svg>
43+
);
44+
45+
export default CollapseMenuIcon;

src/components/Icons/Icons.stories.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ const Template: Story = (args) => {
270270
CollapseIcon
271271
</Grid>
272272

273+
<Grid item xs={3} sm={2} md={1}>
274+
<cicons.CollapseMenuIcon />
275+
<br />
276+
CollapseMenuIcon
277+
</Grid>
278+
273279
<Grid item xs={3} sm={2} md={1}>
274280
<cicons.ComputerLineIcon />
275281
<br />

src/components/Icons/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,4 @@ export { default as VisibilityOnIcon } from "./VisibilityOnIcon";
204204
export { default as VisibilityOffIcon } from "./VisibilityOffIcon";
205205
export { default as AccessRuleIcon } from "./AccessRuleIcon";
206206
export { default as TimeIcon } from "./TimeIcon";
207+
export { default as CollapseMenuIcon } from "./CollapseMenuIcon";

src/components/MainContainer/MainContainer.stories.tsx

+19-13
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
import React, { Fragment } from "react";
17+
import React, { useState } from "react";
1818
import { Meta, Story } from "@storybook/react";
1919

2020
import MainContainer from "./MainContainer";
2121
import { MainContainerProps } from "./MainContainer.types";
2222
import StoryThemeProvider from "../../utils/StoryThemeProvider";
23-
import { Button, GlobalStyles } from "../index";
23+
import { GlobalStyles } from "../index";
2424
import Box from "../Box/Box";
2525

2626
export default {
@@ -29,26 +29,32 @@ export default {
2929
argTypes: {},
3030
} as Meta<typeof MainContainer>;
3131

32-
const Template: Story<MainContainerProps> = (args) => (
33-
<StoryThemeProvider>
34-
<GlobalStyles />
35-
<MainContainer {...args} />
36-
</StoryThemeProvider>
37-
);
32+
const Template: Story<MainContainerProps> = (args) => {
33+
return (
34+
<StoryThemeProvider>
35+
<GlobalStyles />
36+
<MainContainer {...args} />
37+
</StoryThemeProvider>
38+
);
39+
};
3840

3941
export const Default = Template.bind({});
4042

4143
Default.args = {
42-
menu: (
43-
<Box sx={{ width: 250, backgroundColor: "#fac" }}>
44-
A Block simulating a menu box
45-
</Box>
46-
),
4744
children: <Box>This is a Block simulating the content box</Box>,
45+
menu: <div>This is where menu goes</div>,
4846
};
4947

5048
export const NoMenu = Template.bind({});
5149

5250
NoMenu.args = {
5351
children: <Box>This is a Block simulating the content box</Box>,
5452
};
53+
54+
export const HorizontalMenu = Template.bind({});
55+
56+
HorizontalMenu.args = {
57+
children: <Box>This is a Block simulating the content box</Box>,
58+
menu: <div>This is where menu goes</div>,
59+
horizontal: true,
60+
};

src/components/MainContainer/MainContainer.tsx

+13-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
import React, { FC } from "react";
1818
import get from "lodash/get";
1919
import styled from "styled-components";
20-
import { MainContainerProps } from "./MainContainer.types";
20+
import { MainContainerProps, ParentBoxProps } from "./MainContainer.types";
21+
import { breakPoints } from "../../global/utils";
2122

2223
const CustomMain = styled.main(({ theme }) => {
2324
return {
@@ -30,13 +31,21 @@ const CustomMain = styled.main(({ theme }) => {
3031
};
3132
});
3233

33-
const ParentBox = styled.div(() => ({
34+
const ParentBox = styled.div<ParentBoxProps>(({ horizontal }) => ({
3435
display: "flex",
36+
flexDirection: !!horizontal ? "column" : "row",
37+
[`@media (max-width: ${get(breakPoints, "md", 0)}px)`]: {
38+
flexDirection: "column",
39+
},
3540
}));
3641

37-
const MainContainer: FC<MainContainerProps> = ({ children, menu }) => {
42+
const MainContainer: FC<MainContainerProps> = ({
43+
children,
44+
menu,
45+
horizontal,
46+
}) => {
3847
return (
39-
<ParentBox>
48+
<ParentBox horizontal={horizontal}>
4049
{menu}
4150
<CustomMain>{children}</CustomMain>
4251
</ParentBox>

src/components/MainContainer/MainContainer.types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ import React from "react";
1919
export interface MainContainerProps {
2020
menu?: React.ReactNode;
2121
children: React.ReactNode;
22+
horizontal?: boolean;
23+
}
24+
25+
export interface ParentBoxProps {
26+
horizontal?: boolean;
2227
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// This file is part of MinIO Design System
2+
// Copyright (c) 2023 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React, { FC } from "react";
18+
import CircleIcon from "../../Icons/CircleIcon";
19+
20+
const MenuBadge: FC = () => {
21+
return <CircleIcon />;
22+
};
23+
24+
export default MenuBadge;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// This file is part of MinIO Design System
2+
// Copyright (c) 2023 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React, { FC, Fragment } from "react";
18+
import styled from "styled-components";
19+
import get from "lodash/get";
20+
import { MenuConstructProps, MenuProps } from "../Menu.types";
21+
import { lightColors } from "../../../global/themes";
22+
import Box from "../../Box/Box";
23+
import LogoutIcon from "../../Icons/LogoutIcon";
24+
import ApplicationLogo from "../../ApplicationLogo/ApplicationLogo";
25+
import HorizontalMenuItem from "./HorizontalMenuItem";
26+
import IconButton from "../../IconButton/IconButton";
27+
28+
const HorizontalMenuContainer = styled.div<MenuConstructProps>(
29+
({ theme, sx }) => {
30+
return {
31+
"& .headerBar": {
32+
padding: 15,
33+
display: "flex",
34+
justifyContent: "space-between",
35+
alignItems: "center",
36+
gap: 15,
37+
background: get(
38+
theme,
39+
"menu.horizontal.menuHeaderBackground",
40+
lightColors.menuBackground
41+
),
42+
borderBottom: `${get(
43+
theme,
44+
"menu.horizontal.sectionDividerColor",
45+
lightColors.menuColorDivider
46+
)} 1px solid`,
47+
"& svg": {
48+
width: 200,
49+
},
50+
},
51+
"& .sections": {
52+
backgroundColor: get(
53+
theme,
54+
"menu.horizontal.barBackground",
55+
lightColors.mainGrey
56+
),
57+
width: "100%",
58+
height: 45,
59+
display: "flex",
60+
overflowY: "hidden",
61+
overflowX: "auto",
62+
scrollbarWidth: "none",
63+
msOverflowStyle: "none",
64+
"&::-webkit-scrollbar": {
65+
width: 0,
66+
height: 0,
67+
},
68+
},
69+
...sx,
70+
};
71+
}
72+
);
73+
74+
const HorizontalMenu: FC<MenuProps> = ({
75+
applicationLogo,
76+
options,
77+
signOutAction,
78+
callPathAction,
79+
middleComponent,
80+
currentPath,
81+
sx,
82+
}) => {
83+
return (
84+
<HorizontalMenuContainer sx={sx}>
85+
<Box className={"headerBar"}>
86+
<ApplicationLogo inverse {...applicationLogo} />
87+
{middleComponent}
88+
{signOutAction && (
89+
<IconButton id="sign-out" onClick={signOutAction}>
90+
<LogoutIcon />
91+
</IconButton>
92+
)}
93+
</Box>
94+
<Box className={"sections"}>
95+
{options.map((option) => {
96+
const onClickAction = (path: string) => {
97+
if (option.onClick) {
98+
option.onClick(path);
99+
}
100+
101+
callPathAction(path);
102+
};
103+
104+
return (
105+
<HorizontalMenuItem
106+
key={`menu-section-${option.groupName}-${option.id}`}
107+
onClick={onClickAction}
108+
icon={option.icon}
109+
name={option.name}
110+
groupName={option.groupName}
111+
id={option.id}
112+
path={option.path}
113+
currentPath={currentPath}
114+
badge={option.badge}
115+
children={option.children}
116+
/>
117+
);
118+
})}
119+
</Box>
120+
</HorizontalMenuContainer>
121+
);
122+
};
123+
124+
export default HorizontalMenu;

0 commit comments

Comments
 (0)