Added status label, fixed JSdoc

This commit is contained in:
Alex Holliday
2024-05-07 14:22:39 -07:00
parent f8828fe6e8
commit 6359fd52b6
7 changed files with 162 additions and 67 deletions
+4 -4
View File
@@ -21,10 +21,10 @@ 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'} level - The level of the button
* @param {string} label - The label of the button
* @param {boolean} [disabled] - Whether the button is disabled
*/
const Button = ({ level, label, disabled }) => {
@@ -2,4 +2,5 @@
border: 1px solid #000;
display: inline-flex;
justify-content: center;
align-items: center;
}
+25 -43
View File
@@ -2,47 +2,24 @@ import PropTypes from "prop-types";
import "./BaseLabel.css";
import { useTheme } from "@mui/material";
// 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}`;
};
/**
* @typedef {Object} Props
* @property {string} label - The label of the button
* @property {string} color - The base color of the label
* @typedef {Object} Styles
* @param {string} [color] - The text color
* @param {string} [backgroundColor] - The background color
* @param {string} [borderColor] - The border color
*/
const Label = ({ label, 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 - CSS Styles passed from parent component
* @returns {JSX.Element}
*/
const BaseLabel = ({ label, styles, children }) => {
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.textColor;
console.log(color);
}
// Calculate lighter shades for border and bg
const borderColor = lightenColor(color, 20);
const bgColor = lightenColor(color, 75);
// 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.
@@ -53,20 +30,25 @@ const Label = ({ label, color }) => {
className="label"
style={{
borderRadius: borderRadius,
borderColor: borderColor,
backgroundColor: bgColor,
color: color,
borderColor: theme.palette.tertiary.main,
color: theme.palette.tertiary.main,
padding: padding,
...styles,
}}
>
{children}
{label}
</div>
);
};
Label.propTypes = {
BaseLabel.propTypes = {
label: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
styles: PropTypes.shape({
color: PropTypes.string,
backgroundColor: PropTypes.string,
}),
children: PropTypes.node,
};
export default Label;
export default BaseLabel;
@@ -0,0 +1,64 @@
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
* @returns {JSX.Element}
*/
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,42 @@
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}
*/
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,
};
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;
+14 -11
View File
@@ -1,8 +1,9 @@
import DropdownTeamMember from "../../Components/DropdownTeamMember";
import "./index.css";
import Button from "../../Components/Button";
import BaseLabel from "../../Components/Label/BaseLabel";
import ColoredLabel from "../../Components/Label/ColoredLabel";
import { useTheme } from "@mui/material";
import StatusLabel from "../../Components/Label/StautsLabel";
const Home = () => {
const theme = useTheme();
@@ -27,16 +28,18 @@ const Home = () => {
</div>
<h4>Labels</h4>
<div>
<BaseLabel label="Label" color={theme.palette.labelGray.textColor} />
<BaseLabel
label="Label"
color={theme.palette.labelPurple.textColor}
/>
<BaseLabel label="Label" color={theme.palette.labelGreen.textColor} />
<BaseLabel
label="Label"
color={theme.palette.labelOrange.textColor}
/>
<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>
</>
+12 -9
View File
@@ -6,11 +6,11 @@ const secondaryMain = "#475467";
const tertiaryMain = "#475467";
// Label Colors
const labelTextOrange = "#B93815";
const labelTextGray = "#475467";
const labelTextPurple = "#6941C6";
const labelTextGreen = "#067647";
const labelOrange = "#F79009";
const labelGray = "#475467";
const labelPurple = "#6941C6";
const labelGreen = "#067647";
const labelRed = "#F04438";
const theme = createTheme({
palette: {
primary: {
@@ -23,16 +23,19 @@ const theme = createTheme({
main: tertiaryMain,
},
labelOrange: {
textColor: labelTextOrange,
color: labelOrange,
},
labelGray: {
textColor: labelTextGray,
color: labelGray,
},
labelPurple: {
textColor: labelTextPurple,
color: labelPurple,
},
labelGreen: {
textColor: labelTextGreen,
color: labelGreen,
},
labelRed: {
color: labelRed,
},
},
});