UX improvement: Inputs now correctly lose focus on outside gestures
This commit is contained in:
parent
fb53be8fe6
commit
8ca44085de
3 changed files with 30 additions and 4 deletions
|
@ -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(() => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue