From 0918820661953109c1ef4041f25b7d38f03717e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=97=D0=B8=D0=BC=D0=B8=D0=BD?= Date: Sun, 10 May 2026 18:53:07 +0000 Subject: [PATCH] fix(admin-ui): Checkbox indeterminate stale state --- .../src/routes/dictionaries.$name.tsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/ordinis-admin-ui/src/routes/dictionaries.$name.tsx b/ordinis-admin-ui/src/routes/dictionaries.$name.tsx index 382f277..007404a 100644 --- a/ordinis-admin-ui/src/routes/dictionaries.$name.tsx +++ b/ordinis-admin-ui/src/routes/dictionaries.$name.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { createFileRoute, Link, useNavigate } from '@tanstack/react-router' import { useTranslation } from 'react-i18next' import axios from 'axios' @@ -288,6 +288,19 @@ function DictionaryDetail() { const someVisibleSelected = !allVisibleSelected && visibleKeys.some((k) => selection.has(k)) + // Native checkbox indeterminate state — sync через useEffect, не callback ref. + // Callback ref срабатывает только на mount/unmount → state становится stale + // когда user toggle'ает selection per-row. useEffect re-runs на изменение + // someVisibleSelected. См. design handoff review #17 + Checkbox в @nstart/ui: + // ref forwarded к нативному , но `indeterminate` это JS DOM-only prop + // (не HTML attribute), нужен manual sync. + const selectAllRef = useRef(null) + useEffect(() => { + if (selectAllRef.current) { + selectAllRef.current.indeterminate = someVisibleSelected + } + }, [someVisibleSelected]) + const toggleSelect = (key: string) => { setSelection((prev) => { const next = new Set(prev) @@ -737,10 +750,7 @@ function DictionaryDetail() { { - if (el) el.indeterminate = someVisibleSelected - }} + ref={selectAllRef} onChange={toggleSelectAll} />