import { Separator, ShortcutKey } from "components/Layout"; import { useBlocks } from "src/hooks/queries/useBlocks"; import { useEntity, useReplicache } from "src/replicache"; import { useUIState } from "src/useUIState"; import { metaKey } from "src/utils/metaKey"; import { ToolbarButton } from "."; import { indent, outdent, outdentFull, orderListItems, unorderListItems } from "src/utils/list-operations"; import { useEffect } from "react"; import { Props } from "components/Icons/Props"; import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; export const ListButton = (props: { setToolbarState: (s: "list") => void }) => { let focusedBlock = useUIState((s) => s.focusedEntity); let isList = useEntity(focusedBlock?.entityID || null, "block/is-list"); let siblings = useBlocks( focusedBlock?.entityType === "block" ? focusedBlock.parent : null, ); let block = siblings.find((s) => s.value === focusedBlock?.entityID); let { rep } = useReplicache(); return (
Make List
{ <> {metaKey()} +{" "} Alt +{" "} L }
} onClick={(e) => { e.preventDefault(); if (!focusedBlock || !block) return; if (!isList?.data.value) { rep?.mutate.assertFact({ entity: focusedBlock?.entityID, attribute: "block/is-list", data: { value: true, type: "boolean" }, }); } else { outdentFull(block, rep); } }} > {isList?.data.value && ( { props.setToolbarState("list"); }} className="-ml-1" > )} ); }; export const ListToolbar = (props: { onClose: () => void }) => { let focusedBlock = useUIState((s) => s.focusedEntity); let foldedBlocks = useUIState((s) => s.foldedBlocks); let toggleFold = useUIState((s) => s.toggleFold); let siblings = useBlocks( focusedBlock?.entityType === "block" ? focusedBlock.parent : null, ); let isCheckbox = useEntity( focusedBlock?.entityID || null, "block/check-list", ); let isList = useEntity(focusedBlock?.entityID || null, "block/is-list"); let block = siblings.find((s) => s.value === focusedBlock?.entityID); let previousBlock = siblings[siblings.findIndex((b) => b.value === focusedBlock?.entityID) - 1]; let { rep } = useReplicache(); useEffect(() => { if (!isList?.data.value) { let timeout = setTimeout(() => props.onClose(), 50); return () => clearTimeout(timeout); } }, [props, isList]); return (
Outdent Item
Shift + Tab
} onClick={async () => { if (!rep || !block) return; await outdent(block, previousBlock, rep, { foldedBlocks, toggleFold }); }} >
Indent Item
Tab
} disabled={ !previousBlock?.listData || previousBlock.listData.depth < block?.listData?.depth! } onClick={async () => { if (!rep || !block || !previousBlock) return; await indent(block, previousBlock, rep, { foldedBlocks, toggleFold }); }} >
{ if (!block || !rep) return; unorderListItems(block, rep); }} > { if (!block || !rep) return; orderListItems(block, rep); }} >
Add a Checkbox
[ ]
onClick={() => { if (!focusedBlock) return; if (!isCheckbox) { rep?.mutate.assertFact({ entity: focusedBlock.entityID, attribute: "block/check-list", data: { type: "boolean", value: false }, }); } else { rep?.mutate.retractFact({ factID: isCheckbox.id, }); } }} >
); }; export const ListUnorderedSmall = (props: Props) => { return ( ); }; export const ListOrderedSmall = (props: Props) => { return ( {/* Horizontal lines */} {/* Numbers 1, 2, 3 */} 1. 2. 3. ); }; const ListIndentIncreaseSmall = (props: Props) => { return ( ); }; const ListIndentDecreaseSmall = (props: Props) => { return ( ); }; const ListCheckboxSmall = (props: Props) => { return ( ); };