fix(web/channel): stabilize inline priority updates (#6415)
* fix(channel): debounce inline priority updates * fix(channel): commit spinner edits only on Enter or focus leave Blurring the inline edit input to the +/- buttons flushed the pending priority update immediately, bypassing the container focus-containment check and defeating the debounce. Commit now happens via the container blur handler or explicitly on Enter. Add unit tests for the priority update scheduler. * fix(channel): preserve row identity when priority updates reorder channels
This commit is contained in:
@@ -25,6 +25,7 @@ import { cn } from '@/lib/utils'
|
||||
interface NumericSpinnerInputProps {
|
||||
value: number | null | undefined
|
||||
onChange: (value: number) => void
|
||||
onCommit?: () => void
|
||||
min?: number
|
||||
max?: number
|
||||
step?: number
|
||||
@@ -36,6 +37,7 @@ interface NumericSpinnerInputProps {
|
||||
export function NumericSpinnerInput({
|
||||
value,
|
||||
onChange,
|
||||
onCommit,
|
||||
min = 0,
|
||||
max,
|
||||
step = 1,
|
||||
@@ -96,7 +98,7 @@ export function NumericSpinnerInput({
|
||||
const commitValue = () => {
|
||||
setEditing(false)
|
||||
const num = Number(localValue)
|
||||
if (isNaN(num) || localValue === '' || localValue === '-') {
|
||||
if (Number.isNaN(num) || localValue === '' || localValue === '-') {
|
||||
setLocalValue(String(value ?? 0))
|
||||
return
|
||||
}
|
||||
@@ -107,10 +109,21 @@ export function NumericSpinnerInput({
|
||||
}
|
||||
}
|
||||
|
||||
const handleControlBlur = (e: React.FocusEvent<HTMLDivElement>) => {
|
||||
if (
|
||||
e.relatedTarget instanceof Node &&
|
||||
e.currentTarget.contains(e.relatedTarget)
|
||||
) {
|
||||
return
|
||||
}
|
||||
onCommit?.()
|
||||
}
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
commitValue()
|
||||
onCommit?.()
|
||||
} else if (e.key === 'Escape') {
|
||||
setEditing(false)
|
||||
setLocalValue(String(value ?? 0))
|
||||
@@ -126,6 +139,7 @@ export function NumericSpinnerInput({
|
||||
<Label className='text-muted-foreground mr-1.5 text-xs'>{label}</Label>
|
||||
)}
|
||||
<div
|
||||
onBlur={handleControlBlur}
|
||||
className={cn(
|
||||
'group/spinner border-input inline-flex h-7 items-center gap-0 rounded-md border transition-colors',
|
||||
!disabled && 'hover:bg-muted/60',
|
||||
|
||||
Reference in New Issue
Block a user