From 443ff6808d719d65195872695e522619bf05c12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Hatcher?= Date: Sun, 12 Oct 2025 17:01:52 +0200 Subject: [PATCH] UPDATE: WIP --- .../src/components/Toolbar/Toolbar.tsx | 15 ++ .../src/components/Workbook/Workbook.tsx | 169 +++++++++++------- .../src/components/Worksheet/Worksheet.tsx | 8 +- 3 files changed, 124 insertions(+), 68 deletions(-) diff --git a/webapp/IronCalc/src/components/Toolbar/Toolbar.tsx b/webapp/IronCalc/src/components/Toolbar/Toolbar.tsx index cdd9984..512ec5e 100644 --- a/webapp/IronCalc/src/components/Toolbar/Toolbar.tsx +++ b/webapp/IronCalc/src/components/Toolbar/Toolbar.tsx @@ -24,6 +24,7 @@ import { Grid2x2Check, Grid2x2X, ImageDown, + Inbox, Italic, Minus, PaintBucket, @@ -90,6 +91,7 @@ type ToolbarProperties = { showGridLines: boolean; onToggleShowGridLines: (show: boolean) => void; nameManagerProperties: NameManagerProperties; + openDrawer: () => void; }; function Toolbar(properties: ToolbarProperties) { @@ -541,6 +543,19 @@ function Toolbar(properties: ToolbarProperties) { + + + { + properties.openDrawer(); + }} + disabled={!canEdit} + > + + + { // This is needed because `model` or `workbookState` can change without React being aware of it const setRedrawId = useState(0)[1]; + const [isDrawerOpen, setDrawerOpen] = useState(false); + const worksheets = model.getWorksheetsProperties(); const info = worksheets.map( ({ name, color, sheet_id, state }: WorksheetProperties) => { @@ -692,77 +695,119 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => { worksheets, definedNameList: model.getDefinedNameList(), }} - /> - { - setRedrawId((id) => id + 1); - focusWorkbook(); + openDrawer={() => { + setDrawerOpen(true); }} - onTextUpdated={() => { - setRedrawId((id) => id + 1); - }} - model={model} - workbookState={workbookState} - /> - { - setRedrawId((id) => id + 1); - }} - ref={worksheetRef} /> + + { + setRedrawId((id) => id + 1); + focusWorkbook(); + }} + onTextUpdated={() => { + setRedrawId((id) => id + 1); + }} + model={model} + workbookState={workbookState} + /> + { + setRedrawId((id) => id + 1); + }} + ref={worksheetRef} + /> - { - if (info[sheet].state !== "visible") { - model.unhideSheet(sheet); - } - model.setSelectedSheet(sheet); - setRedrawId((value) => value + 1); - }} - onAddBlankSheet={(): void => { - model.newSheet(); - setRedrawId((value) => value + 1); - }} - onSheetColorChanged={(hex: string): void => { - try { - model.setSheetColor(model.getSelectedSheet(), hex); + { + if (info[sheet].state !== "visible") { + model.unhideSheet(sheet); + } + model.setSelectedSheet(sheet); setRedrawId((value) => value + 1); - } catch (e) { - // TODO: Show a proper modal dialog - alert(`${e}`); - } - }} - onSheetRenamed={(name: string): void => { - try { - model.renameSheet(model.getSelectedSheet(), name); + }} + onAddBlankSheet={(): void => { + model.newSheet(); setRedrawId((value) => value + 1); - } catch (e) { - // TODO: Show a proper modal dialog - alert(`${e}`); - } - }} - onSheetDeleted={(): void => { - const selectedSheet = model.getSelectedSheet(); - model.deleteSheet(selectedSheet); - setRedrawId((value) => value + 1); - }} - onHideSheet={(): void => { - const selectedSheet = model.getSelectedSheet(); - model.hideSheet(selectedSheet); - setRedrawId((value) => value + 1); - }} - /> + }} + onSheetColorChanged={(hex: string): void => { + try { + model.setSheetColor(model.getSelectedSheet(), hex); + setRedrawId((value) => value + 1); + } catch (e) { + // TODO: Show a proper modal dialog + alert(`${e}`); + } + }} + onSheetRenamed={(name: string): void => { + try { + model.renameSheet(model.getSelectedSheet(), name); + setRedrawId((value) => value + 1); + } catch (e) { + // TODO: Show a proper modal dialog + alert(`${e}`); + } + }} + onSheetDeleted={(): void => { + const selectedSheet = model.getSelectedSheet(); + model.deleteSheet(selectedSheet); + setRedrawId((value) => value + 1); + }} + onHideSheet={(): void => { + const selectedSheet = model.getSelectedSheet(); + model.hideSheet(selectedSheet); + setRedrawId((value) => value + 1); + }} + /> + + + setDrawerOpen(false)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + setDrawerOpen(false); + } + }} + aria-label="Close drawer" + > + x + + ); }; +const DRAWER_WIDTH = 300; + +type WorksheetAreaLeftProps = { $drawerWidth: number }; +const WorksheetAreaLeft = styled("div")( + ({ $drawerWidth }) => ({ + position: "absolute", + top: `${TOOLBAR_HEIGHT + 1}px`, + width: `calc(100% - ${$drawerWidth}px)`, + height: `calc(100% - ${TOOLBAR_HEIGHT + 1}px)`, + }), +); + +const WorksheetAreaRight = styled("div")( + ({ $drawerWidth }) => ({ + position: "absolute", + overflow: "hidden", + backgroundColor: "red", + right: 0, + top: `${TOOLBAR_HEIGHT + 1}px`, + bottom: 0, + width: `${$drawerWidth}px`, + }), +); + const Container = styled("div")` display: flex; flex-direction: column; diff --git a/webapp/IronCalc/src/components/Worksheet/Worksheet.tsx b/webapp/IronCalc/src/components/Worksheet/Worksheet.tsx index f55b7a7..67b58c8 100644 --- a/webapp/IronCalc/src/components/Worksheet/Worksheet.tsx +++ b/webapp/IronCalc/src/components/Worksheet/Worksheet.tsx @@ -18,11 +18,7 @@ import { outlineColor, } from "../WorksheetCanvas/constants"; import WorksheetCanvas from "../WorksheetCanvas/worksheetCanvas"; -import { - FORMULA_BAR_HEIGHT, - NAVIGATION_HEIGHT, - TOOLBAR_HEIGHT, -} from "../constants"; +import { FORMULA_BAR_HEIGHT, NAVIGATION_HEIGHT } from "../constants"; import type { Cell } from "../types"; import type { WorkbookState } from "../workbookState"; import CellContextMenu from "./CellContextMenu"; @@ -459,7 +455,7 @@ const SheetContainer = styled("div")` const Wrapper = styled("div")({ position: "absolute", overflow: "scroll", - top: TOOLBAR_HEIGHT + FORMULA_BAR_HEIGHT + 1, + top: FORMULA_BAR_HEIGHT + 1, left: 0, right: 0, bottom: NAVIGATION_HEIGHT + 1,