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 DraggableArea from '@theatre/studio/uiComponents/DraggableArea'
|
||||||
import mergeRefs from 'react-merge-refs'
|
import mergeRefs from 'react-merge-refs'
|
||||||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||||
|
import useOnClickOutside from '@theatre/studio/uiComponents/useOnClickOutside'
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -124,6 +125,14 @@ const BasicNumberInput: React.FC<{
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
|
useOnClickOutside(
|
||||||
|
inputRef.current,
|
||||||
|
() => {
|
||||||
|
inputRef.current!.blur()
|
||||||
|
},
|
||||||
|
stateRef.current.mode === 'editingViaKeyboard',
|
||||||
|
)
|
||||||
|
|
||||||
const bodyCursorBeforeDrag = useRef<string | null>(null)
|
const bodyCursorBeforeDrag = useRef<string | null>(null)
|
||||||
|
|
||||||
const callbacks = useMemo(() => {
|
const callbacks = useMemo(() => {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type {MutableRefObject} from 'react'
|
||||||
import React, {useMemo, useRef} from 'react'
|
import React, {useMemo, useRef} from 'react'
|
||||||
import mergeRefs from 'react-merge-refs'
|
import mergeRefs from 'react-merge-refs'
|
||||||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||||
|
import useOnClickOutside from '@theatre/studio/uiComponents/useOnClickOutside'
|
||||||
|
|
||||||
const Input = styled.input.attrs({type: 'text'})`
|
const Input = styled.input.attrs({type: 'text'})`
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -72,6 +73,14 @@ const BasicStringInput: React.FC<{
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
|
useOnClickOutside(
|
||||||
|
inputRef.current,
|
||||||
|
() => {
|
||||||
|
inputRef.current!.blur()
|
||||||
|
},
|
||||||
|
stateRef.current.mode === 'editingViaKeyboard',
|
||||||
|
)
|
||||||
|
|
||||||
const callbacks = useMemo(() => {
|
const callbacks = useMemo(() => {
|
||||||
const inputChange = (e: React.ChangeEvent) => {
|
const inputChange = (e: React.ChangeEvent) => {
|
||||||
const target = e.target as HTMLInputElement
|
const target = e.target as HTMLInputElement
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
import type {$IntentionalAny} from '@theatre/shared/utils/types'
|
||||||
import {useEffect} from 'react'
|
import {useEffect} from 'react'
|
||||||
|
|
||||||
export default function useOnClickOutside(
|
export default function useOnClickOutside(
|
||||||
container: Element | null,
|
container: Element | null,
|
||||||
onOutside: (e: MouseEvent) => void,
|
onOutside: (e: MouseEvent) => void,
|
||||||
|
enabled?: boolean,
|
||||||
) {
|
) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!container) return
|
if (!container || enabled === false) return
|
||||||
|
|
||||||
const onMouseDown = (e: MouseEvent) => {
|
const onMouseDown = (e: MouseEvent) => {
|
||||||
if (!e.composedPath().includes(container)) {
|
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 () => {
|
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