update: add a name manager menu in formula bar

This commit is contained in:
Daniel
2025-11-22 01:07:30 +01:00
committed by Nicolás Hatcher Andrés
parent f96612cf23
commit 294a651ae5
3 changed files with 184 additions and 4 deletions

View File

@@ -1,5 +1,7 @@
import type { Model } from "@ironcalc/wasm";
import { styled } from "@mui/material";
import { ChevronDown } from "lucide-react";
import { useState } from "react";
import { Fx } from "../../icons";
import { theme } from "../../theme";
import { FORMULA_BAR_HEIGHT } from "../constants";
@@ -9,6 +11,7 @@ import {
ROW_HEIGH_SCALE,
} from "../WorksheetCanvas/constants";
import type { WorkbookState } from "../workbookState";
import FormulaBarMenu from "./FormulaBarMenu";
type FormulaBarProps = {
cellAddress: string;
@@ -28,10 +31,32 @@ function FormulaBar(properties: FormulaBarProps) {
onTextUpdated,
workbookState,
} = properties;
const [selectedMenuOption, setSelectedMenuOption] =
useState<string>("show_values");
const [isMenuOpen, setIsMenuOpen] = useState(false);
const handleMenuChange = (option: string): void => {
setSelectedMenuOption(option);
// Handle menu option change here
};
const handleMenuOpenChange = (isOpen: boolean): void => {
setIsMenuOpen(isOpen);
};
return (
<Container>
<AddressContainer>
<CellBarAddress>{cellAddress}</CellBarAddress>
<FormulaBarMenu
selectedOption={selectedMenuOption}
onChange={handleMenuChange}
onMenuOpenChange={handleMenuOpenChange}
>
<CellBarAddress $active={isMenuOpen}>{cellAddress}</CellBarAddress>
<MenuButton $active={isMenuOpen}>
<ChevronDown size={16} />
</MenuButton>
</FormulaBarMenu>
</AddressContainer>
<Divider />
<FormulaContainer>
@@ -101,7 +126,7 @@ const Divider = styled("div")`
background-color: ${theme.palette.grey["300"]};
min-width: 1px;
height: 16px;
margin: 0px 16px;
margin: 0px 16px 0px 8px;
`;
const FormulaContainer = styled("div")`
@@ -124,7 +149,6 @@ const Container = styled("div")`
`;
const AddressContainer = styled("div")`
padding-left: 16px;
color: ${theme.palette.common.black};
font-style: normal;
font-weight: normal;
@@ -132,11 +156,45 @@ const AddressContainer = styled("div")`
display: flex;
font-weight: 600;
flex-grow: row;
align-items: center;
gap: 2px;
border-radius: 4px;
margin-left: 8px;
&:hover {
background-color: ${theme.palette.grey["100"]};
}
`;
const CellBarAddress = styled("div")`
const CellBarAddress = styled("div")<{ $active?: boolean }>`
width: 100%;
box-sizing: border-box;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
text-align: "center";
padding: 4px 8px;
border-radius: 4px 0px 0px 4px;
background-color: ${(props) =>
props.$active ? theme.palette.action.selected : "transparent"};
&:hover {
background-color: ${theme.palette.grey["300"]};
}
`;
const MenuButton = styled("div")<{ $active?: boolean }>`
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 4px 2px;
border-radius: 0px 4px 4px 0px;
color: ${theme.palette.common.black};
background-color: ${(props) =>
props.$active ? theme.palette.action.selected : "transparent"};
&:hover {
background-color: ${theme.palette.grey["300"]};
}
`;
const EditorWrapper = styled("div")`

View File

@@ -0,0 +1,119 @@
import { Menu, MenuItem, styled } from "@mui/material";
import { Tag } from "lucide-react";
import { type ComponentProps, useCallback, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { theme } from "../../theme";
type FormulaBarMenuProps = {
children: React.ReactNode;
selectedOption?: string;
onChange: (option: string) => void;
onExited?: () => void;
onMenuOpenChange?: (isOpen: boolean) => void;
anchorOrigin?: ComponentProps<typeof Menu>["anchorOrigin"];
};
const FormulaBarMenu = (properties: FormulaBarMenuProps) => {
const { t } = useTranslation();
const [isMenuOpen, setMenuOpen] = useState(false);
const anchorElement = useRef<HTMLDivElement>(null);
const handleMenuOpen = useCallback((): void => {
setMenuOpen(true);
properties.onMenuOpenChange?.(true);
}, [properties.onMenuOpenChange]);
const handleMenuClose = useCallback((): void => {
setMenuOpen(false);
properties.onMenuOpenChange?.(false);
}, [properties.onMenuOpenChange]);
return (
<>
<ChildrenWrapper onClick={handleMenuOpen} ref={anchorElement}>
{properties.children}
</ChildrenWrapper>
<StyledMenu
open={isMenuOpen}
onClose={handleMenuClose}
anchorEl={anchorElement.current}
marginThreshold={0}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
>
<MenuItemWrapper disableRipple>
<Tag />
<MenuItemText>Range1</MenuItemText>
<MenuItemExample>$Sheet1!$A$1:$B$2</MenuItemExample>
</MenuItemWrapper>
<MenuDivider />
<MenuItemWrapper disableRipple>
<MenuItemText>{t("formula_bar.manage_named_ranges")}</MenuItemText>
</MenuItemWrapper>
</StyledMenu>
</>
);
};
const StyledMenu = styled(Menu)`
top: 4px;
min-width: 260px;
& .MuiPaper-root {
border-radius: 8px;
padding: 4px 0px;
margin-left: -4px;
}
& .MuiList-root {
padding: 0;
}
`;
const MenuItemWrapper = styled(MenuItem)`
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
gap: 8px;
width: calc(100% - 8px);
min-width: 172px;
margin: 0px 4px;
border-radius: 4px;
padding: 8px;
height: 32px;
& svg {
width: 12px;
height: 12px;
color: ${theme.palette.grey[600]};
}
`;
const ChildrenWrapper = styled("div")`
display: flex;
`;
const MenuDivider = styled("div")`
width: 100%;
margin: auto;
margin-top: 4px;
margin-bottom: 4px;
border-top: 1px solid #eeeeee;
`;
const MenuItemText = styled("div")`
color: #000;
display: flex;
align-items: center;
`;
const MenuItemExample = styled("div")`
color: #bdbdbd;
margin-left: 20px;
`;
export default FormulaBarMenu;

View File

@@ -92,6 +92,9 @@
"label": "Formula",
"title": "Update formula"
},
"formula_bar": {
"manage_named_ranges": "Manage Named Ranges"
},
"navigation": {
"add_sheet": "Add sheet",
"sheet_list": "Sheet list",