Migrating editable to functional component
This commit is contained in:
parent
21a5478b32
commit
57a6ac3bac
4 changed files with 72 additions and 74 deletions
|
@ -30,7 +30,7 @@ type Props = {
|
|||
const CardDetail = (props: Props): JSX.Element|null => {
|
||||
const {cardTree} = props
|
||||
const [title, setTitle] = useState(cardTree.card.title)
|
||||
const titleRef = useRef<Editable>(null)
|
||||
const titleRef = useRef<{focus(selectAll?: boolean): void}>(null)
|
||||
const titleValueRef = useRef(title)
|
||||
titleValueRef.current = title
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ const TableRow = React.memo((props: Props) => {
|
|||
const {boardTree, onSaveWithEnter} = props
|
||||
const {board, activeView} = boardTree
|
||||
|
||||
const titleRef = useRef<Editable>(null)
|
||||
const titleRef = useRef<{focus(selectAll?: boolean): void}>(null)
|
||||
const [title, setTitle] = useState(props.card.title)
|
||||
const {card} = props
|
||||
const isManualSort = activeView.sortOptions.length < 1
|
||||
|
|
|
@ -17,7 +17,7 @@ type Props = {
|
|||
const ViewHeaderSearch = (props: Props) => {
|
||||
const {boardTree, intl} = props
|
||||
|
||||
const searchFieldRef = useRef<Editable>(null)
|
||||
const searchFieldRef = useRef<{focus(selectAll?: boolean): void}>(null)
|
||||
const [isSearching, setIsSearching] = useState(Boolean(props.boardTree.getSearchText()))
|
||||
const [searchValue, setSearchValue] = useState(boardTree.getSearchText())
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react'
|
||||
import React, {useRef, useImperativeHandle, forwardRef} from 'react'
|
||||
|
||||
import './editable.scss'
|
||||
|
||||
|
@ -17,83 +17,81 @@ type Props = {
|
|||
onSave?: (saveType: 'onEnter'|'onEsc'|'onBlur') => void
|
||||
}
|
||||
|
||||
export default class Editable extends React.Component<Props> {
|
||||
private elementRef = React.createRef<HTMLInputElement>()
|
||||
private saveOnBlur = true
|
||||
const Editable = (props: Props, ref: React.Ref<{focus: (selectAll?: boolean) => void}>): JSX.Element => {
|
||||
const elementRef = useRef<HTMLInputElement>(null)
|
||||
const saveOnBlur = useRef<boolean>(true)
|
||||
|
||||
shouldComponentUpdate(): boolean {
|
||||
return true
|
||||
const save = (saveType: 'onEnter'|'onEsc'|'onBlur'): void => {
|
||||
if (props.validator && !props.validator(props.value || '')) {
|
||||
return
|
||||
}
|
||||
if (!props.onSave) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onBlur' && !saveOnBlur.current) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onEsc' && !props.saveOnEsc) {
|
||||
return
|
||||
}
|
||||
props.onSave(saveType)
|
||||
}
|
||||
|
||||
save = (saveType: 'onEnter'|'onEsc'|'onBlur'): void => {
|
||||
if (this.props.validator && !this.props.validator(this.props.value || '')) {
|
||||
return
|
||||
}
|
||||
if (!this.props.onSave) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onBlur' && !this.saveOnBlur) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onEsc' && !this.props.saveOnEsc) {
|
||||
return
|
||||
}
|
||||
this.props.onSave(saveType)
|
||||
}
|
||||
|
||||
public focus(selectAll = false): void {
|
||||
if (this.elementRef.current) {
|
||||
const valueLength = this.elementRef.current.value.length
|
||||
this.elementRef.current.focus()
|
||||
if (selectAll) {
|
||||
this.elementRef.current.setSelectionRange(0, valueLength)
|
||||
} else {
|
||||
this.elementRef.current.setSelectionRange(valueLength, valueLength)
|
||||
useImperativeHandle(ref, () => ({
|
||||
focus: (selectAll = false): void => {
|
||||
if (elementRef.current) {
|
||||
const valueLength = elementRef.current.value.length
|
||||
elementRef.current.focus()
|
||||
if (selectAll) {
|
||||
elementRef.current.setSelectionRange(0, valueLength)
|
||||
} else {
|
||||
elementRef.current.setSelectionRange(valueLength, valueLength)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
const blur = (): void => {
|
||||
saveOnBlur.current = false
|
||||
elementRef.current?.blur()
|
||||
saveOnBlur.current = true
|
||||
}
|
||||
|
||||
public blur = (): void => {
|
||||
this.saveOnBlur = false
|
||||
this.elementRef.current?.blur()
|
||||
this.saveOnBlur = true
|
||||
const {value, onChange, className, placeholderText} = props
|
||||
let error = false
|
||||
if (props.validator) {
|
||||
error = !props.validator(value || '')
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
const {value, onChange, className, placeholderText} = this.props
|
||||
let error = false
|
||||
if (this.props.validator) {
|
||||
error = !this.props.validator(value || '')
|
||||
}
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={this.elementRef}
|
||||
className={'Editable ' + (error ? 'error ' : '') + className}
|
||||
placeholder={placeholderText}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.value)
|
||||
}}
|
||||
value={value}
|
||||
title={value}
|
||||
onBlur={() => this.save('onBlur')}
|
||||
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (e.keyCode === 27 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // ESC
|
||||
e.stopPropagation()
|
||||
if (this.props.saveOnEsc) {
|
||||
this.save('onEsc')
|
||||
} else {
|
||||
this.props.onCancel?.()
|
||||
}
|
||||
this.blur()
|
||||
} else if (e.keyCode === 13 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // Return
|
||||
e.stopPropagation()
|
||||
this.save('onEnter')
|
||||
this.blur()
|
||||
return (
|
||||
<input
|
||||
ref={elementRef}
|
||||
className={'Editable ' + (error ? 'error ' : '') + className}
|
||||
placeholder={placeholderText}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.value)
|
||||
}}
|
||||
value={value}
|
||||
title={value}
|
||||
onBlur={() => save('onBlur')}
|
||||
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (e.keyCode === 27 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // ESC
|
||||
e.stopPropagation()
|
||||
if (props.saveOnEsc) {
|
||||
save('onEsc')
|
||||
} else {
|
||||
props.onCancel?.()
|
||||
}
|
||||
}}
|
||||
readOnly={this.props.readonly}
|
||||
/>
|
||||
)
|
||||
}
|
||||
blur()
|
||||
} else if (e.keyCode === 13 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // Return
|
||||
e.stopPropagation()
|
||||
save('onEnter')
|
||||
blur()
|
||||
}
|
||||
}}
|
||||
readOnly={props.readonly}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default forwardRef(Editable)
|
||||
|
|
Loading…
Reference in a new issue