177 lines
5 KiB
TypeScript
177 lines
5 KiB
TypeScript
import { Box, Button, darken, Theme, Typography } from "@mui/material";
|
|
import { makeStyles } from "@mui/styles";
|
|
import { cloneDeep } from "lodash";
|
|
import { useEffect } from "react";
|
|
import { useState } from "react";
|
|
import { getSecondaryColour } from "services/whiteLabel";
|
|
import { getThemeType } from "theme/themeType";
|
|
|
|
export interface ButtonData {
|
|
/**
|
|
* The title and description of the button
|
|
*/
|
|
title: string
|
|
/**
|
|
* An icon that would replace the text of the button
|
|
*/
|
|
icon?: JSX.Element
|
|
/**
|
|
* The function to run when the button is clicked or toggled on when toggle is true
|
|
*/
|
|
function: () => void
|
|
/**
|
|
* whether the button is disabled or not
|
|
*/
|
|
disabled?: boolean
|
|
}
|
|
|
|
interface Props {
|
|
/**
|
|
* The array of button data to be rendered by the group
|
|
*/
|
|
buttons: ButtonData[]
|
|
/**
|
|
* When true will track the toggle state of the buttons, false will just be basic buttons
|
|
*
|
|
* @default false
|
|
*/
|
|
toggle?: boolean
|
|
/**
|
|
* When true will allow multiple buttons to be toggled, false will untoggle the previous button when another is selected
|
|
*
|
|
* @default false
|
|
*/
|
|
multiToggle?: boolean
|
|
/**
|
|
* Can be used to control which buttons are toggled on from the parent by passing the indexes of the buttons to toggle on.
|
|
* If not passed in will default to toggle the first button and then be controlled internally
|
|
*
|
|
* @default undefined
|
|
*/
|
|
toggledButtons?: number[]
|
|
/**
|
|
* This can be used to set which button starts toggled by default, and from there it will be controlled internally, toggledButtons will override this
|
|
*/
|
|
defaultToggle?: number
|
|
/**
|
|
* Numerical value for the size of the text for buttons that dont use the icon
|
|
*/
|
|
textSize?: number
|
|
/**
|
|
* When true will disable all of the buttons in the group, will be overridded by individual buttons disabled state in the button data
|
|
*/
|
|
disableAll?: boolean
|
|
|
|
}
|
|
|
|
const useStyles = makeStyles((theme: Theme) => {
|
|
return ({
|
|
container: {
|
|
backgroundColor: darken(
|
|
theme.palette.background.paper,
|
|
getThemeType() === "light" ? 0.10 : 0.05
|
|
),
|
|
borderRadius: 24,
|
|
content: "border-box",
|
|
border: "none",
|
|
//padding: theme.spacing(1),
|
|
},
|
|
button: {
|
|
backgroundColor: "transparent",
|
|
color: theme.palette.text.primary,
|
|
overflow: "visible",
|
|
content: "content-box",
|
|
borderRadius: 24,
|
|
marginLeft: theme.spacing(0.05),
|
|
marginRight: theme.spacing(0.05),
|
|
"&:hover": {
|
|
//backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
|
backgroundColor: "gold", //for now Dustin just wants it to be gold
|
|
color: "black",
|
|
}
|
|
},
|
|
buttonToggled: {
|
|
//backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
|
backgroundColor: "gold", //for now Dustin just wants it to be gold
|
|
color: "black",
|
|
borderRadius: 24,
|
|
fontWeight: "bold"
|
|
}
|
|
})
|
|
})
|
|
|
|
export default function ButtonGroup(props: Props){
|
|
const { buttons, toggle, toggledButtons, defaultToggle, multiToggle, textSize, disableAll } = props
|
|
const classes = useStyles()
|
|
const [currentToggle, setCurrentToggle] = useState<number[]>([])
|
|
|
|
useEffect(()=>{
|
|
//determine the default state of the button toggles if toggle is true
|
|
if(toggle){
|
|
let toggled: number [] = [0]
|
|
if(toggledButtons){
|
|
toggled = toggledButtons
|
|
} else if(defaultToggle){
|
|
toggled = [defaultToggle]
|
|
}
|
|
setCurrentToggle(toggled)
|
|
}
|
|
},[toggle, toggledButtons])
|
|
|
|
const checkToggled = (index: number) => {
|
|
return currentToggle.includes(index)
|
|
}
|
|
|
|
const toggleControl = (i: number) => {
|
|
let toggled = cloneDeep(currentToggle)
|
|
//is the button currently toggled
|
|
if(checkToggled(i)){
|
|
//if the button is toggled
|
|
if(multiToggle){
|
|
//un-toggle the button (remove it from the array)
|
|
console.log(toggled)
|
|
toggled.splice(currentToggle.indexOf(i), 1)
|
|
}
|
|
//and if it is single toggle do nothing
|
|
} else {
|
|
//if multiToggle is false
|
|
if(!multiToggle){
|
|
//replace the currentToggle array
|
|
toggled = [i]
|
|
}else{
|
|
//add it to the currentToggle array
|
|
toggled.push(i)
|
|
}
|
|
}
|
|
setCurrentToggle(toggled)
|
|
}
|
|
|
|
return (
|
|
<Box className={classes.container} display="flex" flexDirection="row">
|
|
{buttons.map((b, i) => (
|
|
<Button
|
|
disabled={disableAll ?? b.disabled}
|
|
key={i}
|
|
className={checkToggled(i) ? classes.buttonToggled : classes.button}
|
|
onClick={() => {
|
|
if(toggle){
|
|
//control the toggle internally if the array was not passed in
|
|
if(!toggledButtons){
|
|
toggleControl(i)
|
|
}
|
|
}
|
|
b.function()
|
|
}}>
|
|
{b.icon
|
|
?
|
|
b.icon
|
|
:
|
|
<Typography sx={{fontSize: textSize ?? 13, fontWeight: checkToggled(i) ? 650 : 500}}>
|
|
{b.title}
|
|
</Typography>
|
|
}
|
|
</Button>
|
|
))}
|
|
</Box>
|
|
)
|
|
}
|