Skip to content

Commit

Permalink
Added Badge component (#543)
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Perez <[email protected]>
  • Loading branch information
bexsoft authored Oct 23, 2023
1 parent aab8ddc commit 6d77216
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/components/Badge/Badge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// This file is part of MinIO Design System
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import React from "react";
import { Meta, Story } from "@storybook/react";

import Badge from "./Badge";
import { BadgeProps } from "./Badge.types";

import StoryThemeProvider from "../../utils/StoryThemeProvider";
import GlobalStyles from "../GlobalStyles/GlobalStyles";
import DownloadIcon from "../Icons/DownloadIcon";

export default {
title: "MDS/Information/Badge",
component: Badge,
argTypes: {},
} as Meta<typeof Badge>;

const Template: Story<BadgeProps> = (args) => (
<StoryThemeProvider>
<GlobalStyles />
<Badge {...args} onClick={() => alert("You clicked me!")}>
<DownloadIcon />
</Badge>
</StoryThemeProvider>
);

export const Default = Template.bind({});
Default.args = {
badgeContent: 5,
};

export const DotOnly = Template.bind({});
DotOnly.args = {
badgeContent: 5,
dotOnly: true,
};

export const Warn = Template.bind({});
Warn.args = { badgeContent: 5, color: "warn" };

export const Secondary = Template.bind({});
Secondary.args = {
badgeContent: 5,
color: "secondary",
};

export const Alert = Template.bind({});
Alert.args = {
badgeContent: 5,
color: "alert",
};

export const Ok = Template.bind({});
Ok.args = {
badgeContent: 5,
color: "ok",
};

export const Grey = Template.bind({});
Grey.args = {
badgeContent: 5,
color: "grey",
};
114 changes: 114 additions & 0 deletions src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// This file is part of MinIO Design System
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import React, { FC, Fragment, HTMLAttributes } from "react";
import styled from "styled-components";
import { BadgeConstruct, BadgeProps } from "./Badge.types";
import { lightColors } from "../../global/themes";
import get from "lodash/get";

const BadgeParent = styled.span<
HTMLAttributes<HTMLDivElement> & BadgeConstruct
>(
({
theme,
sx,
verticalPosition,
horizontalPosition,
color,
shape,
dotOnly,
}) => {
let circularRadius = dotOnly ? "100%" : 10;

return {
position: "relative",
display: "inline-flex",
"& .badgeContent": {
fontSize: 10,
userSelect: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
position: "absolute",
padding: dotOnly ? 0 : "0 6px",
borderRadius: shape === "circular" ? circularRadius : 3,
right: horizontalPosition === "right" ? 0 : "initial",
top: verticalPosition === "top" ? 0 : "initial",
left: horizontalPosition === "left" ? 0 : "initial",
bottom: verticalPosition === "bottom" ? 0 : "initial",
minWidth: !dotOnly ? 20 : 10,
width: dotOnly ? 10 : "initial",
height: !dotOnly ? 20 : 10,
backgroundColor: get(
theme,
`badge.${color}.backgroundColor`,
lightColors.mainBlue,
),
color: get(theme, `badge.${color}.textColor`, lightColors.white),
fontWeight: "bold",
textAlign: "center",
zIndex: 1,
transform: `scale(1) translate(${
horizontalPosition === "right" ? "" : "-"
}50%, ${verticalPosition === "bottom" ? "" : "-"}50%)`,
},
...sx,
};
},
);

const Badge: FC<HTMLAttributes<HTMLSpanElement> & BadgeProps> = ({
sx,
children,
horizontalPosition = "right" as "right" | "left",
verticalPosition = "bottom" as "top" | "bottom",
color = "default",
shape = "circular",
dotOnly = false,
invisible = false,
max = 99,
showZero = false,
badgeContent = 0,
...props
}) => {
return (
<BadgeParent
horizontalPosition={horizontalPosition}
verticalPosition={verticalPosition}
color={color}
shape={shape}
dotOnly={dotOnly}
sx={sx}
{...props}
>
{children}
{!invisible &&
(badgeContent >= 0 || (showZero && badgeContent === 0)) && (
<div className={"badgeContent"}>
{!dotOnly ? (
<Fragment>
{badgeContent > max ? `${max}+` : badgeContent}
</Fragment>
) : (
""
)}
</div>
)}
</BadgeParent>
);
};
export default Badge;
35 changes: 35 additions & 0 deletions src/components/Badge/Badge.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This file is part of MinIO Design System
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { CSSObject } from "styled-components";

export interface BadgeMain {
invisible?: boolean;
max?: number;
showZero?: boolean;
badgeContent?: number;
}

export interface BadgeConstruct {
horizontalPosition?: "left" | "right";
verticalPosition?: "bottom" | "top";
sx?: CSSObject;
color?: "default" | "secondary" | "warn" | "alert" | "ok" | "grey";
shape?: "circular" | "rectangular";
dotOnly?: boolean;
}

export type BadgeProps = BadgeMain & BadgeConstruct;
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export { default as Snackbar } from "./Snackbar/Snackbar";
export { default as Accordion } from "./Accordion/Accordion";
export { default as HelpTip } from "./HelpTip/HelpTip";
export { default as Autocomplete } from "./Autocomplete/Autocomplete";
export { default as Badge } from "./Badge/Badge";

/*Icons*/
export * from "./Icons";
Expand Down Expand Up @@ -115,3 +116,4 @@ export * from "./Snackbar/Snackbar.types";
export * from "./Accordion/Accordion.types";
export * from "./HelpTip/HelpTip.types";
export * from "./Autocomplete/Autocomplete.types";
export * from "./Badge/Badge.types";
16 changes: 16 additions & 0 deletions src/global/global.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import React from "react";
import { lightColors } from "./themes";

export interface ButtonThemeProps {
border: string;
Expand Down Expand Up @@ -295,6 +296,20 @@ export interface InformativeMessageProps {
error: InformativeColorElements;
}

export interface BadgeColorElements {
backgroundColor: string;
textColor: string;
}

export interface BadgeStyleProps {
alert: BadgeColorElements;
default: BadgeColorElements;
secondary: BadgeColorElements;
warn: BadgeColorElements;
ok: BadgeColorElements;
grey: BadgeColorElements;
}

export interface ThemeDefinitionProps {
bgColor: string;
fontColor: string;
Expand Down Expand Up @@ -337,6 +352,7 @@ export interface ThemeDefinitionProps {
tag?: TagThemeProps;
snackbar?: SnackBarThemeProps;
informativeMessage?: InformativeMessageProps;
badge?: BadgeStyleProps;
}

export interface SelectorType {
Expand Down
52 changes: 52 additions & 0 deletions src/global/themes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,32 @@ export const lightTheme: ThemeDefinitionProps = {
textColor: lightColors.defaultFontColor,
},
},
badge: {
alert: {
backgroundColor: lightColors.mainRed,
textColor: lightColors.white,
},
default: {
backgroundColor: lightColors.mainBlue,
textColor: lightColors.white,
},
secondary: {
backgroundColor: lightColors.secondAction,
textColor: lightColors.white,
},
warn: {
backgroundColor: lightColors.mainOrange,
textColor: lightColors.defaultFontColor,
},
ok: {
backgroundColor: lightColors.mainGreen,
textColor: lightColors.defaultFontColor,
},
grey: {
backgroundColor: lightColors.actionDisabledGrey,
textColor: lightColors.defaultFontColor,
},
},
};

export const darkTheme: ThemeDefinitionProps = {
Expand Down Expand Up @@ -1032,4 +1058,30 @@ export const darkTheme: ThemeDefinitionProps = {
textColor: darkColors.dark,
},
},
badge: {
alert: {
backgroundColor: darkColors.mainRed,
textColor: darkColors.mainWhite,
},
default: {
backgroundColor: darkColors.mainGrey,
textColor: darkColors.dark,
},
secondary: {
backgroundColor: darkColors.secondAction,
textColor: darkColors.mainWhite,
},
warn: {
backgroundColor: darkColors.mainOrange,
textColor: darkColors.dark,
},
ok: {
backgroundColor: darkColors.mainGreen,
textColor: darkColors.dark,
},
grey: {
backgroundColor: darkColors.disabledBGGrey,
textColor: darkColors.mainWhite,
},
},
};

0 comments on commit 6d77216

Please sign in to comment.