2022-10-24 07:18:22 +00:00
|
|
|
import { Atom, useAtom } from "jotai";
|
2022-10-24 07:10:52 +00:00
|
|
|
import { useState } from "react";
|
2022-10-24 07:40:14 +00:00
|
|
|
import { Form } from "react-bootstrap";
|
|
|
|
import styled from "styled-components";
|
2022-10-24 07:10:52 +00:00
|
|
|
|
2022-10-24 07:18:22 +00:00
|
|
|
export interface Props {
|
|
|
|
valueAtom: Atom<number>;
|
|
|
|
}
|
|
|
|
|
2022-10-24 07:40:14 +00:00
|
|
|
const ClickableContainer = styled.span`
|
|
|
|
&:hover {
|
|
|
|
background-color: #eee;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
2022-10-24 07:18:22 +00:00
|
|
|
export default function EditBox({ valueAtom }: Props) {
|
2022-10-24 07:10:52 +00:00
|
|
|
const [value, setValue] = useAtom(valueAtom);
|
|
|
|
const [valueInput, setValueInput] = useState("");
|
|
|
|
const [editing, setEditing] = useState(false);
|
|
|
|
|
|
|
|
const formatter = new Intl.NumberFormat("en-US", {
|
|
|
|
style: "currency",
|
|
|
|
currency: "USD",
|
|
|
|
});
|
|
|
|
|
2022-10-24 07:18:22 +00:00
|
|
|
const startEditing = (_: any) => {
|
2022-10-24 07:10:52 +00:00
|
|
|
setValueInput(value.toString());
|
|
|
|
setEditing(true);
|
|
|
|
};
|
|
|
|
|
2022-10-24 07:18:22 +00:00
|
|
|
const finalize = (e: Event) => {
|
2022-10-24 07:10:52 +00:00
|
|
|
e.preventDefault();
|
|
|
|
try {
|
|
|
|
const n = parseFloat(valueInput);
|
|
|
|
setValue(n);
|
|
|
|
setEditing(false);
|
|
|
|
} catch (e) {
|
|
|
|
// TODO: Handle
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (editing) {
|
|
|
|
return (
|
|
|
|
<form onSubmit={finalize} style={{ display: "inline" }}>
|
|
|
|
<input
|
|
|
|
autoFocus={true}
|
|
|
|
type="number"
|
|
|
|
step="0.01"
|
|
|
|
value={valueInput}
|
|
|
|
onBlur={finalize}
|
|
|
|
onInput={(e) => setValueInput(e.target.value)}
|
|
|
|
/>
|
|
|
|
</form>
|
|
|
|
);
|
|
|
|
} else {
|
2022-10-24 07:40:14 +00:00
|
|
|
return (
|
|
|
|
<ClickableContainer onClick={startEditing}>
|
|
|
|
{formatter.format(value)}
|
|
|
|
</ClickableContainer>
|
|
|
|
);
|
2022-10-24 07:10:52 +00:00
|
|
|
}
|
|
|
|
}
|