feat: add warning custom extension

This commit is contained in:
swve 2022-12-08 10:31:43 +01:00
parent fe8fdd1769
commit 88644ad902
6 changed files with 99 additions and 9 deletions

View file

@ -3,6 +3,7 @@ import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit"; import StarterKit from "@tiptap/starter-kit";
// Custom Extensions // Custom Extensions
import InfoCallout from "../Editor/Extensions/Callout/Info/InfoCallout"; import InfoCallout from "../Editor/Extensions/Callout/Info/InfoCallout";
import WarningCallout from "../Editor/Extensions/Callout/Warning/WarningCallout";
interface Editor { interface Editor {
content: string; content: string;
@ -16,11 +17,13 @@ function Canva(props: Editor) {
editable: isEditable, editable: isEditable,
extensions: [ extensions: [
StarterKit, StarterKit,
// Custom Extensions // Custom Extensions
InfoCallout.configure({ InfoCallout.configure({
editable: isEditable, editable: isEditable,
}), }),
WarningCallout.configure({
editable: isEditable,
}),
], ],
content: props.content, content: props.content,

View file

@ -14,6 +14,7 @@ import { SlashIcon } from "@radix-ui/react-icons";
import Avvvatars from "avvvatars-react"; import Avvvatars from "avvvatars-react";
// extensions // extensions
import InfoCallout from "./Extensions/Callout/Info/InfoCallout"; import InfoCallout from "./Extensions/Callout/Info/InfoCallout";
import WarningCallout from "./Extensions/Callout/Warning/WarningCallout";
interface Editor { interface Editor {
content: string; content: string;
@ -32,11 +33,14 @@ function Editor(props: Editor) {
extensions: [ extensions: [
StarterKit.configure({ StarterKit.configure({
// The Collaboration extension comes with its own history handling // The Collaboration extension comes with its own history handling
// history: false, // history: false,
}), }),
InfoCallout.configure({ InfoCallout.configure({
editable: true, editable: true,
}), }),
WarningCallout.configure({
editable: true,
}),
// Register the document with Tiptap // Register the document with Tiptap
// Collaboration.configure({ // Collaboration.configure({
// document: props.ydoc, // document: props.ydoc,

View file

@ -1,4 +1,5 @@
import { NodeViewContent, NodeViewWrapper } from "@tiptap/react"; import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
import { AlertCircle } from "lucide-react";
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
@ -6,7 +7,7 @@ function InfoCalloutComponent(props: any) {
return ( return (
<NodeViewWrapper> <NodeViewWrapper>
<InfoCalloutWrapper contentEditable={props.extension.options.editable}> <InfoCalloutWrapper contentEditable={props.extension.options.editable}>
<div> </div> <NodeViewContent contentEditable={props.extension.options.editable} className="content" /> <AlertCircle /> <NodeViewContent contentEditable={props.extension.options.editable} className="content" />
</InfoCalloutWrapper> </InfoCalloutWrapper>
</NodeViewWrapper> </NodeViewWrapper>
); );
@ -15,19 +16,22 @@ function InfoCalloutComponent(props: any) {
const InfoCalloutWrapper = styled.div` const InfoCalloutWrapper = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
background: #fefce8; color: #1f3a8a;
color: #713f11; background-color: #dbe9fe;
border: 1px solid #fff103; border: 1px solid #c1d9fb;
border-radius: 16px; border-radius: 16px;
margin: 1rem 0; margin: 1rem 0;
align-items: center; align-items: center;
padding-left: 15px; padding-left: 15px;
svg{
padding: 3px;
}
.content { .content {
margin: 5px; margin: 5px;
padding: 0.5rem; padding: 0.5rem;
border: ${(props) => (props.contentEditable ? "2px dashed #713f1117" : "none")}; border: ${(props) => (props.contentEditable ? "2px dashed #1f3a8a12" : "none")};
border-radius: 0.5rem; border-radius: 0.5rem;
} }
`; `;

View file

@ -0,0 +1,27 @@
import { mergeAttributes, Node } from "@tiptap/core";
import { ReactNodeViewRenderer } from "@tiptap/react";
import WarningCalloutComponent from "./WarningCalloutComponent";
export default Node.create({
name: "calloutWarning",
group: "block",
draggable: true,
content: "inline*",
parseHTML() {
return [
{
tag: "callout-warning",
},
];
},
renderHTML({ HTMLAttributes }) {
return ["callout-info", mergeAttributes(HTMLAttributes), 0];
},
addNodeView() {
return ReactNodeViewRenderer(WarningCalloutComponent);
},
});

View file

@ -0,0 +1,49 @@
import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
import { AlertTriangle } from "lucide-react";
import React from "react";
import styled from "styled-components";
function WarningCalloutComponent(props: any) {
return (
<NodeViewWrapper>
<CalloutWrapper contentEditable={props.extension.options.editable}>
<AlertTriangle/> <NodeViewContent contentEditable={props.extension.options.editable} className="content" />
</CalloutWrapper>
</NodeViewWrapper>
);
}
const CalloutWrapper = styled.div`
display: flex;
flex-direction: row;
background: #fefce8;
color: #713f11;
border: 1px solid #fff103;
border-radius: 16px;
margin: 1rem 0;
align-items: center;
padding-left: 15px;
svg {
padding: 3px;
}
.content {
margin: 5px;
padding: 0.5rem;
border: ${(props) => (props.contentEditable ? "2px dashed #713f1117" : "none")};
border-radius: 0.5rem;
}
`;
const DragHandle = styled.div`
position: absolute;
top: 0;
left: 0;
width: 1rem;
height: 100%;
cursor: move;
z-index: 1;
`;
export default WarningCalloutComponent;

View file

@ -1,6 +1,6 @@
import styled from "styled-components"; import styled from "styled-components";
import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, OpacityIcon } from "@radix-ui/react-icons"; import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, OpacityIcon } from "@radix-ui/react-icons";
import { AlertTriangle, Info } from "lucide-react"; import { AlertCircle, AlertTriangle, Info } from "lucide-react";
export const ToolbarButtons = ({ editor }: any) => { export const ToolbarButtons = ({ editor }: any) => {
if (!editor) { if (!editor) {
@ -33,9 +33,12 @@ export const ToolbarButtons = ({ editor }: any) => {
<option value="6">Heading 6</option> <option value="6">Heading 6</option>
</ToolSelect> </ToolSelect>
{/* TODO: fix this : toggling only works one-way */} {/* TODO: fix this : toggling only works one-way */}
<ToolBtn onClick={() => editor.chain().focus().toggleNode('calloutInfo').run()} > <ToolBtn onClick={() => editor.chain().focus().toggleNode('calloutWarning').run()} >
<AlertTriangle size={15} /> <AlertTriangle size={15} />
</ToolBtn> </ToolBtn>
<ToolBtn onClick={() => editor.chain().focus().toggleNode('calloutInfo').run()} >
<AlertCircle size={15} />
</ToolBtn>
</ToolButtonsWrapper> </ToolButtonsWrapper>
); );
}; };