;
- },
-) => {
- useEditorStates.setState((oldState) => {
- let existingState = oldState.editorStates[entityID];
- return {
- editorStates: {
- ...oldState.editorStates,
- [entityID]: { ...existingState, ...s },
- },
- };
- });
-};
+import { setEditorState, useEditorStates } from "src/state/useEditorState";
+import { isIOS } from "@react-aria/utils";
export function TextBlock(props: BlockProps & { className: string }) {
let initialized = useInitialPageLoad();
@@ -77,12 +49,48 @@ export function TextBlock(props: BlockProps & { className: string }) {
/>
)}
+
>
);
}
+export function IOSBS(props: BlockProps) {
+ let selected = useUIState((s) =>
+ s.selectedBlock.find((b) => b.value === props.entityID),
+ );
+ if (selected) return null;
+ return (
+ {
+ e.preventDefault();
+ let target = e.target;
+ focusBlock(props, {
+ type: "coord",
+ top: e.clientY,
+ left: e.clientX,
+ });
+ setTimeout(async () => {
+ let vis = await isVisible(target as Element);
+ if (!vis) {
+ let parentEl = document.getElementById(
+ elementId.card(props.parent).container,
+ );
+ if (!parentEl) return;
+ parentEl?.scrollBy({
+ top: 250,
+ behavior: "smooth",
+ });
+ }
+ }, 600);
+ }}
+ />
+ );
+}
+
export function RenderedTextBlock(props: {
entityID: string;
className?: string;
@@ -262,8 +270,7 @@ export function BaseTextBlock(props: BlockProps & { className: string }) {
parent: propsRef.current.parent,
position: p,
},
- "end",
- "bottom",
+ { type: "end" },
);
}
}, 10);
@@ -444,19 +451,6 @@ let SyncView = (props: { entityID: string; parentID: string }) => {
let cursorPosY = coords.top;
let bottomScrollPadding = 100;
if (cursorPosY && parentHeight) {
- if (cursorPosY > parentHeight - bottomScrollPadding) {
- parentID?.scrollBy({
- top: bottomScrollPadding - (parentHeight - cursorPosY),
- behavior: "smooth",
- });
- }
- if (cursorPosY < 50) {
- if (parentID?.scrollTop === 0) return;
- parentID?.scrollBy({
- top: cursorPosY - 50,
- behavior: "smooth",
- });
- }
}
}, 10);
});
diff --git a/components/TextBlock/keymap.ts b/components/TextBlock/keymap.ts
index b2e957e1..52b60bae 100644
--- a/components/TextBlock/keymap.ts
+++ b/components/TextBlock/keymap.ts
@@ -7,9 +7,9 @@ import { MutableRefObject } from "react";
import { Replicache } from "replicache";
import { ReplicacheMutators } from "src/replicache";
import { elementId } from "src/utils/elementId";
-import { setEditorState, useEditorStates } from ".";
import { schema } from "./schema";
import { useUIState } from "src/useUIState";
+import { setEditorState, useEditorStates } from "src/state/useEditorState";
export const TextBlockKeymap = (
propsRef: MutableRefObject,
@@ -19,12 +19,18 @@ export const TextBlockKeymap = (
"Meta-b": toggleMark(schema.marks.strong),
"Meta-u": toggleMark(schema.marks.underline),
"Meta-i": toggleMark(schema.marks.em),
+ Escape: (_state, _dispatch, view) => {
+ view?.dom.blur();
+
+ return true;
+ },
"#": (state, dispatch, view) => {
if (state.selection.content().size > 0) return false;
if (state.selection.anchor > 1) return false;
repRef.current?.mutate.increaseHeadingLevel({
entityID: propsRef.current.entityID,
});
+
setTimeout(
() =>
focusBlock(
@@ -34,8 +40,7 @@ export const TextBlockKeymap = (
position: propsRef.current.position,
parent: propsRef.current.parent,
},
- "start",
- "bottom",
+ { type: "start" },
),
10,
);
@@ -96,7 +101,7 @@ export const TextBlockKeymap = (
let block = propsRef.current.previousBlock;
if (block) {
view.dom.blur();
- focusBlock(block, coords.left, "bottom");
+ focusBlock(block, { left: coords.left, type: "bottom" });
return true;
}
return false;
@@ -114,7 +119,7 @@ export const TextBlockKeymap = (
let block = propsRef.current.nextBlock;
if (block) {
view.dom.blur();
- focusBlock(block, coords.left, "top");
+ focusBlock(block, { left: coords.left, type: "top" });
return true;
}
return false;
@@ -127,7 +132,7 @@ export const TextBlockKeymap = (
let block = propsRef.current.previousBlock;
if (block) {
view?.dom.blur();
- focusBlock(block, "end", "top");
+ focusBlock(block, { type: "end" });
}
return true;
},
@@ -137,7 +142,7 @@ export const TextBlockKeymap = (
let block = propsRef.current.nextBlock;
if (block) {
view?.dom.blur();
- focusBlock(block, "start", "top");
+ focusBlock(block, { type: "start" });
}
return true;
},
@@ -172,8 +177,7 @@ const backspace =
position: propsRef.current.position,
parent: propsRef.current.parent,
},
- "start",
- "bottom",
+ { type: "start" },
),
10,
);
@@ -186,7 +190,7 @@ const backspace =
blockEntity: propsRef.current.entityID,
});
if (propsRef.current.previousBlock) {
- focusBlock(propsRef.current.previousBlock, "end", "bottom");
+ focusBlock(propsRef.current.previousBlock, { type: "end" });
}
return true;
}
@@ -234,14 +238,15 @@ const enter =
tr.delete(state.selection.anchor, state.doc.content.size);
dispatch?.(tr);
let newEntityID = crypto.randomUUID();
+ let position = generateKeyBetween(
+ propsRef.current.position,
+ propsRef.current.nextPosition,
+ );
repRef.current?.mutate.addBlock({
newEntityID,
parent: propsRef.current.parent,
type: "text",
- position: generateKeyBetween(
- propsRef.current.position,
- propsRef.current.nextPosition,
- ),
+ position,
});
setTimeout(() => {
let block = useEditorStates.getState().editorStates[newEntityID];
@@ -255,8 +260,16 @@ const enter =
editor: newState,
});
}
+ focusBlock(
+ {
+ value: newEntityID,
+ parent: propsRef.current.parent,
+ type: "text",
+ position,
+ },
+ { type: "start" },
+ );
}
- document.getElementById(elementId.block(newEntityID).text)?.focus();
}, 10);
return true;
};
diff --git a/components/Toolbar/LinkButton.tsx b/components/Toolbar/LinkButton.tsx
index e3e0f76a..74600504 100644
--- a/components/Toolbar/LinkButton.tsx
+++ b/components/Toolbar/LinkButton.tsx
@@ -1,4 +1,3 @@
-import { setEditorState, useEditorStates } from "components/TextBlock";
import { schema } from "components/TextBlock/schema";
import { EditorState, TextSelection } from "prosemirror-state";
import { useUIState } from "src/useUIState";
@@ -7,6 +6,7 @@ import { CheckTiny, CloseTiny, LinkTextToolbarSmall } from "components/Icons";
import { useState } from "react";
import { Separator } from "components/Layout";
import { MarkType } from "prosemirror-model";
+import { setEditorState, useEditorStates } from "src/state/useEditorState";
export function LinkButton(props: { setToolBarState: (s: "link") => void }) {
let focusedBlock = useUIState((s) => s.focusedBlock);
diff --git a/components/Toolbar/TextBlockTypeButtons.tsx b/components/Toolbar/TextBlockTypeButtons.tsx
index ba103a11..0d669d90 100644
--- a/components/Toolbar/TextBlockTypeButtons.tsx
+++ b/components/Toolbar/TextBlockTypeButtons.tsx
@@ -5,11 +5,11 @@ import {
ParagraphSmall,
} from "components/Icons";
import { Separator } from "components/Layout";
-import { setEditorState, useEditorStates } from "components/TextBlock";
import { CloseToolbarButton, ToolbarButton } from "components/Toolbar";
import { TextSelection } from "prosemirror-state";
import { useCallback } from "react";
import { useEntity, useReplicache } from "src/replicache";
+import { setEditorState, useEditorStates } from "src/state/useEditorState";
import { useUIState } from "src/useUIState";
export const TextBlockTypeButtons = (props: { onClose: () => void }) => {
let focusedBlock = useUIState((s) => s.focusedBlock);
diff --git a/components/Toolbar/TextDecorationButton.tsx b/components/Toolbar/TextDecorationButton.tsx
index 31877048..48699987 100644
--- a/components/Toolbar/TextDecorationButton.tsx
+++ b/components/Toolbar/TextDecorationButton.tsx
@@ -1,10 +1,10 @@
-import { useEditorStates } from "components/TextBlock";
import { MarkType } from "prosemirror-model";
import { useUIState } from "src/useUIState";
import { ToolbarButton } from ".";
import { toggleMark } from "prosemirror-commands";
import { TextSelection } from "prosemirror-state";
import { publishAppEvent } from "src/eventBus";
+import { useEditorStates } from "src/state/useEditorState";
export function TextDecorationButton(props: {
mark: MarkType;
diff --git a/package-lock.json b/package-lock.json
index 9b561e41..096cca1d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@nytimes/react-prosemirror": "^0.6.1",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-slider": "^1.1.2",
+ "@react-aria/utils": "^3.24.1",
"@react-spring/web": "^9.7.3",
"@supabase/ssr": "^0.3.0",
"@supabase/supabase-js": "^2.43.2",
diff --git a/package.json b/package.json
index 14149211..be6f1082 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@nytimes/react-prosemirror": "^0.6.1",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-slider": "^1.1.2",
+ "@react-aria/utils": "^3.24.1",
"@react-spring/web": "^9.7.3",
"@supabase/ssr": "^0.3.0",
"@supabase/supabase-js": "^2.43.2",