yey
This commit is contained in:
parent
157634a0eb
commit
850a4b68cf
@ -23,7 +23,7 @@ export default function Area(props) {
|
|||||||
const [hovered, setHovered] = useState(false);
|
const [hovered, setHovered] = useState(false);
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [saved, setSaved] = useState(false);
|
const [saved, setSaved] = useState(false);
|
||||||
const [editField, setEditField] = useState("");
|
const [editField, setEditField] = useState({});
|
||||||
const { layout } = useContext(LayoutContext);
|
const { layout } = useContext(LayoutContext);
|
||||||
const { tab, setTab } = useContext(TabContext);
|
const { tab, setTab } = useContext(TabContext);
|
||||||
const { updateArea, deleteArea } = useContext(AreaContext);
|
const { updateArea, deleteArea } = useContext(AreaContext);
|
||||||
@ -201,7 +201,7 @@ export default function Area(props) {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
trigger="click"
|
trigger="click"
|
||||||
position="bottomLeft"
|
position="rightTop"
|
||||||
showArrow
|
showArrow
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -1,14 +1,31 @@
|
|||||||
import React, { useContext, useState } from "react";
|
import React, { useContext, useState } from "react";
|
||||||
import { NoteContext, UndoRedoContext } from "../pages/editor";
|
import {
|
||||||
import { Action, ObjectType } from "../data/data";
|
LayoutContext,
|
||||||
|
NoteContext,
|
||||||
|
UndoRedoContext,
|
||||||
|
TabContext,
|
||||||
|
} from "../pages/editor";
|
||||||
|
import { Action, ObjectType, noteThemes, Tab } from "../data/data";
|
||||||
|
import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui";
|
||||||
|
import {
|
||||||
|
IconEdit,
|
||||||
|
IconDeleteStroked,
|
||||||
|
IconCheckboxTick,
|
||||||
|
} from "@douyinfe/semi-icons";
|
||||||
|
|
||||||
export default function Note(props) {
|
export default function Note(props) {
|
||||||
const { updateNote } = useContext(NoteContext);
|
const [editField, setEditField] = useState({});
|
||||||
|
const [hovered, setHovered] = useState(false);
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [saved, setSaved] = useState(false);
|
||||||
const w = 180;
|
const w = 180;
|
||||||
const r = 3;
|
const r = 3;
|
||||||
const fold = 24;
|
const fold = 24;
|
||||||
|
const { updateNote, deleteNote } = useContext(NoteContext);
|
||||||
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
||||||
const [editField, setEditField] = useState({});
|
const { layout } = useContext(LayoutContext);
|
||||||
|
const { tab, setTab } = useContext(TabContext);
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const textarea = document.getElementById(`note_${props.data.id}`);
|
const textarea = document.getElementById(`note_${props.data.id}`);
|
||||||
textarea.style.height = "0";
|
textarea.style.height = "0";
|
||||||
@ -18,7 +35,10 @@ export default function Note(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g>
|
<g
|
||||||
|
onMouseEnter={() => setHovered(true)}
|
||||||
|
onMouseLeave={() => setHovered(false)}
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d={`M${props.data.x + fold} ${props.data.y} L${props.data.x + w - r} ${
|
d={`M${props.data.x + fold} ${props.data.y} L${props.data.x + w - r} ${
|
||||||
props.data.y
|
props.data.y
|
||||||
@ -91,6 +111,151 @@ export default function Note(props) {
|
|||||||
className="w-full resize-none outline-none overflow-y-hidden border-none select-none"
|
className="w-full resize-none outline-none overflow-y-hidden border-none select-none"
|
||||||
style={{ backgroundColor: props.data.color }}
|
style={{ backgroundColor: props.data.color }}
|
||||||
></textarea>
|
></textarea>
|
||||||
|
{hovered && (
|
||||||
|
<div className="absolute top-2 right-3">
|
||||||
|
<Popover
|
||||||
|
visible={visible}
|
||||||
|
content={
|
||||||
|
<div>
|
||||||
|
<div className="font-semibold mb-2 ms-1">Edit note</div>
|
||||||
|
<div className="w-[280px] flex items-center mb-2">
|
||||||
|
<Input
|
||||||
|
value={props.data.title}
|
||||||
|
placeholder="Title"
|
||||||
|
className="me-2"
|
||||||
|
onChange={(value) =>
|
||||||
|
updateNote(props.data.id, { title: value })
|
||||||
|
}
|
||||||
|
onFocus={(e) => setEditField({ title: e.target.value })}
|
||||||
|
onBlur={(e) => {
|
||||||
|
setSaved(true);
|
||||||
|
if (e.target.value === editField.title) return;
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.NOTE,
|
||||||
|
nid: props.data.id,
|
||||||
|
undo: editField,
|
||||||
|
redo: { title: e.target.value },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Popover
|
||||||
|
content={
|
||||||
|
<div>
|
||||||
|
<div className="font-medium">Theme</div>
|
||||||
|
<hr />
|
||||||
|
<div className="py-3">
|
||||||
|
{noteThemes.map((c) => (
|
||||||
|
<button
|
||||||
|
key={c}
|
||||||
|
style={{ backgroundColor: c }}
|
||||||
|
className="p-3 rounded-full mx-1"
|
||||||
|
onClick={() => {
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.NOTE,
|
||||||
|
nid: props.data.id,
|
||||||
|
undo: { color: props.data.color },
|
||||||
|
redo: { color: c },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
|
updateNote(props.data.id, { color: c });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.data.color === c ? (
|
||||||
|
<IconCheckboxTick
|
||||||
|
style={{ color: "white" }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<IconCheckboxTick style={{ color: c }} />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
trigger="click"
|
||||||
|
position="rightTop"
|
||||||
|
showArrow
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="h-[32px] w-[32px] rounded"
|
||||||
|
style={{ backgroundColor: props.data.color }}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
<div className="flex">
|
||||||
|
<Button
|
||||||
|
icon={<IconDeleteStroked />}
|
||||||
|
type="danger"
|
||||||
|
block
|
||||||
|
onClick={() => {
|
||||||
|
Toast.success(`Note deleted!`);
|
||||||
|
deleteNote(props.data.id, true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
block
|
||||||
|
style={{ marginLeft: "8px" }}
|
||||||
|
onClick={() => {
|
||||||
|
if (!saved) {
|
||||||
|
if (props.data.name === editField.name) return;
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.NOTE,
|
||||||
|
aid: props.data.id,
|
||||||
|
undo: editField,
|
||||||
|
redo: { title: props.data.title },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
|
setSaved(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
trigger="custom"
|
||||||
|
position="rightTop"
|
||||||
|
showArrow
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<IconEdit />}
|
||||||
|
size="small"
|
||||||
|
theme="solid"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#2f68ad",
|
||||||
|
opacity: "0.7",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (layout.sidebar) {
|
||||||
|
setTab(Tab.notes);
|
||||||
|
if (tab !== Tab.notes) return;
|
||||||
|
document
|
||||||
|
.getElementById(`scroll_note_${props.data.id}`)
|
||||||
|
.scrollIntoView({ behavior: "smooth" });
|
||||||
|
} else {
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
></Button>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
</g>
|
</g>
|
||||||
|
Loading…
Reference in New Issue
Block a user