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:
RedwindA
2026-07-25 15:59:59 +08:00
committed by GitHub
parent bf8cfcc512
commit a0d0e5049e
8 changed files with 327 additions and 41 deletions
@@ -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',