123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /*
- * Copyright 2021-2024 Avaiga Private Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- import React, { MouseEvent, useCallback, useContext, useEffect, useMemo } from "react";
- import Box from "@mui/material/Box";
- import Typography from "@mui/material/Typography";
- import { PaletteMode, SxProps } from "@mui/material";
- import ToggleButton from "@mui/material/ToggleButton";
- import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
- import WbSunny from "@mui/icons-material/WbSunny";
- import Brightness3 from "@mui/icons-material/Brightness3";
- import { TaipyActiveProps, getCssSize } from "./utils";
- import { TaipyContext } from "../../context/taipyContext";
- import { createThemeAction } from "../../context/taipyReducers";
- import { useClassNames } from "../../utils/hooks";
- import { getLocalStorageValue } from "../../context/utils";
- interface ThemeToggleProps extends TaipyActiveProps {
- style?: SxProps;
- label?: string;
- width?: string | number;
- }
- const boxSx = {
- display: "flex",
- flexDirection: "column",
- alignItems: "center",
- position: "fixed",
- top: "1rem",
- right: "1rem",
- "& > *": {
- m: 1,
- },
- } as SxProps;
- export const emptyStyle = {} as SxProps;
- const groupSx = { verticalAlign: "middle" };
- const ThemeToggle = (props: ThemeToggleProps) => {
- const { id, label = "Mode", style = emptyStyle, active = true } = props;
- const { state, dispatch } = useContext(TaipyContext);
- const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
- const changeMode = useCallback(
- (evt: MouseEvent, mode: PaletteMode) => mode !== null && dispatch(createThemeAction(mode === "dark")),
- [dispatch]
- );
- useEffect(() => {
- const localMode = getLocalStorageValue("theme", state.theme.palette.mode, ["light", "dark"]);
- if (state.theme.palette.mode !== localMode) {
- dispatch(createThemeAction(localMode === "dark"));
- }
- }, [state.theme.palette.mode, dispatch]);
- const mainSx = useMemo(
- () =>
- props.width
- ? ({ ...boxSx, ...style, width: getCssSize(props.width) } as SxProps)
- : ({ ...boxSx, ...style } as SxProps),
- [style, props.width]
- );
- return (
- <Box id={id} sx={mainSx} className={className}>
- <Typography>{label}</Typography>
- <ToggleButtonGroup
- value={state.theme.palette.mode}
- exclusive
- onChange={changeMode}
- aria-label="Theme mode"
- disabled={!active}
- sx={groupSx}
- fullWidth={!!props.width}
- >
- <ToggleButton value="light" aria-label="light" title="Light">
- <WbSunny />
- </ToggleButton>
- <ToggleButton value="dark" aria-label="dark" title="Dark">
- <Brightness3 />
- </ToggleButton>
- </ToggleButtonGroup>
- </Box>
- );
- };
- export default ThemeToggle;
|