fix(ui): завершить основу таблиц и фильтров серверов
This commit is contained in:
1 parent
f9a4a07996
commit
3d3c45e4d2
24 files changed
+385
-263
No files matched your search
@@ -5,8 +5,9 @@ import {
|
||||
useContext,
|
||||
useEffect,
|
||||
useId,
|
||||
useMemo,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react"
|
||||
import type { ReactNode } from "react"
|
||||
import {
|
||||
@@ -878,25 +879,17 @@ function DataGridProvider<TData extends object>({
|
||||
table: DataGridTableInstance<TData>
|
||||
children?: ReactNode
|
||||
}) {
|
||||
// Latest-props ref: context reads always resolve fresh props through the
|
||||
// getter below without the memoized context value depending on unstable
|
||||
// Stable for the grid's lifetime; ARIA ids and relations hang off it.
|
||||
// Rendering reads this snapshot; imperative sizing reads committed values.
|
||||
const gridId = useId()
|
||||
// ReactNode/function prop identities (inline emptyMessage/onRowClick would
|
||||
// otherwise publish a new context value on every consumer render - at
|
||||
// mousemove rate during a resize drag, piercing the body-rows memo).
|
||||
const propsRef = useRef(props)
|
||||
propsRef.current = props
|
||||
const i18n = mergeDataGridI18n(props.i18n)
|
||||
const i18nRef = useRef(i18n)
|
||||
i18nRef.current = i18n
|
||||
|
||||
// Same treatment for the table itself, which v9 - unlike v8 - re-creates on
|
||||
// every state change. Depending on it directly would republish the context
|
||||
// on each resize tick, which is exactly what the memo below exists to
|
||||
// prevent; the getter still hands every consumer the current instance.
|
||||
const tableRef = useRef(table)
|
||||
tableRef.current = table
|
||||
const [sizing] = useState(() => {
|
||||
let committedTable = table
|
||||
return {
|
||||
controller: createDataGridAutoSizeController(() => committedTable),
|
||||
update(next: DataGridTableInstance<TData>) { committedTable = next },
|
||||
}
|
||||
})
|
||||
useLayoutEffect(() => { sizing.update(table) }, [sizing, table])
|
||||
|
||||
// Re-assert an explicit tableLayout resize mode so consumer-level useTable
|
||||
// options cannot flip it back between drags. v9 makes `table.options`
|
||||
@@ -936,70 +929,13 @@ function DataGridProvider<TData extends object>({
|
||||
if (previousPageKeyRef.current === pageKey) return
|
||||
previousPageKeyRef.current = pageKey
|
||||
if (!cellSelectionOn || table.atoms.cellSelection == null) return
|
||||
tableRef.current.resetCellSelection(true)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pageKey, cellSelectionOn])
|
||||
table.resetCellSelection(true)
|
||||
}, [pageKey, cellSelectionOn, table])
|
||||
|
||||
// One autoSize coordinator per table instance so split header/body viewports
|
||||
// cannot apply the growth twice. Keyed on `table.store`, which v9 keeps
|
||||
// stable for the life of the table, rather than on `table` itself: the
|
||||
// wrapper is re-created on every state change, and re-creating the
|
||||
// controller with it would reset its applied-once bookkeeping mid-drag.
|
||||
const autoSize = useMemo(
|
||||
() => createDataGridAutoSizeController(() => tableRef.current),
|
||||
[table.store]
|
||||
)
|
||||
|
||||
const tableState = table.state
|
||||
const tableLayoutKey = JSON.stringify(props.tableLayout)
|
||||
const tableClassNamesKey = JSON.stringify(props.tableClassNames)
|
||||
|
||||
// Memoize context value so consumers don't re-render during column resize.
|
||||
// Column sizing state is intentionally excluded from deps -- CSS variables
|
||||
// on the <table> element handle width updates without React re-renders.
|
||||
// ReactNode/function props (messages, onRowClick) are also excluded: they
|
||||
// are served fresh through the props getter, so unstable inline identities
|
||||
// cannot invalidate the context value.
|
||||
// `cellSelection` state is excluded on purpose too: a drag writes it once
|
||||
// per cell crossed, and nothing reads it through context - cells and the
|
||||
// selection bar subscribe to `table.atoms.cellSelection` directly.
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
get props() {
|
||||
return propsRef.current
|
||||
},
|
||||
get table() {
|
||||
return tableRef.current
|
||||
},
|
||||
get i18n() {
|
||||
return i18nRef.current
|
||||
},
|
||||
recordCount: props.recordCount,
|
||||
isLoading: props.isLoading || false,
|
||||
gridId,
|
||||
autoSize,
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[
|
||||
autoSize,
|
||||
props.recordCount,
|
||||
props.isLoading,
|
||||
props.loadingMode,
|
||||
props.className,
|
||||
tableLayoutKey,
|
||||
tableClassNamesKey,
|
||||
tableState.sorting,
|
||||
tableState.pagination,
|
||||
tableState.columnFilters,
|
||||
tableState.rowSelection,
|
||||
tableState.rowPinning,
|
||||
tableState.expanded,
|
||||
tableState.columnVisibility,
|
||||
tableState.columnOrder,
|
||||
tableState.columnPinning,
|
||||
tableState.globalFilter,
|
||||
]
|
||||
)
|
||||
const value = {
|
||||
props, table, i18n, recordCount: props.recordCount,
|
||||
isLoading: props.isLoading || false, gridId, autoSize: sizing.controller,
|
||||
}
|
||||
|
||||
return (
|
||||
// One React context serves every TData, but v9 declares both TFeatures and
|
||||
|
||||
Reference in new issue
Block a user