mirror of
https://github.com/m1ngsama/chat-bubbles-for-yt.git
synced 2025-12-24 10:51:21 +00:00
fix(bubble-input): maintain focus by handling blur events
Use forwardRef to expose the content editable element and let the parent component control the focus fix #1 #2
This commit is contained in:
parent
5fba2eceaa
commit
5b86470066
3 changed files with 28 additions and 19 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useCallback, useEffect } from 'react'
|
||||
import { useState, useCallback } from 'react'
|
||||
import './App.css'
|
||||
import Chat from './chat'
|
||||
import Bubble from './bubble'
|
||||
|
|
@ -17,13 +17,6 @@ function App() {
|
|||
}
|
||||
}, [newMessage, messages])
|
||||
|
||||
useEffect(() => {
|
||||
const el = document.querySelector('.bubble.input > div')
|
||||
if (el) {
|
||||
el.focus()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<Chat>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import React, { useCallback, useState } from 'react'
|
||||
import React, { useCallback, useState, useRef, useEffect } from 'react'
|
||||
import './bubble-input.css'
|
||||
import ContentEditable from './content-editable'
|
||||
|
||||
const BubbleInput = ({ onChange, onSubmit, value }) => {
|
||||
const refEditable = useRef()
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
|
||||
const handleChange = useCallback(
|
||||
|
|
@ -25,7 +26,15 @@ const BubbleInput = ({ onChange, onSubmit, value }) => {
|
|||
},
|
||||
[onSubmit]
|
||||
)
|
||||
console.log('value:', value)
|
||||
const handleBlur = useCallback(() => {
|
||||
const { current: elDiv } = refEditable
|
||||
if (elDiv) {
|
||||
elDiv.focus()
|
||||
}
|
||||
}, [refEditable])
|
||||
|
||||
useEffect(() => handleBlur(), [handleBlur])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`bubble input ${value.length === 0 ? 'empty' : ''} ${
|
||||
|
|
@ -33,8 +42,10 @@ const BubbleInput = ({ onChange, onSubmit, value }) => {
|
|||
}`}
|
||||
>
|
||||
<ContentEditable
|
||||
ref={refEditable}
|
||||
onChange={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={handleBlur}
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
import * as React from 'react'
|
||||
|
||||
class ContentEditable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.refElement = React.createRef()
|
||||
}
|
||||
render() {
|
||||
const { innerRef } = this.props
|
||||
return (
|
||||
<div
|
||||
key={Math.random()}
|
||||
ref={this.refElement}
|
||||
ref={innerRef}
|
||||
onInput={this.emitChange}
|
||||
onBlur={this.emitChange}
|
||||
onBlur={this.handleBlur}
|
||||
onKeyDown={this.emitKeyDown}
|
||||
contentEditable
|
||||
spellCheck="false"
|
||||
|
|
@ -21,12 +18,12 @@ class ContentEditable extends React.Component {
|
|||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { current: div } = this.refElement
|
||||
const { current: div } = this.props.innerRef
|
||||
return nextProps.value !== div.innerText
|
||||
}
|
||||
|
||||
emitChange = () => {
|
||||
const { current: div } = this.refElement
|
||||
const { current: div } = this.props.innerRef
|
||||
var value = div.innerText
|
||||
if (this.props.onChange && value !== this.lastValue) {
|
||||
this.props.onChange({
|
||||
|
|
@ -42,6 +39,14 @@ class ContentEditable extends React.Component {
|
|||
const { onKeyDown } = this.props
|
||||
onKeyDown && onKeyDown(e)
|
||||
}
|
||||
|
||||
handleBlur = e => {
|
||||
this.emitKeyDown(e)
|
||||
const { onBlur } = this.props
|
||||
onBlur && onBlur(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default ContentEditable
|
||||
export default React.forwardRef((props, ref) => {
|
||||
return <ContentEditable innerRef={ref} {...props} />
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue