UPDATE: Adds cell and formula editing (#92)
* UPDATE: Adds cell and formula editing * FIX: Do not loose focus when clicking on the formula we are editing * FIX: Minimal implementation of browse mode * FIX: Initial browse mode within sheets * UPDATE: Webapp Minimal Web Application
This commit is contained in:
committed by
GitHub
parent
53d3d5144c
commit
48719b6416
103
webapp/src/AppComponents/FileBar.tsx
Normal file
103
webapp/src/AppComponents/FileBar.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import styled from "@emotion/styled";
|
||||
import type { Model } from "@ironcalc/wasm";
|
||||
import { CircleCheck } from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
import { IronCalcLogo } from "./../icons";
|
||||
import { FileMenu } from "./FileMenu";
|
||||
import { ShareButton } from "./ShareButton";
|
||||
import { WorkbookTitle } from "./WorkbookTitle";
|
||||
import { downloadModel, shareModel } from "./rpc";
|
||||
import { updateNameSelectedWorkbook } from "./storage";
|
||||
|
||||
export function FileBar(properties: {
|
||||
model: Model;
|
||||
newModel: () => void;
|
||||
setModel: (key: string) => void;
|
||||
onModelUpload: (blob: ArrayBuffer, fileName: string) => Promise<void>;
|
||||
}) {
|
||||
const hiddenInputRef = useRef<HTMLInputElement>(null);
|
||||
const [toast, setToast] = useState(false);
|
||||
return (
|
||||
<FileBarWrapper>
|
||||
<IronCalcLogo style={{ width: "120px", marginLeft: "10px" }} />
|
||||
<Divider />
|
||||
<FileMenu
|
||||
newModel={properties.newModel}
|
||||
setModel={properties.setModel}
|
||||
onModelUpload={properties.onModelUpload}
|
||||
onDownload={async () => {
|
||||
const model = properties.model;
|
||||
const bytes = model.toBytes();
|
||||
const fileName = model.getName();
|
||||
await downloadModel(bytes, fileName);
|
||||
}}
|
||||
/>
|
||||
<WorkbookTitle
|
||||
name={properties.model.getName()}
|
||||
onNameChange={(name) => {
|
||||
properties.model.setName(name);
|
||||
updateNameSelectedWorkbook(properties.model, name);
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
ref={hiddenInputRef}
|
||||
type="text"
|
||||
style={{ position: "absolute", left: -9999, top: -9999 }}
|
||||
/>
|
||||
<div style={{ marginLeft: "auto" }}>
|
||||
{toast ? (
|
||||
<Toast>
|
||||
<CircleCheck style={{ width: 12 }} />
|
||||
<span style={{ marginLeft: 8, marginRight: 12 }}>
|
||||
URL copied to clipboard
|
||||
</span>
|
||||
</Toast>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<ShareButton
|
||||
onClick={async () => {
|
||||
const model = properties.model;
|
||||
const bytes = model.toBytes();
|
||||
const fileName = model.getName();
|
||||
const hash = await shareModel(bytes, fileName);
|
||||
const value = `${location.origin}/?model=${hash}`;
|
||||
if (hiddenInputRef.current) {
|
||||
hiddenInputRef.current.value = value;
|
||||
hiddenInputRef.current.select();
|
||||
document.execCommand("copy");
|
||||
setToast(true);
|
||||
setTimeout(() => setToast(false), 5000);
|
||||
}
|
||||
console.log(value);
|
||||
}}
|
||||
/>
|
||||
</FileBarWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const Toast = styled("div")`
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #9e9e9e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const Divider = styled("div")`
|
||||
margin: 10px;
|
||||
height: 12px;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
`;
|
||||
|
||||
const FileBarWrapper = styled("div")`
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid grey;
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
Reference in New Issue
Block a user