SurfSense/surfsense_web/components/ui/block-list.tsx

71 lines
1.7 KiB
TypeScript
Raw Normal View History

2026-02-17 12:47:39 +05:30
"use client";
2026-02-17 12:47:39 +05:30
import { isOrderedList } from "@platejs/list";
import { useTodoListElement, useTodoListElementState } from "@platejs/list/react";
2026-02-20 22:44:56 -08:00
import type { TListElement } from "platejs";
2026-02-17 12:47:39 +05:30
import { type PlateElementProps, type RenderNodeWrapper, useReadOnly } from "platejs/react";
2026-02-20 22:44:56 -08:00
import type React from "react";
2026-02-17 12:47:39 +05:30
import { Checkbox } from "@/components/ui/checkbox";
import { cn } from "@/lib/utils";
const config: Record<
2026-02-17 12:47:39 +05:30
string,
{
Li: React.FC<PlateElementProps>;
Marker: React.FC<PlateElementProps>;
}
> = {
2026-02-17 12:47:39 +05:30
todo: {
Li: TodoLi,
Marker: TodoMarker,
},
};
export const BlockList: RenderNodeWrapper = (props) => {
2026-02-17 12:47:39 +05:30
if (!props.element.listStyleType) return;
2026-02-17 12:47:39 +05:30
return (props) => <List {...props} />;
};
function List(props: PlateElementProps) {
2026-02-17 12:47:39 +05:30
const { listStart, listStyleType } = props.element as TListElement;
const { Li, Marker } = config[listStyleType] ?? {};
const List = isOrderedList(props.element) ? "ol" : "ul";
2026-02-17 12:47:39 +05:30
return (
<List className="relative m-0 p-0" style={{ listStyleType }} start={listStart}>
{Marker && <Marker {...props} />}
{Li ? <Li {...props} /> : <li>{props.children}</li>}
</List>
);
}
function TodoMarker(props: PlateElementProps) {
2026-02-17 12:47:39 +05:30
const state = useTodoListElementState({ element: props.element });
const { checkboxProps } = useTodoListElement(state);
const readOnly = useReadOnly();
2026-02-17 12:47:39 +05:30
return (
<div contentEditable={false}>
<Checkbox
className={cn("-left-6 absolute top-1", readOnly && "pointer-events-none")}
{...checkboxProps}
/>
</div>
);
}
function TodoLi(props: PlateElementProps) {
2026-02-17 12:47:39 +05:30
return (
<li
className={cn(
"list-none",
(props.element.checked as boolean) && "text-muted-foreground line-through"
)}
>
{props.children}
</li>
);
}