Add smooth animated caret with line and underline styles#13
Conversation
- Custom ProseMirror plugin renders a virtual caret (hides native) - Smooth 60ms CSS transition between positions while typing - Blink pauses while typing, resumes 0.5s after last keystroke - Line and underline styles switchable via Appearance > Cursor menu - Style persisted to localStorage and restored on startup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| const el = document.createElement("div"); | ||
| el.className = "pm-caret"; | ||
| el.setAttribute("data-style", caretStyle); | ||
| view.dom.parentElement?.appendChild(el); |
There was a problem hiding this comment.
caret element won't be created if view.dom.parentElement is null (the optional chaining causes silent failure)
| view.dom.parentElement?.appendChild(el); | |
| const parent = view.dom.parentElement; | |
| if (!parent) throw new Error("Editor view has no parent element"); | |
| parent.appendChild(el); |
| let caretStyle: CaretStyle = (localStorage.getItem("cursor") as CaretStyle) ?? "line"; | ||
| let activeView: EditorView | null = null; | ||
| let activeEl: HTMLElement | null = null; |
There was a problem hiding this comment.
module-level state means only one editor instance works correctly - if multiple Editor components mount, they'll overwrite each other's activeView and activeEl references
|
@copilot fix the issues Greptile flagged, only is those are legit else just skip those. |
|
@usamaasfar I've opened a new pull request, #14, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@codex[agent] review code. |
|
@usamaasfar I've opened a new pull request, #15, to work on those changes. Once the pull request is ready, I'll request review from you. |
@codex[agent] fix those. |
|
@usamaasfar I've opened a new pull request, #16, to work on those changes. Once the pull request is ready, I'll request review from you. |
) * Initial plan * Fix module-level state and silent failure in caret plugin Co-authored-by: usamaasfar <42825498+usamaasfar@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: usamaasfar <42825498+usamaasfar@users.noreply.github.com>
|
@greptile we good? |
|
Not quite - there are still two unresolved issues from my review:
Both comments are marked as "outdated" (likely because you pushed new commits), but they're not marked as resolved. Did you address these in a follow-up commit, or would you like me to check the current state of the code? |
|
|
@usamaasfar I've opened a new pull request, #17, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@greptile review again, on the issues. |
|
|
||
| export type CaretStyle = "line" | "underline"; | ||
|
|
||
| let caretStyle: CaretStyle = (localStorage.getItem("cursor") as CaretStyle) ?? "line"; |
There was a problem hiding this comment.
Type assertion could silently accept invalid values from localStorage (e.g., if manually set to "foo"). Consider adding runtime validation:
| let caretStyle: CaretStyle = (localStorage.getItem("cursor") as CaretStyle) ?? "line"; | |
| let caretStyle: CaretStyle = (() => { | |
| const stored = localStorage.getItem("cursor"); | |
| return stored === "line" || stored === "underline" ? stored : "line"; | |
| })(); |
Greptile Summary
Implements a custom animated caret for the ProseMirror editor with smooth 60ms position transitions and two visual styles (line and underline). The implementation correctly addresses the previous module-level state issue by using a
Mapto track multiple editor instances, ensuring proper cleanup and style updates across all active carets.Key changes:
caretPluginthat hides the native caret and renders a custom animated divlocalStorageand restored on startupConfidence Score: 4/5
localStorageretrieval which could accept invalid values, though this is unlikely to cause issues in practice.Important Files Changed
caretPluginto ProseMirror plugins array - straightforward integrationlocalStoragepersistence - follows existing patternLast reviewed commit: 7172585