Skip to content

Commit

Permalink
feat: auto-focus text on creation/tile selection (#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
kswenson authored Aug 11, 2024
1 parent 9ed67f4 commit f7e1009
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 15 deletions.
4 changes: 2 additions & 2 deletions v3/cypress/e2e/text.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ context("Text tile", () => {
// focus the text tile
t.getTextTileContent().click()
const textToType = "This is some text."
t.getTextTileContent().type(textToType)
t.typeText(textToType)
t.getTextTileContent().should("have.text", textToType)
// blur the text tile
cy.get(".codap-container").click()
t.blurEditor()
t.getTextTileContent().should("have.text", textToType)
// Undo typing
toolbar.getUndoTool().click()
Expand Down
12 changes: 12 additions & 0 deletions v3/cypress/support/elements/text-tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,17 @@ export const TextTileElements = {
},
getTextTileContent() {
return cy.get(kTextContentClass)
},
getTextTileEditor() {
return cy.get(".slate-editor")
},
focusEditor() {
return this.getTextTileEditor().focus()
},
blurEditor() {
return this.getTextTileEditor().blur()
},
typeText(text: string) {
this.getTextTileEditor().type(text)
}
}
27 changes: 14 additions & 13 deletions v3/src/components/text/text-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, { useEffect, useRef, useState } from "react"
import { useMemo } from "use-memo-one"
import { useTileModelContext } from "../../hooks/use-tile-model-context"
import { ITileBaseProps } from "../tiles/tile-base-props"
import { mstReaction } from "../../utilities/mst-reaction"
import { isTextModel, modelValueToEditorValue } from "./text-model"
import { TextToolbar } from "./text-toolbar"

Expand All @@ -13,7 +14,7 @@ import "./text-tile.scss"

export const TextTile = observer(function TextTile({ tile }: ITileBaseProps) {
const textModel = isTextModel(tile?.content) ? tile.content : undefined
const { selectTile } = useTileModelContext()
const { isTileSelected } = useTileModelContext()
const textOnFocus = useRef("")

const [initialValue, setInitialValue] = useState(() => modelValueToEditorValue(textModel?.value))
Expand All @@ -26,6 +27,17 @@ export const TextTile = observer(function TextTile({ tile }: ITileBaseProps) {
// changes to this value trigger a remount of the slate editor
const mountKey = useRef(0)

useEffect(() => {
return tile && mstReaction(
() => isTileSelected() && tile?.transitionComplete,
isSelected => {
// RAF to delay focus request until after model processing completes
isSelected && requestAnimationFrame(() => ReactEditor.focus(editor))
},
{ name: "FocusEditorOnTileSelect" }, tile
)
}, [editor, isTileSelected, tile])

const textTileRef = useRef<HTMLDivElement | null>(null)
useEffect(() => {
if (textModel) {
Expand Down Expand Up @@ -67,19 +79,8 @@ export const TextTile = observer(function TextTile({ tile }: ITileBaseProps) {
}
}

function handlePointerDownInTile(e: React.MouseEvent<HTMLDivElement>) {
const isWrapperClick = e.target === textTileRef.current
selectTile()
if (e.target === textTileRef.current) {
// clicks in the background of the tile focus the editor
isWrapperClick && ReactEditor.focus(editor)
e.preventDefault()
}
}

return (
<div className="codap-text-content" ref={textTileRef} data-testid="codap-text-content"
onPointerDown={handlePointerDownInTile}>
<div className="codap-text-content" ref={textTileRef} data-testid="codap-text-content">
<Slate editor={editor} initialValue={initialValue}
// updating key triggers remount of editor component
key={mountKey.current}
Expand Down

0 comments on commit f7e1009

Please sign in to comment.