aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components/ui/markdown/markdown-readonly.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/components/ui/markdown/markdown-readonly.tsx')
-rw-r--r--apps/web/components/ui/markdown/markdown-readonly.tsx46
1 files changed, 46 insertions, 0 deletions
diff --git a/apps/web/components/ui/markdown/markdown-readonly.tsx b/apps/web/components/ui/markdown/markdown-readonly.tsx
index 3c6daf31..5436e961 100644
--- a/apps/web/components/ui/markdown/markdown-readonly.tsx
+++ b/apps/web/components/ui/markdown/markdown-readonly.tsx
@@ -25,15 +25,61 @@ function PreWithCopyBtn({ className, ...props }: React.ComponentProps<"pre">) {
export function MarkdownReadonly({
children: markdown,
className,
+ onSave,
}: {
children: string;
className?: string;
+ onSave?: (markdown: string) => void;
}) {
+ /**
+ * This method is triggered when a checkbox is toggled from the masonry view
+ * It finds the index of the clicked checkbox inside of the note
+ * It then finds the corresponding markdown and changes it accordingly
+ */
+ const handleTodoClick = (e: React.ChangeEvent<HTMLInputElement>) => {
+ e.preventDefault();
+ const parent = e.target.closest(".prose");
+ if (!parent) return;
+ const allCheckboxes = parent.querySelectorAll(".todo-checkbox");
+ let checkboxIndex = 0;
+ allCheckboxes.forEach((cb, i) => {
+ if (cb === e.target) checkboxIndex = i;
+ });
+ let i = 0;
+ const todoPattern = /^(\s*[-*+]\s*\[)( |x|X)(\])/gm;
+ const newMarkdown = markdown.replace(
+ todoPattern,
+ (match, prefix: string, state: string, suffix: string) => {
+ const currentIndex = i++;
+ if (currentIndex !== checkboxIndex) {
+ return match;
+ }
+ const isDone = state.toLowerCase() === "x";
+ const nextState = isDone ? " " : "x";
+ return `${prefix}${nextState}${suffix}`;
+ },
+ );
+ if (onSave) {
+ onSave(newMarkdown);
+ }
+ };
+
return (
<Markdown
remarkPlugins={[remarkGfm, remarkBreaks]}
className={cn("prose dark:prose-invert", className)}
components={{
+ input: (props) =>
+ props.type === "checkbox" ? (
+ <input
+ checked={props.checked}
+ onChange={handleTodoClick}
+ type="checkbox"
+ className="todo-checkbox"
+ />
+ ) : (
+ <input {...props} readOnly />
+ ),
pre({ ...props }) {
return <PreWithCopyBtn {...props} />;
},