a tool for shared writing and social publishing
1import { useEntity, useReplicache } from "src/replicache";
2import "katex/dist/katex.min.css";
3import { BlockLayout, BlockProps } from "./Block";
4import Katex from "katex";
5import { useMemo } from "react";
6import { useUIState } from "src/useUIState";
7import { theme } from "tailwind.config";
8import { BaseTextareaBlock } from "./BaseTextareaBlock";
9import { elementId } from "src/utils/elementId";
10
11export function MathBlock(props: BlockProps) {
12 let content = useEntity(props.entityID, "block/math");
13 let focusedBlock = useUIState(
14 (s) => s.focusedEntity?.entityID === props.entityID,
15 );
16 let { rep } = useReplicache();
17 const { html, error } = useMemo(() => {
18 try {
19 const html = Katex.renderToString(content?.data.value || "", {
20 displayMode: true,
21 throwOnError: false,
22 errorColor: theme.colors["accent-contrast"],
23 });
24
25 return { html, error: undefined };
26 } catch (error) {
27 if (error instanceof Katex.ParseError || error instanceof TypeError) {
28 return { error };
29 }
30
31 throw error;
32 }
33 }, [content?.data.value]);
34 return focusedBlock ? (
35 <BlockLayout
36 isSelected={focusedBlock}
37 hasBackground="accent"
38 className="min-h-[48px]"
39 >
40 <BaseTextareaBlock
41 id={elementId.block(props.entityID).input}
42 block={props}
43 spellCheck={false}
44 autoCapitalize="none"
45 autoCorrect="off"
46 className="h-full w-full whitespace-nowrap overflow-auto!"
47 placeholder="write some Tex here..."
48 value={content?.data.value}
49 onChange={async (e) => {
50 // Update the entity with the new value
51 await rep?.mutate.assertFact({
52 attribute: "block/math",
53 entity: props.entityID,
54 data: { type: "string", value: e.target.value },
55 });
56 }}
57 />
58 </BlockLayout>
59 ) : html && content?.data.value ? (
60 <div
61 className="text-lg min-h-[48px] w-full border border-transparent"
62 dangerouslySetInnerHTML={{ __html: html }}
63 />
64 ) : (
65 <BlockLayout
66 isSelected={focusedBlock}
67 hasBackground="accent"
68 className="min-h-[48px]"
69 >
70 <div className="text-tertiary italic w-full ">write some Tex here...</div>
71 </BlockLayout>
72 );
73}