Fix curveEditorPopover overwriting existing curve (#151)

* Fix curveEditorPopover overwriting existing curve

* Fix existing curve overwrite, other reactivity
This commit is contained in:
Elliot 2022-05-10 13:14:32 -04:00 committed by GitHub
parent 417233a7c6
commit cd9d03076b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 18 deletions

View file

@ -102,6 +102,7 @@ const NoResultsFoundContainer = styled.div`
`
enum TextInputMode {
init,
user,
auto,
}
@ -153,14 +154,16 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
inputRef.current?.focus()
}, [inputRef.current])
const [inputValue, setInputValue] = useState<string>('')
const [inputValue, setInputValue] = useState<string>(
cssCubicBezierArgsFromHandles(easing),
)
const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setTextInputMode(TextInputMode.user)
setInputValue(e.target.value)
const maybeHandles = handlesFromCssCubicBezierArgs(inputValue)
if (maybeHandles) setEdit(inputValue)
const maybeHandles = handlesFromCssCubicBezierArgs(e.target.value)
if (maybeHandles) setEdit(e.target.value)
}
const onSearchKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
setTextInputMode(TextInputMode.user)
@ -183,7 +186,7 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
// in user mode, the text input field does not update when the curve
// changes so that the user's search is preserved.
const [textInputMode, setTextInputMode] = useState<TextInputMode>(
TextInputMode.auto,
TextInputMode.init,
)
useEffect(() => {
if (textInputMode === TextInputMode.auto)
@ -191,7 +194,9 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
}, [trackData])
// `edit` keeps track of the current edited state of the curve.
const [edit, setEdit] = useState<CSSCubicBezierArgsString | null>(null)
const [edit, setEdit] = useState<CSSCubicBezierArgsString | null>(
cssCubicBezierArgsFromHandles(easing),
)
// `preview` is used when hovering over a curve to preview it.
const [preview, setPreview] = useState<CSSCubicBezierArgsString | null>(null)
@ -214,18 +219,22 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
////// Preset reactivity //////
const displayedPresets = useMemo(() => {
const presetSearchResults = fuzzy.filter(inputValue, EASING_PRESETS, {
extract: (el) => el.label,
})
const isInputValueAQuery = /^[A-Za-z]/.test(inputValue)
return isInputValueAQuery
? presetSearchResults.map((result) => result.original)
: EASING_PRESETS
if (isInputValueAQuery) {
return fuzzy
.filter(inputValue, EASING_PRESETS, {
extract: (el) => el.label,
})
.map((result) => result.original)
} else {
return EASING_PRESETS
}
}, [inputValue])
// Use the first preset in the search when the displayed presets change
useEffect(() => {
if (displayedPresets[0]) setEdit(displayedPresets[0].value)
if (textInputMode === TextInputMode.user && displayedPresets[0])
setEdit(displayedPresets[0].value)
}, [displayedPresets])
////// Option grid specification and reactivity //////
@ -243,8 +252,10 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
setPreview(item.value)
const onEasingOptionMouseOut = () => setPreview(null)
const onSelectEasingOption = (item: {label: string; value: string}) => {
setTextInputMode(TextInputMode.auto)
setEdit(item.value)
setTempValue(tempTransaction, props, cur, next, item.value)
props.onRequestClose()
return Outcome.Handled
}
// A map to store all html elements corresponding to easing options
@ -316,6 +327,10 @@ const CurveEditorPopover: React.FC<IProps> = (props) => {
optionsRef.current?.[grid.currentSelection.label]?.current
maybePresetEl?.focus()
setEdit(grid.currentSelection.value)
const isInputValueAQuery = /^[A-Za-z]/.test(inputValue)
if (!isInputValueAQuery) {
setInputValue(grid.currentSelection.value)
}
}
}, [grid.currentSelection])

View file

@ -14,13 +14,13 @@ type UIOptionGridOptions<Item> = {
items: Item[]
/** display of items */
renderItem: (value: {
select(): void
select(e?: Event): void
/** data item */
item: Item
/** arrow key nav */
isSelected: boolean
}) => React.ReactNode
onSelectItem(item: Item): void
onSelectItem(item: Item): Outcome
/** Set a callback for what to do if we try to leave the grid */
canVerticleExit?: (exitSide: 'top' | 'bottom') => Outcome
}
@ -98,9 +98,12 @@ export function useUIOptionGrid<T>(
options.renderItem({
isSelected: idx === selectionIndex,
item,
select() {
select(e) {
setSelectionIndex(idx)
options.onSelectItem(item)
if (options.onSelectItem(item) === Outcome.Handled) {
e?.preventDefault()
e?.stopPropagation()
}
},
}),
),