import {
Header1Small,
Header2Small,
Header3Small,
} from "components/Icons/BlockTextSmall";
import { Props } from "components/Icons/Props";
import { QuoteSmall } from "components/Icons/QuoteSmall";
import { ShortcutKey, Separator } from "components/Layout";
import { ToolbarButton } from "components/Toolbar";
import { getSelectedOrFocusedBlocks } from "components/SelectionManager/selectionState";
import { TextSelection } from "prosemirror-state";
import { useCallback } from "react";
import { useEntity, useReplicache } from "src/replicache";
import { useEditorStates } from "src/state/useEditorState";
import { useUIState } from "src/useUIState";
import { setTextBlockStyle, TextBlockStyle } from "src/utils/blockTypeOperations";
export const TextBlockTypeToolbar = (props: {
onClose: () => void;
className?: string;
}) => {
let focusedBlock = useUIState((s) => s.focusedEntity);
let blockType = useEntity(focusedBlock?.entityID || null, "block/type");
let headingLevel = useEntity(
focusedBlock?.entityID || null,
"block/heading-level",
);
let textSize = useEntity(focusedBlock?.entityID || null, "block/text-size");
let { rep, undoManager } = useReplicache();
let setStyle = useCallback(
async (style: TextBlockStyle) => {
if (!rep) return;
// Changing block/type remounts the focused block's editor, so stash the
// caret and put it back afterwards or the user is dropped out of the doc.
let focused = useUIState.getState().focusedEntity;
let previousSelection =
focused?.entityType === "block"
? useEditorStates.getState().editorStates[focused.entityID]?.editor
.selection
: undefined;
let blocks = await getSelectedOrFocusedBlocks(rep);
await setTextBlockStyle(blocks, style, rep, undoManager);
// Refocusing would collapse a multi-block selection down to one editor.
if (blocks.length !== 1) return;
if (!focused || focused.entityType !== "block" || !previousSelection)
return;
let newEditor = useEditorStates.getState().editorStates[focused.entityID];
if (!newEditor) return;
newEditor.view?.dispatch(
newEditor.editor.tr.setSelection(
TextSelection.create(
newEditor.editor.doc,
Math.min(previousSelection.anchor, newEditor.editor.doc.content.size),
),
),
);
newEditor.view?.focus();
},
[rep, undoManager],
);
let setLevel = useCallback(
(level: number) => setStyle({ style: "heading", level }),
[setStyle],
);
return (
// This Toolbar should close once the user starts typing again
<>
{
setLevel(1);
}}
active={
blockType?.data.value === "heading" && headingLevel?.data.value === 1
}
tooltipContent={
}
>
{
setLevel(2);
}}
active={
blockType?.data.value === "heading" && headingLevel?.data.value === 2
}
tooltipContent={
Heading
start line with
##
}
>
{
setLevel(3);
}}
active={
blockType?.data.value === "heading" && headingLevel?.data.value === 3
}
tooltipContent={
Subheading
start line with
###
}
>
setStyle({ style: "text", size: "default" })}
active={
blockType?.data.value === "text" &&
textSize?.data.value !== "small" &&
textSize?.data.value !== "large"
}
tooltipContent={Normal Text
}
>
Text
setStyle({ style: "text", size: "large" })}
active={
blockType?.data.value === "text" && textSize?.data.value === "large"
}
tooltipContent={Large Text
}
>
Large
setStyle({ style: "text", size: "small" })}
active={
blockType?.data.value === "text" && textSize?.data.value === "small"
}
tooltipContent={Small Text
}
>
Small
setStyle(
blockType?.data.value === "blockquote"
? { style: "text", size: "default" }
: { style: "blockquote" },
)
}
active={blockType?.data.value === "blockquote"}
tooltipContent={
Block Quote
start line with
>
}
>
>
);
};
export function TextBlockTypeButton(props: {
setToolbarState: (s: "heading") => void;
className?: string;
}) {
return (
Text Style}
className={`${props.className}`}
onClick={() => {
props.setToolbarState("heading");
}}
>
);
}
const TextSizeSmall = (props: Props) => {
return (
);
};