import type {
BorderOptions,
HorizontalAlignment,
VerticalAlignment,
} from "@ironcalc/wasm";
import { styled } from "@mui/material/styles";
import {
AlignCenter,
AlignLeft,
AlignRight,
ArrowDownToLine,
ArrowUpToLine,
Bold,
ChevronDown,
Euro,
Grid2X2,
Grid2x2Check,
Grid2x2X,
Italic,
PaintBucket,
PaintRoller,
Percent,
Redo2,
Strikethrough,
Type,
Underline,
Undo2,
} from "lucide-react";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
ArrowMiddleFromLine,
DecimalPlacesDecreaseIcon,
DecimalPlacesIncreaseIcon,
} from "../icons";
import { theme } from "../theme";
import BorderPicker from "./borderPicker";
import ColorPicker from "./colorPicker";
import { TOOLBAR_HEIGHT } from "./constants";
import FormatMenu from "./formatMenu";
import {
NumberFormats,
decreaseDecimalPlaces,
increaseDecimalPlaces,
} from "./formatUtil";
type ToolbarProperties = {
canUndo: boolean;
canRedo: boolean;
onRedo: () => void;
onUndo: () => void;
onToggleUnderline: (u: boolean) => void;
onToggleBold: (v: boolean) => void;
onToggleItalic: (v: boolean) => void;
onToggleStrike: (v: boolean) => void;
onToggleHorizontalAlign: (v: string) => void;
onToggleVerticalAlign: (v: string) => void;
onCopyStyles: () => void;
onTextColorPicked: (hex: string) => void;
onFillColorPicked: (hex: string) => void;
onNumberFormatPicked: (numberFmt: string) => void;
onBorderChanged: (border: BorderOptions) => void;
fillColor: string;
fontColor: string;
bold: boolean;
underline: boolean;
italic: boolean;
strike: boolean;
horizontalAlign: HorizontalAlignment;
verticalAlign: VerticalAlignment;
canEdit: boolean;
numFmt: string;
showGridLines: boolean;
onToggleShowGridLines: (show: boolean) => void;
};
function Toolbar(properties: ToolbarProperties) {
const [fontColorPickerOpen, setFontColorPickerOpen] = useState(false);
const [fillColorPickerOpen, setFillColorPickerOpen] = useState(false);
const [borderPickerOpen, setBorderPickerOpen] = useState(false);
const fontColorButton = useRef(null);
const fillColorButton = useRef(null);
const borderButton = useRef(null);
const { t } = useTranslation();
const { canEdit } = properties;
return (
{
properties.onNumberFormatPicked(NumberFormats.CURRENCY_EUR);
}}
disabled={!canEdit}
title={t("toolbar.euro")}
>
{
properties.onNumberFormatPicked(NumberFormats.PERCENTAGE);
}}
disabled={!canEdit}
title={t("toolbar.percentage")}
>
{
properties.onNumberFormatPicked(
decreaseDecimalPlaces(properties.numFmt),
);
}}
disabled={!canEdit}
title={t("toolbar.decimal_places_decrease")}
>
{
properties.onNumberFormatPicked(
increaseDecimalPlaces(properties.numFmt),
);
}}
disabled={!canEdit}
title={t("toolbar.decimal_places_increase")}
>
{
properties.onNumberFormatPicked(numberFmt);
}}
onExited={(): void => {}}
anchorOrigin={{
horizontal: 20, // Aligning the menu to the middle of FormatButton
vertical: "bottom",
}}
>
{"123"}
properties.onToggleBold(!properties.bold)}
disabled={!canEdit}
title={t("toolbar.bold")}
>
properties.onToggleItalic(!properties.italic)}
disabled={!canEdit}
title={t("toolbar.italic")}
>
properties.onToggleUnderline(!properties.underline)}
disabled={!canEdit}
title={t("toolbar.underline")}
>
properties.onToggleStrike(!properties.strike)}
disabled={!canEdit}
title={t("toolbar.strike_through")}
>
setFontColorPickerOpen(true)}
>
setFillColorPickerOpen(true)}
>
setBorderPickerOpen(true)}
ref={borderButton}
disabled={!canEdit}
title={t("toolbar.borders.title")}
>
properties.onToggleHorizontalAlign(
properties.horizontalAlign === "left" ? "general" : "left",
)
}
disabled={!canEdit}
title={t("toolbar.align_left")}
>
properties.onToggleHorizontalAlign(
properties.horizontalAlign === "center" ? "general" : "center",
)
}
disabled={!canEdit}
title={t("toolbar.align_center")}
>
properties.onToggleHorizontalAlign(
properties.horizontalAlign === "right" ? "general" : "right",
)
}
disabled={!canEdit}
title={t("toolbar.align_right")}
>
properties.onToggleVerticalAlign("top")}
disabled={!canEdit}
title={t("toolbar.vertical_align_top")}
>
properties.onToggleVerticalAlign("center")}
disabled={!canEdit}
title={t("toolbar.vertical_align_middle")}
>
properties.onToggleVerticalAlign("bottom")}
disabled={!canEdit}
title={t("toolbar.vertical_align_bottom")}
>
properties.onToggleShowGridLines(!properties.showGridLines)
}
disabled={!canEdit}
title={t("toolbar.show_hide_grid_lines")}
>
{properties.showGridLines ? : }
{
properties.onTextColorPicked(color);
setFontColorPickerOpen(false);
}}
onClose={() => {
setFontColorPickerOpen(false);
}}
anchorEl={fontColorButton}
open={fontColorPickerOpen}
/>
{
properties.onFillColorPicked(color);
setFillColorPickerOpen(false);
}}
onClose={() => {
setFillColorPickerOpen(false);
}}
anchorEl={fillColorButton}
open={fillColorPickerOpen}
/>
{
properties.onBorderChanged(border);
}}
onClose={() => {
setBorderPickerOpen(false);
}}
anchorEl={borderButton}
open={borderPickerOpen}
/>
);
}
const ToolbarContainer = styled("div")`
display: flex;
flex-shrink: 0;
align-items: center;
background: ${({ theme }) => theme.palette.background.paper};
height: ${TOOLBAR_HEIGHT}px;
line-height: ${TOOLBAR_HEIGHT}px;
border-bottom: 1px solid ${({ theme }) => theme.palette.grey["300"]};
font-family: Inter;
border-radius: 4px 4px 0px 0px;
overflow-x: auto;
padding: 0px 12px;
gap: 4px;
scrollbar-width: none;
`;
type TypeButtonProperties = { $pressed: boolean; $underlinedColor?: string };
export const StyledButton = styled("button")(
({ disabled, $pressed, $underlinedColor }) => {
const result = {
width: "24px",
minWidth: "24px",
height: "24px",
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
fontSize: "12px",
border: `0px solid ${theme.palette.common.white}`,
borderRadius: "4px",
transition: "all 0.2s",
outline: `1px solid ${theme.palette.common.white}`,
cursor: "pointer",
backgroundColor: "white",
padding: "0px",
svg: {
width: "16px",
height: "16px",
},
};
if (disabled) {
return {
...result,
color: theme.palette.grey["400"],
cursor: "default",
};
}
return {
...result,
borderTop: $underlinedColor
? `3px solid ${theme.palette.common.white}`
: "none",
borderBottom: $underlinedColor ? `3px solid ${$underlinedColor}` : "none",
color: theme.palette.grey["900"],
backgroundColor: $pressed
? theme.palette.grey["300"]
: theme.palette.common.white,
"&:hover": {
transition: "all 0.2s",
outline: `1px solid ${theme.palette.grey["200"]}`,
borderTopColor: theme.palette.common.white,
},
"&:active": {
backgroundColor: theme.palette.grey["300"],
outline: `1px solid ${theme.palette.grey["300"]}`,
},
};
},
);
const Divider = styled("div")({
width: "0px",
height: "12px",
borderLeft: `1px solid ${theme.palette.grey["300"]}`,
margin: "0px 12px",
});
export default Toolbar;