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}
/>