Compare commits

...

1 Commits

Author SHA1 Message Date
Nicolás Hatcher
443ff6808d UPDATE: WIP 2025-10-12 17:01:52 +02:00
3 changed files with 124 additions and 68 deletions

View File

@@ -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) {
<ImageDown />
</StyledButton>
</Tooltip>
<Tooltip title={t("toolbar.open_drawer")}>
<StyledButton
type="button"
$pressed={false}
onClick={() => {
properties.openDrawer();
}}
disabled={!canEdit}
>
<Inbox />
</StyledButton>
</Tooltip>
</ButtonGroup>
<ColorPicker

View File

@@ -22,6 +22,7 @@ import {
CLIPBOARD_ID_SESSION_STORAGE_KEY,
getNewClipboardId,
} from "../clipboard";
import { TOOLBAR_HEIGHT } from "../constants";
import {
type NavigationKey,
getCellAddress,
@@ -41,6 +42,8 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => {
// 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(),
}}
/>
<FormulaBar
cellAddress={cellAddress()}
formulaValue={formulaValue()}
onChange={() => {
setRedrawId((id) => id + 1);
focusWorkbook();
openDrawer={() => {
setDrawerOpen(true);
}}
onTextUpdated={() => {
setRedrawId((id) => id + 1);
}}
model={model}
workbookState={workbookState}
/>
<Worksheet
model={model}
workbookState={workbookState}
refresh={(): void => {
setRedrawId((id) => id + 1);
}}
ref={worksheetRef}
/>
<WorksheetAreaLeft $drawerWidth={isDrawerOpen ? DRAWER_WIDTH : 0}>
<FormulaBar
cellAddress={cellAddress()}
formulaValue={formulaValue()}
onChange={() => {
setRedrawId((id) => id + 1);
focusWorkbook();
}}
onTextUpdated={() => {
setRedrawId((id) => id + 1);
}}
model={model}
workbookState={workbookState}
/>
<Worksheet
model={model}
workbookState={workbookState}
refresh={(): void => {
setRedrawId((id) => id + 1);
}}
ref={worksheetRef}
/>
<SheetTabBar
sheets={info}
selectedIndex={model.getSelectedSheet()}
workbookState={workbookState}
onSheetSelected={(sheet: number): void => {
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);
<SheetTabBar
sheets={info}
selectedIndex={model.getSelectedSheet()}
workbookState={workbookState}
onSheetSelected={(sheet: number): void => {
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);
}}
/>
</WorksheetAreaLeft>
<WorksheetAreaRight $drawerWidth={isDrawerOpen ? DRAWER_WIDTH : 0}>
<span
onClick={() => setDrawerOpen(false)}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setDrawerOpen(false);
}
}}
aria-label="Close drawer"
>
x
</span>
</WorksheetAreaRight>
</Container>
);
};
const DRAWER_WIDTH = 300;
type WorksheetAreaLeftProps = { $drawerWidth: number };
const WorksheetAreaLeft = styled("div")<WorksheetAreaLeftProps>(
({ $drawerWidth }) => ({
position: "absolute",
top: `${TOOLBAR_HEIGHT + 1}px`,
width: `calc(100% - ${$drawerWidth}px)`,
height: `calc(100% - ${TOOLBAR_HEIGHT + 1}px)`,
}),
);
const WorksheetAreaRight = styled("div")<WorksheetAreaLeftProps>(
({ $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;

View File

@@ -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,