Skip to content

Commit

Permalink
feat(homebrew): Added move and oracle links to markdown editor
Browse files Browse the repository at this point in the history
  • Loading branch information
scottbenton committed Mar 11, 2024
1 parent 51f0519 commit e04b748
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 8 deletions.
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"dependencies": {
"@datasworn/core": "^0.0.6",
"@datasworn/ironsworn-classic": "^0.0.6",
"@datasworn/starforged": "^0.0.6",
"@datasworn/ironsworn-classic-delve": "^0.0.6",
"@datasworn/starforged": "^0.0.6",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@fontsource/bebas-neue": "^5.0.12",
Expand All @@ -26,6 +26,7 @@
"@mui/x-date-pickers": "^6.18.4",
"@tiptap/extension-collaboration": "^2.0.3",
"@tiptap/extension-collaboration-cursor": "^2.0.3",
"@tiptap/extension-link": "^2.2.4",
"@tiptap/extension-placeholder": "^2.0.0-beta.218",
"@tiptap/pm": "^2.0.0-beta.218",
"@tiptap/react": "^2.0.0-beta.218",
Expand Down
8 changes: 7 additions & 1 deletion src/components/shared/RichTextEditor/MarkdownEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Markdown } from "tiptap-markdown";
import { Editor } from "./Editor";
import { Box, Typography } from "@mui/material";
import { MarkdownEditorToolbar } from "./MarkdownEditorToolbar";
import Link from "@tiptap/extension-link";

