158 lines
4.2 KiB
TypeScript
158 lines
4.2 KiB
TypeScript
// import { useTheme, makeStyles, createStyles, Theme } from "@material-ui/core/styles";
|
|
import Joyride, { Step, CallBackProps, STATUS, TooltipRenderProps, Locale } from "react-joyride";
|
|
import {
|
|
Button,
|
|
Card,
|
|
CardContent,
|
|
CardHeader,
|
|
CardActions,
|
|
Grid2 as Grid,
|
|
MobileStepper,
|
|
Tooltip,
|
|
IconButton,
|
|
Theme,
|
|
useTheme
|
|
} from "@mui/material";
|
|
import { KeyboardArrowLeft, KeyboardArrowRight, Close as CloseIcon } from "@mui/icons-material";
|
|
import classNames from "classnames";
|
|
import { grey } from "@mui/material/colors";
|
|
import { makeStyles } from "@mui/styles";
|
|
|
|
const useStyles = makeStyles((theme: Theme) => {
|
|
return ({
|
|
stepContainer: {
|
|
width: "60vw",
|
|
[theme.breakpoints.only("sm")]: {
|
|
width: "50vw"
|
|
},
|
|
[theme.breakpoints.only("md")]: {
|
|
width: "40vw"
|
|
},
|
|
[theme.breakpoints.only("lg")]: {
|
|
width: "30vw"
|
|
},
|
|
[theme.breakpoints.only("xl")]: {
|
|
width: "20vw"
|
|
}
|
|
},
|
|
spacing: {
|
|
padding: theme.spacing(1),
|
|
[theme.breakpoints.up("sm")]: {
|
|
padding: theme.spacing(2)
|
|
}
|
|
},
|
|
stepper: {
|
|
width: "100%"
|
|
}
|
|
})
|
|
});
|
|
|
|
const StepContainer = (props: TooltipRenderProps, numSteps: number, skip: () => void) => {
|
|
const {
|
|
continuous,
|
|
index,
|
|
step,
|
|
backProps,
|
|
isLastStep,
|
|
closeProps,
|
|
primaryProps,
|
|
tooltipProps
|
|
} = props;
|
|
const theme = useTheme();
|
|
const classes = useStyles();
|
|
|
|
return (
|
|
<Card {...tooltipProps} className={classes.stepContainer}>
|
|
<CardHeader
|
|
title={step.title}
|
|
action={
|
|
<Tooltip title="Skip Tutorial">
|
|
<IconButton aria-label="Skip Tutorial" onClick={skip}>
|
|
<CloseIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
}
|
|
className={classes.spacing}
|
|
/>
|
|
|
|
{step.content && <CardContent className={classes.spacing}>{step.content}</CardContent>}
|
|
|
|
{!step.hideFooter &&
|
|
(continuous ? (
|
|
<MobileStepper
|
|
className={classNames(classes.stepper, classes.spacing)}
|
|
variant="text"
|
|
steps={numSteps}
|
|
position="static"
|
|
activeStep={index}
|
|
backButton={
|
|
<Button size="small" {...backProps} disabled={index === 0}>
|
|
{theme.direction === "rtl" ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
|
|
Back
|
|
</Button>
|
|
}
|
|
nextButton={
|
|
<Button size="small" {...primaryProps}>
|
|
{isLastStep ? "Finish" : "Next"}
|
|
{theme.direction === "rtl" ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
|
|
</Button>
|
|
}
|
|
/>
|
|
) : (
|
|
!step.hideCloseButton && (
|
|
<CardActions>
|
|
<Grid container justifyContent="flex-end">
|
|
<Button size="small" {...closeProps}>
|
|
Close
|
|
</Button>
|
|
</Grid>
|
|
</CardActions>
|
|
)
|
|
))}
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
interface Props {
|
|
run: boolean;
|
|
steps: Step[];
|
|
endTourCallback: () => void;
|
|
}
|
|
|
|
export default function Tour(props: Props) {
|
|
const { run, steps, endTourCallback } = props;
|
|
const theme = useTheme();
|
|
|
|
const handleTourCallback = (data: CallBackProps) => {
|
|
const { status } = data;
|
|
const finishedStatuses: string[] = [STATUS.FINISHED, STATUS.SKIPPED];
|
|
|
|
if (finishedStatuses.includes(status)) {
|
|
endTourCallback();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Joyride
|
|
run={run}
|
|
steps={steps}
|
|
continuous
|
|
scrollToFirstStep={true}
|
|
showProgress={true}
|
|
showSkipButton={true}
|
|
callback={handleTourCallback}
|
|
tooltipComponent={props => StepContainer(props, steps.length, endTourCallback)}
|
|
locale={{ back: "Back", close: "Close", last: "Done", next: "Next", skip: "Skip" } as Locale}
|
|
styles={{
|
|
options: {
|
|
arrowColor: theme.palette.mode === "light" ? grey["100"] : grey["800"],
|
|
backgroundColor: theme.palette.background.default,
|
|
overlayColor: "rgba(0, 0, 0, 0.5)",
|
|
primaryColor: theme.palette.primary.main,
|
|
textColor: theme.palette.text.primary,
|
|
zIndex: theme.zIndex.modal
|
|
}
|
|
}}
|
|
/>
|
|
);
|
|
}
|