UX improvement: Inputs now correctly lose focus on outside gestures

This commit is contained in:
Aria Minaei 2021-11-14 21:40:50 +01:00
parent fb53be8fe6
commit 8ca44085de
3 changed files with 30 additions and 4 deletions

View file

@ -5,6 +5,7 @@ import styled from 'styled-components'
import DraggableArea from '@theatre/studio/uiComponents/DraggableArea'
import mergeRefs from 'react-merge-refs'
import useRefAndState from '@theatre/studio/utils/useRefAndState'
import useOnClickOutside from '@theatre/studio/uiComponents/useOnClickOutside'
const Container = styled.div`
height: 100%;
@ -124,6 +125,14 @@ const BasicNumberInput: React.FC<{
const inputRef = useRef<HTMLInputElement | null>(null)
useOnClickOutside(
inputRef.current,
() => {
inputRef.current!.blur()
},
stateRef.current.mode === 'editingViaKeyboard',
)
const bodyCursorBeforeDrag = useRef<string | null>(null)
const callbacks = useMemo(() => {

View file

@ -3,6 +3,7 @@ import type {MutableRefObject} from 'react'
import React, {useMemo, useRef} from 'react'
import mergeRefs from 'react-merge-refs'
import useRefAndState from '@theatre/studio/utils/useRefAndState'
import useOnClickOutside from '@theatre/studio/uiComponents/useOnClickOutside'
const Input = styled.input.attrs({type: 'text'})`
background: transparent;
@ -72,6 +73,14 @@ const BasicStringInput: React.FC<{
const inputRef = useRef<HTMLInputElement | null>(null)
useOnClickOutside(
inputRef.current,
() => {
inputRef.current!.blur()
},
stateRef.current.mode === 'editingViaKeyboard',
)
const callbacks = useMemo(() => {
const inputChange = (e: React.ChangeEvent) => {
const target = e.target as HTMLInputElement

View file

@ -1,11 +1,13 @@
import type {$IntentionalAny} from '@theatre/shared/utils/types'
import {useEffect} from 'react'
export default function useOnClickOutside(
container: Element | null,
onOutside: (e: MouseEvent) => void,
enabled?: boolean,
) {
useEffect(() => {
if (!container) return
if (!container || enabled === false) return
const onMouseDown = (e: MouseEvent) => {
if (!e.composedPath().includes(container)) {
@ -13,9 +15,15 @@ export default function useOnClickOutside(
}
}
window.addEventListener('mousedown', onMouseDown, {capture: true})
window.addEventListener('mousedown', onMouseDown, {
capture: true,
passive: false,
})
return () => {
window.removeEventListener('mousedown', onMouseDown, {capture: true})
window.removeEventListener('mousedown', onMouseDown, {
capture: true,
passive: false,
} as unknown as $IntentionalAny)
}
}, [container, onOutside])
}, [container, enabled])
}