/
githubmirror
/
ydb-embedded-ui
Обзор
Документация
Войти
/
githubmirror
/
ydb-embedded-ui
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/components/SplitPane/SplitPane.tsx
144 строки
4 KB
Konstantin Kozlov
fix: restore object summary schema panel (#4172)
28 июл 2026, 11:16
Не верифицирован
28 июл 2026, 11:16
7fe7f39
Код
Авторство
О чём код?
import React from 'react'; import {debounce} from 'lodash'; import type {SplitProps} from 'react-split'; import SplitPaneLib from 'react-split'; import {cn} from '../../utils/cn'; import {useSetting} from '../../utils/hooks/useSetting'; import './SplitPane.scss'; const b = cn('kv-split'); interface SplitPaneProps { children: React.ReactNode; defaultSizePaneKey: string; direction?: SplitProps['direction']; sizes?: SplitProps['sizes']; defaultSizes?: SplitProps['sizes']; initialSizes?: SplitProps['sizes']; collapsedSizes?: SplitProps['sizes']; minSize?: number[]; gutterSize?: SplitProps['gutterSize']; triggerCollapse?: boolean; triggerExpand?: boolean; onSplitStartDragAdditional?: VoidFunction; onSplitDragAdditional?: VoidFunction; } const minSizeDefaultInner = [0, 100]; const sizesDefaultInner = [50, 50]; const SAVE_DEBOUNCE_MS = 200; const getGutterStyle: NonNullable<SplitProps['gutterStyle']> = (dimension, gutterSize) => ({ [dimension]: `${gutterSize}px`, display: gutterSize === 0 ? 'none' : '', }); function SplitPane(props: SplitPaneProps) { const [innerSizes, setInnerSizes] = React.useState<number[]>(); const { collapsedSizes, triggerCollapse, triggerExpand, defaultSizes: defaultSizesProp, initialSizes, sizes: sizesProp, gutterSize = 8, } = props; const [savedSizesString, setSavedSizesString] = useSetting<string | undefined>( props.defaultSizePaneKey, ); const saveSizesStringDebounced = React.useMemo(() => { return debounce((value: string) => setSavedSizesString(value), SAVE_DEBOUNCE_MS); }, [setSavedSizesString]); React.useEffect(() => { return () => { saveSizesStringDebounced.cancel(); }; }, [saveSizesStringDebounced]); const defaultSizePane = React.useMemo(() => { if (initialSizes) { return initialSizes; } const fallbackSizes = defaultSizesProp || sizesDefaultInner; if (!savedSizesString) { return fallbackSizes; } const parts = savedSizesString.split(','); const parsedSizes = parts.map((part) => { const trimmed = part.trim(); if (!trimmed) { return Number.NaN; } return Number(trimmed); }); const expectedLength = fallbackSizes.length; const isValid = parsedSizes.length === expectedLength && parsedSizes.every((v) => Number.isFinite(v)); return isValid ? parsedSizes : fallbackSizes; }, [defaultSizesProp, initialSizes, savedSizesString]); const setDefaultSizePane = React.useCallback( (sizes: number[]) => { saveSizesStringDebounced(sizes.join(',')); }, [saveSizesStringDebounced], ); const onDragHandler = (sizes: number[]) => { const {onSplitDragAdditional} = props; if (onSplitDragAdditional) { onSplitDragAdditional(); } setDefaultSizePane(sizes); }; const onDragStartHandler = () => { const {onSplitStartDragAdditional} = props; if (onSplitStartDragAdditional) { onSplitStartDragAdditional(); } setInnerSizes(undefined); }; React.useEffect(() => { if (triggerCollapse) { const newSizes = collapsedSizes || minSizeDefaultInner; setDefaultSizePane(newSizes); setInnerSizes(newSizes); } }, [collapsedSizes, triggerCollapse, setDefaultSizePane]); React.useEffect(() => { const newSizes = defaultSizesProp || sizesDefaultInner; if (triggerExpand) { setDefaultSizePane(newSizes); setInnerSizes(newSizes); } }, [defaultSizesProp, triggerExpand, setDefaultSizePane]); return ( <React.Fragment> <SplitPaneLib direction={props.direction || 'horizontal'} sizes={sizesProp ?? innerSizes ?? defaultSizePane} minSize={props.minSize || [0, 0]} onDrag={onDragHandler} className={b(null, props.direction || 'horizontal')} gutterSize={gutterSize} gutterStyle={getGutterStyle} onDragStart={onDragStartHandler} expandToMin > {props.children} </SplitPaneLib> </React.Fragment> ); } export default SplitPane;