Merge pull request #14 from bluewave-labs/feat/labels

Feat/labels
This commit is contained in:
Alexander Holliday authored and GitHub committed 2024-05-07 21:58:54 -07:00
commit 3249132f36
7 files changed
+226 -8

No files matched your search

+8 -4
View File
@@ -21,10 +21,14 @@ const levelConfig = {
};
/**
* @typedef {Object} Props
* @property {'primary' | 'secondary' | 'tertiary' | 'error'} level - The level of the button
* @property {string} label - The label of the button
* @property {boolean} [disabled] - Whether the button is disabled
* @param {Object} props
* @param {'primary' | 'secondary' | 'tertiary' | 'error'} props.level - The level of the button
* @param {string} props.label - The label of the button
* @param {boolean} [props.disabled] - Whether the button is disabled
* @returns {JSX.Element}
* @example
* // Render an error button
* <Button level="error" label="Error" disabled />
*/
const Button = ({ level, label, disabled }) => {
@@ -0,0 +1,6 @@
.label {
border: 1px solid #000;
display: inline-flex;
justify-content: center;
align-items: center;
}
+54
View File
@@ -0,0 +1,54 @@
import PropTypes from "prop-types";
import "./BaseLabel.css";
import { useTheme } from "@mui/material";
/**
* @typedef {Object} Styles
* @param {string} [color] - The text color
* @param {string} [backgroundColor] - The background color
* @param {string} [borderColor] - The border color
*/
/**
* @component
* @param {Object} props
* @param {string} props.label - The label of the label
* @param {Styles} props.styles - CSS Styles passed from parent component
* @param {React.ReactNode} children - Children passed from parent component
* @returns {JSX.Element}
*/
const BaseLabel = ({ label, styles, children }) => {
const theme = useTheme();
// Grab the default borderRadius from the theme to match button style
const { borderRadius } = theme.shape;
// Calculate padding for the label to mimic button. Appears to scale correctly, not 100% sure though.
const padding = theme.spacing(1 * 0.75, 2);
return (
<div
className="label"
style={{
borderRadius: borderRadius,
borderColor: theme.palette.tertiary.main,
color: theme.palette.tertiary.main,
padding: padding,
...styles,
}}
>
{children}
{label}
</div>
);
};
BaseLabel.propTypes = {
label: PropTypes.string.isRequired,
styles: PropTypes.shape({
color: PropTypes.string,
backgroundColor: PropTypes.string,
}),
children: PropTypes.node,
};
export default BaseLabel;
@@ -0,0 +1,67 @@
import { useTheme } from "@mui/material";
import { PropTypes } from "prop-types";
import BaseLabel from "./BaseLabel";
// Produces a lighter color based on a hex color and a percent
// lightenColor("#067647", 20) will produce a color 20% lighter than #067647
const lightenColor = (color, percent) => {
let r = parseInt(color.substring(1, 3), 16);
let g = parseInt(color.substring(3, 5), 16);
let b = parseInt(color.substring(5, 7), 16);
const amt = Math.round((255 * percent) / 100);
r = r + amt <= 255 ? r + amt : 255;
g = g + amt <= 255 ? g + amt : 255;
b = b + amt <= 255 ? b + amt : 255;
r = r.toString(16).padStart(2, "0");
g = g.toString(16).padStart(2, "0");
b = b.toString(16).padStart(2, "0");
return `#${r}${g}${b}`;
};
/**
* @component
* @param {Object} props
* @param {string} props.label - The label of the label
* @param {string} props.color - The color of the label, specified in #RRGGBB format
* @returns {JSX.Element}
* @example
* // Render a red label
* <ColoredLabel label="Label" color="#FF0000" />
*/
const ColoredLabel = ({ label, color }) => {
const theme = useTheme();
// If an invalid color is passed, default to the labelGray color
if (
typeof color !== "string" ||
!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(color)
) {
color = theme.palette.labelGray.color;
}
// Calculate lighter shades for border and bg
const borderColor = lightenColor(color, 20);
const bgColor = lightenColor(color, 75);
return (
<BaseLabel
label={label}
styles={{
color: color,
borderColor: borderColor,
backgroundColor: bgColor,
}}
></BaseLabel>
);
};
ColoredLabel.propTypes = {
label: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
};
export default ColoredLabel;
@@ -0,0 +1,46 @@
import PropTypes from "prop-types";
import BaseLabel from "./BaseLabel";
import { Box } from "@mui/material";
import { useTheme } from "@mui/material";
/**
* @component
* @param {Object} props
* @param {'Seen' | 'Waiting' | 'New' | 'Active'} props.status - The status for the label
* @returns {JSX.Element}
* @example
* // Render an active label
* <StatusLabel status="Active" />
*/
const StatusLabel = ({ status }) => {
const theme = useTheme();
const colorLookup = {
Seen: theme.palette.labelGray.color,
Waiting: theme.palette.labelRed.color,
New: theme.palette.labelOrange.color,
Active: theme.palette.labelGreen.color,
};
// Look up the color for the status, default to labelGray if not found
const color = colorLookup[status] || theme.palette.labelGray.color;
return (
<BaseLabel label={status}>
<Box
width={12}
height={12}
bgcolor={color}
borderRadius="50%"
marginRight={1}
/>
</BaseLabel>
);
};
StatusLabel.propTypes = {
status: PropTypes.oneOf(["Seen", "Waiting", "New", "Active"]),
};
export default StatusLabel;
+20 -4
View File
@@ -1,17 +1,18 @@
import React from "react";
import DropdownTeamMember from "../../Components/DropdownTeamMember";
import "./index.css";
import Button from "../../Components/Button";
import Link from "../../Components/Link";
import ColoredLabel from "../../Components/Label/ColoredLabel";
import { useTheme } from "@mui/material";
import StatusLabel from "../../Components/Label/StautsLabel";
const Home = () => {
const theme = useTheme();
return (
<>
<div>Home</div>
<DropdownTeamMember />
<div
style={{ display: "flex", flexDirection: "column", marginTop: "2rem" }}
>
<div>
<h4>Buttons</h4>
<div>
<Button level="primary" label="Primary" />
@@ -33,6 +34,21 @@ const Home = () => {
url={"https://www.google.com"}
/>
</div>
<h4>Labels</h4>
<div>
<ColoredLabel label="Label" color={theme.palette.labelGray.color} />
<ColoredLabel label="Label" color={theme.palette.labelPurple.color} />
<ColoredLabel label="Label" color={theme.palette.labelGreen.color} />
<ColoredLabel label="Label" color={theme.palette.labelOrange.color} />
</div>
<h4>Status Lables</h4>
<div>
<StatusLabel status="Seen" />
<StatusLabel status="Waiting" />
<StatusLabel status="New" />
<StatusLabel status="Active" />
</div>
</div>
</>
);
+25
View File
@@ -1,12 +1,22 @@
import { createTheme } from "@mui/material";
// Colors for MUI theme
const primaryMain = "#1570EF";
const secondaryMain = "#475467";
const tertiaryMain = "#475467";
const tertiaryLinkHover = "#eff8ff";
// Label Colors
const labelOrange = "#F79009";
const labelGray = "#475467";
const labelPurple = "#6941C6";
const labelGreen = "#067647";
const labelRed = "#F04438";
const theme = createTheme({
palette: {
primary: {
main: primaryMain,
},
secondary: {
main: secondaryMain,
},
@@ -14,6 +24,21 @@ const theme = createTheme({
main: tertiaryMain,
linkHover: tertiaryLinkHover,
},
labelOrange: {
color: labelOrange,
},
labelGray: {
color: labelGray,
},
labelPurple: {
color: labelPurple,
},
labelGreen: {
color: labelGreen,
},
labelRed: {
color: labelRed,
},
},
});