diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx
index 8fa2a138..db77e514 100644
--- a/components/Blocks/Block.tsx
+++ b/components/Blocks/Block.tsx
@@ -104,6 +104,7 @@ export const Block = memo(function Block(
? "pb-0"
: "pb-2"
}
+ ${props.type === "blockquote" && props.previousBlock?.type === "blockquote" ? "-mt-3" : ""}
${
!props.previousBlock
? props.type === "heading" || props.type === "text"
diff --git a/components/Blocks/BlockCommands.tsx b/components/Blocks/BlockCommands.tsx
index 078c66d9..f612ec55 100644
--- a/components/Blocks/BlockCommands.tsx
+++ b/components/Blocks/BlockCommands.tsx
@@ -31,7 +31,6 @@ import { BlockRSVPSmall } from "components/Icons/BlockRSVPSmall";
import { ListUnorderedSmall } from "components/Toolbar/ListToolbar";
import { BlockMathSmall } from "components/Icons/BlockMathSmall";
import { BlockCodeSmall } from "components/Icons/BlockCodeSmall";
-import { QuoteTiny } from "components/Icons/QuoteTiny";
import { QuoteSmall } from "components/Icons/QuoteSmall";
type Props = {
@@ -160,16 +159,16 @@ export const blockCommands: Command[] = [
clearCommandSearchText(entity);
},
},
- // {
- // name: "Block Quote",
- // icon: ,
- // type: "text",
- // onSelect: async (rep, props, um) => {
- // if (props.entityID) clearCommandSearchText(props.entityID);
- // let entity = await createBlockWithType(rep, props, "blockquote");
- // clearCommandSearchText(entity);
- // },
- // },
+ {
+ name: "Block Quote",
+ icon: ,
+ type: "text",
+ onSelect: async (rep, props, um) => {
+ if (props.entityID) clearCommandSearchText(props.entityID);
+ let entity = await createBlockWithType(rep, props, "blockquote");
+ clearCommandSearchText(entity);
+ },
+ },
{
name: "Image",
diff --git a/components/Blocks/TextBlock/RenderYJSFragment.tsx b/components/Blocks/TextBlock/RenderYJSFragment.tsx
index 0ad90ed8..f4c6b69d 100644
--- a/components/Blocks/TextBlock/RenderYJSFragment.tsx
+++ b/components/Blocks/TextBlock/RenderYJSFragment.tsx
@@ -9,7 +9,7 @@ export function RenderYJSFragment({
attrs,
}: {
node: XmlElement | XmlText | XmlHook;
- wrapper?: "h1" | "h2" | "h3" | null;
+ wrapper?: "h1" | "h2" | "h3" | null | "blockquote";
attrs?: { [k: string]: any };
}) {
if (node.constructor === XmlElement) {
@@ -63,13 +63,16 @@ export function RenderYJSFragment({
}
const BlockWrapper = (props: {
- wrapper?: "h1" | "h2" | "h3" | null;
+ wrapper?: "h1" | "h2" | "h3" | null | "blockquote";
children: React.ReactNode;
attrs?: { [k: string]: any };
}) => {
if (props.wrapper === null) return <>{props.children}>;
if (!props.wrapper) return
{props.children}
;
switch (props.wrapper) {
+ case "blockquote":
+ return {props.children}
;
+
case "h1":
return {props.children}
;
case "h2":
diff --git a/components/Blocks/TextBlock/index.tsx b/components/Blocks/TextBlock/index.tsx
index 8441e378..3e26cb04 100644
--- a/components/Blocks/TextBlock/index.tsx
+++ b/components/Blocks/TextBlock/index.tsx
@@ -218,14 +218,9 @@ export function BaseTextBlock(props: BlockProps & { className?: string }) {
let handlePaste = useHandlePaste(props.entityID, propsRef);
useLayoutEffect(() => {
if (!mountRef.current) return;
- let km = TextBlockKeymap(
- propsRef,
- repRef,
- rep.undoManager,
- props.type === "blockquote",
- );
+ let km = TextBlockKeymap(propsRef, repRef, rep.undoManager);
let editor = EditorState.create({
- schema: props.type === "blockquote" ? multiBlockSchema : schema,
+ schema: schema,
plugins: [
ySyncPlugin(value),
keymap(km),
@@ -342,7 +337,7 @@ export function BaseTextBlock(props: BlockProps & { className?: string }) {
},
}));
};
- }, [props.entityID, props.parent, value, handlePaste, rep, props.type]);
+ }, [props.entityID, props.parent, value, handlePaste, rep]);
return (
<>
diff --git a/components/Blocks/TextBlock/inputRules.ts b/components/Blocks/TextBlock/inputRules.ts
index a4748259..eb33bafd 100644
--- a/components/Blocks/TextBlock/inputRules.ts
+++ b/components/Blocks/TextBlock/inputRules.ts
@@ -152,17 +152,17 @@ export const inputrules = (
return tr;
}),
- // //Blockquote
- // new InputRule(/^([>]{1})\s$/, (state, match) => {
- // let tr = state.tr;
- // tr.delete(0, 2);
- // repRef.current?.mutate.assertFact({
- // entity: propsRef.current.entityID,
- // attribute: "block/type",
- // data: { type: "block-type-union", value: "blockquote" },
- // });
- // return tr;
- // }),
+ //Blockquote
+ new InputRule(/^([>]{1})\s$/, (state, match) => {
+ let tr = state.tr;
+ tr.delete(0, 2);
+ repRef.current?.mutate.assertFact({
+ entity: propsRef.current.entityID,
+ attribute: "block/type",
+ data: { type: "block-type-union", value: "blockquote" },
+ });
+ return tr;
+ }),
//Header
new InputRule(/^([#]{1,3})\s$/, (state, match) => {
diff --git a/components/Blocks/TextBlock/useHandlePaste.ts b/components/Blocks/TextBlock/useHandlePaste.ts
index c1161dea..59589496 100644
--- a/components/Blocks/TextBlock/useHandlePaste.ts
+++ b/components/Blocks/TextBlock/useHandlePaste.ts
@@ -254,8 +254,7 @@ const createBlockFromHTML = (
default:
type = null;
}
- let content =
- type === "blockquote" ? multilineParser.parse(child) : parser.parse(child);
+ let content = parser.parse(child);
if (!type) return;
let entityID: string;
@@ -498,11 +497,7 @@ const createBlockFromHTML = (
block.editor.selection.to !== undefined
)
tr.delete(block.editor.selection.from, block.editor.selection.to);
- if (type === "blockquote") {
- tr.replaceWith(0, tr.doc.content.size, content.content);
- } else {
- tr.replaceSelectionWith(content);
- }
+ tr.replaceSelectionWith(content);
let newState = block.editor.apply(tr);
setEditorState(entityID, {
editor: newState,
diff --git a/src/utils/focusBlock.ts b/src/utils/focusBlock.ts
index 931dfa4b..99606df8 100644
--- a/src/utils/focusBlock.ts
+++ b/src/utils/focusBlock.ts
@@ -104,14 +104,9 @@ export function focusBlock(
}
}
- if (block.type === "blockquote" && position.type === "start") {
- let sel = NodeSelection.create(tr.doc, 0);
- nextBlock.view.dispatch(tr.setSelection(sel));
- } else {
- nextBlock.view.dispatch(
- tr.setSelection(TextSelection.create(tr.doc, pos?.pos || 1)),
- );
- }
+ nextBlock.view.dispatch(
+ tr.setSelection(TextSelection.create(tr.doc, pos?.pos || 1)),
+ );
nextBlock.view.focus();
}
diff --git a/src/utils/getBlocksAsHTML.tsx b/src/utils/getBlocksAsHTML.tsx
index cb89a099..8e22afd8 100644
--- a/src/utils/getBlocksAsHTML.tsx
+++ b/src/utils/getBlocksAsHTML.tsx
@@ -74,7 +74,7 @@ async function renderBlock(
tx: ReadTransaction,
ignoreWrapper?: boolean,
) {
- let wrapper: undefined | "h1" | "h2" | "h3";
+ let wrapper: undefined | "h1" | "h2" | "h3" | "blockquote";
let [alignment] = await scanIndex(tx).eav(b.value, "block/text-alignment");
if (b.type === "horizontal-rule") {
return "
";
@@ -125,6 +125,9 @@ async function renderBlock(
,
);
}
+ if (b.type === "blockquote") {
+ wrapper = "blockquote";
+ }
if (b.type === "heading") {
let headingLevel =
(await scanIndex(tx).eav(b.value, "block/heading-level"))[0]?.data
@@ -162,32 +165,8 @@ async function renderBlock(
,
);
}
- if (b.type === "blockquote") {
- let value = (await scanIndex(tx).eav(b.value, "block/text"))[0];
- if (!value) return "";
- let doc = new Y.Doc();
- const update = base64.toByteArray(value.data.value);
- Y.applyUpdate(doc, update);
- let nodes = doc.getXmlElement("prosemirror").toArray();
- //Have to handle this specially because it's a multi-line block
- return `${nodes
- .map((node) => {
- if (node.constructor === Y.XmlElement) {
- let children = node.toArray();
- if (children.length === 0) return "";
- return renderToStaticMarkup(
- ,
- );
- }
- })
- .join("\n")}
`;
- }
let value = (await scanIndex(tx).eav(b.value, "block/text"))[0];
+ console.log("getBlockasHTML", value);
if (!value)
return ignoreWrapper ? "" : `<${wrapper || "p"}>${wrapper || "p"}>`;
let doc = new Y.Doc();
diff --git a/src/utils/isTextBlock.ts b/src/utils/isTextBlock.ts
index f1f95c73..0020cc94 100644
--- a/src/utils/isTextBlock.ts
+++ b/src/utils/isTextBlock.ts
@@ -5,4 +5,5 @@ export const isTextBlock: {
} = {
text: true,
heading: true,
+ blockquote: true,
};