export interface MarkdownEditorProps {
label: string;
content: string;
Expand All @@ -16,7 +18,11 @@ export function MarkdownEditor(props: MarkdownEditorProps) {

const editor = useEditor(
{
extensions: [StarterKit, Markdown],
extensions: [
StarterKit,
Markdown,
Link.extend({ inclusive: false }).configure({ openOnClick: false }),
],
content,
onBlur,
onUpdate: ({ editor }) => {
Expand Down
150 changes: 149 additions & 1 deletion src/components/shared/RichTextEditor/MarkdownEditorToolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { Box, ToggleButton, ToggleButtonGroup, Tooltip } from "@mui/material";
import {
Autocomplete,
Box,
ListItemText,
Popover,
TextField,
ToggleButton,
ToggleButtonGroup,
Tooltip,
} from "@mui/material";
import { Editor } from "@tiptap/react";
import BoldIcon from "@mui/icons-material/FormatBold";
import ItalicIcon from "@mui/icons-material/FormatItalic";
import StrikeThroughIcon from "@mui/icons-material/FormatStrikethrough";
import HorizontalRuleIcon from "@mui/icons-material/HorizontalRule";
import BulletListIcon from "@mui/icons-material/FormatListBulleted";
import NumberedListIcon from "@mui/icons-material/FormatListNumbered";
import { useStore } from "stores/store";
import MovesIcon from "@mui/icons-material/DirectionsRun";
import { OracleIcon } from "assets/OracleIcon";
import { useState } from "react";

export interface MarkdownEditorToolbarProps {
editor: Editor | null;
Expand All @@ -14,10 +27,59 @@ export interface MarkdownEditorToolbarProps {
export function MarkdownEditorToolbar(props: MarkdownEditorToolbarProps) {
const { editor } = props;

const moveMap = useStore((store) => store.rules.moveMaps.moveMap);
const oracleMap = useStore(
(store) => store.rules.oracleMaps.oracleRollableMap
);

const [moveLinkPopoverParent, setMoveLinkPopoverParent] =
useState<HTMLElement | null>(null);
const [oracleLinkPopoverParent, setOracleLinkPopoverParent] =
useState<HTMLElement | null>(null);

if (!editor) {
return null;
}

const autocompleteOptions: {
id: string;
type: "move" | "oracle";
label: string;
}[] = [];
Object.values(moveMap).forEach((move) => {
autocompleteOptions.push({
id: move.id,
type: "move",
label: move.name,
});
});
Object.values(oracleMap).forEach((oracle) => {
autocompleteOptions.push({
id: oracle.id,
type: "oracle",
label: oracle.name,
});
});

const addDataswornLink = (id: string, label: string) => {
setMoveLinkPopoverParent(null);
setOracleLinkPopoverParent(null);

editor.chain().focus().insertContent(label).run();

const { from } = editor.state.selection;
const startPos = from - label.length;
const endPos = startPos + label.length;

editor
.chain()
.setTextSelection({ from: startPos, to: endPos })
.setLink({ href: `id:${id}` })
.setTextSelection(endPos + 1)
.focus()
.run();
};

return (
<Box
display={"flex"}
Expand Down Expand Up @@ -90,6 +152,92 @@ export function MarkdownEditorToolbar(props: MarkdownEditorToolbarProps) {
</ToggleButton>
</Tooltip>
</ToggleButtonGroup>
<ToggleButtonGroup size={"small"} sx={{ mr: 1 }}>
<Tooltip title={"Add Move Link"} enterDelay={300}>
<ToggleButton
value={"move link"}
onClick={(evt) => setMoveLinkPopoverParent(evt.currentTarget)}
selected={false}
>
<MovesIcon />
</ToggleButton>
</Tooltip>
<Tooltip title={"Add Oracle Link"} enterDelay={300}>
<ToggleButton
value={"oracle link"}
onClick={(evt) => setOracleLinkPopoverParent(evt.currentTarget)}
selected={false}
>
<Box
width={24}
height={24}
display={"flex"}
alignItems={"center"}
justifyContent={"center"}
>
<OracleIcon />
</Box>
</ToggleButton>
</Tooltip>
</ToggleButtonGroup>
<Popover
id={"move-link-popover"}
open={!!moveLinkPopoverParent}
anchorEl={moveLinkPopoverParent}
onClose={() => setMoveLinkPopoverParent(null)}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
>
<Box p={1}>
<Autocomplete
options={Object.values(moveMap)}
getOptionKey={(option) => option.id}
getOptionLabel={(option) => option.name}
renderInput={(params) => (
<TextField {...params} label={"Moves"} sx={{ minWidth: 200 }} />
)}
renderOption={(props, option) => (
<Box component={"li"} {...props}>
<ListItemText primary={option.name} secondary={option.id} />
</Box>
)}
onChange={(evt, value) => {
value && addDataswornLink(value.id, value.name);
}}
/>
</Box>
</Popover>
<Popover
id={"oracle-link-popover"}
open={!!oracleLinkPopoverParent}
anchorEl={oracleLinkPopoverParent}
onClose={() => setOracleLinkPopoverParent(null)}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
>
<Box p={1}>
<Autocomplete
options={Object.values(oracleMap)}
getOptionKey={(option) => option.id}
getOptionLabel={(option) => option.name}
renderInput={(params) => (
<TextField {...params} label={"Oracles"} sx={{ minWidth: 200 }} />
)}
renderOption={(props, option) => (
<Box component={"li"} {...props}>
<ListItemText primary={option.name} secondary={option.id} />
</Box>
)}
onChange={(evt, value) => {
value && addDataswornLink(value.id, value.name);
}}
/>
</Box>
</Popover>
</Box>
);
}
10 changes: 5 additions & 5 deletions src/components/shared/SimpleTable/SimpleTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@ export function SimpleTable<T>(props: SimpleTableProps<T>) {
backgroundColor: theme.palette.background.paperInlayDarker,
},

"& th:nth-child(1)": {
"& th:nth-of-type(1)": {
borderTopLeftRadius: theme.shape.borderRadius,
},
"& th:nth-last-child(1)": {
"& th:nth-last-of-type(1)": {
borderTopRightRadius: theme.shape.borderRadius,
},

"& tbody tr:nth-of-type(even) td": {
backgroundColor: theme.palette.background.paperInlay,
},
"& tbody tr:nth-last-child(1)": {
"& td:nth-child(1)": {
"& tbody tr:nth-last-of-type(1)": {
"& td:nth-of-type(1)": {
borderBottomLeftRadius: theme.shape.borderRadius,
},
"& td:nth-last-child(1)": {
"& td:nth-last-of-type(1)": {
borderBottomRightRadius: theme.shape.borderRadius,
},
},
Expand Down

0 comments on commit e04b748

Please sign in to comment.